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