xref: /illumos-gate/usr/src/uts/common/io/audio/drv/audiocmi/audiocmi.c (revision 4e567b4443d7a1680a7319275e5288eef2c92319)
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 2010 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 
93 static int
94 cmpci_open(void *arg, int flag, uint_t *nframesp, caddr_t *bufp)
95 {
96 	cmpci_port_t *port = arg;
97 	cmpci_dev_t *dev = port->dev;
98 
99 	_NOTE(ARGUNUSED(flag));
100 
101 	mutex_enter(&dev->mutex);
102 
103 	*nframesp = port->nframes;
104 	*bufp = port->kaddr;
105 
106 	port->count = 0;
107 	mutex_exit(&dev->mutex);
108 
109 	return (0);
110 }
111 
112 static void
113 cmpci_close(void *arg)
114 {
115 	_NOTE(ARGUNUSED(arg));
116 }
117 
118 static int
119 cmpci_start(void *arg)
120 {
121 	cmpci_port_t	*port = arg;
122 	cmpci_dev_t	*dev = port->dev;
123 
124 	mutex_enter(&dev->mutex);
125 
126 	port->offset = 0;
127 
128 	/* reset channel */
129 	SET32(dev, REG_FUNCTRL0, port->fc0_rst_bit);
130 	drv_usecwait(10);
131 	CLR32(dev, REG_FUNCTRL0, port->fc0_rst_bit);
132 	drv_usecwait(10);
133 
134 	/* Set 48k 16-bit stereo -- these are just with all bits set. */
135 	SET32(dev, REG_FUNCTRL1, port->fc1_rate_mask);
136 	SET32(dev, REG_CHFORMAT, port->chformat_mask);
137 
138 	if ((port->num == 1) && (dev->maxch > 2)) {
139 		CLR32(dev, REG_LEGACY, LEGACY_NXCHG);
140 
141 		if (port->nchan > 2) {
142 			SET32(dev, REG_MISC, MISC_XCHGDAC);
143 			CLR32(dev, REG_MISC, MISC_N4SPK3D);
144 		} else {
145 			CLR32(dev, REG_MISC, MISC_XCHGDAC);
146 			SET32(dev, REG_MISC, MISC_N4SPK3D);
147 		}
148 
149 		switch (port->nchan) {
150 		case 2:
151 			if (dev->maxch >= 8) {
152 				CLR8(dev, REG_MISC2, MISC2_CHB3D8C);
153 			}
154 			if (dev->maxch >= 6) {
155 				CLR32(dev, REG_CHFORMAT, CHFORMAT_CHB3D5C);
156 				CLR32(dev, REG_LEGACY, LEGACY_CHB3D6C);
157 			}
158 			if (dev->maxch >= 4) {
159 				CLR32(dev, REG_CHFORMAT, CHFORMAT_CHB3D);
160 			}
161 			break;
162 		case 4:
163 			if (dev->maxch >= 8) {
164 				CLR8(dev, REG_MISC2, MISC2_CHB3D8C);
165 			}
166 			if (dev->maxch >= 6) {
167 				CLR32(dev, REG_CHFORMAT, CHFORMAT_CHB3D5C);
168 				CLR32(dev, REG_LEGACY, LEGACY_CHB3D6C);
169 				CLR32(dev, REG_MISC, MISC_ENCENTER);
170 				CLR32(dev, REG_LEGACY, LEGACY_EXBASSEN);
171 			}
172 			SET32(dev, REG_CHFORMAT, CHFORMAT_CHB3D);
173 			break;
174 		case 6:
175 			if (dev->maxch >= 8) {
176 				CLR8(dev, REG_MISC2, MISC2_CHB3D8C);
177 			}
178 			SET32(dev, REG_CHFORMAT, CHFORMAT_CHB3D5C);
179 			SET32(dev, REG_LEGACY, LEGACY_CHB3D6C);
180 			CLR32(dev, REG_MISC, MISC_ENCENTER);
181 			CLR32(dev, REG_LEGACY, LEGACY_EXBASSEN);
182 			CLR32(dev, REG_CHFORMAT, CHFORMAT_CHB3D);
183 			break;
184 
185 		case 8:
186 			SET8(dev, REG_MISC2, MISC2_CHB3D8C);
187 			CLR32(dev, REG_MISC, MISC_ENCENTER);
188 			CLR32(dev, REG_LEGACY, LEGACY_EXBASSEN);
189 			CLR32(dev, REG_CHFORMAT, CHFORMAT_CHB3D5C);
190 			CLR32(dev, REG_LEGACY, LEGACY_CHB3D6C);
191 			CLR32(dev, REG_CHFORMAT, CHFORMAT_CHB3D);
192 			break;
193 		}
194 	}
195 
196 	PUT32(dev, port->reg_paddr, port->paddr);
197 	PUT16(dev, port->reg_bufsz, (port->bufsz / 4) - 1);
198 	PUT16(dev, port->reg_fragsz, (port->bufsz  / 4) - 1);
199 
200 	/* Analog output */
201 	if (port->capture) {
202 		/* Analog capture */
203 		SET32(dev, REG_FUNCTRL0, port->fc0_rec_bit);
204 	} else {
205 		CLR32(dev, REG_FUNCTRL0, port->fc0_rec_bit);
206 	}
207 
208 	SET32(dev, REG_FUNCTRL0, port->fc0_en_bit);
209 	mutex_exit(&dev->mutex);
210 
211 	return (0);
212 }
213 
214 static void
215 cmpci_stop(void *arg)
216 {
217 	cmpci_port_t	*port = arg;
218 	cmpci_dev_t	*dev = port->dev;
219 
220 	mutex_enter(&dev->mutex);
221 	CLR32(dev, REG_FUNCTRL0, port->fc0_en_bit);
222 	mutex_exit(&dev->mutex);
223 }
224 
225 static uint64_t
226 cmpci_count(void *arg)
227 {
228 	cmpci_port_t	*port = arg;
229 	cmpci_dev_t	*dev = port->dev;
230 	uint64_t	count;
231 	uint32_t	offset;
232 
233 	mutex_enter(&dev->mutex);
234 
235 	/* this gives us the offset in dwords */
236 	offset = (port->bufsz / 4) - (GET16(dev, port->reg_bufsz) + 1);
237 
238 	/* check for wrap - note that the count is given in dwords */
239 	if (offset < port->offset) {
240 		count = ((port->bufsz / 4) - port->offset) + offset;
241 	} else {
242 		count = offset - port->offset;
243 	}
244 	port->count += count;
245 	port->offset = offset;
246 	count = port->count;
247 
248 	mutex_exit(&dev->mutex);
249 
250 	/*
251 	 * convert dwords to frames - unfortunately this requires a
252 	 * divide
253 	 */
254 	return (count / (port->nchan / 2));
255 }
256 
257 #define	MASK(nbits)	((1 << (nbits)) - 1)
258 #define	SCALE(val, nbits)	\
259 	((uint8_t)((((val) * MASK(nbits)) / 100)) << (8 - (nbits)))
260 
261 #define	LEFT(dev, ctl)	min(((dev->controls[ctl].value) >> 8), 100)
262 #define	RIGHT(dev, ctl)	min(((dev->controls[ctl].value) & 0xff), 100)
263 #define	MONO(dev, ctl)	min(dev->controls[ctl].value, 100)
264 
265 static void
266 cmpci_setmixer(cmpci_dev_t *dev, uint8_t idx, uint8_t val)
267 {
268 	PUT8(dev, REG_IDXADDR, idx);
269 	PUT8(dev, REG_IDXDATA, val);
270 }
271 
272 static uint8_t
273 cmpci_getmixer(cmpci_dev_t *dev, uint8_t idx)
274 {
275 	PUT8(dev, REG_IDXADDR, idx);
276 	return (GET8(dev, REG_IDXDATA));
277 }
278 
279 
280 static void
281 cmpci_configure_mixer(cmpci_dev_t *dev)
282 {
283 	uint64_t	left, right;
284 	uint8_t		outmix;
285 	uint8_t		inmix[2];
286 	uint64_t	recsrcs;
287 	uint64_t	monsrcs;
288 
289 	/* reset all mix values */
290 	outmix = inmix[0] = inmix[1] = 0;
291 
292 	outmix = OUTMIX_MIC |
293 	    OUTMIX_CD_R | OUTMIX_CD_L | OUTMIX_LINE_R | OUTMIX_LINE_L;
294 
295 	inmix[0] = INMIX_LINE_L | INMIX_CD_L | INMIX_MIC;
296 	inmix[1] = INMIX_LINE_R | INMIX_CD_R | INMIX_MIC;
297 
298 	recsrcs = dev->controls[CTL_RECSRCS].value;
299 	monsrcs = dev->controls[CTL_MONSRCS].value;
300 
301 	/* program PCM volume */
302 	left = MONO(dev, CTL_VOLUME);
303 	if (left) {
304 		/* left and right are the same */
305 		cmpci_setmixer(dev, IDX_VOICE_LEFT, SCALE(left, 5));
306 		cmpci_setmixer(dev, IDX_VOICE_RIGHT, SCALE(left, 5));
307 		CLR8(dev, REG_MIX2, MIX2_WSMUTE);
308 	} else {
309 		cmpci_setmixer(dev, IDX_VOICE_LEFT, 0);
310 		cmpci_setmixer(dev, IDX_VOICE_RIGHT, 0);
311 		SET8(dev, REG_MIX2, MIX2_WSMUTE);
312 	}
313 
314 	left = LEFT(dev, CTL_LINEOUT);
315 	right = RIGHT(dev, CTL_LINEOUT);
316 
317 	/* lineout/master volume - no separate mute */
318 	cmpci_setmixer(dev, IDX_MASTER_LEFT, SCALE(left, 5));
319 	cmpci_setmixer(dev, IDX_MASTER_RIGHT, SCALE(right, 5));
320 
321 	/* speaker volume - mute in extension register, but we don't use */
322 	left = MONO(dev, CTL_SPEAKER);
323 	cmpci_setmixer(dev, IDX_SPEAKER, SCALE(left, 2));
324 
325 	/* mic gain */
326 	left = MONO(dev, CTL_MIC);
327 	if (left) {
328 		cmpci_setmixer(dev, IDX_MIC, SCALE(left, 5));
329 		/* set record mic gain */
330 		uint8_t v = GET8(dev, REG_MIX3);
331 		v &= ~(0x7 << 1);
332 		v |= ((left * 7) / 100) << 1;
333 		PUT8(dev, REG_MIX3, v);
334 		cmpci_setmixer(dev, 0x3f, SCALE(100, 2));
335 		cmpci_setmixer(dev, 0x40, SCALE(100, 2));
336 	} else {
337 		cmpci_setmixer(dev, IDX_MIC, 0);
338 		outmix &= ~OUTMIX_MIC;
339 		inmix[0] &= ~INMIX_MIC;
340 		inmix[1] &= ~INMIX_MIC;
341 	}
342 
343 	/* line in */
344 	left = LEFT(dev, CTL_LINEOUT);
345 	right = RIGHT(dev, CTL_LINEOUT);
346 	if (left) {
347 		cmpci_setmixer(dev, IDX_LINEIN_LEFT, SCALE(left, 5));
348 	} else {
349 		cmpci_setmixer(dev, IDX_LINEIN_LEFT, 0);
350 		inmix[0] &= ~INMIX_LINE_L;
351 		outmix &= ~OUTMIX_LINE_L;
352 	}
353 	if (right) {
354 		cmpci_setmixer(dev, IDX_LINEIN_RIGHT, SCALE(left, 5));
355 	} else {
356 		cmpci_setmixer(dev, IDX_LINEIN_RIGHT, 0);
357 		inmix[1] &= ~INMIX_LINE_R;
358 		outmix &= ~OUTMIX_LINE_R;
359 	}
360 
361 	/* cd */
362 	left = LEFT(dev, CTL_CD);
363 	right = RIGHT(dev, CTL_CD);
364 	if (left) {
365 		cmpci_setmixer(dev, IDX_CDDA_LEFT, SCALE(left, 5));
366 	} else {
367 		cmpci_setmixer(dev, IDX_CDDA_LEFT, 0);
368 		inmix[0] &= ~INMIX_CD_L;
369 		outmix &= ~OUTMIX_CD_L;
370 	}
371 	if (right) {
372 		cmpci_setmixer(dev, IDX_CDDA_RIGHT, SCALE(left, 5));
373 	} else {
374 		cmpci_setmixer(dev, IDX_CDDA_RIGHT, 0);
375 		inmix[1] &= ~INMIX_CD_R;
376 		outmix &= ~OUTMIX_CD_R;
377 	}
378 
379 	/* aux - trickier because it doesn't use regular sbpro mixer */
380 	left = LEFT(dev, CTL_AUX);
381 	right = RIGHT(dev, CTL_AUX);
382 	PUT8(dev, REG_VAUX, (((left * 15) / 100) << 4) | ((right * 15) / 100));
383 	/* maybe enable recording */
384 	if ((left || right) && (recsrcs & (1 << SRC_LINE))) {
385 		SET8(dev, REG_MIX3, MIX3_RAUXREN | MIX3_RAUXLEN);
386 	} else {
387 		CLR8(dev, REG_MIX3, MIX3_RAUXREN | MIX3_RAUXLEN);
388 	}
389 	/* maybe enable monitoring */
390 	if ((left || right) && (monsrcs & (1 << SRC_AUX))) {
391 		CLR8(dev, REG_MIX3, MIX3_VAUXRM | MIX3_VAUXLM);
392 	} else {
393 		SET8(dev, REG_MIX3, MIX3_VAUXRM | MIX3_VAUXLM);
394 	}
395 
396 	/* now do the recsrcs */
397 	if ((recsrcs & (1 << SRC_MIC)) == 0) {
398 		inmix[0] &= ~INMIX_MIC;
399 		inmix[1] &= ~INMIX_MIC;
400 	}
401 	if ((recsrcs & (1 << SRC_LINE)) == 0) {
402 		inmix[0] &= ~INMIX_LINE_L;
403 		inmix[1] &= ~INMIX_LINE_R;
404 	}
405 	if ((recsrcs & (1 << SRC_CD)) == 0) {
406 		inmix[0] &= ~INMIX_CD_L;
407 		inmix[1] &= ~INMIX_CD_R;
408 	}
409 	if (recsrcs & (1 << SRC_MIX)) {
410 		SET8(dev, REG_MIX2, MIX2_WAVEIN_L | MIX2_WAVEIN_R);
411 	} else {
412 		CLR8(dev, REG_MIX2, MIX2_WAVEIN_L | MIX2_WAVEIN_R);
413 	}
414 	cmpci_setmixer(dev, IDX_INMIX_L, inmix[0]);
415 	cmpci_setmixer(dev, IDX_INMIX_R, inmix[1]);
416 
417 	/* now the monsrcs */
418 	if ((monsrcs & (1 << SRC_MIC)) == 0) {
419 		outmix &= ~OUTMIX_MIC;
420 	}
421 	if ((monsrcs & (1 << SRC_LINE)) == 0) {
422 		outmix &= ~(OUTMIX_LINE_L | OUTMIX_LINE_R);
423 	}
424 	if ((monsrcs & (1 << SRC_CD)) == 0) {
425 		outmix &= ~(OUTMIX_CD_L | OUTMIX_CD_R);
426 	}
427 	cmpci_setmixer(dev, IDX_OUTMIX, outmix);
428 
429 	/* micboost */
430 	if (dev->controls[CTL_MICBOOST].value != 0) {
431 		CLR8(dev, REG_MIX3, MIX3_MICGAINZ);
432 		cmpci_setmixer(dev, IDX_EXTENSION,
433 		    cmpci_getmixer(dev, IDX_EXTENSION) & ~0x1);
434 	} else {
435 		SET8(dev, REG_MIX3, MIX3_MICGAINZ);
436 		cmpci_setmixer(dev, IDX_EXTENSION,
437 		    cmpci_getmixer(dev, IDX_EXTENSION) | 0x1);
438 	}
439 }
440 
441 static int
442 cmpci_set_ctrl(void *arg, uint64_t val)
443 {
444 	cmpci_ctrl_t *cc = arg;
445 	cmpci_dev_t *dev = cc->dev;
446 
447 	/*
448 	 * We don't bother to check for valid values - a bogus value
449 	 * will give incorrect volumes, but is otherwise harmless.
450 	 */
451 	mutex_enter(&dev->mutex);
452 	cc->value = val;
453 	cmpci_configure_mixer(dev);
454 	mutex_exit(&dev->mutex);
455 
456 	return (0);
457 }
458 
459 static int
460 cmpci_get_ctrl(void *arg, uint64_t *val)
461 {
462 	cmpci_ctrl_t *cc = arg;
463 	cmpci_dev_t *dev = cc->dev;
464 
465 	mutex_enter(&dev->mutex);
466 	*val = cc->value;
467 	mutex_exit(&dev->mutex);
468 	return (0);
469 }
470 
471 #define	PLAYCTL	(AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_PLAY)
472 #define	RECCTL	(AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_REC)
473 #define	MONCTL	(AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_MONITOR)
474 #define	PCMVOL	(PLAYCTL | AUDIO_CTRL_FLAG_PCMVOL)
475 #define	MAINVOL	(PLAYCTL | AUDIO_CTRL_FLAG_MAINVOL)
476 #define	RECVOL	(RECCTL | AUDIO_CTRL_FLAG_RECVOL)
477 
478 static void
479 cmpci_alloc_ctrl(cmpci_dev_t *dev, uint32_t num, uint64_t val)
480 {
481 	audio_ctrl_desc_t	desc;
482 	cmpci_ctrl_t		*cc;
483 
484 	cc = &dev->controls[num];
485 	bzero(&desc, sizeof (desc));
486 	cc->dev = dev;
487 
488 	switch (num) {
489 	case CTL_VOLUME:
490 		desc.acd_name = AUDIO_CTRL_ID_VOLUME;
491 		desc.acd_type = AUDIO_CTRL_TYPE_MONO;
492 		desc.acd_minvalue = 0;
493 		desc.acd_maxvalue = 100;
494 		desc.acd_flags = PCMVOL;
495 		break;
496 
497 	case CTL_LINEOUT:
498 		desc.acd_name = AUDIO_CTRL_ID_LINEOUT;
499 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
500 		desc.acd_minvalue = 0;
501 		desc.acd_maxvalue = 100;
502 		desc.acd_flags = MAINVOL;
503 		break;
504 
505 	case CTL_SPEAKER:
506 		desc.acd_name = AUDIO_CTRL_ID_SPEAKER;
507 		desc.acd_type = AUDIO_CTRL_TYPE_MONO;
508 		desc.acd_minvalue = 0;
509 		desc.acd_maxvalue = 100;
510 		desc.acd_flags = MAINVOL;
511 		break;
512 
513 	case CTL_MIC:
514 		desc.acd_name = AUDIO_CTRL_ID_MIC;
515 		desc.acd_type = AUDIO_CTRL_TYPE_MONO;
516 		desc.acd_minvalue = 0;
517 		desc.acd_maxvalue = 100;
518 		desc.acd_flags = RECVOL;
519 		break;
520 
521 	case CTL_LINEIN:
522 		desc.acd_name = AUDIO_CTRL_ID_LINEIN;
523 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
524 		desc.acd_minvalue = 0;
525 		desc.acd_maxvalue = 100;
526 		desc.acd_flags = RECVOL;
527 		break;
528 
529 	case CTL_CD:
530 		desc.acd_name = AUDIO_CTRL_ID_CD;
531 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
532 		desc.acd_minvalue = 0;
533 		desc.acd_maxvalue = 100;
534 		desc.acd_flags = RECVOL;
535 		break;
536 
537 	case CTL_AUX:
538 		desc.acd_name = AUDIO_CTRL_ID_AUX1IN;
539 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
540 		desc.acd_minvalue = 0;
541 		desc.acd_maxvalue = 100;
542 		desc.acd_flags = RECVOL;
543 		break;
544 
545 	case CTL_RECSRCS:
546 		desc.acd_name = AUDIO_CTRL_ID_RECSRC;
547 		desc.acd_type = AUDIO_CTRL_TYPE_ENUM;
548 		desc.acd_enum[SRC_MIC] = AUDIO_PORT_MIC;
549 		desc.acd_enum[SRC_LINE] = AUDIO_PORT_LINEIN;
550 		desc.acd_enum[SRC_CD] = AUDIO_PORT_CD;
551 		desc.acd_enum[SRC_AUX] = AUDIO_PORT_AUX1IN;
552 		desc.acd_enum[SRC_MIX] = AUDIO_PORT_STEREOMIX;
553 		desc.acd_minvalue = (1 << (SRC_MIX + 1)) - 1;
554 		desc.acd_maxvalue = desc.acd_minvalue;
555 		desc.acd_flags = RECCTL | AUDIO_CTRL_FLAG_MULTI;
556 		break;
557 
558 	case CTL_MONSRCS:
559 		desc.acd_name = AUDIO_CTRL_ID_MONSRC;
560 		desc.acd_type = AUDIO_CTRL_TYPE_ENUM;
561 		desc.acd_enum[SRC_MIC] = AUDIO_PORT_MIC;
562 		desc.acd_enum[SRC_LINE] = AUDIO_PORT_LINEIN;
563 		desc.acd_enum[SRC_CD] = AUDIO_PORT_CD;
564 		desc.acd_enum[SRC_AUX] = AUDIO_PORT_AUX1IN;
565 		desc.acd_minvalue = ((1 << (SRC_AUX + 1)) - 1);
566 		desc.acd_maxvalue = desc.acd_minvalue;
567 		desc.acd_flags = MONCTL | AUDIO_CTRL_FLAG_MULTI;
568 		break;
569 
570 	case CTL_MICBOOST:
571 		desc.acd_name = AUDIO_CTRL_ID_MICBOOST;
572 		desc.acd_type = AUDIO_CTRL_TYPE_BOOLEAN;
573 		desc.acd_minvalue = 0;
574 		desc.acd_maxvalue = 1;
575 		desc.acd_flags = RECCTL;
576 		break;
577 	}
578 
579 	cc->value = val;
580 	cc->ctrl = audio_dev_add_control(dev->adev, &desc,
581 	    cmpci_get_ctrl, cmpci_set_ctrl, cc);
582 }
583 
584 static void
585 cmpci_add_controls(cmpci_dev_t *dev)
586 {
587 	if (dev->softvol) {
588 		(void) audio_dev_add_soft_volume(dev->adev);
589 	} else {
590 		cmpci_alloc_ctrl(dev, CTL_VOLUME, 75);
591 	}
592 	cmpci_alloc_ctrl(dev, CTL_LINEOUT, 90 | (90 << 8));
593 	cmpci_alloc_ctrl(dev, CTL_SPEAKER, 75);
594 	cmpci_alloc_ctrl(dev, CTL_MIC, 32);
595 	cmpci_alloc_ctrl(dev, CTL_LINEIN, 64 | (64 << 8));
596 	cmpci_alloc_ctrl(dev, CTL_CD, 75 | (75 << 8));
597 	cmpci_alloc_ctrl(dev, CTL_AUX, 75 | (75 << 8));
598 	cmpci_alloc_ctrl(dev, CTL_RECSRCS, (1 << SRC_MIC));
599 	cmpci_alloc_ctrl(dev, CTL_MONSRCS, 0);
600 	cmpci_alloc_ctrl(dev, CTL_MICBOOST, 0);
601 }
602 
603 static void
604 cmpci_del_controls(cmpci_dev_t *dev)
605 {
606 	for (int i = 0; i < CTL_NUM; i++) {
607 		if (dev->controls[i].ctrl) {
608 			audio_dev_del_control(dev->controls[i].ctrl);
609 			dev->controls[i].ctrl = NULL;
610 		}
611 	}
612 }
613 
614 static void
615 cmpci_reset(cmpci_dev_t *dev)
616 {
617 	/* Full reset */
618 	SET32(dev, REG_MISC, MISC_RESET);
619 	(void) GET32(dev, REG_MISC);
620 	drv_usecwait(100);
621 	CLR32(dev, REG_MISC, MISC_RESET);
622 
623 	/* reset all channels */
624 	PUT32(dev, REG_FUNCTRL0, 0);
625 
626 	/* disable interrupts and such */
627 	CLR32(dev, REG_FUNCTRL0, FUNCTRL0_CH0_EN | FUNCTRL0_CH1_EN);
628 	CLR32(dev, REG_INTCTRL, INTCTRL_CH0_EN | INTCTRL_CH1_EN);
629 
630 	/* disable uart, joystick in Function Control Reg1 */
631 	CLR32(dev, REG_FUNCTRL1, FUNCTRL1_UART_EN | FUNCTRL1_JYSTK_EN);
632 
633 	/*
634 	 * Set DAC and ADC rates to 48 kHz - note that both rates have
635 	 * all bits set in them, so we can do this with a simple "set".
636 	 */
637 	SET32(dev, REG_FUNCTRL1,
638 	    FUNCTRL1_DAC_RATE_48K | FUNCTRL1_ADC_RATE_48K);
639 
640 	/* Set 16-bit stereo -- also these are just with all bits set. */
641 	SET32(dev, REG_CHFORMAT, CHFORMAT_CH0_16ST | CHFORMAT_CH1_16ST);
642 }
643 
644 static int
645 cmpci_format(void *unused)
646 {
647 	_NOTE(ARGUNUSED(unused));
648 	return (AUDIO_FORMAT_S16_LE);
649 }
650 
651 static int
652 cmpci_channels(void *arg)
653 {
654 	cmpci_port_t *port = arg;
655 
656 	return (port->nchan);
657 }
658 
659 static void
660 cmpci_chinfo(void *arg, int chan, unsigned *offset, unsigned *incr)
661 {
662 	cmpci_port_t *port = arg;
663 	static const int map8ch[] = { 0, 1, 4, 5, 2, 3, 6, 7 };
664 	static const int map4ch[] = { 0, 1, 2, 3 };
665 
666 	if (port->nchan <= 4) {
667 		*offset = map4ch[chan];
668 	} else {
669 		*offset = map8ch[chan];
670 	}
671 	*incr = port->nchan;
672 }
673 
674 static int
675 cmpci_rate(void *unused)
676 {
677 	_NOTE(ARGUNUSED(unused));
678 	return (48000);
679 }
680 
681 static void
682 cmpci_sync(void *arg, unsigned nframes)
683 {
684 	cmpci_port_t *port = arg;
685 
686 	_NOTE(ARGUNUSED(nframes));
687 
688 	(void) ddi_dma_sync(port->dmah, 0, 0, port->sync_dir);
689 }
690 
691 audio_engine_ops_t cmpci_engine_ops = {
692 	AUDIO_ENGINE_VERSION,		/* version number */
693 	cmpci_open,
694 	cmpci_close,
695 	cmpci_start,
696 	cmpci_stop,
697 	cmpci_count,
698 	cmpci_format,
699 	cmpci_channels,
700 	cmpci_rate,
701 	cmpci_sync,
702 	NULL,		/* qlen */
703 	cmpci_chinfo,
704 	NULL,		/* playahead */
705 };
706 
707 static int
708 cmpci_init(cmpci_dev_t *dev)
709 {
710 	audio_dev_t	*adev = dev->adev;
711 	int		playch;
712 
713 	playch  = ddi_prop_get_int(DDI_DEV_T_ANY, dev->dip,
714 	    DDI_PROP_DONTPASS, "channels", dev->maxch);
715 
716 	if ((playch % 2) || (playch < 2) || (playch > dev->maxch)) {
717 		audio_dev_warn(adev,
718 		    "Invalid channels property (%d), resetting to %d",
719 		    playch, dev->maxch);
720 		playch = dev->maxch;
721 	}
722 
723 	for (int i = 0; i < PORT_MAX; i++) {
724 
725 		cmpci_port_t *port;
726 		unsigned dmaflags;
727 		unsigned caps;
728 		size_t rlen;
729 		ddi_dma_cookie_t c;
730 		unsigned ccnt;
731 
732 		port = &dev->port[i];
733 		port->dev = dev;
734 		port->num = i;
735 
736 		/*
737 		 * Channel 0 is recording channel, unless we are in
738 		 * dual DAC mode.  The reason for this is simple --
739 		 * only channel "B" (which I presume to mean channel
740 		 * 1) supports multichannel configuration.
741 		 *
742 		 * However, if we're going to use SPDIF recording,
743 		 * then recording *must* occur on channel 1.  Yes, the
744 		 * hardware is "strange".
745 		 */
746 
747 		switch (i) {
748 		case 0:
749 			caps = ENGINE_INPUT_CAP;
750 			dmaflags = DDI_DMA_READ | DDI_DMA_CONSISTENT;
751 			port->reg_paddr = REG_CH0_PADDR;
752 			port->reg_bufsz = REG_CH0_BUFSZ;
753 			port->reg_fragsz = REG_CH0_FRAGSZ;
754 			port->fc0_rst_bit = FUNCTRL0_CH0_RST;
755 			port->fc0_rec_bit = FUNCTRL0_CH0_REC;
756 			port->fc0_en_bit = FUNCTRL0_CH0_EN;
757 			port->sync_dir = DDI_DMA_SYNC_FORKERNEL;
758 			port->capture = B_TRUE;
759 			port->fc1_rate_mask = FUNCTRL1_ADC_RATE_48K;
760 			port->chformat_mask = CHFORMAT_CH0_16ST;
761 			port->nchan = 2;
762 			break;
763 
764 		case 1:
765 			caps = ENGINE_OUTPUT_CAP;
766 			dmaflags = DDI_DMA_WRITE | DDI_DMA_CONSISTENT;
767 			port->reg_paddr = REG_CH1_PADDR;
768 			port->reg_bufsz = REG_CH1_BUFSZ;
769 			port->reg_fragsz = REG_CH1_FRAGSZ;
770 			port->fc0_rst_bit = FUNCTRL0_CH1_RST;
771 			port->fc0_rec_bit = FUNCTRL0_CH1_REC;
772 			port->fc0_en_bit = FUNCTRL0_CH1_EN;
773 			port->sync_dir = DDI_DMA_SYNC_FORDEV;
774 			port->capture = B_FALSE;
775 			port->fc1_rate_mask = FUNCTRL1_DAC_RATE_48K;
776 			port->chformat_mask = CHFORMAT_CH1_16ST;
777 			port->nchan = playch;
778 			break;
779 		}
780 
781 		/*
782 		 * For efficiency, we'd like to have the fragments
783 		 * evenly divisble by 64 bytes.  Since frames are
784 		 * already evenly divisble by 4 (16-bit stereo), this
785 		 * is adequate.  For a typical configuration (175 Hz
786 		 * requested) this will translate to 166 Hz.
787 		 */
788 		port->nframes = 2048;
789 		port->bufsz = port->nframes * port->nchan * 2;
790 
791 		if (ddi_dma_alloc_handle(dev->dip, &dma_attr, DDI_DMA_DONTWAIT,
792 		    NULL, &port->dmah) != DDI_SUCCESS) {
793 			audio_dev_warn(adev, "ch%d: dma hdl alloc failed", i);
794 			return (DDI_FAILURE);
795 		}
796 		if (ddi_dma_mem_alloc(port->dmah, port->bufsz, &buf_attr,
797 		    DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, NULL, &port->kaddr,
798 		    &rlen, &port->acch) != DDI_SUCCESS) {
799 			audio_dev_warn(adev, "ch%d: dma mem allcoc failed", i);
800 			return (DDI_FAILURE);
801 		}
802 		bzero(port->kaddr, rlen);
803 
804 		if (ddi_dma_addr_bind_handle(port->dmah, NULL, port->kaddr,
805 		    rlen, dmaflags, DDI_DMA_DONTWAIT, NULL, &c, &ccnt) !=
806 		    DDI_DMA_MAPPED) {
807 			audio_dev_warn(adev, "ch%d: dma bind failed", i);
808 			return (DDI_FAILURE);
809 		}
810 		port->paddr = c.dmac_address;
811 
812 		port->engine = audio_engine_alloc(&cmpci_engine_ops, caps);
813 		if (port->engine == NULL) {
814 			audio_dev_warn(adev, "ch%d: alloc engine failed", i);
815 			return (DDI_FAILURE);
816 		}
817 		audio_engine_set_private(port->engine, port);
818 		audio_dev_add_engine(adev, port->engine);
819 	}
820 
821 	cmpci_add_controls(dev);
822 
823 	cmpci_reset(dev);
824 	cmpci_configure_mixer(dev);
825 
826 	if (audio_dev_register(adev) != DDI_SUCCESS) {
827 		audio_dev_warn(adev, "audio_dev_register failed");
828 		return (DDI_FAILURE);
829 	}
830 
831 	return (DDI_SUCCESS);
832 }
833 
834 void
835 cmpci_destroy(cmpci_dev_t *dev)
836 {
837 	mutex_destroy(&dev->mutex);
838 
839 	/* free up ports, including DMA resources for ports */
840 	for (int i = 0; i < PORT_MAX; i++) {
841 		cmpci_port_t	*port = &dev->port[i];
842 
843 		if (port->paddr != 0)
844 			(void) ddi_dma_unbind_handle(port->dmah);
845 		if (port->acch != NULL)
846 			ddi_dma_mem_free(&port->acch);
847 		if (port->dmah != NULL)
848 			ddi_dma_free_handle(&port->dmah);
849 
850 		if (port->engine != NULL) {
851 			audio_dev_remove_engine(dev->adev, port->engine);
852 			audio_engine_free(port->engine);
853 		}
854 	}
855 
856 	if (dev->acch != NULL) {
857 		ddi_regs_map_free(&dev->acch);
858 	}
859 
860 	cmpci_del_controls(dev);
861 
862 	if (dev->adev != NULL) {
863 		audio_dev_free(dev->adev);
864 	}
865 
866 	kmem_free(dev, sizeof (*dev));
867 }
868 
869 int
870 cmpci_attach(dev_info_t *dip)
871 {
872 	uint16_t		vendor, device;
873 	cmpci_dev_t		*dev;
874 	ddi_acc_handle_t	pcih;
875 	audio_dev_t		*adev;
876 	uint32_t		val;
877 
878 	if (pci_config_setup(dip, &pcih) != DDI_SUCCESS) {
879 		audio_dev_warn(NULL, "pci_config_setup failed");
880 		return (DDI_FAILURE);
881 	}
882 
883 	vendor = pci_config_get16(pcih, PCI_CONF_VENID);
884 	device = pci_config_get16(pcih, PCI_CONF_DEVID);
885 
886 	if (vendor != CMEDIA_VENDOR_ID ||
887 	    ((device != CMEDIA_CM8738) && (device != CMEDIA_CM8338A) &&
888 	    (device != CMEDIA_CM8338B))) {
889 		pci_config_teardown(&pcih);
890 		audio_dev_warn(NULL, "device not recognized");
891 		return (DDI_FAILURE);
892 	}
893 
894 	/* enable IO and Master accesses */
895 	pci_config_put16(pcih, PCI_CONF_COMM,
896 	    pci_config_get16(pcih, PCI_CONF_COMM) |
897 	    PCI_COMM_MAE | PCI_COMM_IO);
898 
899 	pci_config_teardown(&pcih);
900 
901 	dev = kmem_zalloc(sizeof (*dev), KM_SLEEP);
902 	dev->dip = dip;
903 	mutex_init(&dev->mutex, NULL, MUTEX_DRIVER, NULL);
904 
905 	ddi_set_driver_private(dip, dev);
906 
907 	if ((adev = audio_dev_alloc(dip, 0)) == NULL) {
908 		goto err_exit;
909 	}
910 	dev->adev = adev;
911 
912 	if (ddi_regs_map_setup(dip, 1, &dev->regs, 0, 0, &acc_attr,
913 	    &dev->acch) != DDI_SUCCESS) {
914 		audio_dev_warn(adev, "can't map registers");
915 		goto err_exit;
916 	}
917 
918 	/* setup some initial values */
919 	dev->maxch = 2;
920 	audio_dev_set_description(adev, "C-Media PCI Audio");
921 	switch (device) {
922 	case CMEDIA_CM8738:
923 		/*
924 		 * Crazy 8738 detection scheme.  Reviewing multiple
925 		 * different open sources gives multiple different
926 		 * answers here.  Its unclear how accurate this is.
927 		 * The approach taken here is a bit conservative in
928 		 * assigning multiple channel support, but for users
929 		 * with newer 8768 cards should offer the best
930 		 * capability.
931 		 */
932 		val = GET32(dev, REG_INTCTRL) & INTCTRL_MDL_MASK;
933 		if (val == 0) {
934 
935 			if (GET32(dev, REG_CHFORMAT & CHFORMAT_VER_MASK)) {
936 				audio_dev_set_version(adev, "CMI-8738-037");
937 				dev->maxch = 4;
938 			} else {
939 				audio_dev_set_version(adev, "CMI-8738-033");
940 			}
941 		} else if ((val & INTCTRL_MDL_068) == INTCTRL_MDL_068) {
942 			audio_dev_set_version(adev, "CMI-8768");
943 			dev->maxch = 8;
944 			dev->softvol = B_TRUE;	/* No hardware PCM volume */
945 		} else if ((val & INTCTRL_MDL_055) == INTCTRL_MDL_055) {
946 			audio_dev_set_version(adev, "CMI-8738-055");
947 			dev->maxch = 6;
948 		} else if ((val & INTCTRL_MDL_039) == INTCTRL_MDL_039) {
949 			audio_dev_set_version(adev, "CMI-8738-039");
950 			dev->maxch = 4;
951 		} else {
952 			audio_dev_set_version(adev, "CMI-8738");
953 		}
954 		break;
955 
956 	case CMEDIA_CM8338A:
957 		audio_dev_set_version(dev->adev, "CMI-8338");
958 		break;
959 
960 	case CMEDIA_CM8338B:
961 		audio_dev_set_version(dev->adev, "CMI-8338B");
962 		break;
963 	}
964 
965 	if (cmpci_init(dev) != DDI_SUCCESS) {
966 		audio_dev_warn(dev->adev, "can't init device");
967 		goto err_exit;
968 	}
969 
970 	return (DDI_SUCCESS);
971 
972 err_exit:
973 	cmpci_destroy(dev);
974 	return (DDI_FAILURE);
975 }
976 
977 static int
978 cmpci_resume(cmpci_dev_t *dev)
979 {
980 	mutex_enter(&dev->mutex);
981 	cmpci_reset(dev);
982 	/* wait one millisecond, to give reset a chance to get up */
983 	drv_usecwait(1000);
984 	mutex_exit(&dev->mutex);
985 
986 	audio_dev_resume(dev->adev);
987 
988 	return (DDI_SUCCESS);
989 }
990 
991 static int
992 cmpci_detach(cmpci_dev_t *dev)
993 {
994 	if (audio_dev_unregister(dev->adev) != DDI_SUCCESS)
995 		return (DDI_FAILURE);
996 
997 	mutex_enter(&dev->mutex);
998 
999 	/* disable channels */
1000 	PUT32(dev, REG_FUNCTRL0, 0);
1001 
1002 	mutex_exit(&dev->mutex);
1003 
1004 	cmpci_destroy(dev);
1005 
1006 	return (DDI_SUCCESS);
1007 }
1008 
1009 static int
1010 cmpci_quiesce(dev_info_t *dip)
1011 {
1012 	cmpci_dev_t	*dev;
1013 
1014 	if ((dev = ddi_get_driver_private(dip)) == NULL) {
1015 		return (DDI_FAILURE);
1016 	}
1017 
1018 	/* disable channels */
1019 	PUT32(dev, REG_FUNCTRL0, 0);
1020 
1021 	return (DDI_SUCCESS);
1022 }
1023 
1024 static int
1025 cmpci_ddi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1026 {
1027 	cmpci_dev_t *dev;
1028 
1029 	switch (cmd) {
1030 	case DDI_ATTACH:
1031 		return (cmpci_attach(dip));
1032 
1033 	case DDI_RESUME:
1034 		if ((dev = ddi_get_driver_private(dip)) == NULL) {
1035 			return (DDI_FAILURE);
1036 		}
1037 		return (cmpci_resume(dev));
1038 
1039 	default:
1040 		return (DDI_FAILURE);
1041 	}
1042 }
1043 
1044 static int
1045 cmpci_ddi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1046 {
1047 	cmpci_dev_t *dev;
1048 
1049 	if ((dev = ddi_get_driver_private(dip)) == NULL) {
1050 		return (DDI_FAILURE);
1051 	}
1052 
1053 	switch (cmd) {
1054 	case DDI_DETACH:
1055 		return (cmpci_detach(dev));
1056 
1057 	case DDI_SUSPEND:
1058 		audio_dev_suspend(dev->adev);
1059 		return (DDI_SUCCESS);
1060 
1061 	default:
1062 		return (DDI_FAILURE);
1063 	}
1064 }
1065 
1066 static struct dev_ops cmpci_dev_ops = {
1067 	DEVO_REV,		/* rev */
1068 	0,			/* refcnt */
1069 	NULL,			/* getinfo */
1070 	nulldev,		/* identify */
1071 	nulldev,		/* probe */
1072 	cmpci_ddi_attach,	/* attach */
1073 	cmpci_ddi_detach,	/* detach */
1074 	nodev,			/* reset */
1075 	NULL,			/* cb_ops */
1076 	NULL,			/* bus_ops */
1077 	NULL,			/* power */
1078 	cmpci_quiesce,		/* quiesce */
1079 };
1080 
1081 static struct modldrv cmpci_modldrv = {
1082 	&mod_driverops,			/* drv_modops */
1083 	"C-Media PCI Audio",		/* linkinfo */
1084 	&cmpci_dev_ops,			/* dev_ops */
1085 };
1086 
1087 static struct modlinkage modlinkage = {
1088 	MODREV_1,
1089 	{ &cmpci_modldrv, NULL }
1090 };
1091 
1092 int
1093 _init(void)
1094 {
1095 	int	rv;
1096 
1097 	audio_init_ops(&cmpci_dev_ops, "audiocmi");
1098 	if ((rv = mod_install(&modlinkage)) != 0) {
1099 		audio_fini_ops(&cmpci_dev_ops);
1100 	}
1101 	return (rv);
1102 }
1103 
1104 int
1105 _fini(void)
1106 {
1107 	int	rv;
1108 	if ((rv = mod_remove(&modlinkage)) == 0) {
1109 		audio_fini_ops(&cmpci_dev_ops);
1110 	}
1111 	return (rv);
1112 }
1113 
1114 int
1115 _info(struct modinfo *modinfop)
1116 {
1117 	return (mod_info(&modlinkage, modinfop));
1118 }
1119