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