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  * This software is released under CDDL 1.0 source license.
34  * See the COPYING file included in the main directory of this source
35  * distribution for the license terms and conditions.
36  */
37 
38 #ifndef	_AUDIOCMI_H
39 #define	_AUDIOCMI_H
40 
41 #define	CMEDIA_VENDOR_ID	0x13F6
42 #define	CMEDIA_CM8738		0x0111
43 #define	CMEDIA_CM8338A		0x0100
44 #define	CMEDIA_CM8338B		0x0101
45 
46 /*
47  * CM8338 registers definition
48  */
49 
50 #define	REG_FUNCTRL0		0x00
51 #define	REG_FUNCTRL1		0x04
52 #define	REG_CHFORMAT		0x08
53 #define	REG_INTCTRL		0x0C
54 #define	REG_INTSTAT		0x10
55 #define	REG_LEGACY		0x14
56 #define	REG_MISC		0x18
57 #define	REG_TDMAPOS		0x1C
58 #define	REG_SBVER		0x20	/* 8 bit access only */
59 #define	REG_IDXDATA		0x22	/* 8 bit access only */
60 #define	REG_IDXADDR		0x23	/* 8 bit access only */
61 #define	REG_MIX2		0x24
62 #define	REG_MIX3		0x25
63 #define	REG_VAUX		0x26
64 #define	REG_CH0_PADDR		0x80	/* buffer address (32b) */
65 #define	REG_CH0_BUFSZ		0x84	/* buffer size in samples (16b) */
66 #define	REG_CH0_FRAGSZ		0x86	/* fragment size in samples (16b) */
67 #define	REG_CH1_PADDR		0x88
68 #define	REG_CH1_BUFSZ		0x8C
69 #define	REG_CH1_FRAGSZ		0x8E
70 #define	REG_SPDIF_STAT		0x90
71 #define	REG_MISC2		0x92
72 
73 #define	FUNCTRL0_CH1_RST	BIT(19)
74 #define	FUNCTRL0_CH0_RST	BIT(18)
75 #define	FUNCTRL0_CH1_EN		BIT(17)
76 #define	FUNCTRL0_CH0_EN		BIT(16)
77 #define	FUNCTRL0_CH1_PAUSE	BIT(3)
78 #define	FUNCTRL0_CH0_PAUSE	BIT(2)
79 #define	FUNCTRL0_CH1_REC	BIT(1)
80 #define	FUNCTRL0_CH0_REC	BIT(0)
81 
82 #define	FUNCTRL1_DAC_RATE_MASK	(0x7 << 13)
83 #define	FUNCTRL1_DAC_RATE_48K	(0x7 << 13)
84 #define	FUNCTRL1_DAC_RATE_32K	(0x6 << 13)
85 #define	FUNCTRL1_DAC_RATE_16K	(0x5 << 13)
86 #define	FUNCTRL1_DAC_RATE_8K	(0x4 << 13)
87 #define	FUNCTRL1_DAC_RATE_44K	(0x3 << 13)
88 #define	FUNCTRL1_DAC_RATE_22K	(0x2 << 13)
89 #define	FUNCTRL1_DAC_RATE_11K	(0x1 << 13)
90 #define	FUNCTRL1_DAC_RATE_5K	(0x0 << 13)
91 #define	FUNCTRL1_ADC_RATE_MASK	(0x7 << 10)
92 #define	FUNCTRL1_ADC_RATE_48K	(0x7 << 10)
93 #define	FUNCTRL1_ADC_RATE_32K	(0x6 << 10)
94 #define	FUNCTRL1_ADC_RATE_16K	(0x5 << 10)
95 #define	FUNCTRL1_ADC_RATE_8K	(0x4 << 10)
96 #define	FUNCTRL1_ADC_RATE_44K	(0x3 << 10)
97 #define	FUNCTRL1_ADC_RATE_22K	(0x2 << 10)
98 #define	FUNCTRL1_ADC_RATE_11K	(0x1 << 10)
99 #define	FUNCTRL1_ADC_RATE_5K	(0x0 << 10)
100 #define	FUNCTRL1_INTRM		BIT(5)		/* enable MCB intr */
101 #define	FUNCTRL1_BREQ		BIT(4)		/* bus master enable */
102 #define	FUNCTRL1_VOICE_EN	BIT(3)
103 #define	FUNCTRL1_UART_EN	BIT(2)
104 #define	FUNCTRL1_JYSTK_EN	BIT(1)
105 
106 #define	CHFORMAT_CHB3D5C	BIT(31)		/* 5 channel surround */
107 #define	CHFORMAT_CHB3D		BIT(29)		/* 4 channel surround */
108 #define	CHFORMAT_VER_MASK	(0x1f << 24)
109 #define	CHFORMAT_VER_033	0
110 #define	CHFORMAT_VER_037	1
111 #define	CHFORMAT_CH1_MASK	(0x3 << 2)
112 #define	CHFORMAT_CH1_16ST	(0x3 << 2)
113 #define	CHFORMAT_CH1_16MO	(0x2 << 2)
114 #define	CHFORMAT_CH1_8ST	(0x1 << 2)
115 #define	CHFORMAT_CH1_8MO	(0x0 << 2)
116 #define	CHFORMAT_CH0_MASK	(0x3 << 0)
117 #define	CHFORMAT_CH0_16ST	(0x3 << 0)
118 #define	CHFORMAT_CH0_16MO	(0x2 << 0)
119 #define	CHFORMAT_CH0_8ST	(0x1 << 0)
120 #define	CHFORMAT_CH0_8MO	(0x0 << 0)
121 
122 #define	INTCTRL_MDL_MASK	(0xffU << 24)
123 #define	INTCTRL_MDL_068		(0x28 << 24)
124 #define	INTCTRL_MDL_055		(0x8 << 24)
125 #define	INTCTRL_MDL_039		(0x4 << 24)
126 #define	INTCTRL_TDMA_EN		BIT(18)
127 #define	INTCTRL_CH1_EN		BIT(17)
128 #define	INTCTRL_CH0_EN		BIT(16)
129 
130 #define	INTSTAT_INTR		BIT(31)
131 #define	INTSTAT_MCB_INT		BIT(26)
132 #define	INTSTAT_UART_INT	BIT(16)
133 #define	INTSTAT_LTDMA_INT	BIT(15)
134 #define	INTSTAT_HTDMA_INT	BIT(14)
135 #define	INTSTAT_LHBTOG		BIT(7)
136 #define	INTSTAT_LEGDMA		BIT(6)
137 #define	INTSTAT_LEGHIGH		BIT(5)
138 #define	INTSTAT_LEGSTEREO	BIT(4)
139 #define	INTSTAT_CH1_BUSY	BIT(3)
140 #define	INTSTAT_CH0_BUSY	BIT(2)
141 #define	INTSTAT_CH1_INT		BIT(1)
142 #define	INTSTAT_CH0_INT		BIT(0)
143 
144 #define	LEGACY_NXCHG		BIT(31)
145 #define	LEGACY_CHB3D6C		BIT(15)	/* 6 channel surround */
146 #define	LEGACY_CENTR2LN		BIT(14)	/* line in as center out */
147 #define	LEGACY_BASS2LN		BIT(13)	/* line in as lfe */
148 #define	LEGACY_EXBASSEN		BIT(12)	/* external bass input enable */
149 
150 #define	MISC_PWD		BIT(31)	/* power down */
151 #define	MISC_RESET		BIT(30)
152 #define	MISC_N4SPK3D		BIT(26)	/* 4 channel emulation */
153 #define	MISC_ENDBDAC		BIT(23)	/* dual dac */
154 #define	MISC_XCHGDAC		BIT(22)	/* swap front/rear dacs */
155 #define	MISC_SPD32SEL		BIT(21)	/* 32-bit SPDIF (default 16-bit) */
156 #define	MISC_FM_EN		BIT(19)	/* enable legacy FM */
157 #define	MISC_SPDF_AC97		BIT(15)	/* spdif out 44.1k (0), 48 k (1) */
158 #define	MISC_ENCENTER		BIT(7)	/* enable center */
159 #define	MISC_REAR2LN		BIT(6)	/* send rear to line in */
160 
161 #define	MIX2_FMMUTE		BIT(7)
162 #define	MIX2_WSMUTE		BIT(6)
163 #define	MIX2_SPK4		BIT(5)	/* line-in is rear out */
164 #define	MIX2_REAR2FRONT		BIT(4)	/* swap front and rear */
165 #define	MIX2_WAVEIN_L		BIT(3)	/* for recording wave out */
166 #define	MIX2_WAVEIN_R		BIT(2)	/* for recording wave out */
167 #define	MIX2_X3DEN		BIT(1)	/* 3D surround enable */
168 #define	MIX2_CDPLAY		BIT(0)	/* spdif-in PCM to DAC */
169 
170 #define	MIX3_RAUXREN		BIT(7)
171 #define	MIX3_RAUXLEN		BIT(6)
172 #define	MIX3_VAUXRM		BIT(5)	/* r-aux mute */
173 #define	MIX3_VAUXLM		BIT(4)	/* l-aux mute */
174 #define	MIX3_VADCMIC_MASK	(0x7 << 1)	/* rec mic volume */
175 #define	MIX3_CEN2MIC		BIT(2)
176 #define	MIX3_MICGAINZ		BIT(0)	/* mic gain */
177 
178 #define	VAUX_L_MASK		0xf0
179 #define	VAUX_R_MASK		0x0f
180 
181 #define	MISC2_CHB3D8C		BIT(5)	/* 8 channel surround */
182 #define	MISC2_SPD32FMT		BIT(4)	/* spdif at 32 kHz */
183 #define	MISC2_ADC2SPDIF		BIT(3)	/* send adc to spdif out */
184 #define	MISC2_SHAREADC		BIT(2)	/* use adc for cen/lfe */
185 
186 /* Indexes via SBINDEX */
187 #define	IDX_MASTER_LEFT		0x30
188 #define	IDX_MASTER_RIGHT	0x31
189 #define	IDX_VOICE_LEFT		0x32	/* PCM volume */
190 #define	IDX_VOICE_RIGHT		0x33
191 #define	IDX_CDDA_LEFT		0x36
192 #define	IDX_CDDA_RIGHT		0x37
193 #define	IDX_LINEIN_LEFT		0x38
194 #define	IDX_LINEIN_RIGHT	0x39
195 #define	IDX_MIC			0x3A
196 #define	IDX_SPEAKER		0x3B
197 #define	IDX_OUTMIX		0x3C
198 #define		OUTMIX_MIC	0x01
199 #define		OUTMIX_CD_R	0x02
200 #define		OUTMIX_CD_L	0x04
201 #define		OUTMIX_LINE_R	0x08
202 #define		OUTMIX_LINE_L	0x10
203 #define	IDX_INMIX_L		0x3D
204 #define	IDX_INMIX_R		0x3E
205 #define		INMIX_LINE_R	0x08
206 #define		INMIX_LINE_L	0x10
207 #define		INMIX_CD_R	0x20
208 #define		INMIX_CD_L	0x40
209 #define		INMIX_MIC	0x01
210 #define	IDX_IGAIN_L		0x3F
211 #define	IDX_IGAIN_R		0x40
212 #define	IDX_OGAIN_L		0x41
213 #define	IDX_OGAIN_R		0x42
214 #define	IDX_AGC			0x43
215 #define	IDX_TREBLE_L		0x44
216 #define	IDX_TREBLE_R		0x45
217 #define	IDX_BASS_L		0x46
218 #define	IDX_BASS_R		0x47
219 
220 
221 #define	IDX_EXTENSION		0xf0
222 
223 #define	EXTENSION_VPHONE_MASK	(0x7 << 5)
224 #define	EXTENSION_VPHONE_MUTE	BIT(4)
225 #define	EXTENSION_BEEPER_MUTE	BIT(3)
226 #define	EXTENSION_VADCMIC3	BIT(0)
227 
228 enum {
229 	SRC_MIC = 0,
230 	SRC_LINE,
231 	SRC_CD,
232 	SRC_AUX,
233 	SRC_MIX,
234 };
235 
236 enum {
237 	CTL_VOLUME = 0,
238 	CTL_LINEOUT,
239 	CTL_SPEAKER,
240 	CTL_MIC,
241 	CTL_LINEIN,
242 	CTL_CD,
243 	CTL_AUX,
244 	CTL_RECSRCS,
245 	CTL_MONSRCS,
246 	CTL_MICBOOST,
247 	CTL_NUM
248 };
249 
250 typedef struct cmpci_port cmpci_port_t;
251 typedef struct cmpci_dev cmpci_dev_t;
252 typedef struct cmpci_ctrl cmpci_ctrl_t;
253 
254 struct cmpci_ctrl {
255 	cmpci_dev_t		*dev;
256 	audio_ctrl_t		*ctrl;
257 	uint64_t		value;
258 };
259 
260 struct cmpci_port {
261 	cmpci_dev_t		*dev;
262 	audio_engine_t		*engine;
263 	int			num;
264 	ddi_acc_handle_t	acch;
265 	ddi_dma_handle_t	dmah;
266 	caddr_t			kaddr;
267 	uint32_t		paddr;
268 	unsigned		nframes;
269 	unsigned		bufsz;
270 	unsigned		nchan;
271 
272 	boolean_t		capture;
273 	boolean_t		open;
274 
275 	/* registers & bit masks */
276 	uint8_t			reg_paddr;
277 	uint8_t			reg_bufsz;
278 	uint8_t			reg_fragsz;
279 
280 	uint32_t		fc0_rst_bit;
281 	uint32_t		fc0_rec_bit;
282 	uint32_t		fc0_en_bit;
283 	uint32_t		int_en_bit;
284 	uint32_t		fc1_rate_mask;
285 	uint32_t		chformat_mask;
286 	int			sync_dir;
287 
288 	uint32_t		offset;	/* in bytes */
289 	uint64_t		count;	/* in bytes */
290 
291 	void			(*callb)(audio_engine_t *);
292 	cmpci_ctrl_t		controls[CTL_NUM];
293 };
294 
295 #define	PORT_MAX	2
296 
297 struct cmpci_dev {
298 	audio_dev_t		*adev;
299 	dev_info_t		*dip;
300 	ddi_acc_handle_t	acch;
301 	caddr_t			regs;
302 
303 	boolean_t		softvol;
304 
305 	int			pintrs;
306 	int			rintrs;
307 	ddi_intr_handle_t	ihandle;
308 	kstat_t			*ksp;
309 
310 	int			maxch;
311 
312 	kmutex_t		mutex;
313 	cmpci_port_t		port[PORT_MAX];
314 	cmpci_ctrl_t		controls[CTL_NUM];
315 };
316 
317 /*
318  * The hardware appears to be able to address up to 16-bits worth of samples,
319  * giving a total address space of 256K.  Note, however, that we will restrict
320  * this further when we do fragment and memory allocation.
321  */
322 #define	DEFINTS		175
323 
324 #define	GET8(dev, offset)	\
325 	ddi_get8(dev->acch, (uint8_t *)(dev->regs + (offset)))
326 #define	GET16(dev, offset)	\
327 	ddi_get16(dev->acch, (uint16_t *)(void *)(dev->regs + (offset)))
328 #define	GET32(dev, offset)	\
329 	ddi_get32(dev->acch, (uint32_t *)(void *)(dev->regs + (offset)))
330 #define	PUT8(dev, offset, v)	\
331 	ddi_put8(dev->acch, (uint8_t *)(dev->regs + (offset)), v)
332 #define	PUT16(dev, offset, v)	\
333 	ddi_put16(dev->acch, (uint16_t *)(void *)(dev->regs + (offset)), v)
334 #define	PUT32(dev, offset, v)	\
335 	ddi_put32(dev->acch, (uint32_t *)(void *)(dev->regs + (offset)), v)
336 
337 #define	CLR8(dev, offset, v)	PUT8(dev, offset, GET8(dev, offset) & ~(v))
338 #define	SET8(dev, offset, v)	PUT8(dev, offset, GET8(dev, offset) | (v))
339 #define	CLR16(dev, offset, v)	PUT16(dev, offset, GET16(dev, offset) & ~(v))
340 #define	SET16(dev, offset, v)	PUT16(dev, offset, GET16(dev, offset) | (v))
341 #define	CLR32(dev, offset, v)	PUT32(dev, offset, GET32(dev, offset) & ~(v))
342 #define	SET32(dev, offset, v)	PUT32(dev, offset, GET32(dev, offset) | (v))
343 
344 #define	BIT(n)		(1U << (n))
345 
346 #endif	/* _AUDIOCMI_H */
347