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