audiocmi.c revision 11936:54dc8a89ba0d
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
65static ddi_device_acc_attr_t acc_attr = {
66	DDI_DEVICE_ATTR_V0,
67	DDI_STRUCTURE_LE_ACC,
68	DDI_STRICTORDER_ACC
69};
70
71static ddi_device_acc_attr_t buf_attr = {
72	DDI_DEVICE_ATTR_V0,
73	DDI_NEVERSWAP_ACC,
74	DDI_STRICTORDER_ACC
75};
76
77static 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
93static int
94cmpci_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
112static void
113cmpci_close(void *arg)
114{
115	_NOTE(ARGUNUSED(arg));
116}
117
118static int
119cmpci_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
214static void
215cmpci_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
225static uint64_t
226cmpci_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
265static void
266cmpci_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
272static uint8_t
273cmpci_getmixer(cmpci_dev_t *dev, uint8_t idx)
274{
275	PUT8(dev, REG_IDXADDR, idx);
276	return (GET8(dev, REG_IDXDATA));
277}
278
279
280static void
281cmpci_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
441static int
442cmpci_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
459static int
460cmpci_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
478static void
479cmpci_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
584static void
585cmpci_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
603static void
604cmpci_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
614static void
615cmpci_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
644static int
645cmpci_format(void *unused)
646{
647	_NOTE(ARGUNUSED(unused));
648	return (AUDIO_FORMAT_S16_LE);
649}
650
651static int
652cmpci_channels(void *arg)
653{
654	cmpci_port_t *port = arg;
655
656	return (port->nchan);
657}
658
659static void
660cmpci_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
674static int
675cmpci_rate(void *unused)
676{
677	_NOTE(ARGUNUSED(unused));
678	return (48000);
679}
680
681static void
682cmpci_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
691audio_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
707static int
708cmpci_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
834void
835cmpci_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
869int
870cmpci_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
972err_exit:
973	cmpci_destroy(dev);
974	return (DDI_FAILURE);
975}
976
977static int
978cmpci_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
991static int
992cmpci_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
1009static int
1010cmpci_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
1024static int
1025cmpci_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
1044static int
1045cmpci_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
1066static 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
1081static struct modldrv cmpci_modldrv = {
1082	&mod_driverops,			/* drv_modops */
1083	"C-Media PCI Audio",		/* linkinfo */
1084	&cmpci_dev_ops,			/* dev_ops */
1085};
1086
1087static struct modlinkage modlinkage = {
1088	MODREV_1,
1089	{ &cmpci_modldrv, NULL }
1090};
1091
1092int
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
1104int
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
1114int
1115_info(struct modinfo *modinfop)
1116{
1117	return (mod_info(&modlinkage, modinfop));
1118}
1119