xref: /openbsd-src/sys/dev/pci/cmpci.c (revision a28daedfc357b214be5c701aa8ba8adb29a7f1c2)
1 /*	$OpenBSD: cmpci.c,v 1.22 2009/03/29 21:53:52 sthen 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(": can't map i/o space\n");
382 		return;
383 	}
384 
385 	/* interrupt */
386 	if (pci_intr_map(pa, &ih)) {
387 		printf(": can't 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(": can't 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 				p->channels = 2;
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 		if (p->precision > 16)
707 			p->precision = 16;
708 		p->sw_code = NULL;
709 		switch (p->channels) {
710 		case 1:
711 			md_format = CMPCI_REG_FORMAT_MONO;
712 			break;
713 		case 2:
714 			md_format = CMPCI_REG_FORMAT_STEREO;
715 			break;
716 		case 4:
717 			if (mode & AUMODE_PLAY) {
718 				if (sc->sc_capable & CMPCI_CAP_4CH) {
719 					cmpci_reg_clear_reg_misc(sc,
720 					    CMPCI_REG_N4SPK3D);
721 					cmpci_reg_set_4(sc,
722 					    CMPCI_REG_CHANNEL_FORMAT,
723 					    CMPCI_REG_CHB3D);
724 					cmpci_reg_set_4(sc,
725 					    CMPCI_REG_LEGACY_CTRL,
726 					    CMPCI_REG_NXCHG);
727 				} else
728 					p->channels = 2;
729 			}
730 			md_format = CMPCI_REG_FORMAT_STEREO;
731 			break;
732 		case 6:
733 			if (mode & AUMODE_PLAY) {
734 				if (sc->sc_capable & CMPCI_CAP_6CH) {
735 					cmpci_reg_clear_reg_misc(sc,
736 					    CMPCI_REG_N4SPK3D);
737 					cmpci_reg_set_4(sc,
738 					    CMPCI_REG_CHANNEL_FORMAT,
739 					    CMPCI_REG_CHB3D5C);
740 					cmpci_reg_set_4(sc,
741 					    CMPCI_REG_LEGACY_CTRL,
742 					    CMPCI_REG_CHB3D6C);
743 					cmpci_reg_set_reg_misc(sc,
744 					    CMPCI_REG_ENCENTER);
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 		case 8:
754 			if (mode & AUMODE_PLAY) {
755 				if (sc->sc_capable & CMPCI_CAP_8CH) {
756 					cmpci_reg_clear_reg_misc(sc,
757 					    CMPCI_REG_N4SPK3D);
758 					cmpci_reg_set_4(sc,
759 					    CMPCI_REG_CHANNEL_FORMAT,
760 					    CMPCI_REG_CHB3D5C);
761 					cmpci_reg_set_4(sc,
762 					    CMPCI_REG_LEGACY_CTRL,
763 					    CMPCI_REG_CHB3D6C);
764 					cmpci_reg_set_reg_misc(sc,
765 					    CMPCI_REG_ENCENTER);
766 					cmpci_reg_set_4(sc,
767 					    CMPCI_REG_8768_MISC,
768 					    CMPCI_REG_CHB3D8C);
769 					cmpci_reg_set_4(sc,
770 					    CMPCI_REG_LEGACY_CTRL,
771 					    CMPCI_REG_NXCHG);
772 				} else
773 					p->channels = 2;
774 			}
775 			md_format = CMPCI_REG_FORMAT_STEREO;
776 			break;
777 		default:
778 			return (EINVAL);
779 		}
780 		switch (p->encoding) {
781 		case AUDIO_ENCODING_ULAW:
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 (mode & AUMODE_PLAY) {
793 				p->factor = 2;
794 				p->sw_code = alaw_to_slinear16_le;
795 				md_format |= CMPCI_REG_FORMAT_16BIT;
796 			} else {
797 				p->sw_code = ulinear8_to_alaw;
798 				md_format |= CMPCI_REG_FORMAT_8BIT;
799 			}
800 			break;
801 		case AUDIO_ENCODING_SLINEAR_LE:
802 			switch (p->precision) {
803 			case 8:
804 				p->sw_code = change_sign8;
805 				md_format |= CMPCI_REG_FORMAT_8BIT;
806 				break;
807 			case 16:
808 				md_format |= CMPCI_REG_FORMAT_16BIT;
809 				break;
810 			default:
811 				return (EINVAL);
812 			}
813 			break;
814 		case AUDIO_ENCODING_SLINEAR_BE:
815 			switch (p->precision) {
816 			case 8:
817 				md_format |= CMPCI_REG_FORMAT_8BIT;
818 				p->sw_code = change_sign8;
819 				break;
820 			case 16:
821 				md_format |= CMPCI_REG_FORMAT_16BIT;
822 				p->sw_code = swap_bytes;
823 				break;
824 			default:
825 				return (EINVAL);
826 			}
827 			break;
828 		case AUDIO_ENCODING_ULINEAR_LE:
829 			switch (p->precision) {
830 			case 8:
831 				md_format |= CMPCI_REG_FORMAT_8BIT;
832 				break;
833 			case 16:
834 				md_format |= CMPCI_REG_FORMAT_16BIT;
835 				p->sw_code = change_sign16_le;
836 				break;
837 			default:
838 				return (EINVAL);
839 			}
840 			break;
841 		case AUDIO_ENCODING_ULINEAR_BE:
842 			switch (p->precision) {
843 			case 8:
844 				md_format |= CMPCI_REG_FORMAT_8BIT;
845 				break;
846 			case 16:
847 				md_format |= CMPCI_REG_FORMAT_16BIT;
848 				if (mode & AUMODE_PLAY)
849 					p->sw_code =
850 					    swap_bytes_change_sign16_le;
851 				else
852 					p->sw_code =
853 					    change_sign16_swap_bytes_le;
854 				break;
855 			default:
856 				return (EINVAL);
857 			}
858 			break;
859 		default:
860 			return (EINVAL);
861 		}
862 		if (mode & AUMODE_PLAY) {
863 			if (sc->sc_play_channel == 1) {
864 				cmpci_reg_partial_write_4(sc,
865 				   CMPCI_REG_CHANNEL_FORMAT,
866 				   CMPCI_REG_CH1_FORMAT_SHIFT,
867 				   CMPCI_REG_CH1_FORMAT_MASK, md_format);
868 			} else {
869 				cmpci_reg_partial_write_4(sc,
870 				   CMPCI_REG_CHANNEL_FORMAT,
871 				   CMPCI_REG_CH0_FORMAT_SHIFT,
872 				   CMPCI_REG_CH0_FORMAT_MASK, md_format);
873 			}
874 		} else {
875 			cmpci_reg_partial_write_4(sc,
876 			   CMPCI_REG_CHANNEL_FORMAT,
877 			   CMPCI_REG_CH1_FORMAT_SHIFT,
878 			   CMPCI_REG_CH1_FORMAT_MASK, md_format);
879 		}
880 		/* sample rate */
881 		md_index = cmpci_rate_to_index(p->sample_rate);
882 		md_divide = cmpci_index_to_divider(md_index);
883 		p->sample_rate = cmpci_index_to_rate(md_index);
884 		DPRINTF(("%s: sample:%d, divider=%d\n",
885 			 sc->sc_dev.dv_xname, (int)p->sample_rate, md_divide));
886 		if (mode & AUMODE_PLAY) {
887 			if (sc->sc_play_channel == 1) {
888 				cmpci_reg_partial_write_4(sc,
889 				    CMPCI_REG_FUNC_1, CMPCI_REG_ADC_FS_SHIFT,
890 				    CMPCI_REG_ADC_FS_MASK, md_divide);
891 				sc->sc_ch1.md_divide = md_divide;
892 			} else {
893 				cmpci_reg_partial_write_4(sc,
894 				    CMPCI_REG_FUNC_1, CMPCI_REG_DAC_FS_SHIFT,
895 				    CMPCI_REG_DAC_FS_MASK, md_divide);
896 				sc->sc_ch0.md_divide = md_divide;
897 			}
898 		} else {
899 			cmpci_reg_partial_write_4(sc,
900 			    CMPCI_REG_FUNC_1, CMPCI_REG_ADC_FS_SHIFT,
901 			    CMPCI_REG_ADC_FS_MASK, md_divide);
902 			sc->sc_ch1.md_divide = md_divide;
903 		}
904 		cmpci_set_out_ports(sc);
905 		cmpci_set_in_ports(sc);
906 	}
907 	return 0;
908 }
909 
910 /* ARGSUSED */
911 int
912 cmpci_round_blocksize(void *handle, int block)
913 {
914 	return ((block + 3) & -4);
915 }
916 
917 int
918 cmpci_halt_output(void *handle)
919 {
920 	struct cmpci_softc *sc = handle;
921 	uint32_t reg_intr, reg_enable, reg_reset;
922 	int s;
923 
924 	s = splaudio();
925 	if (sc->sc_play_channel == 1) {
926 		sc->sc_ch1.intr = NULL;
927 		reg_intr = CMPCI_REG_CH1_INTR_ENABLE;
928 		reg_enable = CMPCI_REG_CH1_ENABLE;
929 		reg_reset = CMPCI_REG_CH1_RESET;
930 	} else {
931 		sc->sc_ch0.intr = NULL;
932 		reg_intr = CMPCI_REG_CH0_INTR_ENABLE;
933 		reg_enable = CMPCI_REG_CH0_ENABLE;
934 		reg_reset = CMPCI_REG_CH0_RESET;
935 	}
936 	cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL, reg_intr);
937 	cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, reg_enable);
938 	/* wait for reset DMA */
939 	cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, reg_reset);
940 	delay(10);
941 	cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, reg_reset);
942 	splx(s);
943 
944 	return 0;
945 }
946 
947 int
948 cmpci_halt_input(void *handle)
949 {
950 	struct cmpci_softc *sc = handle;
951 	int s;
952 
953 	s = splaudio();
954 	sc->sc_ch1.intr = NULL;
955 	cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH1_INTR_ENABLE);
956 	cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_ENABLE);
957 	/* wait for reset DMA */
958 	cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_RESET);
959 	delay(10);
960 	cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_RESET);
961 	splx(s);
962 
963 	return 0;
964 }
965 
966 /* get audio device information */
967 int
968 cmpci_getdev(void *handle, struct audio_device *ad)
969 {
970 	struct cmpci_softc *sc = handle;
971 
972 	strncpy(ad->name, "CMI PCI Audio", sizeof(ad->name));
973 	snprintf(ad->version, sizeof(ad->version), "0x%02x (%d)",
974 		 PCI_REVISION(sc->sc_class), sc->sc_version);
975 	switch (PCI_PRODUCT(sc->sc_id)) {
976 	case PCI_PRODUCT_CMI_CMI8338A:
977 		strncpy(ad->config, "CMI8338A", sizeof(ad->config));
978 		break;
979 	case PCI_PRODUCT_CMI_CMI8338B:
980 		strncpy(ad->config, "CMI8338B", sizeof(ad->config));
981 		break;
982 	case PCI_PRODUCT_CMI_CMI8738:
983 		strncpy(ad->config, "CMI8738", sizeof(ad->config));
984 		break;
985 	case PCI_PRODUCT_CMI_CMI8738B:
986 		strncpy(ad->config, "CMI8738B", sizeof(ad->config));
987 		break;
988 	default:
989 		strncpy(ad->config, "unknown", sizeof(ad->config));
990 	}
991 
992 	return 0;
993 }
994 
995 /* mixer device information */
996 int
997 cmpci_query_devinfo(void *handle, mixer_devinfo_t *dip)
998 {
999 	static const char *const mixer_port_names[] = {
1000 		AudioNdac, AudioNfmsynth, AudioNcd, AudioNline, AudioNaux,
1001 		AudioNmicrophone
1002 	};
1003 	static const char *const mixer_classes[] = {
1004 		AudioCinputs, AudioCoutputs, AudioCrecord, CmpciCplayback,
1005 		CmpciCspdif
1006 	};
1007 	struct cmpci_softc *sc = handle;
1008 	int i;
1009 
1010 	dip->prev = dip->next = AUDIO_MIXER_LAST;
1011 
1012 	switch (dip->index) {
1013 	case CMPCI_INPUT_CLASS:
1014 	case CMPCI_OUTPUT_CLASS:
1015 	case CMPCI_RECORD_CLASS:
1016 	case CMPCI_PLAYBACK_CLASS:
1017 	case CMPCI_SPDIF_CLASS:
1018 		dip->type = AUDIO_MIXER_CLASS;
1019 		dip->mixer_class = dip->index;
1020 		strlcpy(dip->label.name,
1021 		    mixer_classes[dip->index - CMPCI_INPUT_CLASS],
1022 		    sizeof dip->label.name);
1023 		return 0;
1024 
1025 	case CMPCI_AUX_IN_VOL:
1026 		dip->un.v.delta = 1 << (8 - CMPCI_REG_AUX_VALBITS);
1027 		goto vol1;
1028 	case CMPCI_DAC_VOL:
1029 	case CMPCI_FM_VOL:
1030 	case CMPCI_CD_VOL:
1031 	case CMPCI_LINE_IN_VOL:
1032 	case CMPCI_MIC_VOL:
1033 		dip->un.v.delta = 1 << (8 - CMPCI_SB16_MIXER_VALBITS);
1034 	vol1:	dip->mixer_class = CMPCI_INPUT_CLASS;
1035 		dip->next = dip->index + 6;	/* CMPCI_xxx_MUTE */
1036 		strlcpy(dip->label.name, mixer_port_names[dip->index],
1037 		    sizeof dip->label.name);
1038 		dip->un.v.num_channels = (dip->index == CMPCI_MIC_VOL ? 1 : 2);
1039 	vol:
1040 		dip->type = AUDIO_MIXER_VALUE;
1041 		strlcpy(dip->un.v.units.name, AudioNvolume,
1042 		    sizeof dip->un.v.units.name);
1043 		return 0;
1044 
1045 	case CMPCI_MIC_MUTE:
1046 		dip->next = CMPCI_MIC_PREAMP;
1047 		/* FALLTHROUGH */
1048 	case CMPCI_DAC_MUTE:
1049 	case CMPCI_FM_MUTE:
1050 	case CMPCI_CD_MUTE:
1051 	case CMPCI_LINE_IN_MUTE:
1052 	case CMPCI_AUX_IN_MUTE:
1053 		dip->prev = dip->index - 6;	/* CMPCI_xxx_VOL */
1054 		dip->mixer_class = CMPCI_INPUT_CLASS;
1055 		strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name);
1056 		goto on_off;
1057 	on_off:
1058 		dip->type = AUDIO_MIXER_ENUM;
1059 		dip->un.e.num_mem = 2;
1060 		strlcpy(dip->un.e.member[0].label.name, AudioNoff,
1061 		    sizeof dip->un.e.member[0].label.name);
1062 		dip->un.e.member[0].ord = 0;
1063 		strlcpy(dip->un.e.member[1].label.name, AudioNon,
1064 		    sizeof dip->un.e.member[1].label.name);
1065 		dip->un.e.member[1].ord = 1;
1066 		return 0;
1067 
1068 	case CMPCI_MIC_PREAMP:
1069 		dip->mixer_class = CMPCI_INPUT_CLASS;
1070 		dip->prev = CMPCI_MIC_MUTE;
1071 		strlcpy(dip->label.name, AudioNpreamp, sizeof dip->label.name);
1072 		goto on_off;
1073 	case CMPCI_PCSPEAKER:
1074 		dip->mixer_class = CMPCI_INPUT_CLASS;
1075 		strlcpy(dip->label.name, AudioNspeaker, sizeof dip->label.name);
1076 		dip->un.v.num_channels = 1;
1077 		dip->un.v.delta = 1 << (8 - CMPCI_SB16_MIXER_SPEAKER_VALBITS);
1078 		goto vol;
1079 	case CMPCI_RECORD_SOURCE:
1080 		dip->mixer_class = CMPCI_RECORD_CLASS;
1081 		strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name);
1082 		dip->type = AUDIO_MIXER_SET;
1083 		dip->un.s.num_mem = 7;
1084 		strlcpy(dip->un.s.member[0].label.name, AudioNmicrophone,
1085 		    sizeof dip->un.s.member[0].label.name);
1086 		dip->un.s.member[0].mask = CMPCI_RECORD_SOURCE_MIC;
1087 		strlcpy(dip->un.s.member[1].label.name, AudioNcd,
1088 		    sizeof dip->un.s.member[1].label.name);
1089 		dip->un.s.member[1].mask = CMPCI_RECORD_SOURCE_CD;
1090 		strlcpy(dip->un.s.member[2].label.name, AudioNline,
1091 		    sizeof dip->un.s.member[2].label.name);
1092 		dip->un.s.member[2].mask = CMPCI_RECORD_SOURCE_LINE_IN;
1093 		strlcpy(dip->un.s.member[3].label.name, AudioNaux,
1094 		    sizeof dip->un.s.member[3].label.name);
1095 		dip->un.s.member[3].mask = CMPCI_RECORD_SOURCE_AUX_IN;
1096 		strlcpy(dip->un.s.member[4].label.name, AudioNwave,
1097 		    sizeof dip->un.s.member[4].label.name);
1098 		dip->un.s.member[4].mask = CMPCI_RECORD_SOURCE_WAVE;
1099 		strlcpy(dip->un.s.member[5].label.name, AudioNfmsynth,
1100 		    sizeof dip->un.s.member[5].label.name);
1101 		dip->un.s.member[5].mask = CMPCI_RECORD_SOURCE_FM;
1102 		strlcpy(dip->un.s.member[6].label.name, CmpciNspdif,
1103 		    sizeof dip->un.s.member[6].label.name);
1104 		dip->un.s.member[6].mask = CMPCI_RECORD_SOURCE_SPDIF;
1105 		return 0;
1106 	case CMPCI_MIC_RECVOL:
1107 		dip->mixer_class = CMPCI_RECORD_CLASS;
1108 		strlcpy(dip->label.name, AudioNmicrophone, sizeof dip->label.name);
1109 		dip->un.v.num_channels = 1;
1110 		dip->un.v.delta = 1 << (8 - CMPCI_REG_ADMIC_VALBITS);
1111 		goto vol;
1112 
1113 	case CMPCI_PLAYBACK_MODE:
1114 		dip->mixer_class = CMPCI_PLAYBACK_CLASS;
1115 		dip->type = AUDIO_MIXER_ENUM;
1116 		strlcpy(dip->label.name, AudioNmode, sizeof dip->label.name);
1117 		dip->un.e.num_mem = 2;
1118 		strlcpy(dip->un.e.member[0].label.name, AudioNdac,
1119 		    sizeof dip->un.e.member[0].label.name);
1120 		dip->un.e.member[0].ord = CMPCI_PLAYBACK_MODE_WAVE;
1121 		strlcpy(dip->un.e.member[1].label.name, CmpciNspdif,
1122 		    sizeof dip->un.e.member[1].label.name);
1123 		dip->un.e.member[1].ord = CMPCI_PLAYBACK_MODE_SPDIF;
1124 		return 0;
1125 	case CMPCI_SPDIF_IN_SELECT:
1126 		dip->mixer_class = CMPCI_SPDIF_CLASS;
1127 		dip->type = AUDIO_MIXER_ENUM;
1128 		dip->next = CMPCI_SPDIF_IN_PHASE;
1129 		strlcpy(dip->label.name, AudioNinput, sizeof dip->label.name);
1130 		i = 0;
1131 		strlcpy(dip->un.e.member[i].label.name, CmpciNspdin1,
1132 		    sizeof dip->un.e.member[i].label.name);
1133 		dip->un.e.member[i++].ord = CMPCI_SPDIF_IN_SPDIN1;
1134 		if (CMPCI_ISCAP(sc, 2ND_SPDIN)) {
1135 			strlcpy(dip->un.e.member[i].label.name, CmpciNspdin2,
1136 			    sizeof dip->un.e.member[i].label.name);
1137 			dip->un.e.member[i++].ord = CMPCI_SPDIF_IN_SPDIN2;
1138 		}
1139 		strlcpy(dip->un.e.member[i].label.name, CmpciNspdout,
1140 		    sizeof dip->un.e.member[i].label.name);
1141 		dip->un.e.member[i++].ord = CMPCI_SPDIF_IN_SPDOUT;
1142 		dip->un.e.num_mem = i;
1143 		return 0;
1144 	case CMPCI_SPDIF_IN_PHASE:
1145 		dip->mixer_class = CMPCI_SPDIF_CLASS;
1146 		dip->prev = CMPCI_SPDIF_IN_SELECT;
1147 		strlcpy(dip->label.name, CmpciNphase, sizeof dip->label.name);
1148 		dip->type = AUDIO_MIXER_ENUM;
1149 		dip->un.e.num_mem = 2;
1150 		strlcpy(dip->un.e.member[0].label.name, CmpciNpositive,
1151 		    sizeof dip->un.e.member[0].label.name);
1152 		dip->un.e.member[0].ord = CMPCI_SPDIF_IN_PHASE_POSITIVE;
1153 		strlcpy(dip->un.e.member[1].label.name, CmpciNnegative,
1154 		    sizeof dip->un.e.member[1].label.name);
1155 		dip->un.e.member[1].ord = CMPCI_SPDIF_IN_PHASE_NEGATIVE;
1156 		return 0;
1157 	case CMPCI_SPDIF_LOOP:
1158 		dip->mixer_class = CMPCI_SPDIF_CLASS;
1159 		dip->next = CMPCI_SPDIF_OUT_PLAYBACK;
1160 		strlcpy(dip->label.name, AudioNoutput, sizeof dip->label.name);
1161 		dip->type = AUDIO_MIXER_ENUM;
1162 		dip->un.e.num_mem = 2;
1163 		strlcpy(dip->un.e.member[0].label.name, CmpciNplayback,
1164 		    sizeof dip->un.e.member[0].label.name);
1165 		dip->un.e.member[0].ord = CMPCI_SPDIF_LOOP_OFF;
1166 		strlcpy(dip->un.e.member[1].label.name, CmpciNspdin,
1167 		    sizeof dip->un.e.member[1].label.name);
1168 		dip->un.e.member[1].ord = CMPCI_SPDIF_LOOP_ON;
1169 		return 0;
1170 	case CMPCI_SPDIF_OUT_PLAYBACK:
1171 		dip->mixer_class = CMPCI_SPDIF_CLASS;
1172 		dip->prev = CMPCI_SPDIF_LOOP;
1173 		dip->next = CMPCI_SPDIF_OUT_VOLTAGE;
1174 		strlcpy(dip->label.name, CmpciNplayback, sizeof dip->label.name);
1175 		dip->type = AUDIO_MIXER_ENUM;
1176 		dip->un.e.num_mem = 2;
1177 		strlcpy(dip->un.e.member[0].label.name, AudioNwave,
1178 		    sizeof dip->un.e.member[0].label.name);
1179 		dip->un.e.member[0].ord = CMPCI_SPDIF_OUT_PLAYBACK_WAVE;
1180 		strlcpy(dip->un.e.member[1].label.name, CmpciNlegacy,
1181 		    sizeof dip->un.e.member[1].label.name);
1182 		dip->un.e.member[1].ord = CMPCI_SPDIF_OUT_PLAYBACK_LEGACY;
1183 		return 0;
1184 	case CMPCI_SPDIF_OUT_VOLTAGE:
1185 		dip->mixer_class = CMPCI_SPDIF_CLASS;
1186 		dip->prev = CMPCI_SPDIF_OUT_PLAYBACK;
1187 		strlcpy(dip->label.name, CmpciNvoltage, sizeof dip->label.name);
1188 		dip->type = AUDIO_MIXER_ENUM;
1189 		dip->un.e.num_mem = 2;
1190 		strlcpy(dip->un.e.member[0].label.name, CmpciNhigh_v,
1191 		    sizeof dip->un.e.member[0].label.name);
1192 		dip->un.e.member[0].ord = CMPCI_SPDIF_OUT_VOLTAGE_HIGH;
1193 		strlcpy(dip->un.e.member[1].label.name, CmpciNlow_v,
1194 		    sizeof dip->un.e.member[1].label.name);
1195 		dip->un.e.member[1].ord = CMPCI_SPDIF_OUT_VOLTAGE_LOW;
1196 		return 0;
1197 	case CMPCI_MONITOR_DAC:
1198 		dip->mixer_class = CMPCI_SPDIF_CLASS;
1199 		strlcpy(dip->label.name, AudioNmonitor, sizeof dip->label.name);
1200 		dip->type = AUDIO_MIXER_ENUM;
1201 		dip->un.e.num_mem = 3;
1202 		strlcpy(dip->un.e.member[0].label.name, AudioNoff,
1203 		    sizeof dip->un.e.member[0].label.name);
1204 		dip->un.e.member[0].ord = CMPCI_MONITOR_DAC_OFF;
1205 		strlcpy(dip->un.e.member[1].label.name, CmpciNspdin,
1206 		    sizeof dip->un.e.member[1].label.name);
1207 		dip->un.e.member[1].ord = CMPCI_MONITOR_DAC_SPDIN;
1208 		strlcpy(dip->un.e.member[2].label.name, CmpciNspdout,
1209 		    sizeof dip->un.e.member[2].label.name);
1210 		dip->un.e.member[2].ord = CMPCI_MONITOR_DAC_SPDOUT;
1211 		return 0;
1212 
1213 	case CMPCI_MASTER_VOL:
1214 		dip->mixer_class = CMPCI_OUTPUT_CLASS;
1215 		strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name);
1216 		dip->un.v.num_channels = 2;
1217 		dip->un.v.delta = 1 << (8 - CMPCI_SB16_MIXER_VALBITS);
1218 		goto vol;
1219 	case CMPCI_REAR:
1220 		dip->mixer_class = CMPCI_OUTPUT_CLASS;
1221 		dip->next = CMPCI_INDIVIDUAL;
1222 		strlcpy(dip->label.name, CmpciNrear, sizeof dip->label.name);
1223 		goto on_off;
1224 	case CMPCI_INDIVIDUAL:
1225 		dip->mixer_class = CMPCI_OUTPUT_CLASS;
1226 		dip->prev = CMPCI_REAR;
1227 		dip->next = CMPCI_REVERSE;
1228 		strlcpy(dip->label.name, CmpciNindividual, sizeof dip->label.name);
1229 		goto on_off;
1230 	case CMPCI_REVERSE:
1231 		dip->mixer_class = CMPCI_OUTPUT_CLASS;
1232 		dip->prev = CMPCI_INDIVIDUAL;
1233 		strlcpy(dip->label.name, CmpciNreverse, sizeof dip->label.name);
1234 		goto on_off;
1235 	case CMPCI_SURROUND:
1236 		dip->mixer_class = CMPCI_OUTPUT_CLASS;
1237 		strlcpy(dip->label.name, CmpciNsurround, sizeof dip->label.name);
1238 		goto on_off;
1239 	}
1240 
1241 	return ENXIO;
1242 }
1243 
1244 int
1245 cmpci_alloc_dmamem(struct cmpci_softc *sc, size_t size, int type, int flags,
1246     caddr_t *r_addr)
1247 {
1248 	int error = 0;
1249 	struct cmpci_dmanode *n;
1250 	int w;
1251 
1252 	n = malloc(sizeof(struct cmpci_dmanode), type, flags);
1253 	if (n == NULL) {
1254 		error = ENOMEM;
1255 		goto quit;
1256 	}
1257 
1258 	w = (flags & M_NOWAIT) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK;
1259 #define CMPCI_DMABUF_ALIGN    0x4
1260 #define CMPCI_DMABUF_BOUNDARY 0x0
1261 	n->cd_tag = sc->sc_dmat;
1262 	n->cd_size = size;
1263 	error = bus_dmamem_alloc(n->cd_tag, n->cd_size,
1264 	    CMPCI_DMABUF_ALIGN, CMPCI_DMABUF_BOUNDARY, n->cd_segs,
1265 	    sizeof(n->cd_segs)/sizeof(n->cd_segs[0]), &n->cd_nsegs, w);
1266 	if (error)
1267 		goto mfree;
1268 	error = bus_dmamem_map(n->cd_tag, n->cd_segs, n->cd_nsegs, n->cd_size,
1269 	    &n->cd_addr, w | BUS_DMA_COHERENT);
1270 	if (error)
1271 		goto dmafree;
1272 	error = bus_dmamap_create(n->cd_tag, n->cd_size, 1, n->cd_size, 0,
1273 	    w, &n->cd_map);
1274 	if (error)
1275 		goto unmap;
1276 	error = bus_dmamap_load(n->cd_tag, n->cd_map, n->cd_addr, n->cd_size,
1277 	    NULL, w);
1278 	if (error)
1279 		goto destroy;
1280 
1281 	n->cd_next = sc->sc_dmap;
1282 	sc->sc_dmap = n;
1283 	*r_addr = KVADDR(n);
1284 	return 0;
1285 
1286  destroy:
1287 	bus_dmamap_destroy(n->cd_tag, n->cd_map);
1288  unmap:
1289 	bus_dmamem_unmap(n->cd_tag, n->cd_addr, n->cd_size);
1290  dmafree:
1291 	bus_dmamem_free(n->cd_tag,
1292 			n->cd_segs, sizeof(n->cd_segs)/sizeof(n->cd_segs[0]));
1293  mfree:
1294 	free(n, type);
1295  quit:
1296 	return error;
1297 }
1298 
1299 int
1300 cmpci_free_dmamem(struct cmpci_softc *sc, caddr_t addr, int type)
1301 {
1302 	struct cmpci_dmanode **nnp;
1303 
1304 	for (nnp = &sc->sc_dmap; *nnp; nnp = &(*nnp)->cd_next) {
1305 		if ((*nnp)->cd_addr == addr) {
1306 			struct cmpci_dmanode *n = *nnp;
1307 			bus_dmamap_unload(n->cd_tag, n->cd_map);
1308 			bus_dmamap_destroy(n->cd_tag, n->cd_map);
1309 			bus_dmamem_unmap(n->cd_tag, n->cd_addr, n->cd_size);
1310 			bus_dmamem_free(n->cd_tag, n->cd_segs,
1311 			    sizeof(n->cd_segs)/sizeof(n->cd_segs[0]));
1312 			free(n, type);
1313 			return 0;
1314 		}
1315 	}
1316 	return -1;
1317 }
1318 
1319 struct cmpci_dmanode *
1320 cmpci_find_dmamem(struct cmpci_softc *sc, caddr_t addr)
1321 {
1322 	struct cmpci_dmanode *p;
1323 
1324 	for (p = sc->sc_dmap; p; p = p->cd_next) {
1325 		if (KVADDR(p) == (void *)addr)
1326 			break;
1327 	}
1328 	return p;
1329 }
1330 
1331 #if 0
1332 void cmpci_print_dmamem(struct cmpci_dmanode *p);
1333 
1334 void
1335 cmpci_print_dmamem(struct cmpci_dmanode *p)
1336 {
1337 	DPRINTF(("DMA at virt:%p, dmaseg:%p, mapseg:%p, size:%p\n",
1338 		 (void *)p->cd_addr, (void *)p->cd_segs[0].ds_addr,
1339 		 (void *)DMAADDR(p), (void *)p->cd_size));
1340 }
1341 #endif /* DEBUG */
1342 
1343 void *
1344 cmpci_malloc(void *handle, int direction, size_t size, int type,
1345     int flags)
1346 {
1347 	caddr_t addr;
1348 
1349 	if (cmpci_alloc_dmamem(handle, size, type, flags, &addr))
1350 		return NULL;
1351 	return addr;
1352 }
1353 
1354 void
1355 cmpci_free(void *handle, void *addr, int type)
1356 {
1357 	cmpci_free_dmamem(handle, addr, type);
1358 }
1359 
1360 #define MAXVAL 256
1361 int
1362 cmpci_adjust(int val, int mask)
1363 {
1364 	val += (MAXVAL - mask) >> 1;
1365 	if (val >= MAXVAL)
1366 		val = MAXVAL-1;
1367 	return val & mask;
1368 }
1369 
1370 void
1371 cmpci_set_mixer_gain(struct cmpci_softc *sc, int port)
1372 {
1373 	int src;
1374 	int bits, mask;
1375 
1376 	switch (port) {
1377 	case CMPCI_MIC_VOL:
1378 		cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_MIC,
1379 		    CMPCI_ADJUST_MIC_GAIN(sc, sc->sc_gain[port][CMPCI_LR]));
1380 		return;
1381 	case CMPCI_MASTER_VOL:
1382 		src = CMPCI_SB16_MIXER_MASTER_L;
1383 		break;
1384 	case CMPCI_LINE_IN_VOL:
1385 		src = CMPCI_SB16_MIXER_LINE_L;
1386 		break;
1387 	case CMPCI_AUX_IN_VOL:
1388 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, CMPCI_REG_MIXER_AUX,
1389 		    CMPCI_ADJUST_AUX_GAIN(sc, sc->sc_gain[port][CMPCI_LEFT],
1390 					      sc->sc_gain[port][CMPCI_RIGHT]));
1391 		return;
1392 	case CMPCI_MIC_RECVOL:
1393 		cmpci_reg_partial_write_1(sc, CMPCI_REG_MIXER25,
1394 		    CMPCI_REG_ADMIC_SHIFT, CMPCI_REG_ADMIC_MASK,
1395 		    CMPCI_ADJUST_ADMIC_GAIN(sc, sc->sc_gain[port][CMPCI_LR]));
1396 		return;
1397 	case CMPCI_DAC_VOL:
1398 		src = CMPCI_SB16_MIXER_VOICE_L;
1399 		break;
1400 	case CMPCI_FM_VOL:
1401 		src = CMPCI_SB16_MIXER_FM_L;
1402 		break;
1403 	case CMPCI_CD_VOL:
1404 		src = CMPCI_SB16_MIXER_CDDA_L;
1405 		break;
1406 	case CMPCI_PCSPEAKER:
1407 		cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_SPEAKER,
1408 		    CMPCI_ADJUST_2_GAIN(sc, sc->sc_gain[port][CMPCI_LR]));
1409 		return;
1410 	case CMPCI_MIC_PREAMP:
1411 		if (sc->sc_gain[port][CMPCI_LR])
1412 			cmpci_reg_clear_1(sc, CMPCI_REG_MIXER25,
1413 			    CMPCI_REG_MICGAINZ);
1414 		else
1415 			cmpci_reg_set_1(sc, CMPCI_REG_MIXER25,
1416 			    CMPCI_REG_MICGAINZ);
1417 		return;
1418 
1419 	case CMPCI_DAC_MUTE:
1420 		if (sc->sc_gain[port][CMPCI_LR])
1421 			cmpci_reg_set_1(sc, CMPCI_REG_MIXER24,
1422 			    CMPCI_REG_WSMUTE);
1423 		else
1424 			cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24,
1425 			    CMPCI_REG_WSMUTE);
1426 		return;
1427 	case CMPCI_FM_MUTE:
1428 		if (sc->sc_gain[port][CMPCI_LR])
1429 			cmpci_reg_set_1(sc, CMPCI_REG_MIXER24,
1430 			    CMPCI_REG_FMMUTE);
1431 		else
1432 			cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24,
1433 			    CMPCI_REG_FMMUTE);
1434 		return;
1435 	case CMPCI_AUX_IN_MUTE:
1436 		if (sc->sc_gain[port][CMPCI_LR])
1437 			cmpci_reg_clear_1(sc, CMPCI_REG_MIXER25,
1438 			    CMPCI_REG_VAUXRM|CMPCI_REG_VAUXLM);
1439 		else
1440 			cmpci_reg_set_1(sc, CMPCI_REG_MIXER25,
1441 			    CMPCI_REG_VAUXRM|CMPCI_REG_VAUXLM);
1442 		return;
1443 	case CMPCI_CD_MUTE:
1444 		mask = CMPCI_SB16_SW_CD;
1445 		goto sbmute;
1446 	case CMPCI_MIC_MUTE:
1447 		mask = CMPCI_SB16_SW_MIC;
1448 		goto sbmute;
1449 	case CMPCI_LINE_IN_MUTE:
1450 		mask = CMPCI_SB16_SW_LINE;
1451 	sbmute:
1452 		bits = cmpci_mixerreg_read(sc, CMPCI_SB16_MIXER_OUTMIX);
1453 		if (sc->sc_gain[port][CMPCI_LR])
1454 			bits = bits & ~mask;
1455 		else
1456 			bits = bits | mask;
1457 		cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_OUTMIX, bits);
1458 		return;
1459 
1460 	case CMPCI_SPDIF_IN_SELECT:
1461 	case CMPCI_MONITOR_DAC:
1462 	case CMPCI_PLAYBACK_MODE:
1463 	case CMPCI_SPDIF_LOOP:
1464 	case CMPCI_SPDIF_OUT_PLAYBACK:
1465 		cmpci_set_out_ports(sc);
1466 		return;
1467 	case CMPCI_SPDIF_OUT_VOLTAGE:
1468 		if (CMPCI_ISCAP(sc, SPDOUT_VOLTAGE)) {
1469 			if (sc->sc_gain[CMPCI_SPDIF_OUT_VOLTAGE][CMPCI_LR]
1470 			    == CMPCI_SPDIF_OUT_VOLTAGE_HIGH)
1471 				cmpci_reg_clear_reg_misc(sc, CMPCI_REG_5V);
1472 			else
1473 				cmpci_reg_set_reg_misc(sc, CMPCI_REG_5V);
1474 		}
1475 		return;
1476 	case CMPCI_SURROUND:
1477 		if (CMPCI_ISCAP(sc, SURROUND)) {
1478 			if (sc->sc_gain[CMPCI_SURROUND][CMPCI_LR])
1479 				cmpci_reg_set_1(sc, CMPCI_REG_MIXER24,
1480 						CMPCI_REG_SURROUND);
1481 			else
1482 				cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24,
1483 						  CMPCI_REG_SURROUND);
1484 		}
1485 		return;
1486 	case CMPCI_REAR:
1487 		if (CMPCI_ISCAP(sc, REAR)) {
1488 			if (sc->sc_gain[CMPCI_REAR][CMPCI_LR])
1489 				cmpci_reg_set_reg_misc(sc, CMPCI_REG_N4SPK3D);
1490 			else
1491 				cmpci_reg_clear_reg_misc(sc, CMPCI_REG_N4SPK3D);
1492 		}
1493 		return;
1494 	case CMPCI_INDIVIDUAL:
1495 		if (CMPCI_ISCAP(sc, INDIVIDUAL_REAR)) {
1496 			if (sc->sc_gain[CMPCI_REAR][CMPCI_LR])
1497 				cmpci_reg_set_1(sc, CMPCI_REG_MIXER24,
1498 						CMPCI_REG_INDIVIDUAL);
1499 			else
1500 				cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24,
1501 						  CMPCI_REG_INDIVIDUAL);
1502 		}
1503 		return;
1504 	case CMPCI_REVERSE:
1505 		if (CMPCI_ISCAP(sc, REVERSE_FR)) {
1506 			if (sc->sc_gain[CMPCI_REVERSE][CMPCI_LR])
1507 				cmpci_reg_set_1(sc, CMPCI_REG_MIXER24,
1508 						CMPCI_REG_REVERSE_FR);
1509 			else
1510 				cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24,
1511 						  CMPCI_REG_REVERSE_FR);
1512 		}
1513 		return;
1514 	case CMPCI_SPDIF_IN_PHASE:
1515 		if (CMPCI_ISCAP(sc, SPDIN_PHASE)) {
1516 			if (sc->sc_gain[CMPCI_SPDIF_IN_PHASE][CMPCI_LR]
1517 			    == CMPCI_SPDIF_IN_PHASE_POSITIVE)
1518 				cmpci_reg_clear_1(sc, CMPCI_REG_CHANNEL_FORMAT,
1519 						  CMPCI_REG_SPDIN_PHASE);
1520 			else
1521 				cmpci_reg_set_1(sc, CMPCI_REG_CHANNEL_FORMAT,
1522 						CMPCI_REG_SPDIN_PHASE);
1523 		}
1524 		return;
1525 	default:
1526 		return;
1527 	}
1528 
1529 	cmpci_mixerreg_write(sc, src,
1530 	    CMPCI_ADJUST_GAIN(sc, sc->sc_gain[port][CMPCI_LEFT]));
1531 	cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_L_TO_R(src),
1532 	    CMPCI_ADJUST_GAIN(sc, sc->sc_gain[port][CMPCI_RIGHT]));
1533 }
1534 
1535 void
1536 cmpci_set_out_ports(struct cmpci_softc *sc)
1537 {
1538 	struct cmpci_channel *chan;
1539 	u_int8_t v;
1540 	int enspdout = 0;
1541 
1542 	if (!CMPCI_ISCAP(sc, SPDLOOP))
1543 		return;
1544 
1545 	/* SPDIF/out select */
1546 	if (sc->sc_gain[CMPCI_SPDIF_LOOP][CMPCI_LR] == CMPCI_SPDIF_LOOP_OFF) {
1547 		/* playback */
1548 		cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1, CMPCI_REG_SPDIF_LOOP);
1549 	} else {
1550 		/* monitor SPDIF/in */
1551 		cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1, CMPCI_REG_SPDIF_LOOP);
1552 	}
1553 
1554 	/* SPDIF in select */
1555 	v = sc->sc_gain[CMPCI_SPDIF_IN_SELECT][CMPCI_LR];
1556 	if (v & CMPCI_SPDIFIN_SPDIFIN2)
1557 		cmpci_reg_set_reg_misc(sc, CMPCI_REG_2ND_SPDIFIN);
1558 	else
1559 		cmpci_reg_clear_reg_misc(sc, CMPCI_REG_2ND_SPDIFIN);
1560 	if (v & CMPCI_SPDIFIN_SPDIFOUT)
1561 		cmpci_reg_set_reg_misc(sc, CMPCI_REG_SPDFLOOPI);
1562 	else
1563 		cmpci_reg_clear_reg_misc(sc, CMPCI_REG_SPDFLOOPI);
1564 
1565 	if (sc->sc_play_channel == 1)
1566 		chan = &sc->sc_ch1;
1567 	else
1568 		chan = &sc->sc_ch0;
1569 
1570 	/* playback to ... */
1571 	if (CMPCI_ISCAP(sc, SPDOUT) &&
1572 	    sc->sc_gain[CMPCI_PLAYBACK_MODE][CMPCI_LR]
1573 		== CMPCI_PLAYBACK_MODE_SPDIF &&
1574 	    (chan->md_divide == CMPCI_REG_RATE_44100 ||
1575 		(CMPCI_ISCAP(sc, SPDOUT_48K) &&
1576 		    chan->md_divide==CMPCI_REG_RATE_48000))) {
1577 		/* playback to SPDIF */
1578 		cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1, CMPCI_REG_SPDIF0_ENABLE);
1579 		enspdout = 1;
1580 		if (chan->md_divide==CMPCI_REG_RATE_48000)
1581 			cmpci_reg_set_reg_misc(sc,
1582 				CMPCI_REG_SPDIFOUT_48K | CMPCI_REG_SPDIF48K);
1583 		else
1584 			cmpci_reg_clear_reg_misc(sc,
1585 				CMPCI_REG_SPDIFOUT_48K | CMPCI_REG_SPDIF48K);
1586 	} else {
1587 		/* playback to DAC */
1588 		cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1,
1589 				  CMPCI_REG_SPDIF0_ENABLE);
1590 		if (CMPCI_ISCAP(sc, SPDOUT_48K))
1591 			cmpci_reg_clear_reg_misc(sc,
1592 				CMPCI_REG_SPDIFOUT_48K | CMPCI_REG_SPDIF48K);
1593 	}
1594 
1595 	/* legacy to SPDIF/out or not */
1596 	if (CMPCI_ISCAP(sc, SPDLEGACY)) {
1597 		if (sc->sc_gain[CMPCI_SPDIF_OUT_PLAYBACK][CMPCI_LR]
1598 		    == CMPCI_SPDIF_OUT_PLAYBACK_WAVE)
1599 			cmpci_reg_clear_4(sc, CMPCI_REG_LEGACY_CTRL,
1600 					CMPCI_REG_LEGACY_SPDIF_ENABLE);
1601 		else {
1602 			cmpci_reg_set_4(sc, CMPCI_REG_LEGACY_CTRL,
1603 					CMPCI_REG_LEGACY_SPDIF_ENABLE);
1604 			enspdout = 1;
1605 		}
1606 	}
1607 
1608 	/* enable/disable SPDIF/out */
1609 	if (CMPCI_ISCAP(sc, XSPDOUT) && enspdout)
1610 		cmpci_reg_set_4(sc, CMPCI_REG_LEGACY_CTRL,
1611 				CMPCI_REG_XSPDIF_ENABLE);
1612 	else
1613 		cmpci_reg_clear_4(sc, CMPCI_REG_LEGACY_CTRL,
1614 				CMPCI_REG_XSPDIF_ENABLE);
1615 
1616 	/* SPDIF monitor (digital to analog output) */
1617 	if (CMPCI_ISCAP(sc, SPDIN_MONITOR)) {
1618 		v = sc->sc_gain[CMPCI_MONITOR_DAC][CMPCI_LR];
1619 		if (!(v & CMPCI_MONDAC_ENABLE))
1620 			cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24,
1621 					CMPCI_REG_SPDIN_MONITOR);
1622 		if (v & CMPCI_MONDAC_SPDOUT)
1623 			cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1,
1624 					CMPCI_REG_SPDIFOUT_DAC);
1625 		else
1626 			cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1,
1627 					CMPCI_REG_SPDIFOUT_DAC);
1628 		if (v & CMPCI_MONDAC_ENABLE)
1629 			cmpci_reg_set_1(sc, CMPCI_REG_MIXER24,
1630 					CMPCI_REG_SPDIN_MONITOR);
1631 	}
1632 }
1633 
1634 int
1635 cmpci_set_in_ports(struct cmpci_softc *sc)
1636 {
1637 	int mask;
1638 	int bitsl, bitsr;
1639 
1640 	mask = sc->sc_in_mask;
1641 
1642 	/*
1643 	 * Note CMPCI_RECORD_SOURCE_CD, CMPCI_RECORD_SOURCE_LINE_IN and
1644 	 * CMPCI_RECORD_SOURCE_FM are defined to the corresponding bit
1645 	 * of the mixer register.
1646 	 */
1647 	bitsr = mask & (CMPCI_RECORD_SOURCE_CD | CMPCI_RECORD_SOURCE_LINE_IN |
1648 	    CMPCI_RECORD_SOURCE_FM);
1649 
1650 	bitsl = CMPCI_SB16_MIXER_SRC_R_TO_L(bitsr);
1651 	if (mask & CMPCI_RECORD_SOURCE_MIC) {
1652 		bitsl |= CMPCI_SB16_MIXER_MIC_SRC;
1653 		bitsr |= CMPCI_SB16_MIXER_MIC_SRC;
1654 	}
1655 	cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_L, bitsl);
1656 	cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_R, bitsr);
1657 
1658 	if (mask & CMPCI_RECORD_SOURCE_AUX_IN)
1659 		cmpci_reg_set_1(sc, CMPCI_REG_MIXER25,
1660 		    CMPCI_REG_RAUXREN | CMPCI_REG_RAUXLEN);
1661 	else
1662 		cmpci_reg_clear_1(sc, CMPCI_REG_MIXER25,
1663 		    CMPCI_REG_RAUXREN | CMPCI_REG_RAUXLEN);
1664 
1665 	if (mask & CMPCI_RECORD_SOURCE_WAVE)
1666 		cmpci_reg_set_1(sc, CMPCI_REG_MIXER24,
1667 		    CMPCI_REG_WAVEINL | CMPCI_REG_WAVEINR);
1668 	else
1669 		cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24,
1670 		    CMPCI_REG_WAVEINL | CMPCI_REG_WAVEINR);
1671 
1672 	if (CMPCI_ISCAP(sc, SPDIN) &&
1673 	    (sc->sc_ch1.md_divide == CMPCI_REG_RATE_44100 ||
1674 		(CMPCI_ISCAP(sc, SPDOUT_48K) &&
1675 		    sc->sc_ch1.md_divide == CMPCI_REG_RATE_48000/* XXX? */))) {
1676 		if (mask & CMPCI_RECORD_SOURCE_SPDIF) {
1677 			/* enable SPDIF/in */
1678 			cmpci_reg_set_4(sc,
1679 					CMPCI_REG_FUNC_1,
1680 					CMPCI_REG_SPDIF1_ENABLE);
1681 		} else {
1682 			cmpci_reg_clear_4(sc,
1683 					CMPCI_REG_FUNC_1,
1684 					CMPCI_REG_SPDIF1_ENABLE);
1685 		}
1686 	}
1687 
1688 	return 0;
1689 }
1690 
1691 int
1692 cmpci_set_port(void *handle, mixer_ctrl_t *cp)
1693 {
1694 	struct cmpci_softc *sc = handle;
1695 	int lgain, rgain;
1696 
1697 	switch (cp->dev) {
1698 	case CMPCI_MIC_VOL:
1699 	case CMPCI_PCSPEAKER:
1700 	case CMPCI_MIC_RECVOL:
1701 		if (cp->un.value.num_channels != 1)
1702 			return EINVAL;
1703 		/* FALLTHROUGH */
1704 	case CMPCI_DAC_VOL:
1705 	case CMPCI_FM_VOL:
1706 	case CMPCI_CD_VOL:
1707 	case CMPCI_LINE_IN_VOL:
1708 	case CMPCI_AUX_IN_VOL:
1709 	case CMPCI_MASTER_VOL:
1710 		if (cp->type != AUDIO_MIXER_VALUE)
1711 			return EINVAL;
1712 		switch (cp->un.value.num_channels) {
1713 		case 1:
1714 			lgain = rgain =
1715 			    cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
1716 			break;
1717 		case 2:
1718 			lgain = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
1719 			rgain = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
1720 			break;
1721 		default:
1722 			return EINVAL;
1723 		}
1724 		sc->sc_gain[cp->dev][CMPCI_LEFT]  = lgain;
1725 		sc->sc_gain[cp->dev][CMPCI_RIGHT] = rgain;
1726 
1727 		cmpci_set_mixer_gain(sc, cp->dev);
1728 		break;
1729 
1730 	case CMPCI_RECORD_SOURCE:
1731 		if (cp->type != AUDIO_MIXER_SET)
1732 			return EINVAL;
1733 
1734 		if (cp->un.mask & ~(CMPCI_RECORD_SOURCE_MIC |
1735 		    CMPCI_RECORD_SOURCE_CD | CMPCI_RECORD_SOURCE_LINE_IN |
1736 		    CMPCI_RECORD_SOURCE_AUX_IN | CMPCI_RECORD_SOURCE_WAVE |
1737 		    CMPCI_RECORD_SOURCE_FM | CMPCI_RECORD_SOURCE_SPDIF))
1738 			return EINVAL;
1739 
1740 		if (cp->un.mask & CMPCI_RECORD_SOURCE_SPDIF)
1741 			cp->un.mask = CMPCI_RECORD_SOURCE_SPDIF;
1742 
1743 		sc->sc_in_mask = cp->un.mask;
1744 		return cmpci_set_in_ports(sc);
1745 
1746 	/* boolean */
1747 	case CMPCI_DAC_MUTE:
1748 	case CMPCI_FM_MUTE:
1749 	case CMPCI_CD_MUTE:
1750 	case CMPCI_LINE_IN_MUTE:
1751 	case CMPCI_AUX_IN_MUTE:
1752 	case CMPCI_MIC_MUTE:
1753 	case CMPCI_MIC_PREAMP:
1754 	case CMPCI_PLAYBACK_MODE:
1755 	case CMPCI_SPDIF_IN_PHASE:
1756 	case CMPCI_SPDIF_LOOP:
1757 	case CMPCI_SPDIF_OUT_PLAYBACK:
1758 	case CMPCI_SPDIF_OUT_VOLTAGE:
1759 	case CMPCI_REAR:
1760 	case CMPCI_INDIVIDUAL:
1761 	case CMPCI_REVERSE:
1762 	case CMPCI_SURROUND:
1763 		if (cp->type != AUDIO_MIXER_ENUM)
1764 			return EINVAL;
1765 		sc->sc_gain[cp->dev][CMPCI_LR] = cp->un.ord != 0;
1766 		cmpci_set_mixer_gain(sc, cp->dev);
1767 		break;
1768 
1769 	case CMPCI_SPDIF_IN_SELECT:
1770 		switch (cp->un.ord) {
1771 		case CMPCI_SPDIF_IN_SPDIN1:
1772 		case CMPCI_SPDIF_IN_SPDIN2:
1773 		case CMPCI_SPDIF_IN_SPDOUT:
1774 			break;
1775 		default:
1776 			return EINVAL;
1777 		}
1778 		goto xenum;
1779 	case CMPCI_MONITOR_DAC:
1780 		switch (cp->un.ord) {
1781 		case CMPCI_MONITOR_DAC_OFF:
1782 		case CMPCI_MONITOR_DAC_SPDIN:
1783 		case CMPCI_MONITOR_DAC_SPDOUT:
1784 			break;
1785 		default:
1786 			return EINVAL;
1787 		}
1788 	xenum:
1789 		if (cp->type != AUDIO_MIXER_ENUM)
1790 			return EINVAL;
1791 		sc->sc_gain[cp->dev][CMPCI_LR] = cp->un.ord;
1792 		cmpci_set_mixer_gain(sc, cp->dev);
1793 		break;
1794 
1795 	default:
1796 	    return EINVAL;
1797 	}
1798 
1799 	return 0;
1800 }
1801 
1802 int
1803 cmpci_get_port(void *handle, mixer_ctrl_t *cp)
1804 {
1805 	struct cmpci_softc *sc = handle;
1806 
1807 	switch (cp->dev) {
1808 	case CMPCI_MIC_VOL:
1809 	case CMPCI_PCSPEAKER:
1810 	case CMPCI_MIC_RECVOL:
1811 		if (cp->un.value.num_channels != 1)
1812 			return EINVAL;
1813 		/*FALLTHROUGH*/
1814 	case CMPCI_DAC_VOL:
1815 	case CMPCI_FM_VOL:
1816 	case CMPCI_CD_VOL:
1817 	case CMPCI_LINE_IN_VOL:
1818 	case CMPCI_AUX_IN_VOL:
1819 	case CMPCI_MASTER_VOL:
1820 		switch (cp->un.value.num_channels) {
1821 		case 1:
1822 			cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1823 				sc->sc_gain[cp->dev][CMPCI_LEFT];
1824 			break;
1825 		case 2:
1826 			cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
1827 				sc->sc_gain[cp->dev][CMPCI_LEFT];
1828 			cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
1829 				sc->sc_gain[cp->dev][CMPCI_RIGHT];
1830 			break;
1831 		default:
1832 			return EINVAL;
1833 		}
1834 		break;
1835 
1836 	case CMPCI_RECORD_SOURCE:
1837 		cp->un.mask = sc->sc_in_mask;
1838 		break;
1839 
1840 	case CMPCI_DAC_MUTE:
1841 	case CMPCI_FM_MUTE:
1842 	case CMPCI_CD_MUTE:
1843 	case CMPCI_LINE_IN_MUTE:
1844 	case CMPCI_AUX_IN_MUTE:
1845 	case CMPCI_MIC_MUTE:
1846 	case CMPCI_MIC_PREAMP:
1847 	case CMPCI_PLAYBACK_MODE:
1848 	case CMPCI_SPDIF_IN_SELECT:
1849 	case CMPCI_SPDIF_IN_PHASE:
1850 	case CMPCI_SPDIF_LOOP:
1851 	case CMPCI_SPDIF_OUT_PLAYBACK:
1852 	case CMPCI_SPDIF_OUT_VOLTAGE:
1853 	case CMPCI_MONITOR_DAC:
1854 	case CMPCI_REAR:
1855 	case CMPCI_INDIVIDUAL:
1856 	case CMPCI_REVERSE:
1857 	case CMPCI_SURROUND:
1858 		cp->un.ord = sc->sc_gain[cp->dev][CMPCI_LR];
1859 		break;
1860 
1861 	default:
1862 		return EINVAL;
1863 	}
1864 
1865 	return 0;
1866 }
1867 
1868 /* ARGSUSED */
1869 size_t
1870 cmpci_round_buffersize(void *handle, int direction, size_t bufsize)
1871 {
1872 	if (bufsize > 0x10000)
1873 		bufsize = 0x10000;
1874 
1875 	return bufsize;
1876 }
1877 
1878 paddr_t
1879 cmpci_mappage(void *handle, void *addr, off_t offset, int prot)
1880 {
1881 	struct cmpci_softc *sc = handle;
1882 	struct cmpci_dmanode *p;
1883 
1884 	if (offset < 0 || NULL == (p = cmpci_find_dmamem(sc, addr)))
1885 		return -1;
1886 
1887 	return bus_dmamem_mmap(p->cd_tag, p->cd_segs,
1888 		   sizeof(p->cd_segs)/sizeof(p->cd_segs[0]),
1889 		   offset, prot, BUS_DMA_WAITOK);
1890 }
1891 
1892 /* ARGSUSED */
1893 int
1894 cmpci_get_props(void *handle)
1895 {
1896 	return AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX;
1897 }
1898 
1899 int
1900 cmpci_trigger_output(void *handle, void *start, void *end, int blksize,
1901     void (*intr)(void *), void *arg, struct audio_params *param)
1902 {
1903 	struct cmpci_softc *sc = handle;
1904 	struct cmpci_dmanode *p;
1905 	struct cmpci_channel *chan;
1906 	uint32_t reg_dma_base, reg_dma_bytes, reg_dma_samples, reg_dir,
1907 	    reg_intr_enable, reg_enable;
1908 	uint32_t length;
1909 	int bps;
1910 
1911 	if (sc->sc_play_channel == 1) {
1912 		chan = &sc->sc_ch1;
1913 		reg_dma_base = CMPCI_REG_DMA1_BASE;
1914 		reg_dma_bytes = CMPCI_REG_DMA1_BYTES;
1915 		reg_dma_samples = CMPCI_REG_DMA1_SAMPLES;
1916 		reg_dir = CMPCI_REG_CH1_DIR;
1917 		reg_intr_enable = CMPCI_REG_CH1_INTR_ENABLE;
1918 		reg_enable = CMPCI_REG_CH1_ENABLE;
1919 	} else {
1920 		chan = &sc->sc_ch0;
1921 		reg_dma_base = CMPCI_REG_DMA0_BASE;
1922 		reg_dma_bytes = CMPCI_REG_DMA0_BYTES;
1923 		reg_dma_samples = CMPCI_REG_DMA0_SAMPLES;
1924 		reg_dir = CMPCI_REG_CH0_DIR;
1925 		reg_intr_enable = CMPCI_REG_CH0_INTR_ENABLE;
1926 		reg_enable = CMPCI_REG_CH0_ENABLE;
1927 	}
1928 
1929 	chan->intr = intr;
1930 	chan->intr_arg = arg;
1931 	bps = (param->channels > 1 ? 2 : 1) * param->precision *
1932 	    param->factor / 8;
1933 	if (!bps)
1934 		return EINVAL;
1935 
1936 	/* set DMA frame */
1937 	if (!(p = cmpci_find_dmamem(sc, start)))
1938 		return EINVAL;
1939 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, reg_dma_base,
1940 	    DMAADDR(p));
1941 	delay(10);
1942 	length = ((caddr_t)end - (caddr_t)start + 1) / bps - 1;
1943 	bus_space_write_2(sc->sc_iot, sc->sc_ioh, reg_dma_bytes, length);
1944 	delay(10);
1945 
1946 	/* set interrupt count */
1947 	length = (blksize + bps - 1) / bps - 1;
1948 	bus_space_write_2(sc->sc_iot, sc->sc_ioh, reg_dma_samples, length);
1949 	delay(10);
1950 
1951 	/* start DMA */
1952 	cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, reg_dir); /* PLAY */
1953 	cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL, reg_intr_enable);
1954 	cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, reg_enable);
1955 
1956 	return 0;
1957 }
1958 
1959 int
1960 cmpci_trigger_input(void *handle, void *start, void *end, int blksize,
1961     void (*intr)(void *), void *arg, struct audio_params *param)
1962 {
1963 	struct cmpci_softc *sc = handle;
1964 	struct cmpci_dmanode *p;
1965 	int bps;
1966 
1967 	sc->sc_ch1.intr = intr;
1968 	sc->sc_ch1.intr_arg = arg;
1969 	bps = param->channels*param->precision*param->factor/8;
1970 	if (!bps)
1971 		return EINVAL;
1972 
1973 	/* set DMA frame */
1974 	if (!(p = cmpci_find_dmamem(sc, start)))
1975 		return EINVAL;
1976 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA1_BASE,
1977 	    DMAADDR(p));
1978 	delay(10);
1979 	bus_space_write_2(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA1_BYTES,
1980 	    ((caddr_t)end - (caddr_t)start + 1) / bps - 1);
1981 	delay(10);
1982 
1983 	/* set interrupt count */
1984 	bus_space_write_2(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA1_SAMPLES,
1985 	    (blksize + bps - 1) / bps - 1);
1986 	delay(10);
1987 
1988 	/* start DMA */
1989 	cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_DIR); /* REC */
1990 	cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH1_INTR_ENABLE);
1991 	cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_ENABLE);
1992 
1993 	return 0;
1994 }
1995 
1996 /* end of file */
1997