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