via82c686.c revision 65340
1/*
2 * Copyright (c) 2000 David Jones <dej@ox.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/sys/dev/sound/pci/via82c686.c 65340 2000-09-01 20:09:24Z cg $
27 */
28
29#include <dev/sound/pcm/sound.h>
30#include <dev/sound/pcm/ac97.h>
31
32#include <pci/pcireg.h>
33#include <pci/pcivar.h>
34#include <sys/sysctl.h>
35
36#include <dev/sound/pci/via82c686.h>
37
38#define VIA_PCI_ID 0x30581106
39#define	NSEGS		16	/* Number of segments in SGD table */
40
41#define SEGS_PER_CHAN	(NSEGS/2)
42
43#undef DEB
44#define DEB(x)
45
46struct via_info;
47
48struct via_chinfo {
49	struct via_info *parent;
50	pcm_channel *channel;
51	snd_dbuf *buffer;
52	int dir;
53};
54
55struct via_info {
56	bus_space_tag_t st;
57	bus_space_handle_t sh;
58	bus_dma_tag_t	parent_dmat;
59	bus_dma_tag_t	sgd_dmat;
60
61	struct via_chinfo pch, rch;
62	struct via_dma_op *sgd_table;
63	u_int16_t	codec_caps;
64};
65
66static u_int32_t via_rd(struct via_info *via, int regno, int size);
67static void via_wr(struct via_info *, int regno, u_int32_t data, int size);
68
69int via_waitready_codec(struct via_info *via);
70int via_waitvalid_codec(struct via_info *via);
71u_int32_t via_read_codec(void *addr, int reg);
72void via_write_codec(void *addr, int reg, u_int32_t val);
73
74static void via_intr(void *);
75bus_dmamap_callback_t dma_cb;
76
77
78/* channel interface */
79static void *viachan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir);
80static int viachan_setdir(void *data, int dir);
81static int viachan_setformat(void *data, u_int32_t format);
82static int viachan_setspeed(void *data, u_int32_t speed);
83static int viachan_setblocksize(void *data, u_int32_t blocksize);
84static int viachan_trigger(void *data, int go);
85static int viachan_getptr(void *data);
86static pcmchan_caps *viachan_getcaps(void *data);
87
88static u_int32_t via_playfmt[] = {
89	AFMT_U8,
90	AFMT_STEREO | AFMT_U8,
91	AFMT_S16_LE,
92	AFMT_STEREO | AFMT_S16_LE,
93	0
94};
95static pcmchan_caps via_playcaps = {4000, 48000, via_playfmt, 0};
96
97static u_int32_t via_recfmt[] = {
98	AFMT_U8,
99	AFMT_STEREO | AFMT_U8,
100	AFMT_S16_LE,
101	AFMT_STEREO | AFMT_S16_LE,
102	0
103};
104static pcmchan_caps via_reccaps = {4000, 48000, via_recfmt, 0};
105
106static pcm_channel via_chantemplate = {
107	viachan_init,
108	viachan_setdir,
109	viachan_setformat,
110	viachan_setspeed,
111	viachan_setblocksize,
112	viachan_trigger,
113	viachan_getptr,
114	viachan_getcaps,
115	NULL, 			/* free */
116	NULL, 			/* nop1 */
117	NULL, 			/* nop2 */
118	NULL, 			/* nop3 */
119	NULL, 			/* nop4 */
120	NULL, 			/* nop5 */
121	NULL, 			/* nop6 */
122	NULL, 			/* nop7 */
123};
124
125
126/*
127 *  Probe and attach the card
128 */
129static int
130via_probe(device_t dev)
131{
132	if (pci_get_devid(dev) == VIA_PCI_ID) {
133	    device_set_desc(dev, "VIA VT82C686A AC'97 Audio");
134	    return 0;
135	}
136	return ENXIO;
137}
138
139
140void dma_cb(void *p, bus_dma_segment_t *bds, int a, int b)
141{
142}
143
144
145static int
146via_attach(device_t dev)
147{
148	struct via_info *via = 0;
149	struct ac97_info *codec;
150	char		status[SND_STATUSLEN];
151
152	u_int32_t	data;
153	struct resource *reg = 0;
154	int		regid;
155	struct resource *irq = 0;
156	void		*ih = 0;
157	int		irqid;
158
159	u_int16_t	v;
160	bus_dmamap_t	sgd_dma_map;
161
162	if ((via = malloc(sizeof *via, M_DEVBUF, M_NOWAIT)) == NULL) {
163		device_printf(dev, "cannot allocate softc\n");
164		return ENXIO;
165	}
166	bzero(via, sizeof *via);
167
168	/* Get resources */
169	data = pci_read_config(dev, PCIR_COMMAND, 2);
170	data |= (PCIM_CMD_PORTEN | PCIM_CMD_BUSMASTEREN);
171	pci_write_config(dev, PCIR_COMMAND, data, 2);
172	data = pci_read_config(dev, PCIR_COMMAND, 2);
173
174	pci_write_config(dev, VIA_PCICONF_MISC,
175		VIA_PCICONF_ACLINKENAB | VIA_PCICONF_ACSGD |
176		VIA_PCICONF_ACNOTRST | VIA_PCICONF_ACVSR, 1);
177
178	regid = PCIR_MAPS;
179	reg = bus_alloc_resource(dev, SYS_RES_IOPORT, &regid,
180		0, ~0, 1, RF_ACTIVE);
181	if (!reg) {
182		device_printf(dev, "via: Cannot allocate bus resource.");
183		goto bad;
184	}
185	via->st = rman_get_bustag(reg);
186	via->sh = rman_get_bushandle(reg);
187
188	irqid = 0;
189	irq = bus_alloc_resource(dev, SYS_RES_IRQ, &irqid,
190		0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
191	if (!irq
192	    || bus_setup_intr(dev, irq, INTR_TYPE_TTY, via_intr, via, &ih)){
193		device_printf(dev, "unable to map interrupt\n");
194		goto bad;
195	}
196
197	via_wr(via, VIA_PLAY_MODE,
198		VIA_RPMODE_AUTOSTART |
199		VIA_RPMODE_INTR_FLAG | VIA_RPMODE_INTR_EOL, 1);
200	via_wr(via, VIA_RECORD_MODE,
201		VIA_RPMODE_AUTOSTART |
202		VIA_RPMODE_INTR_FLAG | VIA_RPMODE_INTR_EOL, 1);
203
204	codec = ac97_create(dev, via, NULL,
205		via_read_codec, via_write_codec);
206	if (!codec) goto bad;
207
208	mixer_init(dev, &ac97_mixer, codec);
209
210	/*
211	 *  The mixer init resets the codec.  So enabling VRA must be done
212	 *  afterwards.
213	 */
214	v = via_read_codec(via, AC97_REG_EXT_AUDIO_ID);
215	v &= (AC97_ENAB_VRA | AC97_ENAB_MICVRA);
216	via_write_codec(via, AC97_REG_EXT_AUDIO_STAT, v);
217	via->codec_caps = v;
218	{
219	v = via_read_codec(via, AC97_REG_EXT_AUDIO_STAT);
220	DEB(printf("init: codec stat: %d\n", v));
221	}
222
223	if (!(v & AC97_CODEC_DOES_VRA)) {
224		/* no VRA => can do only 48 kbps */
225		via_playcaps.minspeed = 48000;
226		via_reccaps.minspeed = 48000;
227	}
228
229	/* DMA tag for buffers */
230	if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
231		/*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
232		/*highaddr*/BUS_SPACE_MAXADDR,
233		/*filter*/NULL, /*filterarg*/NULL,
234		/*maxsize*/VIA_BUFFSIZE, /*nsegments*/1, /*maxsegz*/0x3ffff,
235		/*flags*/0, &via->parent_dmat) != 0) {
236		device_printf(dev, "unable to create dma tag\n");
237		goto bad;
238	}
239
240	/*
241	 *  DMA tag for SGD table.  The 686 uses scatter/gather DMA and
242	 *  requires a list in memory of work to do.  We need only 16 bytes
243	 *  for this list, and it is wasteful to allocate 16K.
244	 */
245	if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
246		/*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
247		/*highaddr*/BUS_SPACE_MAXADDR,
248		/*filter*/NULL, /*filterarg*/NULL,
249		/*maxsize*/NSEGS * sizeof(struct via_dma_op),
250		/*nsegments*/1, /*maxsegz*/0x3ffff,
251		/*flags*/0, &via->sgd_dmat) != 0) {
252		device_printf(dev, "unable to create dma tag\n");
253		goto bad;
254	}
255
256	if (bus_dmamem_alloc(via->sgd_dmat, (void **)&via->sgd_table,
257		BUS_DMA_NOWAIT, &sgd_dma_map) == -1) goto bad;
258	if (bus_dmamap_load(via->sgd_dmat, sgd_dma_map, via->sgd_table,
259		NSEGS * sizeof(struct via_dma_op), dma_cb, 0, 0)) goto bad;
260
261	snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld",
262		rman_get_start(reg), rman_get_start(irq));
263
264	/* Register */
265	if (pcm_register(dev, via, 1, 1)) goto bad;
266	pcm_addchan(dev, PCMDIR_PLAY, &via_chantemplate, via);
267	pcm_addchan(dev, PCMDIR_REC, &via_chantemplate, via);
268	pcm_setstatus(dev, status);
269	return 0;
270bad:
271	if (via) free(via, M_DEVBUF);
272	bus_release_resource(dev, SYS_RES_IOPORT, regid, reg);
273	if (ih) bus_teardown_intr(dev, irq, ih);
274	if (irq) bus_release_resource(dev, SYS_RES_IRQ, irqid, irq);
275	return ENXIO;
276}
277
278
279static device_method_t via_methods[] = {
280	DEVMETHOD(device_probe,		via_probe),
281	DEVMETHOD(device_attach,	via_attach),
282	{ 0, 0}
283};
284
285static driver_t via_driver = {
286	"pcm",
287	via_methods,
288	sizeof(snddev_info),
289};
290
291static devclass_t pcm_devclass;
292
293DRIVER_MODULE(via, pci, via_driver, pcm_devclass, 0, 0);
294MODULE_DEPEND(via, snd_pcm, PCM_MINVER, PCM_PREFVER, PCM_MAXVER);
295MODULE_VERSION(via, 1);
296
297
298static u_int32_t
299via_rd(struct via_info *via, int regno, int size)
300{
301
302	switch (size) {
303	case 1:
304		return bus_space_read_1(via->st, via->sh, regno);
305	case 2:
306		return bus_space_read_2(via->st, via->sh, regno);
307	case 4:
308		return bus_space_read_4(via->st, via->sh, regno);
309	default:
310		return 0xFFFFFFFF;
311	}
312}
313
314
315static void
316via_wr(struct via_info *via, int regno, u_int32_t data, int size)
317{
318
319	switch (size) {
320	case 1:
321		bus_space_write_1(via->st, via->sh, regno, data);
322		break;
323	case 2:
324		bus_space_write_2(via->st, via->sh, regno, data);
325		break;
326	case 4:
327		bus_space_write_4(via->st, via->sh, regno, data);
328		break;
329	}
330}
331
332
333/* Codec interface */
334int
335via_waitready_codec(struct via_info *via)
336{
337	int i;
338
339	/* poll until codec not busy */
340	for (i = 0; (i < TIMEOUT) &&
341	    (via_rd(via, VIA_CODEC_CTL, 4) & VIA_CODEC_BUSY); i++)
342		DELAY(1);
343	if (i >= TIMEOUT) {
344		printf("via: codec busy\n");
345		return 1;
346	}
347
348	return 0;
349}
350
351
352int
353via_waitvalid_codec(struct via_info *via)
354{
355	int i;
356
357	/* poll until codec valid */
358	for (i = 0; (i < TIMEOUT) &&
359	    !(via_rd(via, VIA_CODEC_CTL, 4) & VIA_CODEC_PRIVALID); i++)
360		    DELAY(1);
361	if (i >= TIMEOUT) {
362		printf("via: codec invalid\n");
363		return 1;
364	}
365
366	return 0;
367}
368
369
370void
371via_write_codec(void *addr, int reg, u_int32_t val)
372{
373	struct via_info *via = addr;
374
375	if (via_waitready_codec(via)) return;
376
377	via_wr(via, VIA_CODEC_CTL,
378		VIA_CODEC_PRIVALID | VIA_CODEC_INDEX(reg) | val, 4);
379}
380
381
382u_int32_t
383via_read_codec(void *addr, int reg)
384{
385	struct via_info *via = addr;
386
387	if (via_waitready_codec(via))
388		return 1;
389
390	via_wr(via, VIA_CODEC_CTL,
391	    VIA_CODEC_PRIVALID | VIA_CODEC_READ | VIA_CODEC_INDEX(reg),4);
392
393	if (via_waitready_codec(via))
394		return 1;
395
396	if (via_waitvalid_codec(via))
397		return 1;
398
399	return via_rd(via, VIA_CODEC_CTL, 2);
400}
401
402
403/* channel interface */
404static void *
405viachan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
406{
407	struct via_info *via = devinfo;
408	struct via_chinfo *ch = (dir == PCMDIR_PLAY) ? &via->pch : &via->rch;
409
410	ch->parent = via;
411	ch->channel = c;
412	ch->buffer = b;
413	b->bufsize = VIA_BUFFSIZE;
414
415	if (chn_allocbuf(ch->buffer, via->parent_dmat) == -1) return NULL;
416	return ch;
417}
418
419static int
420viachan_setdir(void *data, int dir)
421{
422	struct via_chinfo *ch = data;
423	struct via_info *via = ch->parent;
424	struct via_dma_op *ado;
425	int i, chunk_size;
426	int	phys_addr, flag;
427
428	ch->dir = dir;
429	/*
430	 *  Build the scatter/gather DMA (SGD) table.
431	 *  There are four slots in the table: two for play, two for record.
432	 *  This creates two half-buffers, one of which is playing; the other
433	 *  is feeding.
434	 */
435	ado = via->sgd_table;
436	chunk_size = ch->buffer->bufsize / SEGS_PER_CHAN;
437
438	if (dir == PCMDIR_REC) {
439		ado += SEGS_PER_CHAN;
440	}
441
442DEB(printf("SGD table located at va %p\n", ado));
443	phys_addr = vtophys(ch->buffer->buf);
444	for (i = 0; i < SEGS_PER_CHAN; i++) {
445		ado->ptr = phys_addr;
446		flag = (i == SEGS_PER_CHAN-1) ?
447			VIA_DMAOP_EOL : VIA_DMAOP_FLAG;
448		ado->flags = flag | chunk_size;
449DEB(printf("ado->ptr/flags = %x/%x\n", phys_addr, flag));
450		phys_addr += chunk_size;
451		ado++;
452	}
453	return 0;
454}
455
456static int
457viachan_setformat(void *data, u_int32_t format)
458{
459	struct via_chinfo *ch = data;
460	struct via_info *via = ch->parent;
461	int	mode, mode_set;
462
463	mode_set = 0;
464	if (format & AFMT_STEREO)
465		mode_set |= VIA_RPMODE_STEREO;
466	if (format & AFMT_S16_LE)
467		mode_set |= VIA_RPMODE_16BIT;
468
469	/* Set up for output format */
470	if (ch->dir == PCMDIR_PLAY) {
471DEB(printf("set play format: %x\n", format));
472		mode = via_rd(via, VIA_PLAY_MODE, 1);
473		mode &= ~(VIA_RPMODE_16BIT | VIA_RPMODE_STEREO);
474		mode |= mode_set;
475		via_wr(via, VIA_PLAY_MODE, mode, 1);
476	}
477	else {
478DEB(printf("set record format: %x\n", format));
479		mode = via_rd(via, VIA_RECORD_MODE, 1);
480		mode &= ~(VIA_RPMODE_16BIT | VIA_RPMODE_STEREO);
481		mode |= mode_set;
482		via_wr(via, VIA_RECORD_MODE, mode, 1);
483	}
484
485	return 0;
486}
487
488static int
489viachan_setspeed(void *data, u_int32_t speed)
490{
491	struct via_chinfo *ch = data;
492	struct via_info *via = ch->parent;
493
494	/*
495	 *  Basic AC'97 defines a 48 kHz sample rate only.  For other rates,
496	 *  upsampling is required.
497	 *
498	 *  The VT82C686A does not perform upsampling, and neither do we.
499	 *  If the codec supports variable-rate audio (i.e. does the upsampling
500	 *  itself), then negotiate the rate with the codec.  Otherwise,
501	 *  return 48 kHz cuz that's all you got.
502	 */
503	if (ch->dir == PCMDIR_PLAY) {
504DEB(printf("requested play speed: %d\n", speed));
505		if (via->codec_caps & AC97_CODEC_DOES_VRA) {
506			via_write_codec(via, AC97_REG_EXT_DAC_RATE, speed);
507			speed = via_read_codec(via, AC97_REG_EXT_DAC_RATE);
508		}
509		else {
510DEB(printf("VRA not supported!\n"));
511			speed = 48000;
512		}
513DEB(printf("obtained play speed: %d\n", speed));
514	}
515	else {
516DEB(printf("requested record speed: %d\n", speed));
517		if (via->codec_caps & AC97_CODEC_DOES_VRA) {
518			via_write_codec(via, AC97_REG_EXT_ADC_RATE, speed);
519			speed = via_read_codec(via, AC97_REG_EXT_ADC_RATE);
520		}
521		else {
522DEB(printf("VRA not supported!\n"));
523			speed = 48000;
524		}
525DEB(printf("obtained record speed: %d\n", speed));
526	}
527	return speed;
528}
529
530static int
531viachan_setblocksize(void *data, u_int32_t blocksize)
532{
533	struct via_chinfo *ch = data;
534
535	return ch->buffer->bufsize / 2;
536}
537
538static int
539viachan_trigger(void *data, int go)
540{
541	struct via_chinfo *ch = data;
542	struct via_info *via = ch->parent;
543	struct via_dma_op *ado;
544
545	if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) return 0;
546	if (ch->dir == PCMDIR_PLAY) {
547		if (go == PCMTRIG_START) {
548			ado = &via->sgd_table[0];
549DEB(printf("ado located at va=%p pa=%x\n", ado, vtophys(ado)));
550			via_wr(via, VIA_PLAY_DMAOPS_BASE, vtophys(ado),4);
551			via_wr(via, VIA_PLAY_CONTROL,
552				VIA_RPCTRL_START, 1);
553		}
554		else {
555			/* Stop DMA */
556			via_wr(via, VIA_PLAY_CONTROL,
557				VIA_RPCTRL_TERMINATE, 1);
558		}
559	} else {
560		if (go == PCMTRIG_START) {
561			ado = &via->sgd_table[SEGS_PER_CHAN];
562DEB(printf("ado located at va=%p pa=%x\n", ado, vtophys(ado)));
563			via_wr(via, VIA_RECORD_DMAOPS_BASE,
564				vtophys(ado),4);
565			via_wr(via, VIA_RECORD_CONTROL,
566				VIA_RPCTRL_START, 1);
567		}
568		else {
569			/* Stop DMA */
570			via_wr(via, VIA_RECORD_CONTROL,
571				VIA_RPCTRL_TERMINATE, 1);
572		}
573	}
574
575DEB(printf("viachan_trigger: go=%d\n", go));
576	return 0;
577}
578
579static int
580viachan_getptr(void *data)
581{
582	struct via_chinfo *ch = data;
583	struct via_info *via = ch->parent;
584	struct via_dma_op *ado;
585	int	ptr, base, len, seg;
586	int base1;
587
588	if (ch->dir == PCMDIR_PLAY) {
589		ado = &via->sgd_table[0];
590		base1 = via_rd(via, VIA_PLAY_DMAOPS_BASE, 4);
591		len = via_rd(via, VIA_PLAY_DMAOPS_COUNT, 4);
592		base = via_rd(via, VIA_PLAY_DMAOPS_BASE, 4);
593		if (base != base1) {	/* Avoid race hazzard	*/
594			len = via_rd(via, VIA_PLAY_DMAOPS_COUNT, 4);
595		}
596DEB(printf("viachan_getptr: len / base = %x / %x\n", len, base));
597
598		/* Base points to SGD segment to do, one past current */
599
600		/* Determine how many segments have been done */
601		seg = (base - vtophys(ado)) / sizeof(struct via_dma_op);
602		if (seg == 0) seg = SEGS_PER_CHAN;
603
604		/* Now work out offset: seg less count */
605		ptr = seg * ch->buffer->bufsize / SEGS_PER_CHAN - len;
606DEB(printf("return ptr=%d\n", ptr));
607		return ptr;
608	}
609	else {
610		base1 = via_rd(via, VIA_RECORD_DMAOPS_BASE, 4);
611		ado = &via->sgd_table[SEGS_PER_CHAN];
612		len = via_rd(via, VIA_RECORD_DMAOPS_COUNT, 4);
613		base = via_rd(via, VIA_RECORD_DMAOPS_BASE, 4);
614		if (base != base1) {	/* Avoid race hazzard	*/
615			len = via_rd(via, VIA_RECORD_DMAOPS_COUNT, 4);
616		}
617DEB(printf("viachan_getptr: len / base = %x / %x\n", len, base));
618
619		/* Base points to next block to do, one past current */
620
621		/* Determine how many segments have been done */
622		seg = (base - vtophys(ado)) / sizeof(struct via_dma_op);
623		if (seg == 0) seg = SEGS_PER_CHAN;
624
625		/* Now work out offset: seg less count */
626		ptr = seg * ch->buffer->bufsize / SEGS_PER_CHAN - len;
627
628		/* DMA appears to operate on memory 'lines' of 32 bytes	*/
629		/* so don't return any part line - it isn't in RAM yet	*/
630		ptr = ptr & ~0x1f;
631DEB(printf("return ptr=%d\n", ptr));
632		return ptr;
633	}
634	return 0;
635}
636
637static pcmchan_caps *
638viachan_getcaps(void *data)
639{
640	struct via_chinfo *ch = data;
641	return (ch->dir == PCMDIR_PLAY) ? &via_playcaps : &via_reccaps;
642}
643
644static void
645via_intr(void *p)
646{
647	struct via_info *via = p;
648	int		st;
649
650DEB(printf("viachan_intr\n"));
651	/* Read channel */
652	st = via_rd(via, VIA_PLAY_STAT, 1);
653	if (st & VIA_RPSTAT_INTR) {
654		via_wr(via, VIA_PLAY_STAT, VIA_RPSTAT_INTR, 1);
655		chn_intr(via->pch.channel);
656	}
657
658	/* Write channel */
659	st = via_rd(via, VIA_RECORD_STAT, 1);
660	if (st & VIA_RPSTAT_INTR) {
661		via_wr(via, VIA_RECORD_STAT, VIA_RPSTAT_INTR, 1);
662		chn_intr(via->rch.channel);
663	}
664}
665
666
667