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