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