xref: /illumos-gate/usr/src/uts/common/io/audio/drv/audiocmi/audiocmi.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 /*
26  * Purpose: Driver for CMEDIA CM8738 PCI audio controller.
27  */
28 /*
29  * This file is part of Open Sound System
30  *
31  * Copyright (C) 4Front Technologies 1996-2008.
32  *
33  * This software is released under CDDL 1.0 source license.
34  * See the COPYING file included in the main directory of this source
35  * distribution for the license terms and conditions.
36  */
37 
38 #include <sys/audio/audio_driver.h>
39 #include <sys/note.h>
40 #include <sys/pci.h>
41 #include "audiocmi.h"
42 
43 /*
44  * Note: The original 4Front driver had support SPDIF, dual dac, and
45  * multichannel surround options.  However, we haven't got any cards
46  * with these advanced features available on them for testing, so
47  * we're just going to support basic analog stereo for now.
48  *
49  * Adding back support for the advanced features would be an
50  * interesting project for someone with access to suitable hardware.
51  *
52  * Note that each variant (CMI 8338, 8738-033, -037, -055, and 8768)
53  * seems to have significant differences in some of the registers.
54  * While programming these parts for basic stereo is pretty much the
55  * same on all parts, doing anything more than that can be
56  * sigificantly different for each part.
57  */
58 
59 static ddi_device_acc_attr_t acc_attr = {
60 	DDI_DEVICE_ATTR_V0,
61 	DDI_STRUCTURE_LE_ACC,
62 	DDI_STRICTORDER_ACC
63 };
64 
65 static ddi_device_acc_attr_t buf_attr = {
66 	DDI_DEVICE_ATTR_V0,
67 	DDI_NEVERSWAP_ACC,
68 	DDI_STRICTORDER_ACC
69 };
70 
71 static ddi_dma_attr_t dma_attr = {
72 	DMA_ATTR_VERSION,	/* dma_attr_version */
73 	0x0,			/* dma_attr_addr_lo */
74 	0xffffffffU,		/* dma_attr_addr_hi */
75 	0x3ffff,		/* dma_attr_count_max */
76 	0x8,			/* dma_attr_align */
77 	0x7f,			/* dma_attr_burstsizes */
78 	0x1,			/* dma_attr_minxfer */
79 	0x3ffff,		/* dma_attr_maxxfer */
80 	0x3ffff,		/* dma_attr_seg */
81 	0x1,			/* dma_attr_sgllen */
82 	0x1,			/* dma_attr_granular */
83 	0			/* dma_attr_flags */
84 };
85 
86 static uint_t
87 cmpci_intr(caddr_t arg1, caddr_t arg2)
88 {
89 	cmpci_dev_t	*dev = (void *)arg1;
90 
91 	uint32_t	intstat, intctrl, intclear;
92 	void		(*cb0)(audio_engine_t *) = NULL;
93 	void		(*cb1)(audio_engine_t *) = NULL;
94 	uint_t		rv;
95 
96 	_NOTE(ARGUNUSED(arg2));
97 
98 	rv = DDI_INTR_UNCLAIMED;
99 
100 	mutex_enter(&dev->mutex);
101 	if (dev->suspended) {
102 		mutex_exit(&dev->mutex);
103 		return (rv);
104 	}
105 
106 	intclear = 0;
107 	intstat = GET32(dev, REG_INTSTAT);
108 	intctrl = GET32(dev, REG_INTCTRL);
109 	if ((intstat & INTSTAT_CH0_INT) && (intctrl & INTCTRL_CH0_EN)) {
110 		intclear |= INTCTRL_CH0_EN;
111 		cb0 = dev->port[0].callb;
112 	}
113 	if ((intstat & INTSTAT_CH1_INT) && (intctrl & INTCTRL_CH1_EN)) {
114 		intclear |= INTCTRL_CH1_EN;
115 		cb1 = dev->port[1].callb;
116 	}
117 
118 	/* toggle the bits that we are going to handle */
119 	if (intclear) {
120 		CLR32(dev, REG_INTCTRL, intclear);
121 		SET32(dev, REG_INTCTRL, intclear);
122 		rv = DDI_INTR_CLAIMED;
123 
124 		KSINTR(dev)->intrs[KSTAT_INTR_HARD]++;
125 	}
126 
127 	mutex_exit(&dev->mutex);
128 
129 	if (cb0) {
130 		(*cb0)(dev->port[0].engine);
131 	}
132 	if (cb1) {
133 		(*cb1)(dev->port[1].engine);
134 	}
135 
136 	return (rv);
137 }
138 
139 static void
140 cmpci_reset_port(cmpci_port_t *port)
141 {
142 	cmpci_dev_t *dev = port->dev;
143 
144 	if (dev->suspended)
145 		return;
146 
147 	port->offset = 0;
148 
149 	/* reset channel */
150 	SET32(dev, REG_FUNCTRL0, port->fc0_rst_bit);
151 	drv_usecwait(10);
152 	CLR32(dev, REG_FUNCTRL0, port->fc0_rst_bit);
153 	drv_usecwait(10);
154 
155 	/* Set 48k 16-bit stereo -- these are just with all bits set. */
156 	SET32(dev, REG_FUNCTRL1, port->fc1_rate_mask);
157 	SET32(dev, REG_CHFORMAT, port->chformat_mask);
158 
159 	PUT32(dev, port->reg_paddr, port->paddr);
160 	PUT16(dev, port->reg_bufsz, port->nframes - 1);
161 	PUT16(dev, port->reg_fragsz, port->fragfr - 1);
162 
163 	/* Analog output */
164 	if (port->capture) {
165 		/* Analog capture */
166 		SET32(dev, REG_FUNCTRL0, port->fc0_rec_bit);
167 	} else {
168 		CLR32(dev, REG_FUNCTRL0, port->fc0_rec_bit);
169 	}
170 }
171 
172 static void
173 cmpci_start_port(cmpci_port_t *port)
174 {
175 	cmpci_dev_t	*dev = port->dev;
176 
177 	if (dev->suspended)
178 		return;
179 
180 	SET32(dev, REG_FUNCTRL0, port->fc0_en_bit);
181 	SET32(dev, REG_INTCTRL, port->int_en_bit);
182 }
183 
184 static void
185 cmpci_stop_port(cmpci_port_t *port)
186 {
187 	cmpci_dev_t	*dev = port->dev;
188 
189 	if (dev->suspended)
190 		return;
191 
192 	CLR32(dev, REG_FUNCTRL0, port->fc0_en_bit);
193 	CLR32(dev, REG_INTCTRL, port->int_en_bit);
194 }
195 
196 static int
197 cmpci_open(void *arg, int flag, uint_t *fragfrp, uint_t *nfp, caddr_t *bufp)
198 {
199 	cmpci_port_t *port = arg;
200 	cmpci_dev_t *dev = port->dev;
201 	int intrs;
202 
203 	mutex_enter(&dev->mutex);
204 
205 	if (flag & ENGINE_INPUT) {
206 		intrs = dev->rintrs;
207 	} else {
208 		intrs = dev->pintrs;
209 	}
210 
211 	/*
212 	 * Calculate fragfr, nfrags, buf.
213 	 *
214 	 * 48 as minimum is chosen to ensure that we will have at
215 	 * least 4 fragments.  512 is just an arbitrary limit, and at
216 	 * the smallest frame size will result in no more than 176
217 	 * fragments.
218 	 */
219 	intrs = min(512, max(48, intrs));
220 
221 	port->fragfr = (48000 / intrs);
222 	port->nfrags = CMPCI_BUF_LEN / (port->fragfr * 4);
223 	port->nframes = port->nfrags * port->fragfr;
224 	port->count = 0;
225 	port->bufsz = port->nframes * 4;
226 
227 	*fragfrp = port->fragfr;
228 	*nfp = port->nfrags;
229 	*bufp = port->kaddr;
230 
231 	port->open = B_TRUE;
232 
233 	cmpci_reset_port(port);
234 	cmpci_start_port(port);
235 
236 	mutex_exit(&dev->mutex);
237 	return (0);
238 }
239 
240 static void
241 cmpci_close(void *arg)
242 {
243 	cmpci_port_t *port = arg;
244 	cmpci_dev_t *dev = port->dev;
245 
246 	mutex_enter(&dev->mutex);
247 	port->open = B_FALSE;
248 	cmpci_stop_port(port);
249 	mutex_exit(&dev->mutex);
250 }
251 
252 static void
253 cmpci_update_port(cmpci_port_t *port)
254 {
255 	cmpci_dev_t	*dev = port->dev;
256 	uint32_t	count;
257 	uint32_t	offset;
258 
259 	if ((dev->suspended) || (!port->open))
260 		return;
261 
262 	offset = GET32(dev, port->reg_paddr) - port->paddr;
263 
264 	/* check for wrap */
265 	if (offset < port->offset) {
266 		count = (port->bufsz - port->offset) + offset;
267 	} else {
268 		count = offset - port->offset;
269 	}
270 	port->count += count;
271 	port->offset = offset;
272 }
273 
274 static uint64_t
275 cmpci_count(void *arg)
276 {
277 	cmpci_port_t	*port = arg;
278 	cmpci_dev_t	*dev = port->dev;
279 	uint64_t	count;
280 
281 	mutex_enter(&dev->mutex);
282 	cmpci_update_port(port);
283 
284 	/* 4 is from 16-bit stereo */
285 	count = port->count / 4;
286 	mutex_exit(&dev->mutex);
287 
288 	/* NB: 2 because each sample is 2 bytes wide */
289 	return (count);
290 }
291 
292 
293 static int
294 cmpci_setup_interrupts(cmpci_dev_t *dev)
295 {
296 	int actual;
297 	uint_t ipri;
298 
299 	if ((ddi_intr_alloc(dev->dip, &dev->ihandle, DDI_INTR_TYPE_FIXED,
300 	    0, 1, &actual, DDI_INTR_ALLOC_NORMAL) != DDI_SUCCESS) ||
301 	    (actual != 1)) {
302 		audio_dev_warn(dev->adev, "can't alloc intr handle");
303 		return (DDI_FAILURE);
304 	}
305 
306 	if (ddi_intr_get_pri(dev->ihandle, &ipri) != DDI_SUCCESS) {
307 		audio_dev_warn(dev->adev,  "can't determine intr priority");
308 		(void) ddi_intr_free(dev->ihandle);
309 		dev->ihandle = NULL;
310 		return (DDI_FAILURE);
311 	}
312 
313 	if (ddi_intr_add_handler(dev->ihandle, cmpci_intr, dev,
314 	    NULL) != DDI_SUCCESS) {
315 		audio_dev_warn(dev->adev, "can't add intr handler");
316 		(void) ddi_intr_free(dev->ihandle);
317 		dev->ihandle = NULL;
318 		return (DDI_FAILURE);
319 	}
320 
321 	mutex_init(&dev->mutex, NULL, MUTEX_DRIVER, DDI_INTR_PRI(ipri));
322 
323 	return (DDI_SUCCESS);
324 }
325 
326 
327 #define	MASK(nbits)	((1 << (nbits)) - 1)
328 #define	SCALE(val, nbits)	\
329 	((uint8_t)((((val) * MASK(nbits)) / 100)) << (8 - (nbits)))
330 
331 #define	LEFT(dev, ctl)	min(((dev->controls[ctl].value) >> 8), 100)
332 #define	RIGHT(dev, ctl)	min(((dev->controls[ctl].value) & 0xff), 100)
333 #define	MONO(dev, ctl)	min(dev->controls[ctl].value, 100)
334 
335 static void
336 cmpci_setmixer(cmpci_dev_t *dev, uint8_t idx, uint8_t val)
337 {
338 	PUT8(dev, REG_IDXADDR, idx);
339 	PUT8(dev, REG_IDXDATA, val);
340 }
341 
342 static uint8_t
343 cmpci_getmixer(cmpci_dev_t *dev, uint8_t idx)
344 {
345 	PUT8(dev, REG_IDXADDR, idx);
346 	return (GET8(dev, REG_IDXDATA));
347 }
348 
349 
350 static void
351 cmpci_configure_mixer(cmpci_dev_t *dev)
352 {
353 	uint64_t	left, right;
354 	uint8_t		outmix;
355 	uint8_t		inmix[2];
356 	uint64_t	recsrcs;
357 	uint64_t	monsrcs;
358 
359 	if (dev->suspended)
360 		return;
361 
362 	/* reset all mix values */
363 	outmix = inmix[0] = inmix[1] = 0;
364 
365 	outmix = OUTMIX_MIC |
366 	    OUTMIX_CD_R | OUTMIX_CD_L | OUTMIX_LINE_R | OUTMIX_LINE_L;
367 
368 	inmix[0] = INMIX_LINE_L | INMIX_CD_L | INMIX_MIC;
369 	inmix[1] = INMIX_LINE_R | INMIX_CD_R | INMIX_MIC;
370 
371 	recsrcs = dev->controls[CTL_RECSRCS].value;
372 	monsrcs = dev->controls[CTL_MONSRCS].value;
373 
374 	/* program PCM volume */
375 	left = MONO(dev, CTL_VOLUME);
376 	if (left) {
377 		/* left and right are the same */
378 		cmpci_setmixer(dev, IDX_VOICE_LEFT, SCALE(left, 5));
379 		cmpci_setmixer(dev, IDX_VOICE_RIGHT, SCALE(left, 5));
380 		CLR8(dev, REG_MIX2, MIX2_WSMUTE);
381 	} else {
382 		cmpci_setmixer(dev, IDX_VOICE_LEFT, 0);
383 		cmpci_setmixer(dev, IDX_VOICE_RIGHT, 0);
384 		SET8(dev, REG_MIX2, MIX2_WSMUTE);
385 	}
386 
387 	left = LEFT(dev, CTL_LINEOUT);
388 	right = RIGHT(dev, CTL_LINEOUT);
389 
390 	/* lineout/master volume - no separate mute */
391 	cmpci_setmixer(dev, IDX_MASTER_LEFT, SCALE(left, 5));
392 	cmpci_setmixer(dev, IDX_MASTER_RIGHT, SCALE(right, 5));
393 
394 	/* speaker volume - mute in extension register, but we don't use */
395 	left = MONO(dev, CTL_SPEAKER);
396 	cmpci_setmixer(dev, IDX_SPEAKER, SCALE(left, 2));
397 
398 	/* mic gain */
399 	left = MONO(dev, CTL_MIC);
400 	if (left) {
401 		cmpci_setmixer(dev, IDX_MIC, SCALE(left, 5));
402 		/* set record mic gain */
403 		uint8_t v = GET8(dev, REG_MIX3);
404 		v &= ~(0x7 << 1);
405 		v |= ((left * 7) / 100) << 1;
406 		PUT8(dev, REG_MIX3, v);
407 		cmpci_setmixer(dev, 0x3f, SCALE(100, 2));
408 		cmpci_setmixer(dev, 0x40, SCALE(100, 2));
409 	} else {
410 		cmpci_setmixer(dev, IDX_MIC, 0);
411 		outmix &= ~OUTMIX_MIC;
412 		inmix[0] &= ~INMIX_MIC;
413 		inmix[1] &= ~INMIX_MIC;
414 	}
415 
416 	/* line in */
417 	left = LEFT(dev, CTL_LINEOUT);
418 	right = RIGHT(dev, CTL_LINEOUT);
419 	if (left) {
420 		cmpci_setmixer(dev, IDX_LINEIN_LEFT, SCALE(left, 5));
421 	} else {
422 		cmpci_setmixer(dev, IDX_LINEIN_LEFT, 0);
423 		inmix[0] &= ~INMIX_LINE_L;
424 		outmix &= ~OUTMIX_LINE_L;
425 	}
426 	if (right) {
427 		cmpci_setmixer(dev, IDX_LINEIN_RIGHT, SCALE(left, 5));
428 	} else {
429 		cmpci_setmixer(dev, IDX_LINEIN_RIGHT, 0);
430 		inmix[1] &= ~INMIX_LINE_R;
431 		outmix &= ~OUTMIX_LINE_R;
432 	}
433 
434 	/* cd */
435 	left = LEFT(dev, CTL_CD);
436 	right = RIGHT(dev, CTL_CD);
437 	if (left) {
438 		cmpci_setmixer(dev, IDX_CDDA_LEFT, SCALE(left, 5));
439 	} else {
440 		cmpci_setmixer(dev, IDX_CDDA_LEFT, 0);
441 		inmix[0] &= ~INMIX_CD_L;
442 		outmix &= ~OUTMIX_CD_L;
443 	}
444 	if (right) {
445 		cmpci_setmixer(dev, IDX_CDDA_RIGHT, SCALE(left, 5));
446 	} else {
447 		cmpci_setmixer(dev, IDX_CDDA_RIGHT, 0);
448 		inmix[1] &= ~INMIX_CD_R;
449 		outmix &= ~OUTMIX_CD_R;
450 	}
451 
452 	/* aux - trickier because it doesn't use regular sbpro mixer */
453 	left = LEFT(dev, CTL_AUX);
454 	right = RIGHT(dev, CTL_AUX);
455 	PUT8(dev, REG_VAUX, (((left * 15) / 100) << 4) | ((right * 15) / 100));
456 	/* maybe enable recording */
457 	if ((left || right) && (recsrcs & (1 << SRC_LINE))) {
458 		SET8(dev, REG_MIX3, MIX3_RAUXREN | MIX3_RAUXLEN);
459 	} else {
460 		CLR8(dev, REG_MIX3, MIX3_RAUXREN | MIX3_RAUXLEN);
461 	}
462 	/* maybe enable monitoring */
463 	if ((left || right) && (monsrcs & (1 << SRC_AUX))) {
464 		CLR8(dev, REG_MIX3, MIX3_VAUXRM | MIX3_VAUXLM);
465 	} else {
466 		SET8(dev, REG_MIX3, MIX3_VAUXRM | MIX3_VAUXLM);
467 	}
468 
469 	/* now do the recsrcs */
470 	if ((recsrcs & (1 << SRC_MIC)) == 0) {
471 		inmix[0] &= ~INMIX_MIC;
472 		inmix[1] &= ~INMIX_MIC;
473 	}
474 	if ((recsrcs & (1 << SRC_LINE)) == 0) {
475 		inmix[0] &= ~INMIX_LINE_L;
476 		inmix[1] &= ~INMIX_LINE_R;
477 	}
478 	if ((recsrcs & (1 << SRC_CD)) == 0) {
479 		inmix[0] &= ~INMIX_CD_L;
480 		inmix[1] &= ~INMIX_CD_R;
481 	}
482 	if (recsrcs & (1 << SRC_MIX)) {
483 		SET8(dev, REG_MIX2, MIX2_WAVEIN_L | MIX2_WAVEIN_R);
484 	} else {
485 		CLR8(dev, REG_MIX2, MIX2_WAVEIN_L | MIX2_WAVEIN_R);
486 	}
487 	cmpci_setmixer(dev, IDX_INMIX_L, inmix[0]);
488 	cmpci_setmixer(dev, IDX_INMIX_R, inmix[1]);
489 
490 	/* now the monsrcs */
491 	if ((monsrcs & (1 << SRC_MIC)) == 0) {
492 		outmix &= ~OUTMIX_MIC;
493 	}
494 	if ((monsrcs & (1 << SRC_LINE)) == 0) {
495 		outmix &= ~(OUTMIX_LINE_L | OUTMIX_LINE_R);
496 	}
497 	if ((monsrcs & (1 << SRC_CD)) == 0) {
498 		outmix &= ~(OUTMIX_CD_L | OUTMIX_CD_R);
499 	}
500 	cmpci_setmixer(dev, IDX_OUTMIX, outmix);
501 
502 	/* micboost */
503 	if (dev->controls[CTL_MICBOOST].value != 0) {
504 		CLR8(dev, REG_MIX3, MIX3_MICGAINZ);
505 		cmpci_setmixer(dev, IDX_EXTENSION,
506 		    cmpci_getmixer(dev, IDX_EXTENSION) & ~0x1);
507 	} else {
508 		SET8(dev, REG_MIX3, MIX3_MICGAINZ);
509 		cmpci_setmixer(dev, IDX_EXTENSION,
510 		    cmpci_getmixer(dev, IDX_EXTENSION) | 0x1);
511 	}
512 }
513 
514 static int
515 cmpci_set_ctrl(void *arg, uint64_t val)
516 {
517 	cmpci_ctrl_t *cc = arg;
518 	cmpci_dev_t *dev = cc->dev;
519 
520 	/*
521 	 * We don't bother to check for valid values - a bogus value
522 	 * will give incorrect volumes, but is otherwise harmless.
523 	 */
524 	mutex_enter(&dev->mutex);
525 	cc->value = val;
526 	cmpci_configure_mixer(dev);
527 	mutex_exit(&dev->mutex);
528 
529 	return (0);
530 }
531 
532 static int
533 cmpci_get_ctrl(void *arg, uint64_t *val)
534 {
535 	cmpci_ctrl_t *cc = arg;
536 	cmpci_dev_t *dev = cc->dev;
537 
538 	mutex_enter(&dev->mutex);
539 	*val = cc->value;
540 	mutex_exit(&dev->mutex);
541 	return (0);
542 }
543 
544 #define	PLAYCTL	(AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_PLAY)
545 #define	RECCTL	(AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_REC)
546 #define	MONCTL	(AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_MONITOR)
547 #define	PCMVOL	(PLAYCTL | AUDIO_CTRL_FLAG_PCMVOL)
548 #define	MAINVOL	(PLAYCTL | AUDIO_CTRL_FLAG_MAINVOL)
549 #define	RECVOL	(RECCTL | AUDIO_CTRL_FLAG_RECVOL)
550 
551 static void
552 cmpci_alloc_ctrl(cmpci_dev_t *dev, uint32_t num, uint64_t val)
553 {
554 	audio_ctrl_desc_t	desc;
555 	cmpci_ctrl_t		*cc;
556 
557 	cc = &dev->controls[num];
558 	bzero(&desc, sizeof (desc));
559 	cc->dev = dev;
560 
561 	switch (num) {
562 	case CTL_VOLUME:
563 		desc.acd_name = AUDIO_CTRL_ID_VOLUME;
564 		desc.acd_type = AUDIO_CTRL_TYPE_MONO;
565 		desc.acd_minvalue = 0;
566 		desc.acd_maxvalue = 100;
567 		desc.acd_flags = PCMVOL;
568 		break;
569 
570 	case CTL_LINEOUT:
571 		desc.acd_name = AUDIO_CTRL_ID_LINEOUT;
572 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
573 		desc.acd_minvalue = 0;
574 		desc.acd_maxvalue = 100;
575 		desc.acd_flags = MAINVOL;
576 		break;
577 
578 	case CTL_SPEAKER:
579 		desc.acd_name = AUDIO_CTRL_ID_SPEAKER;
580 		desc.acd_type = AUDIO_CTRL_TYPE_MONO;
581 		desc.acd_minvalue = 0;
582 		desc.acd_maxvalue = 100;
583 		desc.acd_flags = MAINVOL;
584 		break;
585 
586 	case CTL_MIC:
587 		desc.acd_name = AUDIO_CTRL_ID_MIC;
588 		desc.acd_type = AUDIO_CTRL_TYPE_MONO;
589 		desc.acd_minvalue = 0;
590 		desc.acd_maxvalue = 100;
591 		desc.acd_flags = RECVOL;
592 		break;
593 
594 	case CTL_LINEIN:
595 		desc.acd_name = AUDIO_CTRL_ID_LINEIN;
596 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
597 		desc.acd_minvalue = 0;
598 		desc.acd_maxvalue = 100;
599 		desc.acd_flags = RECVOL;
600 		break;
601 
602 	case CTL_CD:
603 		desc.acd_name = AUDIO_CTRL_ID_CD;
604 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
605 		desc.acd_minvalue = 0;
606 		desc.acd_maxvalue = 100;
607 		desc.acd_flags = RECVOL;
608 		break;
609 
610 	case CTL_AUX:
611 		desc.acd_name = AUDIO_CTRL_ID_AUX1IN;
612 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
613 		desc.acd_minvalue = 0;
614 		desc.acd_maxvalue = 100;
615 		desc.acd_flags = RECVOL;
616 		break;
617 
618 	case CTL_RECSRCS:
619 		desc.acd_name = AUDIO_CTRL_ID_RECSRC;
620 		desc.acd_type = AUDIO_CTRL_TYPE_ENUM;
621 		desc.acd_enum[SRC_MIC] = AUDIO_PORT_MIC;
622 		desc.acd_enum[SRC_LINE] = AUDIO_PORT_LINEIN;
623 		desc.acd_enum[SRC_CD] = AUDIO_PORT_CD;
624 		desc.acd_enum[SRC_AUX] = AUDIO_PORT_AUX1IN;
625 		desc.acd_enum[SRC_MIX] = AUDIO_PORT_STEREOMIX;
626 		desc.acd_minvalue = (1 << (SRC_MIX + 1)) - 1;
627 		desc.acd_maxvalue = desc.acd_minvalue;
628 		desc.acd_flags = RECCTL | AUDIO_CTRL_FLAG_MULTI;
629 		break;
630 
631 	case CTL_MONSRCS:
632 		desc.acd_name = AUDIO_CTRL_ID_MONSRC;
633 		desc.acd_type = AUDIO_CTRL_TYPE_ENUM;
634 		desc.acd_enum[SRC_MIC] = AUDIO_PORT_MIC;
635 		desc.acd_enum[SRC_LINE] = AUDIO_PORT_LINEIN;
636 		desc.acd_enum[SRC_CD] = AUDIO_PORT_CD;
637 		desc.acd_enum[SRC_AUX] = AUDIO_PORT_AUX1IN;
638 		desc.acd_minvalue = ((1 << (SRC_AUX + 1)) - 1);
639 		desc.acd_maxvalue = desc.acd_minvalue;
640 		desc.acd_flags = MONCTL | AUDIO_CTRL_FLAG_MULTI;
641 		break;
642 
643 	case CTL_MICBOOST:
644 		desc.acd_name = AUDIO_CTRL_ID_MICBOOST;
645 		desc.acd_type = AUDIO_CTRL_TYPE_BOOLEAN;
646 		desc.acd_minvalue = 0;
647 		desc.acd_maxvalue = 1;
648 		desc.acd_flags = RECCTL;
649 		break;
650 	}
651 
652 	cc->value = val;
653 	cc->ctrl = audio_dev_add_control(dev->adev, &desc,
654 	    cmpci_get_ctrl, cmpci_set_ctrl, cc);
655 }
656 
657 static void
658 cmpci_add_controls(cmpci_dev_t *dev)
659 {
660 	cmpci_alloc_ctrl(dev, CTL_VOLUME, 75);
661 	cmpci_alloc_ctrl(dev, CTL_LINEOUT, 90 | (90 << 8));
662 	cmpci_alloc_ctrl(dev, CTL_SPEAKER, 75);
663 	cmpci_alloc_ctrl(dev, CTL_MIC, 32);
664 	cmpci_alloc_ctrl(dev, CTL_LINEIN, 64 | (64 << 8));
665 	cmpci_alloc_ctrl(dev, CTL_CD, 75 | (75 << 8));
666 	cmpci_alloc_ctrl(dev, CTL_AUX, 75 | (75 << 8));
667 	cmpci_alloc_ctrl(dev, CTL_RECSRCS, (1 << SRC_MIC));
668 	cmpci_alloc_ctrl(dev, CTL_MONSRCS, 0);
669 	cmpci_alloc_ctrl(dev, CTL_MICBOOST, 0);
670 }
671 
672 static void
673 cmpci_del_controls(cmpci_dev_t *dev)
674 {
675 	for (int i = 0; i < CTL_NUM; i++) {
676 		if (dev->controls[i].ctrl) {
677 			audio_dev_del_control(dev->controls[i].ctrl);
678 			dev->controls[i].ctrl = NULL;
679 		}
680 	}
681 }
682 
683 static void
684 cmpci_reset(cmpci_dev_t *dev)
685 {
686 	/* Full reset */
687 	SET32(dev, REG_MISC, MISC_RESET);
688 	(void) GET32(dev, REG_MISC);
689 	drv_usecwait(100);
690 	CLR32(dev, REG_MISC, MISC_RESET);
691 
692 	/* reset all channels */
693 	PUT32(dev, REG_FUNCTRL0, 0);
694 
695 	/* disable interrupts and such */
696 	CLR32(dev, REG_FUNCTRL0, FUNCTRL0_CH0_EN | FUNCTRL0_CH1_EN);
697 	CLR32(dev, REG_INTCTRL, INTCTRL_CH0_EN | INTCTRL_CH1_EN);
698 
699 	/* disable uart, joystick in Function Control Reg1 */
700 	CLR32(dev, REG_FUNCTRL1, FUNCTRL1_UART_EN | FUNCTRL1_JYSTK_EN);
701 
702 	/*
703 	 * Set DAC and ADC rates to 48 kHz - note that both rates have
704 	 * all bits set in them, so we can do this with a simple "set".
705 	 */
706 	SET32(dev, REG_FUNCTRL1,
707 	    FUNCTRL1_DAC_RATE_48K | FUNCTRL1_ADC_RATE_48K);
708 
709 	/* Set 16-bit stereo -- also these are just with all bits set. */
710 	SET32(dev, REG_CHFORMAT, CHFORMAT_CH0_16ST | CHFORMAT_CH1_16ST);
711 }
712 
713 static int
714 cmpci_format(void *unused)
715 {
716 	_NOTE(ARGUNUSED(unused));
717 	return (AUDIO_FORMAT_S16_LE);
718 }
719 
720 static int
721 cmpci_channels(void *unused)
722 {
723 	_NOTE(ARGUNUSED(unused));
724 	return (2);
725 }
726 
727 static int
728 cmpci_rate(void *unused)
729 {
730 	_NOTE(ARGUNUSED(unused));
731 	return (48000);
732 }
733 
734 static void
735 cmpci_sync(void *arg, unsigned nframes)
736 {
737 	cmpci_port_t *port = arg;
738 
739 	_NOTE(ARGUNUSED(nframes));
740 
741 	(void) ddi_dma_sync(port->dmah, 0, 0, port->sync_dir);
742 }
743 
744 static size_t
745 cmpci_qlen(void *unused)
746 {
747 	_NOTE(ARGUNUSED(unused));
748 
749 	return (0);
750 }
751 
752 audio_engine_ops_t cmpci_engine_ops = {
753 	AUDIO_ENGINE_VERSION,		/* version number */
754 	cmpci_open,
755 	cmpci_close,
756 	NULL,		/* start */
757 	NULL,		/* stop */
758 	cmpci_count,
759 	cmpci_format,
760 	cmpci_channels,
761 	cmpci_rate,
762 	cmpci_sync,
763 	cmpci_qlen,
764 	NULL,
765 };
766 
767 static int
768 cmpci_init(cmpci_dev_t *dev)
769 {
770 	audio_dev_t	*adev = dev->adev;
771 
772 	dev->pintrs = ddi_prop_get_int(DDI_DEV_T_ANY, dev->dip,
773 	    DDI_PROP_DONTPASS, "play-interrupts", DEFINTS);
774 
775 	dev->rintrs = ddi_prop_get_int(DDI_DEV_T_ANY, dev->dip,
776 	    DDI_PROP_DONTPASS, "record-interrupts", DEFINTS);
777 
778 	for (int i = 0; i < PORT_MAX; i++) {
779 
780 		cmpci_port_t *port;
781 		unsigned dmaflags;
782 		unsigned caps;
783 		size_t rlen;
784 		ddi_dma_cookie_t c;
785 		unsigned ccnt;
786 
787 		port = &dev->port[i];
788 		port->dev = dev;
789 		port->num = i;
790 
791 		/*
792 		 * Channel 0 is recording channel, unless we are in
793 		 * dual DAC mode.  The reason for this is simple --
794 		 * only channel "B" (which I presume to mean channel
795 		 * 1) supports multichannel configuration.
796 		 *
797 		 * However, if we're going to use SPDIF recording,
798 		 * then recording *must* occur on channel 1.  Yes, the
799 		 * hardware is "strange".
800 		 */
801 
802 		switch (i) {
803 		case 0:
804 			caps = ENGINE_INPUT_CAP;
805 			dmaflags = DDI_DMA_READ | DDI_DMA_CONSISTENT;
806 			port->callb = audio_engine_produce;
807 			port->reg_paddr = REG_CH0_PADDR;
808 			port->reg_bufsz = REG_CH0_BUFSZ;
809 			port->reg_fragsz = REG_CH0_FRAGSZ;
810 			port->fc0_rst_bit = FUNCTRL0_CH0_RST;
811 			port->fc0_rec_bit = FUNCTRL0_CH0_REC;
812 			port->fc0_en_bit = FUNCTRL0_CH0_EN;
813 			port->int_en_bit = INTCTRL_CH0_EN;
814 			port->sync_dir = DDI_DMA_SYNC_FORKERNEL;
815 			port->capture = B_TRUE;
816 			port->fc1_rate_mask = FUNCTRL1_ADC_RATE_48K;
817 			port->chformat_mask = CHFORMAT_CH0_16ST;
818 			break;
819 
820 		case 1:
821 			caps = ENGINE_OUTPUT_CAP;
822 			dmaflags = DDI_DMA_WRITE | DDI_DMA_CONSISTENT;
823 			port->callb = audio_engine_consume;
824 			port->reg_paddr = REG_CH1_PADDR;
825 			port->reg_bufsz = REG_CH1_BUFSZ;
826 			port->reg_fragsz = REG_CH1_FRAGSZ;
827 			port->fc0_rst_bit = FUNCTRL0_CH1_RST;
828 			port->fc0_rec_bit = FUNCTRL0_CH1_REC;
829 			port->fc0_en_bit = FUNCTRL0_CH1_EN;
830 			port->int_en_bit = INTCTRL_CH1_EN;
831 			port->sync_dir = DDI_DMA_SYNC_FORDEV;
832 			port->capture = B_FALSE;
833 			port->fc1_rate_mask = FUNCTRL1_DAC_RATE_48K;
834 			port->chformat_mask = CHFORMAT_CH1_16ST;
835 			break;
836 		}
837 
838 		if (ddi_dma_alloc_handle(dev->dip, &dma_attr, DDI_DMA_DONTWAIT,
839 		    NULL, &port->dmah) != DDI_SUCCESS) {
840 			audio_dev_warn(adev, "ch%d: dma hdl alloc failed", i);
841 			return (DDI_FAILURE);
842 		}
843 		if (ddi_dma_mem_alloc(port->dmah, CMPCI_BUF_LEN, &buf_attr,
844 		    DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, NULL, &port->kaddr,
845 		    &rlen, &port->acch) != DDI_SUCCESS) {
846 			audio_dev_warn(adev, "ch%d: dma mem allcoc failed", i);
847 			return (DDI_FAILURE);
848 		}
849 		bzero(port->kaddr, rlen);
850 
851 		if (ddi_dma_addr_bind_handle(port->dmah, NULL, port->kaddr,
852 		    rlen, dmaflags, DDI_DMA_DONTWAIT, NULL, &c, &ccnt) !=
853 		    DDI_DMA_MAPPED) {
854 			audio_dev_warn(adev, "ch%d: dma bind failed", i);
855 			return (DDI_FAILURE);
856 		}
857 		port->paddr = c.dmac_address;
858 
859 		port->engine = audio_engine_alloc(&cmpci_engine_ops, caps);
860 		if (port->engine == NULL) {
861 			audio_dev_warn(adev, "ch%d: alloc engine failed", i);
862 			return (DDI_FAILURE);
863 		}
864 		audio_engine_set_private(port->engine, port);
865 		audio_dev_add_engine(adev, port->engine);
866 	}
867 
868 	cmpci_add_controls(dev);
869 
870 	dev->ksp = kstat_create(ddi_driver_name(dev->dip),
871 	    ddi_get_instance(dev->dip), ddi_driver_name(dev->dip),
872 	    "controller", KSTAT_TYPE_INTR, 1, KSTAT_FLAG_PERSISTENT);
873 	if (dev->ksp != NULL) {
874 		kstat_install(dev->ksp);
875 	}
876 
877 	cmpci_reset(dev);
878 	cmpci_configure_mixer(dev);
879 
880 	if (audio_dev_register(adev) != DDI_SUCCESS) {
881 		audio_dev_warn(adev, "audio_dev_register failed");
882 		return (DDI_FAILURE);
883 	}
884 
885 	return (DDI_SUCCESS);
886 }
887 
888 void
889 cmpci_destroy(cmpci_dev_t *dev)
890 {
891 	if (dev->ihandle != NULL) {
892 		(void) ddi_intr_disable(dev->ihandle);
893 		(void) ddi_intr_remove_handler(dev->ihandle);
894 		(void) ddi_intr_free(dev->ihandle);
895 		mutex_destroy(&dev->mutex);
896 	}
897 
898 	if (dev->ksp != NULL) {
899 		kstat_delete(dev->ksp);
900 	}
901 
902 	/* free up ports, including DMA resources for ports */
903 	for (int i = 0; i < PORT_MAX; i++) {
904 		cmpci_port_t	*port = &dev->port[i];
905 
906 		if (port->paddr != 0)
907 			(void) ddi_dma_unbind_handle(port->dmah);
908 		if (port->acch != NULL)
909 			ddi_dma_mem_free(&port->acch);
910 		if (port->dmah != NULL)
911 			ddi_dma_free_handle(&port->dmah);
912 
913 		if (port->engine != NULL) {
914 			audio_dev_remove_engine(dev->adev, port->engine);
915 			audio_engine_free(port->engine);
916 		}
917 	}
918 
919 	if (dev->acch != NULL) {
920 		ddi_regs_map_free(&dev->acch);
921 	}
922 
923 	cmpci_del_controls(dev);
924 
925 	if (dev->adev != NULL) {
926 		audio_dev_free(dev->adev);
927 	}
928 
929 	kmem_free(dev, sizeof (*dev));
930 }
931 
932 int
933 cmpci_attach(dev_info_t *dip)
934 {
935 	uint16_t		vendor, device;
936 	cmpci_dev_t		*dev;
937 	ddi_acc_handle_t	pcih;
938 	audio_dev_t		*adev;
939 	uint32_t		val;
940 
941 	if (pci_config_setup(dip, &pcih) != DDI_SUCCESS) {
942 		audio_dev_warn(NULL, "pci_config_setup failed");
943 		return (DDI_FAILURE);
944 	}
945 
946 	vendor = pci_config_get16(pcih, PCI_CONF_VENID);
947 	device = pci_config_get16(pcih, PCI_CONF_DEVID);
948 
949 	if (vendor != CMEDIA_VENDOR_ID ||
950 	    ((device != CMEDIA_CM8738) && (device != CMEDIA_CM8338A) &&
951 	    (device != CMEDIA_CM8338B))) {
952 		pci_config_teardown(&pcih);
953 		audio_dev_warn(NULL, "device not recognized");
954 		return (DDI_FAILURE);
955 	}
956 
957 	/* enable IO and Master accesses */
958 	pci_config_put16(pcih, PCI_CONF_COMM,
959 	    pci_config_get16(pcih, PCI_CONF_COMM) |
960 	    PCI_COMM_MAE | PCI_COMM_IO);
961 
962 	pci_config_teardown(&pcih);
963 
964 	dev = kmem_zalloc(sizeof (*dev), KM_SLEEP);
965 	dev->dip = dip;
966 
967 	ddi_set_driver_private(dip, dev);
968 
969 	if ((adev = audio_dev_alloc(dip, 0)) == NULL) {
970 		goto err_exit;
971 	}
972 	dev->adev = adev;
973 
974 	if (ddi_regs_map_setup(dip, 1, &dev->regs, 0, 0, &acc_attr,
975 	    &dev->acch) != DDI_SUCCESS) {
976 		audio_dev_warn(adev, "can't map registers");
977 		goto err_exit;
978 	}
979 
980 	/* setup some initial values */
981 	audio_dev_set_description(adev, "C-Media PCI Audio");
982 	switch (device) {
983 	case CMEDIA_CM8738:
984 		/* Crazy 8738 detection scheme */
985 		val = GET32(dev, REG_INTCTRL) & 0x1F000000;
986 		if (val == 0) {
987 
988 			if (GET32(dev, REG_CHFORMAT & 0x1F000000)) {
989 				audio_dev_set_version(adev, "CM8738-037");
990 			} else {
991 				audio_dev_set_version(adev, "CM8738-033");
992 			}
993 		} else if (val & 0x0C000000) {
994 			audio_dev_set_version(adev, "CMI8768");
995 		} else if (val & 0x08000000) {
996 			audio_dev_set_version(adev, "CMI8738-055");
997 		} else if (val & 0x04000000) {
998 			audio_dev_set_version(adev, "CMI8738-039");
999 		} else {
1000 			audio_dev_set_version(adev, "CMI8738");
1001 		}
1002 		break;
1003 
1004 	case CMEDIA_CM8338A:
1005 		audio_dev_set_version(dev->adev, "CM8338A");
1006 		break;
1007 
1008 	case CMEDIA_CM8338B:
1009 		audio_dev_set_version(dev->adev, "CM8338B");
1010 		break;
1011 	}
1012 
1013 	if (cmpci_setup_interrupts(dev) != DDI_SUCCESS) {
1014 		audio_dev_warn(dev->adev, "can't register interrupts");
1015 		goto err_exit;
1016 	}
1017 
1018 	if (cmpci_init(dev) != DDI_SUCCESS) {
1019 		audio_dev_warn(dev->adev, "can't init device");
1020 		goto err_exit;
1021 	}
1022 
1023 	(void) ddi_intr_enable(dev->ihandle);
1024 	return (DDI_SUCCESS);
1025 
1026 err_exit:
1027 	cmpci_destroy(dev);
1028 	return (DDI_FAILURE);
1029 }
1030 
1031 static int
1032 cmpci_resume(cmpci_dev_t *dev)
1033 {
1034 	audio_engine_reset(dev->port[0].engine);
1035 	audio_engine_reset(dev->port[1].engine);
1036 
1037 	mutex_enter(&dev->mutex);
1038 	dev->suspended = B_FALSE;
1039 
1040 	cmpci_reset(dev);
1041 	/* wait one millisecond, to give reset a chance to get up */
1042 	drv_usecwait(1000);
1043 
1044 	cmpci_configure_mixer(dev);
1045 
1046 	for (int i = 0; i < PORT_MAX; i++) {
1047 		cmpci_port_t *port = &dev->port[i];
1048 
1049 		cmpci_reset_port(port);
1050 		if (port->open) {
1051 			cmpci_start_port(port);
1052 		}
1053 	}
1054 	mutex_exit(&dev->mutex);
1055 	return (DDI_SUCCESS);
1056 }
1057 
1058 static int
1059 cmpci_detach(cmpci_dev_t *dev)
1060 {
1061 	if (audio_dev_unregister(dev->adev) != DDI_SUCCESS)
1062 		return (DDI_FAILURE);
1063 
1064 	mutex_enter(&dev->mutex);
1065 
1066 	/* disable interrupts */
1067 	CLR32(dev, REG_INTCTRL, INTCTRL_CH1_EN | INTCTRL_CH0_EN);
1068 
1069 	/* disable channels */
1070 	PUT32(dev, REG_FUNCTRL0, 0);
1071 
1072 	mutex_exit(&dev->mutex);
1073 
1074 	cmpci_destroy(dev);
1075 
1076 	return (DDI_SUCCESS);
1077 }
1078 
1079 static int
1080 cmpci_suspend(cmpci_dev_t *dev)
1081 {
1082 	mutex_enter(&dev->mutex);
1083 
1084 	cmpci_update_port(&dev->port[0]);
1085 	cmpci_stop_port(&dev->port[0]);
1086 
1087 	cmpci_update_port(&dev->port[1]);
1088 	cmpci_stop_port(&dev->port[1]);
1089 
1090 	dev->suspended = B_TRUE;
1091 	mutex_exit(&dev->mutex);
1092 
1093 	return (DDI_SUCCESS);
1094 }
1095 
1096 static int
1097 cmpci_quiesce(dev_info_t *dip)
1098 {
1099 	cmpci_dev_t	*dev;
1100 
1101 	if ((dev = ddi_get_driver_private(dip)) == NULL) {
1102 		return (DDI_FAILURE);
1103 	}
1104 
1105 	/* disable interrupts */
1106 	PUT32(dev, REG_INTCTRL, 0);
1107 
1108 	/* disable channels */
1109 	PUT32(dev, REG_FUNCTRL0, 0);
1110 
1111 	return (DDI_SUCCESS);
1112 }
1113 
1114 static int
1115 cmpci_ddi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1116 {
1117 	cmpci_dev_t *dev;
1118 
1119 	switch (cmd) {
1120 	case DDI_ATTACH:
1121 		return (cmpci_attach(dip));
1122 
1123 	case DDI_RESUME:
1124 		if ((dev = ddi_get_driver_private(dip)) == NULL) {
1125 			return (DDI_FAILURE);
1126 		}
1127 		return (cmpci_resume(dev));
1128 
1129 	default:
1130 		return (DDI_FAILURE);
1131 	}
1132 }
1133 
1134 static int
1135 cmpci_ddi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1136 {
1137 	cmpci_dev_t *dev;
1138 
1139 	if ((dev = ddi_get_driver_private(dip)) == NULL) {
1140 		return (DDI_FAILURE);
1141 	}
1142 
1143 	switch (cmd) {
1144 	case DDI_DETACH:
1145 		return (cmpci_detach(dev));
1146 
1147 	case DDI_SUSPEND:
1148 		return (cmpci_suspend(dev));
1149 	default:
1150 		return (DDI_FAILURE);
1151 	}
1152 }
1153 
1154 static struct dev_ops cmpci_dev_ops = {
1155 	DEVO_REV,		/* rev */
1156 	0,			/* refcnt */
1157 	NULL,			/* getinfo */
1158 	nulldev,		/* identify */
1159 	nulldev,		/* probe */
1160 	cmpci_ddi_attach,	/* attach */
1161 	cmpci_ddi_detach,	/* detach */
1162 	nodev,			/* reset */
1163 	NULL,			/* cb_ops */
1164 	NULL,			/* bus_ops */
1165 	NULL,			/* power */
1166 	cmpci_quiesce,		/* quiesce */
1167 };
1168 
1169 static struct modldrv cmpci_modldrv = {
1170 	&mod_driverops,			/* drv_modops */
1171 	"C-Media PCI Audio",		/* linkinfo */
1172 	&cmpci_dev_ops,			/* dev_ops */
1173 };
1174 
1175 static struct modlinkage modlinkage = {
1176 	MODREV_1,
1177 	{ &cmpci_modldrv, NULL }
1178 };
1179 
1180 int
1181 _init(void)
1182 {
1183 	int	rv;
1184 
1185 	audio_init_ops(&cmpci_dev_ops, "audiocmi");
1186 	if ((rv = mod_install(&modlinkage)) != 0) {
1187 		audio_fini_ops(&cmpci_dev_ops);
1188 	}
1189 	return (rv);
1190 }
1191 
1192 int
1193 _fini(void)
1194 {
1195 	int	rv;
1196 	if ((rv = mod_remove(&modlinkage)) == 0) {
1197 		audio_fini_ops(&cmpci_dev_ops);
1198 	}
1199 	return (rv);
1200 }
1201 
1202 int
1203 _info(struct modinfo *modinfop)
1204 {
1205 	return (mod_info(&modlinkage, modinfop));
1206 }
1207