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