xref: /openbsd/sys/dev/pci/cmpci.c (revision 37ecb596)
1 /*	$OpenBSD: cmpci.c,v 1.36 2013/12/06 21:03:03 deraadt Exp $	*/
2 /*	$NetBSD: cmpci.c,v 1.25 2004/10/26 06:32:20 xtraeme Exp $	*/
3 
4 /*
5  * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to The NetBSD Foundation
9  * by Takuya SHIOZAKI <tshiozak@NetBSD.org> .
10  *
11  * This code is derived from software contributed to The NetBSD Foundation
12  * by ITOH Yasufumi.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions
16  * are met:
17  * 1. Redistributions of source code must retain the above copyright
18  *    notice, this list of conditions and the following disclaimer.
19  * 2. Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in the
21  *    documentation and/or other materials provided with the distribution.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  */
36 
37 /*
38  * C-Media CMI8x38, CMI8768 Audio Chip Support.
39  *
40  * TODO:
41  *   - Joystick support.
42  *
43  */
44 
45 #if defined(AUDIO_DEBUG) || defined(DEBUG)
46 #define DPRINTF(x) if (cmpcidebug) printf x
47 int cmpcidebug = 0;
48 #else
49 #define DPRINTF(x)
50 #endif
51 
52 #include <sys/param.h>
53 #include <sys/systm.h>
54 #include <sys/kernel.h>
55 #include <sys/malloc.h>
56 #include <sys/device.h>
57 
58 #include <dev/pci/pcidevs.h>
59 #include <dev/pci/pcivar.h>
60 
61 #include <sys/audioio.h>
62 #include <dev/audio_if.h>
63 #include <dev/midi_if.h>
64 
65 #include <dev/mulaw.h>
66 #include <dev/auconv.h>
67 #include <dev/pci/cmpcireg.h>
68 #include <dev/pci/cmpcivar.h>
69 
70 #include <dev/ic/mpuvar.h>
71 #include <machine/bus.h>
72 #include <machine/intr.h>
73 
74 /*
75  * Low-level HW interface
76  */
77 uint8_t cmpci_mixerreg_read(struct cmpci_softc *, uint8_t);
78 void cmpci_mixerreg_write(struct cmpci_softc *, uint8_t, uint8_t);
79 void cmpci_reg_partial_write_1(struct cmpci_softc *, int, int,
80 						    unsigned, unsigned);
81 void cmpci_reg_partial_write_4(struct cmpci_softc *, int, int,
82 						    uint32_t, uint32_t);
83 void cmpci_reg_set_1(struct cmpci_softc *, int, uint8_t);
84 void cmpci_reg_clear_1(struct cmpci_softc *, int, uint8_t);
85 void cmpci_reg_set_4(struct cmpci_softc *, int, uint32_t);
86 void cmpci_reg_clear_4(struct cmpci_softc *, int, uint32_t);
87 void cmpci_reg_set_reg_misc(struct cmpci_softc *, uint32_t);
88 void cmpci_reg_clear_reg_misc(struct cmpci_softc *, uint32_t);
89 int cmpci_rate_to_index(int);
90 int cmpci_index_to_rate(int);
91 int cmpci_index_to_divider(int);
92 
93 int cmpci_adjust(int, int);
94 void cmpci_set_mixer_gain(struct cmpci_softc *, int);
95 void cmpci_set_out_ports(struct cmpci_softc *);
96 int cmpci_set_in_ports(struct cmpci_softc *);
97 
98 int cmpci_resume(struct cmpci_softc *);
99 
100 /*
101  * autoconf interface
102  */
103 int cmpci_match(struct device *, void *, void *);
104 void cmpci_attach(struct device *, struct device *, void *);
105 int cmpci_activate(struct device *, int);
106 
107 struct cfdriver cmpci_cd = {
108 	NULL, "cmpci", DV_DULL
109 };
110 
111 struct cfattach cmpci_ca = {
112 	sizeof (struct cmpci_softc), cmpci_match, cmpci_attach, NULL,
113 	cmpci_activate
114 };
115 
116 /* interrupt */
117 int cmpci_intr(void *);
118 
119 /*
120  * DMA stuff
121  */
122 int cmpci_alloc_dmamem(struct cmpci_softc *,
123 				   size_t, int,
124 				   int, caddr_t *);
125 int cmpci_free_dmamem(struct cmpci_softc *, caddr_t,
126 				  int);
127 struct cmpci_dmanode * cmpci_find_dmamem(struct cmpci_softc *,
128 						     caddr_t);
129 
130 /*
131  * Interface to machine independent layer
132  */
133 int cmpci_open(void *, int);
134 void cmpci_close(void *);
135 int cmpci_query_encoding(void *, struct audio_encoding *);
136 int cmpci_set_params(void *, int, int,
137 				 struct audio_params *,
138 				 struct audio_params *);
139 void cmpci_get_default_params(void *, int, struct audio_params*);
140 int cmpci_round_blocksize(void *, int);
141 int cmpci_halt_output(void *);
142 int cmpci_halt_input(void *);
143 int cmpci_getdev(void *, struct audio_device *);
144 int cmpci_set_port(void *, mixer_ctrl_t *);
145 int cmpci_get_port(void *, mixer_ctrl_t *);
146 int cmpci_query_devinfo(void *, mixer_devinfo_t *);
147 void *cmpci_malloc(void *, int, size_t, int, int);
148 void cmpci_free(void *, void *, int);
149 size_t cmpci_round_buffersize(void *, int, size_t);
150 paddr_t cmpci_mappage(void *, void *, off_t, int);
151 int cmpci_get_props(void *);
152 int cmpci_trigger_output(void *, void *, void *, int,
153 				     void (*)(void *), void *,
154 				     struct audio_params *);
155 int cmpci_trigger_input(void *, void *, void *, int,
156 				    void (*)(void *), void *,
157 				    struct audio_params *);
158 
159 struct audio_hw_if cmpci_hw_if = {
160 	cmpci_open,		/* open */
161 	cmpci_close,		/* close */
162 	NULL,			/* drain */
163 	cmpci_query_encoding,	/* query_encoding */
164 	cmpci_set_params,	/* set_params */
165 	cmpci_round_blocksize,	/* round_blocksize */
166 	NULL,			/* commit_settings */
167 	NULL,			/* init_output */
168 	NULL,			/* init_input */
169 	NULL,			/* start_output */
170 	NULL,			/* start_input */
171 	cmpci_halt_output,	/* halt_output */
172 	cmpci_halt_input,	/* halt_input */
173 	NULL,			/* speaker_ctl */
174 	cmpci_getdev,		/* getdev */
175 	NULL,			/* setfd */
176 	cmpci_set_port,		/* set_port */
177 	cmpci_get_port,		/* get_port */
178 	cmpci_query_devinfo,	/* query_devinfo */
179 	cmpci_malloc,		/* malloc */
180 	cmpci_free,		/* free */
181 	cmpci_round_buffersize,/* round_buffersize */
182 	cmpci_mappage,		/* mappage */
183 	cmpci_get_props,	/* get_props */
184 	cmpci_trigger_output,	/* trigger_output */
185 	cmpci_trigger_input,	/* trigger_input */
186 	cmpci_get_default_params
187 };
188 
189 /*
190  * Low-level HW interface
191  */
192 
193 /* mixer register read/write */
194 uint8_t
195 cmpci_mixerreg_read(struct cmpci_softc *sc, uint8_t no)
196 {
197 	uint8_t ret;
198 
199 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, CMPCI_REG_SBADDR, no);
200 	delay(10);
201 	ret = bus_space_read_1(sc->sc_iot, sc->sc_ioh, CMPCI_REG_SBDATA);
202 	delay(10);
203 	return ret;
204 }
205 
206 void
207 cmpci_mixerreg_write(struct cmpci_softc *sc, uint8_t no, uint8_t val)
208 {
209 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, CMPCI_REG_SBADDR, no);
210 	delay(10);
211 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, CMPCI_REG_SBDATA, val);
212 	delay(10);
213 }
214 
215 /* register partial write */
216 void
217 cmpci_reg_partial_write_1(struct cmpci_softc *sc, int no, int shift,
218     unsigned mask, unsigned val)
219 {
220 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, no,
221 	    (val<<shift) |
222 	    (bus_space_read_1(sc->sc_iot, sc->sc_ioh, no) & ~(mask<<shift)));
223 	delay(10);
224 }
225 
226 void
227 cmpci_reg_partial_write_4(struct cmpci_softc *sc, int no, int shift,
228     uint32_t mask, uint32_t val)
229 {
230 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, no,
231 	    (val<<shift) |
232 	    (bus_space_read_4(sc->sc_iot, sc->sc_ioh, no) & ~(mask<<shift)));
233 	delay(10);
234 }
235 
236 /* register set/clear bit */
237 void
238 cmpci_reg_set_1(struct cmpci_softc *sc, int no, uint8_t mask)
239 {
240 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, no,
241 	    (bus_space_read_1(sc->sc_iot, sc->sc_ioh, no) | mask));
242 	delay(10);
243 }
244 
245 void
246 cmpci_reg_clear_1(struct cmpci_softc *sc, int no, uint8_t mask)
247 {
248 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, no,
249 	    (bus_space_read_1(sc->sc_iot, sc->sc_ioh, no) & ~mask));
250 	delay(10);
251 }
252 
253 void
254 cmpci_reg_set_4(struct cmpci_softc *sc, int no, uint32_t mask)
255 {
256 	/* use cmpci_reg_set_reg_misc() for CMPCI_REG_MISC */
257 	KDASSERT(no != CMPCI_REG_MISC);
258 
259 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, no,
260 	    (bus_space_read_4(sc->sc_iot, sc->sc_ioh, no) | mask));
261 	delay(10);
262 }
263 
264 void
265 cmpci_reg_clear_4(struct cmpci_softc *sc, int no, uint32_t mask)
266 {
267 	/* use cmpci_reg_clear_reg_misc() for CMPCI_REG_MISC */
268 	KDASSERT(no != CMPCI_REG_MISC);
269 
270 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, no,
271 	    (bus_space_read_4(sc->sc_iot, sc->sc_ioh, no) & ~mask));
272 	delay(10);
273 }
274 
275 /*
276  * The CMPCI_REG_MISC register needs special handling, since one of
277  * its bits has different read/write values.
278  */
279 void
280 cmpci_reg_set_reg_misc(struct cmpci_softc *sc, uint32_t mask)
281 {
282 	sc->sc_reg_misc |= mask;
283 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, CMPCI_REG_MISC,
284 	    sc->sc_reg_misc);
285 	delay(10);
286 }
287 
288 void
289 cmpci_reg_clear_reg_misc(struct cmpci_softc *sc, uint32_t mask)
290 {
291 	sc->sc_reg_misc &= ~mask;
292 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, CMPCI_REG_MISC,
293 	    sc->sc_reg_misc);
294 	delay(10);
295 }
296 
297 /* rate */
298 static const struct {
299 	int rate;
300 	int divider;
301 } cmpci_rate_table[CMPCI_REG_NUMRATE] = {
302 #define _RATE(n) { n, CMPCI_REG_RATE_ ## n }
303 	_RATE(5512),
304 	_RATE(8000),
305 	_RATE(11025),
306 	_RATE(16000),
307 	_RATE(22050),
308 	_RATE(32000),
309 	_RATE(44100),
310 	_RATE(48000)
311 #undef	_RATE
312 };
313 
314 int
315 cmpci_rate_to_index(int rate)
316 {
317 	int i;
318 
319 	for (i = 0; i < CMPCI_REG_NUMRATE - 1; i++)
320 		if (rate <=
321 		    (cmpci_rate_table[i].rate + cmpci_rate_table[i+1].rate) / 2)
322 			return i;
323 	return i;  /* 48000 */
324 }
325 
326 int
327 cmpci_index_to_rate(int index)
328 {
329 	return cmpci_rate_table[index].rate;
330 }
331 
332 int
333 cmpci_index_to_divider(int index)
334 {
335 	return cmpci_rate_table[index].divider;
336 }
337 
338 const struct pci_matchid cmpci_devices[] = {
339 	{ PCI_VENDOR_CMI, PCI_PRODUCT_CMI_CMI8338A },
340 	{ PCI_VENDOR_CMI, PCI_PRODUCT_CMI_CMI8338B },
341 	{ PCI_VENDOR_CMI, PCI_PRODUCT_CMI_CMI8738 },
342 	{ PCI_VENDOR_CMI, PCI_PRODUCT_CMI_CMI8738B }
343 };
344 
345 /*
346  * interface to configure the device.
347  */
348 
349 int
350 cmpci_match(struct device *parent, void *match, void *aux)
351 {
352 	return (pci_matchbyid((struct pci_attach_args *)aux, cmpci_devices,
353 	    nitems(cmpci_devices)));
354 }
355 
356 void
357 cmpci_attach(struct device *parent, struct device *self, void *aux)
358 {
359 	struct cmpci_softc *sc = (struct cmpci_softc *)self;
360 	struct pci_attach_args *pa = (struct pci_attach_args *)aux;
361 	struct audio_attach_args aa;
362 	pci_intr_handle_t ih;
363 	char const *intrstr;
364 	int i, v, d;
365 
366 	sc->sc_id = pa->pa_id;
367 	sc->sc_class = pa->pa_class;
368 	switch (PCI_PRODUCT(sc->sc_id)) {
369 	case PCI_PRODUCT_CMI_CMI8338A:
370 		/*FALLTHROUGH*/
371 	case PCI_PRODUCT_CMI_CMI8338B:
372 		sc->sc_capable = CMPCI_CAP_CMI8338;
373 		break;
374 	case PCI_PRODUCT_CMI_CMI8738:
375 		/*FALLTHROUGH*/
376 	case PCI_PRODUCT_CMI_CMI8738B:
377 		sc->sc_capable = CMPCI_CAP_CMI8738;
378 		break;
379 	}
380 
381 	/* map I/O space */
382 	if (pci_mapreg_map(pa, CMPCI_PCI_IOBASEREG, PCI_MAPREG_TYPE_IO, 0,
383 			   &sc->sc_iot, &sc->sc_ioh, NULL, NULL, 0)) {
384 		printf(": can't map i/o space\n");
385 		return;
386 	}
387 
388 	/* interrupt */
389 	if (pci_intr_map(pa, &ih)) {
390 		printf(": can't map interrupt\n");
391 		return;
392 	}
393 	intrstr = pci_intr_string(pa->pa_pc, ih);
394 	sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_AUDIO | IPL_MPSAFE,
395 	    cmpci_intr, sc, sc->sc_dev.dv_xname);
396 	if (sc->sc_ih == NULL) {
397 		printf(": can't establish interrupt");
398 		if (intrstr != NULL)
399 			printf(" at %s", intrstr);
400 		printf("\n");
401 		return;
402 	}
403 	printf(": %s\n", intrstr);
404 
405 	sc->sc_dmat = pa->pa_dmat;
406 
407 	audio_attach_mi(&cmpci_hw_if, sc, &sc->sc_dev);
408 
409 	/* attach OPL device */
410 	aa.type = AUDIODEV_TYPE_OPL;
411 	aa.hwif = NULL;
412 	aa.hdl = NULL;
413 	(void)config_found(&sc->sc_dev, &aa, audioprint);
414 
415 	/* attach MPU-401 device */
416 	aa.type = AUDIODEV_TYPE_MPU;
417 	aa.hwif = NULL;
418 	aa.hdl = NULL;
419 	if (bus_space_subregion(sc->sc_iot, sc->sc_ioh,
420 	    CMPCI_REG_MPU_BASE, CMPCI_REG_MPU_SIZE, &sc->sc_mpu_ioh) == 0)
421 		sc->sc_mpudev = config_found(&sc->sc_dev, &aa, audioprint);
422 
423 	/* get initial value (this is 0 and may be omitted but just in case) */
424 	sc->sc_reg_misc = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
425 	    CMPCI_REG_MISC) & ~CMPCI_REG_SPDIF48K;
426 
427 	/* extra capabilitites check */
428 	d = bus_space_read_4(sc->sc_iot, sc->sc_ioh, CMPCI_REG_INTR_CTRL) &
429 	    CMPCI_REG_CHIP_MASK2;
430 	if (d) {
431 		if (d & CMPCI_REG_CHIP_8768) {
432 			sc->sc_version = 68;
433 			sc->sc_capable |= CMPCI_CAP_4CH | CMPCI_CAP_6CH |
434 			    CMPCI_CAP_8CH;
435 		} else if (d & CMPCI_REG_CHIP_055) {
436 			sc->sc_version = 55;
437 			sc->sc_capable |= CMPCI_CAP_4CH | CMPCI_CAP_6CH;
438 		} else if (d & CMPCI_REG_CHIP_039) {
439 			sc->sc_version = 39;
440 			sc->sc_capable |= CMPCI_CAP_4CH |
441 			    ((d & CMPCI_REG_CHIP_039_6CH) ? CMPCI_CAP_6CH : 0);
442 		} else {
443 			/* unknown version */
444 			sc->sc_version = 0;
445 		}
446 	} else {
447 		d = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
448 		    CMPCI_REG_CHANNEL_FORMAT) & CMPCI_REG_CHIP_MASK1;
449 		if (d)
450 			sc->sc_version = 37;
451 		else
452 			sc->sc_version = 33;
453 	}
454 
455 	cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_RESET, 0);
456 	cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_L, 0);
457 	cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_R, 0);
458 	cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_OUTMIX,
459 	    CMPCI_SB16_SW_CD|CMPCI_SB16_SW_MIC|CMPCI_SB16_SW_LINE);
460 	for (i = 0; i < CMPCI_NDEVS; i++) {
461 		switch(i) {
462 		/*
463 		 * CMI8738 defaults are
464 		 *  master:	0xe0	(0x00 - 0xf8)
465 		 *  FM, DAC:	0xc0	(0x00 - 0xf8)
466 		 *  PC speaker:	0x80	(0x00 - 0xc0)
467 		 *  others:	0
468 		 */
469 		/* volume */
470 		case CMPCI_MASTER_VOL:
471 			v = 128;	/* 224 */
472 			break;
473 		case CMPCI_FM_VOL:
474 		case CMPCI_DAC_VOL:
475 			v = 192;
476 			break;
477 		case CMPCI_PCSPEAKER:
478 			v = 128;
479 			break;
480 
481 		/* booleans, set to true */
482 		case CMPCI_CD_MUTE:
483 		case CMPCI_MIC_MUTE:
484 		case CMPCI_LINE_IN_MUTE:
485 		case CMPCI_AUX_IN_MUTE:
486 			v = 1;
487 			break;
488 
489 		/* volume with inital value 0 */
490 		case CMPCI_CD_VOL:
491 		case CMPCI_LINE_IN_VOL:
492 		case CMPCI_AUX_IN_VOL:
493 		case CMPCI_MIC_VOL:
494 		case CMPCI_MIC_RECVOL:
495 			/* FALLTHROUGH */
496 
497 		/* others are cleared */
498 		case CMPCI_MIC_PREAMP:
499 		case CMPCI_RECORD_SOURCE:
500 		case CMPCI_PLAYBACK_MODE:
501 		case CMPCI_SPDIF_IN_SELECT:
502 		case CMPCI_SPDIF_IN_PHASE:
503 		case CMPCI_SPDIF_LOOP:
504 		case CMPCI_SPDIF_OUT_PLAYBACK:
505 		case CMPCI_SPDIF_OUT_VOLTAGE:
506 		case CMPCI_MONITOR_DAC:
507 		case CMPCI_REAR:
508 		case CMPCI_INDIVIDUAL:
509 		case CMPCI_REVERSE:
510 		case CMPCI_SURROUND:
511 		default:
512 			v = 0;
513 			break;
514 		}
515 		sc->sc_gain[i][CMPCI_LEFT] = sc->sc_gain[i][CMPCI_RIGHT] = v;
516 		cmpci_set_mixer_gain(sc, i);
517 	}
518 
519 	sc->sc_play_channel = 0;
520 }
521 
522 int
523 cmpci_activate(struct device *self, int act)
524 {
525 	struct cmpci_softc *sc = (struct cmpci_softc *)self;
526 	int rv = 0;
527 
528 	switch (act) {
529 	case DVACT_RESUME:
530 		cmpci_resume(sc);
531 		rv = config_activate_children(self, act);
532 		break;
533 	default:
534 		rv = config_activate_children(self, act);
535 		break;
536 	}
537 	return (rv);
538 }
539 
540 int
541 cmpci_resume(struct cmpci_softc *sc)
542 {
543 	int i;
544 
545 	cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_RESET, 0);
546 	for (i = 0; i < CMPCI_NDEVS; i++)
547 		cmpci_set_mixer_gain(sc, i);
548 
549 	return 0;
550 }
551 
552 int
553 cmpci_intr(void *handle)
554 {
555 	struct cmpci_softc *sc = handle;
556 	struct cmpci_channel *chan;
557 	uint32_t intrstat;
558 	uint16_t hwpos;
559 
560 	mtx_enter(&audio_lock);
561 	intrstat = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
562 	    CMPCI_REG_INTR_STATUS);
563 
564 	if (!(intrstat & CMPCI_REG_ANY_INTR)) {
565 		mtx_leave(&audio_lock);
566 		return 0;
567 	}
568 
569 	delay(10);
570 
571 	/* disable and reset intr */
572 	if (intrstat & CMPCI_REG_CH0_INTR)
573 		cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL,
574 		   CMPCI_REG_CH0_INTR_ENABLE);
575 	if (intrstat & CMPCI_REG_CH1_INTR)
576 		cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL,
577 		    CMPCI_REG_CH1_INTR_ENABLE);
578 
579 	if (intrstat & CMPCI_REG_CH0_INTR) {
580 		chan = &sc->sc_ch0;
581 		if (chan->intr != NULL) {
582 			hwpos = bus_space_read_2(sc->sc_iot, sc->sc_ioh,
583 			    CMPCI_REG_DMA0_BYTES);
584 			hwpos = hwpos * chan->bps / chan->blksize;
585 			hwpos = chan->nblocks - hwpos - 1;
586 			while (chan->swpos != hwpos) {
587 				(*chan->intr)(chan->intr_arg);
588 				chan->swpos++;
589 				if (chan->swpos >= chan->nblocks)
590 					chan->swpos = 0;
591 				if (chan->swpos != hwpos) {
592 					DPRINTF(("%s: DMA0 hwpos=%d swpos=%d\n",
593 					    __func__, hwpos, chan->swpos));
594 				}
595 			}
596 		}
597 	}
598 	if (intrstat & CMPCI_REG_CH1_INTR) {
599 		chan = &sc->sc_ch1;
600 		if (chan->intr != NULL) {
601 			hwpos = bus_space_read_2(sc->sc_iot, sc->sc_ioh,
602 			    CMPCI_REG_DMA1_BYTES);
603 			hwpos = hwpos * chan->bps / chan->blksize;
604 			hwpos = chan->nblocks - hwpos - 1;
605 			while (chan->swpos != hwpos) {
606 				(*chan->intr)(chan->intr_arg);
607 				chan->swpos++;
608 				if (chan->swpos >= chan->nblocks)
609 					chan->swpos = 0;
610 				if (chan->swpos != hwpos) {
611 					DPRINTF(("%s: DMA1 hwpos=%d swpos=%d\n",
612 					    __func__, hwpos, chan->swpos));
613 				}
614 			}
615 		}
616 	}
617 
618 	/* enable intr */
619 	if (intrstat & CMPCI_REG_CH0_INTR)
620 		cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL,
621 		    CMPCI_REG_CH0_INTR_ENABLE);
622 	if (intrstat & CMPCI_REG_CH1_INTR)
623 		cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL,
624 		    CMPCI_REG_CH1_INTR_ENABLE);
625 
626 #if 0
627 	if (intrstat & CMPCI_REG_UART_INTR && sc->sc_mpudev != NULL)
628 		mpu_intr(sc->sc_mpudev);
629 #endif
630 
631 	mtx_leave(&audio_lock);
632 	return 1;
633 }
634 
635 /* open/close */
636 int
637 cmpci_open(void *handle, int flags)
638 {
639 	return 0;
640 }
641 
642 void
643 cmpci_close(void *handle)
644 {
645 }
646 
647 int
648 cmpci_query_encoding(void *handle, struct audio_encoding *fp)
649 {
650 	switch (fp->index) {
651 	case 0:
652 		strlcpy(fp->name, AudioEulinear, sizeof fp->name);
653 		fp->encoding = AUDIO_ENCODING_ULINEAR;
654 		fp->precision = 8;
655 		fp->flags = 0;
656 		break;
657 	case 1:
658 		strlcpy(fp->name, AudioEmulaw, sizeof fp->name);
659 		fp->encoding = AUDIO_ENCODING_ULAW;
660 		fp->precision = 8;
661 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
662 		break;
663 	case 2:
664 		strlcpy(fp->name, AudioEalaw, sizeof fp->name);
665 		fp->encoding = AUDIO_ENCODING_ALAW;
666 		fp->precision = 8;
667 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
668 		break;
669 	case 3:
670 		strlcpy(fp->name, AudioEslinear, sizeof fp->name);
671 		fp->encoding = AUDIO_ENCODING_SLINEAR;
672 		fp->precision = 8;
673 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
674 		break;
675 	case 4:
676 		strlcpy(fp->name, AudioEslinear_le, sizeof fp->name);
677 		fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
678 		fp->precision = 16;
679 		fp->flags = 0;
680 		break;
681 	case 5:
682 		strlcpy(fp->name, AudioEulinear_le, sizeof fp->name);
683 		fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
684 		fp->precision = 16;
685 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
686 		break;
687 	case 6:
688 		strlcpy(fp->name, AudioEslinear_be, sizeof fp->name);
689 		fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
690 		fp->precision = 16;
691 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
692 		break;
693 	case 7:
694 		strlcpy(fp->name, AudioEulinear_be, sizeof fp->name);
695 		fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
696 		fp->precision = 16;
697 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
698 		break;
699 	default:
700 		return EINVAL;
701 	}
702 	fp->bps = AUDIO_BPS(fp->precision);
703 	fp->msb = 1;
704 
705 	return 0;
706 }
707 
708 void
709 cmpci_get_default_params(void *addr, int mode, struct audio_params *params)
710 {
711 	params->sample_rate = 48000;
712 	params->encoding = AUDIO_ENCODING_SLINEAR_LE;
713 	params->precision = 16;
714 	params->bps = 2;
715 	params->msb = 1;
716 	params->channels = 2;
717 	params->sw_code = NULL;
718 	params->factor = 1;
719 }
720 
721 int
722 cmpci_set_params(void *handle, int setmode, int usemode,
723     struct audio_params *play, struct audio_params *rec)
724 {
725 	int i;
726 	struct cmpci_softc *sc = handle;
727 
728 	for (i = 0; i < 2; i++) {
729 		int md_format;
730 		int md_divide;
731 		int md_index;
732 		int mode;
733 		struct audio_params *p;
734 
735 		switch (i) {
736 		case 0:
737 			mode = AUMODE_PLAY;
738 			p = play;
739 			break;
740 		case 1:
741 			mode = AUMODE_RECORD;
742 			p = rec;
743 			break;
744 		default:
745 			return EINVAL;
746 		}
747 
748 		if (!(setmode & mode))
749 			continue;
750 
751 		if (setmode & AUMODE_RECORD) {
752 			if (p->channels > 2)
753 				p->channels = 2;
754 			sc->sc_play_channel = 0;
755 			cmpci_reg_clear_reg_misc(sc, CMPCI_REG_ENDBDAC);
756 			cmpci_reg_clear_reg_misc(sc, CMPCI_REG_XCHGDAC);
757 		} else {
758 			sc->sc_play_channel = 1;
759 			cmpci_reg_set_reg_misc(sc, CMPCI_REG_ENDBDAC);
760 			cmpci_reg_set_reg_misc(sc, CMPCI_REG_XCHGDAC);
761 		}
762 
763 		cmpci_reg_clear_4(sc, CMPCI_REG_LEGACY_CTRL,
764 		    CMPCI_REG_NXCHG);
765 		if (sc->sc_capable & CMPCI_CAP_4CH)
766 			cmpci_reg_clear_4(sc, CMPCI_REG_CHANNEL_FORMAT,
767 			    CMPCI_REG_CHB3D);
768 		if (sc->sc_capable & CMPCI_CAP_6CH) {
769 			cmpci_reg_clear_4(sc, CMPCI_REG_CHANNEL_FORMAT,
770 			    CMPCI_REG_CHB3D5C);
771 			cmpci_reg_clear_4(sc, CMPCI_REG_LEGACY_CTRL,
772 		    	    CMPCI_REG_CHB3D6C);
773 			cmpci_reg_clear_reg_misc(sc, CMPCI_REG_ENCENTER);
774 		}
775 		if (sc->sc_capable & CMPCI_CAP_8CH)
776 			cmpci_reg_clear_4(sc, CMPCI_REG_8768_MISC,
777 			    CMPCI_REG_CHB3D8C);
778 
779 		/* format */
780 		if (p->precision > 16)
781 			p->precision = 16;
782 		p->sw_code = NULL;
783 		switch (p->channels) {
784 		case 1:
785 			md_format = CMPCI_REG_FORMAT_MONO;
786 			break;
787 		case 2:
788 			md_format = CMPCI_REG_FORMAT_STEREO;
789 			break;
790 		case 4:
791 			if (mode & AUMODE_PLAY) {
792 				if (sc->sc_capable & CMPCI_CAP_4CH) {
793 					cmpci_reg_clear_reg_misc(sc,
794 					    CMPCI_REG_N4SPK3D);
795 					cmpci_reg_set_4(sc,
796 					    CMPCI_REG_CHANNEL_FORMAT,
797 					    CMPCI_REG_CHB3D);
798 					cmpci_reg_set_4(sc,
799 					    CMPCI_REG_LEGACY_CTRL,
800 					    CMPCI_REG_NXCHG);
801 				} else
802 					p->channels = 2;
803 			}
804 			md_format = CMPCI_REG_FORMAT_STEREO;
805 			break;
806 		case 6:
807 			if (mode & AUMODE_PLAY) {
808 				if (sc->sc_capable & CMPCI_CAP_6CH) {
809 					cmpci_reg_clear_reg_misc(sc,
810 					    CMPCI_REG_N4SPK3D);
811 					cmpci_reg_set_4(sc,
812 					    CMPCI_REG_CHANNEL_FORMAT,
813 					    CMPCI_REG_CHB3D5C);
814 					cmpci_reg_set_4(sc,
815 					    CMPCI_REG_LEGACY_CTRL,
816 					    CMPCI_REG_CHB3D6C);
817 					cmpci_reg_set_reg_misc(sc,
818 					    CMPCI_REG_ENCENTER);
819 					cmpci_reg_set_4(sc,
820 					    CMPCI_REG_LEGACY_CTRL,
821 					    CMPCI_REG_NXCHG);
822 				} else
823 					p->channels = 2;
824 			}
825 			md_format = CMPCI_REG_FORMAT_STEREO;
826 			break;
827 		case 8:
828 			if (mode & AUMODE_PLAY) {
829 				if (sc->sc_capable & CMPCI_CAP_8CH) {
830 					cmpci_reg_clear_reg_misc(sc,
831 					    CMPCI_REG_N4SPK3D);
832 					cmpci_reg_set_4(sc,
833 					    CMPCI_REG_CHANNEL_FORMAT,
834 					    CMPCI_REG_CHB3D5C);
835 					cmpci_reg_set_4(sc,
836 					    CMPCI_REG_LEGACY_CTRL,
837 					    CMPCI_REG_CHB3D6C);
838 					cmpci_reg_set_reg_misc(sc,
839 					    CMPCI_REG_ENCENTER);
840 					cmpci_reg_set_4(sc,
841 					    CMPCI_REG_8768_MISC,
842 					    CMPCI_REG_CHB3D8C);
843 					cmpci_reg_set_4(sc,
844 					    CMPCI_REG_LEGACY_CTRL,
845 					    CMPCI_REG_NXCHG);
846 				} else
847 					p->channels = 2;
848 			}
849 			md_format = CMPCI_REG_FORMAT_STEREO;
850 			break;
851 		default:
852 			return (EINVAL);
853 		}
854 		switch (p->encoding) {
855 		case AUDIO_ENCODING_ULAW:
856 			if (mode & AUMODE_PLAY) {
857 				p->factor = 2;
858 				p->sw_code = mulaw_to_slinear16_le;
859 				md_format |= CMPCI_REG_FORMAT_16BIT;
860 			} else {
861 				p->sw_code = ulinear8_to_mulaw;
862 				md_format |= CMPCI_REG_FORMAT_8BIT;
863 			}
864 			break;
865 		case AUDIO_ENCODING_ALAW:
866 			if (mode & AUMODE_PLAY) {
867 				p->factor = 2;
868 				p->sw_code = alaw_to_slinear16_le;
869 				md_format |= CMPCI_REG_FORMAT_16BIT;
870 			} else {
871 				p->sw_code = ulinear8_to_alaw;
872 				md_format |= CMPCI_REG_FORMAT_8BIT;
873 			}
874 			break;
875 		case AUDIO_ENCODING_SLINEAR_LE:
876 			switch (p->precision) {
877 			case 8:
878 				p->sw_code = change_sign8;
879 				md_format |= CMPCI_REG_FORMAT_8BIT;
880 				break;
881 			case 16:
882 				md_format |= CMPCI_REG_FORMAT_16BIT;
883 				break;
884 			default:
885 				return (EINVAL);
886 			}
887 			break;
888 		case AUDIO_ENCODING_SLINEAR_BE:
889 			switch (p->precision) {
890 			case 8:
891 				md_format |= CMPCI_REG_FORMAT_8BIT;
892 				p->sw_code = change_sign8;
893 				break;
894 			case 16:
895 				md_format |= CMPCI_REG_FORMAT_16BIT;
896 				p->sw_code = swap_bytes;
897 				break;
898 			default:
899 				return (EINVAL);
900 			}
901 			break;
902 		case AUDIO_ENCODING_ULINEAR_LE:
903 			switch (p->precision) {
904 			case 8:
905 				md_format |= CMPCI_REG_FORMAT_8BIT;
906 				break;
907 			case 16:
908 				md_format |= CMPCI_REG_FORMAT_16BIT;
909 				p->sw_code = change_sign16_le;
910 				break;
911 			default:
912 				return (EINVAL);
913 			}
914 			break;
915 		case AUDIO_ENCODING_ULINEAR_BE:
916 			switch (p->precision) {
917 			case 8:
918 				md_format |= CMPCI_REG_FORMAT_8BIT;
919 				break;
920 			case 16:
921 				md_format |= CMPCI_REG_FORMAT_16BIT;
922 				if (mode & AUMODE_PLAY)
923 					p->sw_code =
924 					    swap_bytes_change_sign16_le;
925 				else
926 					p->sw_code =
927 					    change_sign16_swap_bytes_le;
928 				break;
929 			default:
930 				return (EINVAL);
931 			}
932 			break;
933 		default:
934 			return (EINVAL);
935 		}
936 		p->bps = AUDIO_BPS(p->precision);
937 		p->msb = 1;
938 		if (mode & AUMODE_PLAY) {
939 			if (sc->sc_play_channel == 1) {
940 				cmpci_reg_partial_write_4(sc,
941 				   CMPCI_REG_CHANNEL_FORMAT,
942 				   CMPCI_REG_CH1_FORMAT_SHIFT,
943 				   CMPCI_REG_CH1_FORMAT_MASK, md_format);
944 			} else {
945 				cmpci_reg_partial_write_4(sc,
946 				   CMPCI_REG_CHANNEL_FORMAT,
947 				   CMPCI_REG_CH0_FORMAT_SHIFT,
948 				   CMPCI_REG_CH0_FORMAT_MASK, md_format);
949 			}
950 		} else {
951 			cmpci_reg_partial_write_4(sc,
952 			   CMPCI_REG_CHANNEL_FORMAT,
953 			   CMPCI_REG_CH1_FORMAT_SHIFT,
954 			   CMPCI_REG_CH1_FORMAT_MASK, md_format);
955 		}
956 		/* sample rate */
957 		md_index = cmpci_rate_to_index(p->sample_rate);
958 		md_divide = cmpci_index_to_divider(md_index);
959 		p->sample_rate = cmpci_index_to_rate(md_index);
960 		DPRINTF(("%s: sample:%d, divider=%d\n",
961 			 sc->sc_dev.dv_xname, (int)p->sample_rate, md_divide));
962 		if (mode & AUMODE_PLAY) {
963 			if (sc->sc_play_channel == 1) {
964 				cmpci_reg_partial_write_4(sc,
965 				    CMPCI_REG_FUNC_1, CMPCI_REG_ADC_FS_SHIFT,
966 				    CMPCI_REG_ADC_FS_MASK, md_divide);
967 				sc->sc_ch1.md_divide = md_divide;
968 			} else {
969 				cmpci_reg_partial_write_4(sc,
970 				    CMPCI_REG_FUNC_1, CMPCI_REG_DAC_FS_SHIFT,
971 				    CMPCI_REG_DAC_FS_MASK, md_divide);
972 				sc->sc_ch0.md_divide = md_divide;
973 			}
974 		} else {
975 			cmpci_reg_partial_write_4(sc,
976 			    CMPCI_REG_FUNC_1, CMPCI_REG_ADC_FS_SHIFT,
977 			    CMPCI_REG_ADC_FS_MASK, md_divide);
978 			sc->sc_ch1.md_divide = md_divide;
979 		}
980 	}
981 
982 	return 0;
983 }
984 
985 /* ARGSUSED */
986 int
987 cmpci_round_blocksize(void *handle, int block)
988 {
989 	return ((block + 3) & -4);
990 }
991 
992 int
993 cmpci_halt_output(void *handle)
994 {
995 	struct cmpci_softc *sc = handle;
996 	uint32_t reg_intr, reg_enable, reg_reset;
997 
998 	mtx_enter(&audio_lock);
999 	if (sc->sc_play_channel == 1) {
1000 		sc->sc_ch1.intr = NULL;
1001 		reg_intr = CMPCI_REG_CH1_INTR_ENABLE;
1002 		reg_enable = CMPCI_REG_CH1_ENABLE;
1003 		reg_reset = CMPCI_REG_CH1_RESET;
1004 	} else {
1005 		sc->sc_ch0.intr = NULL;
1006 		reg_intr = CMPCI_REG_CH0_INTR_ENABLE;
1007 		reg_enable = CMPCI_REG_CH0_ENABLE;
1008 		reg_reset = CMPCI_REG_CH0_RESET;
1009 	}
1010 	cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL, reg_intr);
1011 	cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, reg_enable);
1012 	/* wait for reset DMA */
1013 	cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, reg_reset);
1014 	delay(10);
1015 	cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, reg_reset);
1016 	mtx_leave(&audio_lock);
1017 	return 0;
1018 }
1019 
1020 int
1021 cmpci_halt_input(void *handle)
1022 {
1023 	struct cmpci_softc *sc = handle;
1024 
1025 	mtx_enter(&audio_lock);
1026 	sc->sc_ch1.intr = NULL;
1027 	cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH1_INTR_ENABLE);
1028 	cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_ENABLE);
1029 	/* wait for reset DMA */
1030 	cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_RESET);
1031 	delay(10);
1032 	cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_RESET);
1033 	mtx_leave(&audio_lock);
1034 	return 0;
1035 }
1036 
1037 /* get audio device information */
1038 int
1039 cmpci_getdev(void *handle, struct audio_device *ad)
1040 {
1041 	struct cmpci_softc *sc = handle;
1042 
1043 	strncpy(ad->name, "CMI PCI Audio", sizeof(ad->name));
1044 	snprintf(ad->version, sizeof(ad->version), "0x%02x (%d)",
1045 		 PCI_REVISION(sc->sc_class), sc->sc_version);
1046 	switch (PCI_PRODUCT(sc->sc_id)) {
1047 	case PCI_PRODUCT_CMI_CMI8338A:
1048 		strncpy(ad->config, "CMI8338A", sizeof(ad->config));
1049 		break;
1050 	case PCI_PRODUCT_CMI_CMI8338B:
1051 		strncpy(ad->config, "CMI8338B", sizeof(ad->config));
1052 		break;
1053 	case PCI_PRODUCT_CMI_CMI8738:
1054 		strncpy(ad->config, "CMI8738", sizeof(ad->config));
1055 		break;
1056 	case PCI_PRODUCT_CMI_CMI8738B:
1057 		strncpy(ad->config, "CMI8738B", sizeof(ad->config));
1058 		break;
1059 	default:
1060 		strncpy(ad->config, "unknown", sizeof(ad->config));
1061 	}
1062 
1063 	return 0;
1064 }
1065 
1066 /* mixer device information */
1067 int
1068 cmpci_query_devinfo(void *handle, mixer_devinfo_t *dip)
1069 {
1070 	static const char *const mixer_port_names[] = {
1071 		AudioNdac, AudioNfmsynth, AudioNcd, AudioNline, AudioNaux,
1072 		AudioNmicrophone
1073 	};
1074 	static const char *const mixer_classes[] = {
1075 		AudioCinputs, AudioCoutputs, AudioCrecord, CmpciCplayback,
1076 		CmpciCspdif
1077 	};
1078 	struct cmpci_softc *sc = handle;
1079 	int i;
1080 
1081 	dip->prev = dip->next = AUDIO_MIXER_LAST;
1082 
1083 	switch (dip->index) {
1084 	case CMPCI_INPUT_CLASS:
1085 	case CMPCI_OUTPUT_CLASS:
1086 	case CMPCI_RECORD_CLASS:
1087 	case CMPCI_PLAYBACK_CLASS:
1088 	case CMPCI_SPDIF_CLASS:
1089 		dip->type = AUDIO_MIXER_CLASS;
1090 		dip->mixer_class = dip->index;
1091 		strlcpy(dip->label.name,
1092 		    mixer_classes[dip->index - CMPCI_INPUT_CLASS],
1093 		    sizeof dip->label.name);
1094 		return 0;
1095 
1096 	case CMPCI_AUX_IN_VOL:
1097 		dip->un.v.delta = 1 << (8 - CMPCI_REG_AUX_VALBITS);
1098 		goto vol1;
1099 	case CMPCI_DAC_VOL:
1100 	case CMPCI_FM_VOL:
1101 	case CMPCI_CD_VOL:
1102 	case CMPCI_LINE_IN_VOL:
1103 	case CMPCI_MIC_VOL:
1104 		dip->un.v.delta = 1 << (8 - CMPCI_SB16_MIXER_VALBITS);
1105 	vol1:	dip->mixer_class = CMPCI_INPUT_CLASS;
1106 		dip->next = dip->index + 6;	/* CMPCI_xxx_MUTE */
1107 		strlcpy(dip->label.name, mixer_port_names[dip->index],
1108 		    sizeof dip->label.name);
1109 		dip->un.v.num_channels = (dip->index == CMPCI_MIC_VOL ? 1 : 2);
1110 	vol:
1111 		dip->type = AUDIO_MIXER_VALUE;
1112 		strlcpy(dip->un.v.units.name, AudioNvolume,
1113 		    sizeof dip->un.v.units.name);
1114 		return 0;
1115 
1116 	case CMPCI_MIC_MUTE:
1117 		dip->next = CMPCI_MIC_PREAMP;
1118 		/* FALLTHROUGH */
1119 	case CMPCI_DAC_MUTE:
1120 	case CMPCI_FM_MUTE:
1121 	case CMPCI_CD_MUTE:
1122 	case CMPCI_LINE_IN_MUTE:
1123 	case CMPCI_AUX_IN_MUTE:
1124 		dip->prev = dip->index - 6;	/* CMPCI_xxx_VOL */
1125 		dip->mixer_class = CMPCI_INPUT_CLASS;
1126 		strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name);
1127 		goto on_off;
1128 	on_off:
1129 		dip->type = AUDIO_MIXER_ENUM;
1130 		dip->un.e.num_mem = 2;
1131 		strlcpy(dip->un.e.member[0].label.name, AudioNoff,
1132 		    sizeof dip->un.e.member[0].label.name);
1133 		dip->un.e.member[0].ord = 0;
1134 		strlcpy(dip->un.e.member[1].label.name, AudioNon,
1135 		    sizeof dip->un.e.member[1].label.name);
1136 		dip->un.e.member[1].ord = 1;
1137 		return 0;
1138 
1139 	case CMPCI_MIC_PREAMP:
1140 		dip->mixer_class = CMPCI_INPUT_CLASS;
1141 		dip->prev = CMPCI_MIC_MUTE;
1142 		strlcpy(dip->label.name, AudioNpreamp, sizeof dip->label.name);
1143 		goto on_off;
1144 	case CMPCI_PCSPEAKER:
1145 		dip->mixer_class = CMPCI_INPUT_CLASS;
1146 		strlcpy(dip->label.name, AudioNspeaker, sizeof dip->label.name);
1147 		dip->un.v.num_channels = 1;
1148 		dip->un.v.delta = 1 << (8 - CMPCI_SB16_MIXER_SPEAKER_VALBITS);
1149 		goto vol;
1150 	case CMPCI_RECORD_SOURCE:
1151 		dip->mixer_class = CMPCI_RECORD_CLASS;
1152 		strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name);
1153 		dip->type = AUDIO_MIXER_SET;
1154 		dip->un.s.num_mem = 7;
1155 		strlcpy(dip->un.s.member[0].label.name, AudioNmicrophone,
1156 		    sizeof dip->un.s.member[0].label.name);
1157 		dip->un.s.member[0].mask = CMPCI_RECORD_SOURCE_MIC;
1158 		strlcpy(dip->un.s.member[1].label.name, AudioNcd,
1159 		    sizeof dip->un.s.member[1].label.name);
1160 		dip->un.s.member[1].mask = CMPCI_RECORD_SOURCE_CD;
1161 		strlcpy(dip->un.s.member[2].label.name, AudioNline,
1162 		    sizeof dip->un.s.member[2].label.name);
1163 		dip->un.s.member[2].mask = CMPCI_RECORD_SOURCE_LINE_IN;
1164 		strlcpy(dip->un.s.member[3].label.name, AudioNaux,
1165 		    sizeof dip->un.s.member[3].label.name);
1166 		dip->un.s.member[3].mask = CMPCI_RECORD_SOURCE_AUX_IN;
1167 		strlcpy(dip->un.s.member[4].label.name, AudioNwave,
1168 		    sizeof dip->un.s.member[4].label.name);
1169 		dip->un.s.member[4].mask = CMPCI_RECORD_SOURCE_WAVE;
1170 		strlcpy(dip->un.s.member[5].label.name, AudioNfmsynth,
1171 		    sizeof dip->un.s.member[5].label.name);
1172 		dip->un.s.member[5].mask = CMPCI_RECORD_SOURCE_FM;
1173 		strlcpy(dip->un.s.member[6].label.name, CmpciNspdif,
1174 		    sizeof dip->un.s.member[6].label.name);
1175 		dip->un.s.member[6].mask = CMPCI_RECORD_SOURCE_SPDIF;
1176 		return 0;
1177 	case CMPCI_MIC_RECVOL:
1178 		dip->mixer_class = CMPCI_RECORD_CLASS;
1179 		strlcpy(dip->label.name, AudioNmicrophone, sizeof dip->label.name);
1180 		dip->un.v.num_channels = 1;
1181 		dip->un.v.delta = 1 << (8 - CMPCI_REG_ADMIC_VALBITS);
1182 		goto vol;
1183 
1184 	case CMPCI_PLAYBACK_MODE:
1185 		dip->mixer_class = CMPCI_PLAYBACK_CLASS;
1186 		dip->type = AUDIO_MIXER_ENUM;
1187 		strlcpy(dip->label.name, AudioNmode, sizeof dip->label.name);
1188 		dip->un.e.num_mem = 2;
1189 		strlcpy(dip->un.e.member[0].label.name, AudioNdac,
1190 		    sizeof dip->un.e.member[0].label.name);
1191 		dip->un.e.member[0].ord = CMPCI_PLAYBACK_MODE_WAVE;
1192 		strlcpy(dip->un.e.member[1].label.name, CmpciNspdif,
1193 		    sizeof dip->un.e.member[1].label.name);
1194 		dip->un.e.member[1].ord = CMPCI_PLAYBACK_MODE_SPDIF;
1195 		return 0;
1196 	case CMPCI_SPDIF_IN_SELECT:
1197 		dip->mixer_class = CMPCI_SPDIF_CLASS;
1198 		dip->type = AUDIO_MIXER_ENUM;
1199 		dip->next = CMPCI_SPDIF_IN_PHASE;
1200 		strlcpy(dip->label.name, AudioNinput, sizeof dip->label.name);
1201 		i = 0;
1202 		strlcpy(dip->un.e.member[i].label.name, CmpciNspdin1,
1203 		    sizeof dip->un.e.member[i].label.name);
1204 		dip->un.e.member[i++].ord = CMPCI_SPDIF_IN_SPDIN1;
1205 		if (CMPCI_ISCAP(sc, 2ND_SPDIN)) {
1206 			strlcpy(dip->un.e.member[i].label.name, CmpciNspdin2,
1207 			    sizeof dip->un.e.member[i].label.name);
1208 			dip->un.e.member[i++].ord = CMPCI_SPDIF_IN_SPDIN2;
1209 		}
1210 		strlcpy(dip->un.e.member[i].label.name, CmpciNspdout,
1211 		    sizeof dip->un.e.member[i].label.name);
1212 		dip->un.e.member[i++].ord = CMPCI_SPDIF_IN_SPDOUT;
1213 		dip->un.e.num_mem = i;
1214 		return 0;
1215 	case CMPCI_SPDIF_IN_PHASE:
1216 		dip->mixer_class = CMPCI_SPDIF_CLASS;
1217 		dip->prev = CMPCI_SPDIF_IN_SELECT;
1218 		strlcpy(dip->label.name, CmpciNphase, sizeof dip->label.name);
1219 		dip->type = AUDIO_MIXER_ENUM;
1220 		dip->un.e.num_mem = 2;
1221 		strlcpy(dip->un.e.member[0].label.name, CmpciNpositive,
1222 		    sizeof dip->un.e.member[0].label.name);
1223 		dip->un.e.member[0].ord = CMPCI_SPDIF_IN_PHASE_POSITIVE;
1224 		strlcpy(dip->un.e.member[1].label.name, CmpciNnegative,
1225 		    sizeof dip->un.e.member[1].label.name);
1226 		dip->un.e.member[1].ord = CMPCI_SPDIF_IN_PHASE_NEGATIVE;
1227 		return 0;
1228 	case CMPCI_SPDIF_LOOP:
1229 		dip->mixer_class = CMPCI_SPDIF_CLASS;
1230 		dip->next = CMPCI_SPDIF_OUT_PLAYBACK;
1231 		strlcpy(dip->label.name, AudioNoutput, sizeof dip->label.name);
1232 		dip->type = AUDIO_MIXER_ENUM;
1233 		dip->un.e.num_mem = 2;
1234 		strlcpy(dip->un.e.member[0].label.name, CmpciNplayback,
1235 		    sizeof dip->un.e.member[0].label.name);
1236 		dip->un.e.member[0].ord = CMPCI_SPDIF_LOOP_OFF;
1237 		strlcpy(dip->un.e.member[1].label.name, CmpciNspdin,
1238 		    sizeof dip->un.e.member[1].label.name);
1239 		dip->un.e.member[1].ord = CMPCI_SPDIF_LOOP_ON;
1240 		return 0;
1241 	case CMPCI_SPDIF_OUT_PLAYBACK:
1242 		dip->mixer_class = CMPCI_SPDIF_CLASS;
1243 		dip->prev = CMPCI_SPDIF_LOOP;
1244 		dip->next = CMPCI_SPDIF_OUT_VOLTAGE;
1245 		strlcpy(dip->label.name, CmpciNplayback, sizeof dip->label.name);
1246 		dip->type = AUDIO_MIXER_ENUM;
1247 		dip->un.e.num_mem = 2;
1248 		strlcpy(dip->un.e.member[0].label.name, AudioNwave,
1249 		    sizeof dip->un.e.member[0].label.name);
1250 		dip->un.e.member[0].ord = CMPCI_SPDIF_OUT_PLAYBACK_WAVE;
1251 		strlcpy(dip->un.e.member[1].label.name, CmpciNlegacy,
1252 		    sizeof dip->un.e.member[1].label.name);
1253 		dip->un.e.member[1].ord = CMPCI_SPDIF_OUT_PLAYBACK_LEGACY;
1254 		return 0;
1255 	case CMPCI_SPDIF_OUT_VOLTAGE:
1256 		dip->mixer_class = CMPCI_SPDIF_CLASS;
1257 		dip->prev = CMPCI_SPDIF_OUT_PLAYBACK;
1258 		strlcpy(dip->label.name, CmpciNvoltage, sizeof dip->label.name);
1259 		dip->type = AUDIO_MIXER_ENUM;
1260 		dip->un.e.num_mem = 2;
1261 		strlcpy(dip->un.e.member[0].label.name, CmpciNhigh_v,
1262 		    sizeof dip->un.e.member[0].label.name);
1263 		dip->un.e.member[0].ord = CMPCI_SPDIF_OUT_VOLTAGE_HIGH;
1264 		strlcpy(dip->un.e.member[1].label.name, CmpciNlow_v,
1265 		    sizeof dip->un.e.member[1].label.name);
1266 		dip->un.e.member[1].ord = CMPCI_SPDIF_OUT_VOLTAGE_LOW;
1267 		return 0;
1268 	case CMPCI_MONITOR_DAC:
1269 		dip->mixer_class = CMPCI_SPDIF_CLASS;
1270 		strlcpy(dip->label.name, AudioNmonitor, sizeof dip->label.name);
1271 		dip->type = AUDIO_MIXER_ENUM;
1272 		dip->un.e.num_mem = 3;
1273 		strlcpy(dip->un.e.member[0].label.name, AudioNoff,
1274 		    sizeof dip->un.e.member[0].label.name);
1275 		dip->un.e.member[0].ord = CMPCI_MONITOR_DAC_OFF;
1276 		strlcpy(dip->un.e.member[1].label.name, CmpciNspdin,
1277 		    sizeof dip->un.e.member[1].label.name);
1278 		dip->un.e.member[1].ord = CMPCI_MONITOR_DAC_SPDIN;
1279 		strlcpy(dip->un.e.member[2].label.name, CmpciNspdout,
1280 		    sizeof dip->un.e.member[2].label.name);
1281 		dip->un.e.member[2].ord = CMPCI_MONITOR_DAC_SPDOUT;
1282 		return 0;
1283 
1284 	case CMPCI_MASTER_VOL:
1285 		dip->mixer_class = CMPCI_OUTPUT_CLASS;
1286 		strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name);
1287 		dip->un.v.num_channels = 2;
1288 		dip->un.v.delta = 1 << (8 - CMPCI_SB16_MIXER_VALBITS);
1289 		goto vol;
1290 	case CMPCI_REAR:
1291 		dip->mixer_class = CMPCI_OUTPUT_CLASS;
1292 		dip->next = CMPCI_INDIVIDUAL;
1293 		strlcpy(dip->label.name, CmpciNrear, sizeof dip->label.name);
1294 		goto on_off;
1295 	case CMPCI_INDIVIDUAL:
1296 		dip->mixer_class = CMPCI_OUTPUT_CLASS;
1297 		dip->prev = CMPCI_REAR;
1298 		dip->next = CMPCI_REVERSE;
1299 		strlcpy(dip->label.name, CmpciNindividual, sizeof dip->label.name);
1300 		goto on_off;
1301 	case CMPCI_REVERSE:
1302 		dip->mixer_class = CMPCI_OUTPUT_CLASS;
1303 		dip->prev = CMPCI_INDIVIDUAL;
1304 		strlcpy(dip->label.name, CmpciNreverse, sizeof dip->label.name);
1305 		goto on_off;
1306 	case CMPCI_SURROUND:
1307 		dip->mixer_class = CMPCI_OUTPUT_CLASS;
1308 		strlcpy(dip->label.name, CmpciNsurround, sizeof dip->label.name);
1309 		goto on_off;
1310 	}
1311 
1312 	return ENXIO;
1313 }
1314 
1315 int
1316 cmpci_alloc_dmamem(struct cmpci_softc *sc, size_t size, int type, int flags,
1317     caddr_t *r_addr)
1318 {
1319 	int error = 0;
1320 	struct cmpci_dmanode *n;
1321 	int w;
1322 
1323 	n = malloc(sizeof(struct cmpci_dmanode), type, flags);
1324 	if (n == NULL) {
1325 		error = ENOMEM;
1326 		goto quit;
1327 	}
1328 
1329 	w = (flags & M_NOWAIT) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK;
1330 #define CMPCI_DMABUF_ALIGN    0x4
1331 #define CMPCI_DMABUF_BOUNDARY 0x0
1332 	n->cd_tag = sc->sc_dmat;
1333 	n->cd_size = size;
1334 	error = bus_dmamem_alloc(n->cd_tag, n->cd_size,
1335 	    CMPCI_DMABUF_ALIGN, CMPCI_DMABUF_BOUNDARY, n->cd_segs,
1336 	    nitems(n->cd_segs), &n->cd_nsegs, w);
1337 	if (error)
1338 		goto mfree;
1339 	error = bus_dmamem_map(n->cd_tag, n->cd_segs, n->cd_nsegs, n->cd_size,
1340 	    &n->cd_addr, w | BUS_DMA_COHERENT);
1341 	if (error)
1342 		goto dmafree;
1343 	error = bus_dmamap_create(n->cd_tag, n->cd_size, 1, n->cd_size, 0,
1344 	    w, &n->cd_map);
1345 	if (error)
1346 		goto unmap;
1347 	error = bus_dmamap_load(n->cd_tag, n->cd_map, n->cd_addr, n->cd_size,
1348 	    NULL, w);
1349 	if (error)
1350 		goto destroy;
1351 
1352 	n->cd_next = sc->sc_dmap;
1353 	sc->sc_dmap = n;
1354 	*r_addr = KVADDR(n);
1355 	return 0;
1356 
1357  destroy:
1358 	bus_dmamap_destroy(n->cd_tag, n->cd_map);
1359  unmap:
1360 	bus_dmamem_unmap(n->cd_tag, n->cd_addr, n->cd_size);
1361  dmafree:
1362 	bus_dmamem_free(n->cd_tag,
1363 			n->cd_segs, nitems(n->cd_segs));
1364  mfree:
1365 	free(n, type);
1366  quit:
1367 	return error;
1368 }
1369 
1370 int
1371 cmpci_free_dmamem(struct cmpci_softc *sc, caddr_t addr, int type)
1372 {
1373 	struct cmpci_dmanode **nnp;
1374 
1375 	for (nnp = &sc->sc_dmap; *nnp; nnp = &(*nnp)->cd_next) {
1376 		if ((*nnp)->cd_addr == addr) {
1377 			struct cmpci_dmanode *n = *nnp;
1378 			bus_dmamap_unload(n->cd_tag, n->cd_map);
1379 			bus_dmamap_destroy(n->cd_tag, n->cd_map);
1380 			bus_dmamem_unmap(n->cd_tag, n->cd_addr, n->cd_size);
1381 			bus_dmamem_free(n->cd_tag, n->cd_segs,
1382 			    nitems(n->cd_segs));
1383 			free(n, type);
1384 			return 0;
1385 		}
1386 	}
1387 	return -1;
1388 }
1389 
1390 struct cmpci_dmanode *
1391 cmpci_find_dmamem(struct cmpci_softc *sc, caddr_t addr)
1392 {
1393 	struct cmpci_dmanode *p;
1394 
1395 	for (p = sc->sc_dmap; p; p = p->cd_next) {
1396 		if (KVADDR(p) == (void *)addr)
1397 			break;
1398 	}
1399 	return p;
1400 }
1401 
1402 #if 0
1403 void cmpci_print_dmamem(struct cmpci_dmanode *p);
1404 
1405 void
1406 cmpci_print_dmamem(struct cmpci_dmanode *p)
1407 {
1408 	DPRINTF(("DMA at virt:%p, dmaseg:%p, mapseg:%p, size:%p\n",
1409 		 (void *)p->cd_addr, (void *)p->cd_segs[0].ds_addr,
1410 		 (void *)DMAADDR(p), (void *)p->cd_size));
1411 }
1412 #endif /* DEBUG */
1413 
1414 void *
1415 cmpci_malloc(void *handle, int direction, size_t size, int type,
1416     int flags)
1417 {
1418 	caddr_t addr;
1419 
1420 	if (cmpci_alloc_dmamem(handle, size, type, flags, &addr))
1421 		return NULL;
1422 	return addr;
1423 }
1424 
1425 void
1426 cmpci_free(void *handle, void *addr, int type)
1427 {
1428 	cmpci_free_dmamem(handle, addr, type);
1429 }
1430 
1431 #define MAXVAL 256
1432 int
1433 cmpci_adjust(int val, int mask)
1434 {
1435 	val += (MAXVAL - mask) >> 1;
1436 	if (val >= MAXVAL)
1437 		val = MAXVAL-1;
1438 	return val & mask;
1439 }
1440 
1441 void
1442 cmpci_set_mixer_gain(struct cmpci_softc *sc, int port)
1443 {
1444 	int src;
1445 	int bits, mask;
1446 
1447 	switch (port) {
1448 	case CMPCI_MIC_VOL:
1449 		cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_MIC,
1450 		    CMPCI_ADJUST_MIC_GAIN(sc, sc->sc_gain[port][CMPCI_LR]));
1451 		return;
1452 	case CMPCI_MASTER_VOL:
1453 		src = CMPCI_SB16_MIXER_MASTER_L;
1454 		break;
1455 	case CMPCI_LINE_IN_VOL:
1456 		src = CMPCI_SB16_MIXER_LINE_L;
1457 		break;
1458 	case CMPCI_AUX_IN_VOL:
1459 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, CMPCI_REG_MIXER_AUX,
1460 		    CMPCI_ADJUST_AUX_GAIN(sc, sc->sc_gain[port][CMPCI_LEFT],
1461 					      sc->sc_gain[port][CMPCI_RIGHT]));
1462 		return;
1463 	case CMPCI_MIC_RECVOL:
1464 		cmpci_reg_partial_write_1(sc, CMPCI_REG_MIXER25,
1465 		    CMPCI_REG_ADMIC_SHIFT, CMPCI_REG_ADMIC_MASK,
1466 		    CMPCI_ADJUST_ADMIC_GAIN(sc, sc->sc_gain[port][CMPCI_LR]));
1467 		return;
1468 	case CMPCI_DAC_VOL:
1469 		src = CMPCI_SB16_MIXER_VOICE_L;
1470 		break;
1471 	case CMPCI_FM_VOL:
1472 		src = CMPCI_SB16_MIXER_FM_L;
1473 		break;
1474 	case CMPCI_CD_VOL:
1475 		src = CMPCI_SB16_MIXER_CDDA_L;
1476 		break;
1477 	case CMPCI_PCSPEAKER:
1478 		cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_SPEAKER,
1479 		    CMPCI_ADJUST_2_GAIN(sc, sc->sc_gain[port][CMPCI_LR]));
1480 		return;
1481 	case CMPCI_MIC_PREAMP:
1482 		if (sc->sc_gain[port][CMPCI_LR])
1483 			cmpci_reg_clear_1(sc, CMPCI_REG_MIXER25,
1484 			    CMPCI_REG_MICGAINZ);
1485 		else
1486 			cmpci_reg_set_1(sc, CMPCI_REG_MIXER25,
1487 			    CMPCI_REG_MICGAINZ);
1488 		return;
1489 
1490 	case CMPCI_DAC_MUTE:
1491 		if (sc->sc_gain[port][CMPCI_LR])
1492 			cmpci_reg_set_1(sc, CMPCI_REG_MIXER24,
1493 			    CMPCI_REG_WSMUTE);
1494 		else
1495 			cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24,
1496 			    CMPCI_REG_WSMUTE);
1497 		return;
1498 	case CMPCI_FM_MUTE:
1499 		if (sc->sc_gain[port][CMPCI_LR])
1500 			cmpci_reg_set_1(sc, CMPCI_REG_MIXER24,
1501 			    CMPCI_REG_FMMUTE);
1502 		else
1503 			cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24,
1504 			    CMPCI_REG_FMMUTE);
1505 		return;
1506 	case CMPCI_AUX_IN_MUTE:
1507 		if (sc->sc_gain[port][CMPCI_LR])
1508 			cmpci_reg_clear_1(sc, CMPCI_REG_MIXER25,
1509 			    CMPCI_REG_VAUXRM|CMPCI_REG_VAUXLM);
1510 		else
1511 			cmpci_reg_set_1(sc, CMPCI_REG_MIXER25,
1512 			    CMPCI_REG_VAUXRM|CMPCI_REG_VAUXLM);
1513 		return;
1514 	case CMPCI_CD_MUTE:
1515 		mask = CMPCI_SB16_SW_CD;
1516 		goto sbmute;
1517 	case CMPCI_MIC_MUTE:
1518 		mask = CMPCI_SB16_SW_MIC;
1519 		goto sbmute;
1520 	case CMPCI_LINE_IN_MUTE:
1521 		mask = CMPCI_SB16_SW_LINE;
1522 	sbmute:
1523 		bits = cmpci_mixerreg_read(sc, CMPCI_SB16_MIXER_OUTMIX);
1524 		if (sc->sc_gain[port][CMPCI_LR])
1525 			bits = bits & ~mask;
1526 		else
1527 			bits = bits | mask;
1528 		cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_OUTMIX, bits);
1529 		return;
1530 
1531 	case CMPCI_SPDIF_IN_SELECT:
1532 	case CMPCI_MONITOR_DAC:
1533 	case CMPCI_PLAYBACK_MODE:
1534 	case CMPCI_SPDIF_LOOP:
1535 	case CMPCI_SPDIF_OUT_PLAYBACK:
1536 		cmpci_set_out_ports(sc);
1537 		return;
1538 	case CMPCI_SPDIF_OUT_VOLTAGE:
1539 		if (CMPCI_ISCAP(sc, SPDOUT_VOLTAGE)) {
1540 			if (sc->sc_gain[CMPCI_SPDIF_OUT_VOLTAGE][CMPCI_LR]
1541 			    == CMPCI_SPDIF_OUT_VOLTAGE_HIGH)
1542 				cmpci_reg_clear_reg_misc(sc, CMPCI_REG_5V);
1543 			else
1544 				cmpci_reg_set_reg_misc(sc, CMPCI_REG_5V);
1545 		}
1546 		return;
1547 	case CMPCI_SURROUND:
1548 		if (CMPCI_ISCAP(sc, SURROUND)) {
1549 			if (sc->sc_gain[CMPCI_SURROUND][CMPCI_LR])
1550 				cmpci_reg_set_1(sc, CMPCI_REG_MIXER24,
1551 						CMPCI_REG_SURROUND);
1552 			else
1553 				cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24,
1554 						  CMPCI_REG_SURROUND);
1555 		}
1556 		return;
1557 	case CMPCI_REAR:
1558 		if (CMPCI_ISCAP(sc, REAR)) {
1559 			if (sc->sc_gain[CMPCI_REAR][CMPCI_LR])
1560 				cmpci_reg_set_reg_misc(sc, CMPCI_REG_N4SPK3D);
1561 			else
1562 				cmpci_reg_clear_reg_misc(sc, CMPCI_REG_N4SPK3D);
1563 		}
1564 		return;
1565 	case CMPCI_INDIVIDUAL:
1566 		if (CMPCI_ISCAP(sc, INDIVIDUAL_REAR)) {
1567 			if (sc->sc_gain[CMPCI_REAR][CMPCI_LR])
1568 				cmpci_reg_set_1(sc, CMPCI_REG_MIXER24,
1569 						CMPCI_REG_INDIVIDUAL);
1570 			else
1571 				cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24,
1572 						  CMPCI_REG_INDIVIDUAL);
1573 		}
1574 		return;
1575 	case CMPCI_REVERSE:
1576 		if (CMPCI_ISCAP(sc, REVERSE_FR)) {
1577 			if (sc->sc_gain[CMPCI_REVERSE][CMPCI_LR])
1578 				cmpci_reg_set_1(sc, CMPCI_REG_MIXER24,
1579 						CMPCI_REG_REVERSE_FR);
1580 			else
1581 				cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24,
1582 						  CMPCI_REG_REVERSE_FR);
1583 		}
1584 		return;
1585 	case CMPCI_SPDIF_IN_PHASE:
1586 		if (CMPCI_ISCAP(sc, SPDIN_PHASE)) {
1587 			if (sc->sc_gain[CMPCI_SPDIF_IN_PHASE][CMPCI_LR]
1588 			    == CMPCI_SPDIF_IN_PHASE_POSITIVE)
1589 				cmpci_reg_clear_1(sc, CMPCI_REG_CHANNEL_FORMAT,
1590 						  CMPCI_REG_SPDIN_PHASE);
1591 			else
1592 				cmpci_reg_set_1(sc, CMPCI_REG_CHANNEL_FORMAT,
1593 						CMPCI_REG_SPDIN_PHASE);
1594 		}
1595 		return;
1596 	default:
1597 		return;
1598 	}
1599 
1600 	cmpci_mixerreg_write(sc, src,
1601 	    CMPCI_ADJUST_GAIN(sc, sc->sc_gain[port][CMPCI_LEFT]));
1602 	cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_L_TO_R(src),
1603 	    CMPCI_ADJUST_GAIN(sc, sc->sc_gain[port][CMPCI_RIGHT]));
1604 }
1605 
1606 void
1607 cmpci_set_out_ports(struct cmpci_softc *sc)
1608 {
1609 	struct cmpci_channel *chan;
1610 	u_int8_t v;
1611 	int enspdout = 0;
1612 
1613 	if (!CMPCI_ISCAP(sc, SPDLOOP))
1614 		return;
1615 
1616 	/* SPDIF/out select */
1617 	if (sc->sc_gain[CMPCI_SPDIF_LOOP][CMPCI_LR] == CMPCI_SPDIF_LOOP_OFF) {
1618 		/* playback */
1619 		cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1, CMPCI_REG_SPDIF_LOOP);
1620 	} else {
1621 		/* monitor SPDIF/in */
1622 		cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1, CMPCI_REG_SPDIF_LOOP);
1623 	}
1624 
1625 	/* SPDIF in select */
1626 	v = sc->sc_gain[CMPCI_SPDIF_IN_SELECT][CMPCI_LR];
1627 	if (v & CMPCI_SPDIFIN_SPDIFIN2)
1628 		cmpci_reg_set_reg_misc(sc, CMPCI_REG_2ND_SPDIFIN);
1629 	else
1630 		cmpci_reg_clear_reg_misc(sc, CMPCI_REG_2ND_SPDIFIN);
1631 	if (v & CMPCI_SPDIFIN_SPDIFOUT)
1632 		cmpci_reg_set_reg_misc(sc, CMPCI_REG_SPDFLOOPI);
1633 	else
1634 		cmpci_reg_clear_reg_misc(sc, CMPCI_REG_SPDFLOOPI);
1635 
1636 	if (sc->sc_play_channel == 1)
1637 		chan = &sc->sc_ch1;
1638 	else
1639 		chan = &sc->sc_ch0;
1640 
1641 	/* disable ac3 and 24 and 32 bit s/pdif modes */
1642 	cmpci_reg_clear_4(sc, CMPCI_REG_CHANNEL_FORMAT, CMPCI_REG_AC3EN1);
1643 	cmpci_reg_clear_reg_misc(sc, CMPCI_REG_AC3EN2);
1644 	cmpci_reg_clear_reg_misc(sc, CMPCI_REG_SPD32SEL);
1645 	cmpci_reg_clear_4(sc, CMPCI_REG_CHANNEL_FORMAT, CMPCI_REG_SPDIF_24);
1646 
1647 	/* playback to ... */
1648 	if (CMPCI_ISCAP(sc, SPDOUT) &&
1649 	    sc->sc_gain[CMPCI_PLAYBACK_MODE][CMPCI_LR]
1650 		== CMPCI_PLAYBACK_MODE_SPDIF &&
1651 	    (chan->md_divide == CMPCI_REG_RATE_44100 ||
1652 		(CMPCI_ISCAP(sc, SPDOUT_48K) &&
1653 		    chan->md_divide == CMPCI_REG_RATE_48000))) {
1654 		/* playback to SPDIF */
1655 		if (sc->sc_play_channel == 0)
1656 			cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1,
1657 			    CMPCI_REG_SPDIF0_ENABLE);
1658 		else
1659 			cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1,
1660 			    CMPCI_REG_SPDIF1_ENABLE);
1661 		enspdout = 1;
1662 		if (chan->md_divide == CMPCI_REG_RATE_48000)
1663 			cmpci_reg_set_reg_misc(sc,
1664 				CMPCI_REG_SPDIFOUT_48K | CMPCI_REG_SPDIF48K);
1665 		else
1666 			cmpci_reg_clear_reg_misc(sc,
1667 				CMPCI_REG_SPDIFOUT_48K | CMPCI_REG_SPDIF48K);
1668 		/* XXX assume sample rate <= 48kHz */
1669 		cmpci_reg_clear_4(sc, CMPCI_REG_CHANNEL_FORMAT,
1670 		    CMPCI_REG_DBL_SPD_RATE);
1671 	} else {
1672 		/* playback to DAC */
1673 		if (sc->sc_play_channel == 0)
1674 			cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1,
1675 			    CMPCI_REG_SPDIF0_ENABLE);
1676 		else
1677 			cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1,
1678 			    CMPCI_REG_SPDIF1_ENABLE);
1679 		if (CMPCI_ISCAP(sc, SPDOUT_48K))
1680 			cmpci_reg_clear_reg_misc(sc,
1681 				CMPCI_REG_SPDIFOUT_48K | CMPCI_REG_SPDIF48K);
1682 	}
1683 
1684 	/* legacy to SPDIF/out or not */
1685 	if (CMPCI_ISCAP(sc, SPDLEGACY)) {
1686 		if (sc->sc_gain[CMPCI_SPDIF_OUT_PLAYBACK][CMPCI_LR]
1687 		    == CMPCI_SPDIF_OUT_PLAYBACK_WAVE)
1688 			cmpci_reg_clear_4(sc, CMPCI_REG_LEGACY_CTRL,
1689 					CMPCI_REG_LEGACY_SPDIF_ENABLE);
1690 		else {
1691 			cmpci_reg_set_4(sc, CMPCI_REG_LEGACY_CTRL,
1692 					CMPCI_REG_LEGACY_SPDIF_ENABLE);
1693 			enspdout = 1;
1694 		}
1695 	}
1696 
1697 	/* enable/disable SPDIF/out */
1698 	if (CMPCI_ISCAP(sc, XSPDOUT) && enspdout)
1699 		cmpci_reg_set_4(sc, CMPCI_REG_LEGACY_CTRL,
1700 				CMPCI_REG_XSPDIF_ENABLE);
1701 	else
1702 		cmpci_reg_clear_4(sc, CMPCI_REG_LEGACY_CTRL,
1703 				CMPCI_REG_XSPDIF_ENABLE);
1704 
1705 	/* SPDIF monitor (digital to analog output) */
1706 	if (CMPCI_ISCAP(sc, SPDIN_MONITOR)) {
1707 		v = sc->sc_gain[CMPCI_MONITOR_DAC][CMPCI_LR];
1708 		if (!(v & CMPCI_MONDAC_ENABLE))
1709 			cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24,
1710 					CMPCI_REG_SPDIN_MONITOR);
1711 		if (v & CMPCI_MONDAC_SPDOUT)
1712 			cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1,
1713 					CMPCI_REG_SPDIFOUT_DAC);
1714 		else
1715 			cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1,
1716 					CMPCI_REG_SPDIFOUT_DAC);
1717 		if (v & CMPCI_MONDAC_ENABLE)
1718 			cmpci_reg_set_1(sc, CMPCI_REG_MIXER24,
1719 					CMPCI_REG_SPDIN_MONITOR);
1720 	}
1721 }
1722 
1723 int
1724 cmpci_set_in_ports(struct cmpci_softc *sc)
1725 {
1726 	int mask;
1727 	int bitsl, bitsr;
1728 
1729 	mask = sc->sc_in_mask;
1730 
1731 	/*
1732 	 * Note CMPCI_RECORD_SOURCE_CD, CMPCI_RECORD_SOURCE_LINE_IN and
1733 	 * CMPCI_RECORD_SOURCE_FM are defined to the corresponding bit
1734 	 * of the mixer register.
1735 	 */
1736 	bitsr = mask & (CMPCI_RECORD_SOURCE_CD | CMPCI_RECORD_SOURCE_LINE_IN |
1737 	    CMPCI_RECORD_SOURCE_FM);
1738 
1739 	bitsl = CMPCI_SB16_MIXER_SRC_R_TO_L(bitsr);
1740 	if (mask & CMPCI_RECORD_SOURCE_MIC) {
1741 		bitsl |= CMPCI_SB16_MIXER_MIC_SRC;
1742 		bitsr |= CMPCI_SB16_MIXER_MIC_SRC;
1743 	}
1744 	cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_L, bitsl);
1745 	cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_R, bitsr);
1746 
1747 	if (mask & CMPCI_RECORD_SOURCE_AUX_IN)
1748 		cmpci_reg_set_1(sc, CMPCI_REG_MIXER25,
1749 		    CMPCI_REG_RAUXREN | CMPCI_REG_RAUXLEN);
1750 	else
1751 		cmpci_reg_clear_1(sc, CMPCI_REG_MIXER25,
1752 		    CMPCI_REG_RAUXREN | CMPCI_REG_RAUXLEN);
1753 
1754 	if (mask & CMPCI_RECORD_SOURCE_WAVE)
1755 		cmpci_reg_set_1(sc, CMPCI_REG_MIXER24,
1756 		    CMPCI_REG_WAVEINL | CMPCI_REG_WAVEINR);
1757 	else
1758 		cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24,
1759 		    CMPCI_REG_WAVEINL | CMPCI_REG_WAVEINR);
1760 
1761 	if (CMPCI_ISCAP(sc, SPDIN) &&
1762 	    (sc->sc_ch1.md_divide == CMPCI_REG_RATE_44100 ||
1763 		(CMPCI_ISCAP(sc, SPDOUT_48K) &&
1764 		    sc->sc_ch1.md_divide == CMPCI_REG_RATE_48000/* XXX? */))) {
1765 		if (mask & CMPCI_RECORD_SOURCE_SPDIF) {
1766 			/* enable SPDIF/in */
1767 			cmpci_reg_set_4(sc,
1768 					CMPCI_REG_FUNC_1,
1769 					CMPCI_REG_SPDIF1_ENABLE);
1770 		} else {
1771 			cmpci_reg_clear_4(sc,
1772 					CMPCI_REG_FUNC_1,
1773 					CMPCI_REG_SPDIF1_ENABLE);
1774 		}
1775 	}
1776 
1777 	return 0;
1778 }
1779 
1780 int
1781 cmpci_set_port(void *handle, mixer_ctrl_t *cp)
1782 {
1783 	struct cmpci_softc *sc = handle;
1784 	int lgain, rgain;
1785 
1786 	switch (cp->dev) {
1787 	case CMPCI_MIC_VOL:
1788 	case CMPCI_PCSPEAKER:
1789 	case CMPCI_MIC_RECVOL:
1790 		if (cp->un.value.num_channels != 1)
1791 			return EINVAL;
1792 		/* FALLTHROUGH */
1793 	case CMPCI_DAC_VOL:
1794 	case CMPCI_FM_VOL:
1795 	case CMPCI_CD_VOL:
1796 	case CMPCI_LINE_IN_VOL:
1797 	case CMPCI_AUX_IN_VOL:
1798 	case CMPCI_MASTER_VOL:
1799 		if (cp->type != AUDIO_MIXER_VALUE)
1800 			return EINVAL;
1801 		switch (cp->un.value.num_channels) {
1802 		case 1:
1803 			lgain = rgain =
1804 			    cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
1805 			break;
1806 		case 2:
1807 			lgain = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
1808 			rgain = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
1809 			break;
1810 		default:
1811 			return EINVAL;
1812 		}
1813 		sc->sc_gain[cp->dev][CMPCI_LEFT]  = lgain;
1814 		sc->sc_gain[cp->dev][CMPCI_RIGHT] = rgain;
1815 
1816 		cmpci_set_mixer_gain(sc, cp->dev);
1817 		break;
1818 
1819 	case CMPCI_RECORD_SOURCE:
1820 		if (cp->type != AUDIO_MIXER_SET)
1821 			return EINVAL;
1822 
1823 		if (cp->un.mask & ~(CMPCI_RECORD_SOURCE_MIC |
1824 		    CMPCI_RECORD_SOURCE_CD | CMPCI_RECORD_SOURCE_LINE_IN |
1825 		    CMPCI_RECORD_SOURCE_AUX_IN | CMPCI_RECORD_SOURCE_WAVE |
1826 		    CMPCI_RECORD_SOURCE_FM | CMPCI_RECORD_SOURCE_SPDIF))
1827 			return EINVAL;
1828 
1829 		if (cp->un.mask & CMPCI_RECORD_SOURCE_SPDIF)
1830 			cp->un.mask = CMPCI_RECORD_SOURCE_SPDIF;
1831 
1832 		sc->sc_in_mask = cp->un.mask;
1833 		return cmpci_set_in_ports(sc);
1834 
1835 	/* boolean */
1836 	case CMPCI_DAC_MUTE:
1837 	case CMPCI_FM_MUTE:
1838 	case CMPCI_CD_MUTE:
1839 	case CMPCI_LINE_IN_MUTE:
1840 	case CMPCI_AUX_IN_MUTE:
1841 	case CMPCI_MIC_MUTE:
1842 	case CMPCI_MIC_PREAMP:
1843 	case CMPCI_PLAYBACK_MODE:
1844 	case CMPCI_SPDIF_IN_PHASE:
1845 	case CMPCI_SPDIF_LOOP:
1846 	case CMPCI_SPDIF_OUT_PLAYBACK:
1847 	case CMPCI_SPDIF_OUT_VOLTAGE:
1848 	case CMPCI_REAR:
1849 	case CMPCI_INDIVIDUAL:
1850 	case CMPCI_REVERSE:
1851 	case CMPCI_SURROUND:
1852 		if (cp->type != AUDIO_MIXER_ENUM)
1853 			return EINVAL;
1854 		sc->sc_gain[cp->dev][CMPCI_LR] = cp->un.ord != 0;
1855 		cmpci_set_mixer_gain(sc, cp->dev);
1856 		break;
1857 
1858 	case CMPCI_SPDIF_IN_SELECT:
1859 		switch (cp->un.ord) {
1860 		case CMPCI_SPDIF_IN_SPDIN1:
1861 		case CMPCI_SPDIF_IN_SPDIN2:
1862 		case CMPCI_SPDIF_IN_SPDOUT:
1863 			break;
1864 		default:
1865 			return EINVAL;
1866 		}
1867 		goto xenum;
1868 	case CMPCI_MONITOR_DAC:
1869 		switch (cp->un.ord) {
1870 		case CMPCI_MONITOR_DAC_OFF:
1871 		case CMPCI_MONITOR_DAC_SPDIN:
1872 		case CMPCI_MONITOR_DAC_SPDOUT:
1873 			break;
1874 		default:
1875 			return EINVAL;
1876 		}
1877 	xenum:
1878 		if (cp->type != AUDIO_MIXER_ENUM)
1879 			return EINVAL;
1880 		sc->sc_gain[cp->dev][CMPCI_LR] = cp->un.ord;
1881 		cmpci_set_mixer_gain(sc, cp->dev);
1882 		break;
1883 
1884 	default:
1885 	    return EINVAL;
1886 	}
1887 
1888 	return 0;
1889 }
1890 
1891 int
1892 cmpci_get_port(void *handle, mixer_ctrl_t *cp)
1893 {
1894 	struct cmpci_softc *sc = handle;
1895 
1896 	switch (cp->dev) {
1897 	case CMPCI_MIC_VOL:
1898 	case CMPCI_PCSPEAKER:
1899 	case CMPCI_MIC_RECVOL:
1900 		if (cp->un.value.num_channels != 1)
1901 			return EINVAL;
1902 		/*FALLTHROUGH*/
1903 	case CMPCI_DAC_VOL:
1904 	case CMPCI_FM_VOL:
1905 	case CMPCI_CD_VOL:
1906 	case CMPCI_LINE_IN_VOL:
1907 	case CMPCI_AUX_IN_VOL:
1908 	case CMPCI_MASTER_VOL:
1909 		switch (cp->un.value.num_channels) {
1910 		case 1:
1911 			cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1912 				sc->sc_gain[cp->dev][CMPCI_LEFT];
1913 			break;
1914 		case 2:
1915 			cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
1916 				sc->sc_gain[cp->dev][CMPCI_LEFT];
1917 			cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
1918 				sc->sc_gain[cp->dev][CMPCI_RIGHT];
1919 			break;
1920 		default:
1921 			return EINVAL;
1922 		}
1923 		break;
1924 
1925 	case CMPCI_RECORD_SOURCE:
1926 		cp->un.mask = sc->sc_in_mask;
1927 		break;
1928 
1929 	case CMPCI_DAC_MUTE:
1930 	case CMPCI_FM_MUTE:
1931 	case CMPCI_CD_MUTE:
1932 	case CMPCI_LINE_IN_MUTE:
1933 	case CMPCI_AUX_IN_MUTE:
1934 	case CMPCI_MIC_MUTE:
1935 	case CMPCI_MIC_PREAMP:
1936 	case CMPCI_PLAYBACK_MODE:
1937 	case CMPCI_SPDIF_IN_SELECT:
1938 	case CMPCI_SPDIF_IN_PHASE:
1939 	case CMPCI_SPDIF_LOOP:
1940 	case CMPCI_SPDIF_OUT_PLAYBACK:
1941 	case CMPCI_SPDIF_OUT_VOLTAGE:
1942 	case CMPCI_MONITOR_DAC:
1943 	case CMPCI_REAR:
1944 	case CMPCI_INDIVIDUAL:
1945 	case CMPCI_REVERSE:
1946 	case CMPCI_SURROUND:
1947 		cp->un.ord = sc->sc_gain[cp->dev][CMPCI_LR];
1948 		break;
1949 
1950 	default:
1951 		return EINVAL;
1952 	}
1953 
1954 	return 0;
1955 }
1956 
1957 /* ARGSUSED */
1958 size_t
1959 cmpci_round_buffersize(void *handle, int direction, size_t bufsize)
1960 {
1961 	if (bufsize > 0x10000)
1962 		bufsize = 0x10000;
1963 
1964 	return bufsize;
1965 }
1966 
1967 paddr_t
1968 cmpci_mappage(void *handle, void *addr, off_t offset, int prot)
1969 {
1970 	struct cmpci_softc *sc = handle;
1971 	struct cmpci_dmanode *p;
1972 
1973 	if (offset < 0 || NULL == (p = cmpci_find_dmamem(sc, addr)))
1974 		return -1;
1975 
1976 	return bus_dmamem_mmap(p->cd_tag, p->cd_segs,
1977 		   nitems(p->cd_segs), offset, prot, BUS_DMA_WAITOK);
1978 }
1979 
1980 /* ARGSUSED */
1981 int
1982 cmpci_get_props(void *handle)
1983 {
1984 	return AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX;
1985 }
1986 
1987 int
1988 cmpci_trigger_output(void *handle, void *start, void *end, int blksize,
1989     void (*intr)(void *), void *arg, struct audio_params *param)
1990 {
1991 	struct cmpci_softc *sc = handle;
1992 	struct cmpci_dmanode *p;
1993 	struct cmpci_channel *chan;
1994 	uint32_t reg_dma_base, reg_dma_bytes, reg_dma_samples, reg_dir,
1995 	    reg_intr_enable, reg_enable;
1996 	uint32_t length;
1997 	size_t buffer_size = (caddr_t)end - (caddr_t)start;
1998 
1999 	cmpci_set_out_ports(sc);
2000 
2001 	if (sc->sc_play_channel == 1) {
2002 		chan = &sc->sc_ch1;
2003 		reg_dma_base = CMPCI_REG_DMA1_BASE;
2004 		reg_dma_bytes = CMPCI_REG_DMA1_BYTES;
2005 		reg_dma_samples = CMPCI_REG_DMA1_SAMPLES;
2006 		reg_dir = CMPCI_REG_CH1_DIR;
2007 		reg_intr_enable = CMPCI_REG_CH1_INTR_ENABLE;
2008 		reg_enable = CMPCI_REG_CH1_ENABLE;
2009 	} else {
2010 		chan = &sc->sc_ch0;
2011 		reg_dma_base = CMPCI_REG_DMA0_BASE;
2012 		reg_dma_bytes = CMPCI_REG_DMA0_BYTES;
2013 		reg_dma_samples = CMPCI_REG_DMA0_SAMPLES;
2014 		reg_dir = CMPCI_REG_CH0_DIR;
2015 		reg_intr_enable = CMPCI_REG_CH0_INTR_ENABLE;
2016 		reg_enable = CMPCI_REG_CH0_ENABLE;
2017 	}
2018 
2019 	chan->bps = (param->channels > 1 ? 2 : 1) * param->bps * param->factor;
2020 	if (!chan->bps)
2021 		return EINVAL;
2022 
2023 	chan->intr = intr;
2024 	chan->intr_arg = arg;
2025 	chan->blksize = blksize;
2026 	chan->nblocks = buffer_size / chan->blksize;
2027 	chan->swpos = 0;
2028 
2029 	/* set DMA frame */
2030 	if (!(p = cmpci_find_dmamem(sc, start)))
2031 		return EINVAL;
2032 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, reg_dma_base,
2033 	    DMAADDR(p));
2034 	delay(10);
2035 	length = (buffer_size + 1) / chan->bps - 1;
2036 	bus_space_write_2(sc->sc_iot, sc->sc_ioh, reg_dma_bytes, length);
2037 	delay(10);
2038 
2039 	/* set interrupt count */
2040 	length = (chan->blksize + chan->bps - 1) / chan->bps - 1;
2041 	bus_space_write_2(sc->sc_iot, sc->sc_ioh, reg_dma_samples, length);
2042 	delay(10);
2043 
2044 	/* start DMA */
2045 	mtx_enter(&audio_lock);
2046 	cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, reg_dir); /* PLAY */
2047 	cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL, reg_intr_enable);
2048 	cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, reg_enable);
2049 	mtx_leave(&audio_lock);
2050 	return 0;
2051 }
2052 
2053 int
2054 cmpci_trigger_input(void *handle, void *start, void *end, int blksize,
2055     void (*intr)(void *), void *arg, struct audio_params *param)
2056 {
2057 	struct cmpci_softc *sc = handle;
2058 	struct cmpci_dmanode *p;
2059 	struct cmpci_channel *chan = &sc->sc_ch1;
2060 	size_t buffer_size = (caddr_t)end - (caddr_t)start;
2061 
2062 	cmpci_set_in_ports(sc);
2063 
2064 	chan->bps = param->channels * param->bps * param->factor;
2065 	if (!chan->bps)
2066 		return EINVAL;
2067 
2068 	chan->intr = intr;
2069 	chan->intr_arg = arg;
2070 	chan->blksize = blksize;
2071 	chan->nblocks = buffer_size / chan->blksize;
2072 	chan->swpos = 0;
2073 
2074 	/* set DMA frame */
2075 	if (!(p = cmpci_find_dmamem(sc, start)))
2076 		return EINVAL;
2077 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA1_BASE,
2078 	    DMAADDR(p));
2079 	delay(10);
2080 	bus_space_write_2(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA1_BYTES,
2081 	    (buffer_size + 1) / chan->bps - 1);
2082 	delay(10);
2083 
2084 	/* set interrupt count */
2085 	bus_space_write_2(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA1_SAMPLES,
2086 	    (chan->blksize + chan->bps - 1) / chan->bps - 1);
2087 	delay(10);
2088 
2089 	/* start DMA */
2090 	mtx_enter(&audio_lock);
2091 	cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_DIR); /* REC */
2092 	cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH1_INTR_ENABLE);
2093 	cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_ENABLE);
2094 	mtx_leave(&audio_lock);
2095 	return 0;
2096 }
2097 
2098 /* end of file */
2099