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