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 /*
23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*
28  * Purpose: Definitions for the CMedia 8788 driver.
29  */
30 /*
31  * This file is part of Open Sound System
32  *
33  * Copyright (C) 4Front Technologies 1996-2011.
34  *
35  * This software is released under CDDL 1.0 source license.
36  * See the COPYING file included in the main directory of this source
37  * distribution for the license terms and conditions.
38  */
39 #ifndef	CMEDIAHD_H
40 #define	CMEDIAHD_H
41 
42 #define	CMEDIAHD_NAME		"audiocmihd"
43 
44 #define	CMEDIAHD_NUM_PORTC		2
45 #define	CMEDIAHD_PLAY			0
46 #define	CMEDIAHD_REC			1
47 
48 /*
49  * Number of fragments must be multiple of 2 because the
50  * hardware supports only full and half buffer interrupts. In
51  * addition it looks like 8 fragments is the minimum.
52  */
53 #define	CMEDIAHD_BUF_LEN		(65536)
54 
55 #define	PCI_VENDOR_ID_CMEDIA 		0x13F6
56 #define	PCI_DEVICE_ID_CMEDIAHD		0x8788
57 
58 #define	CMEDIAHD_MAX_INTRS		512
59 #define	CMEDIAHD_MIN_INTRS		48
60 #define	CMEDIAHD_INTRS			100
61 
62 /*
63  * PCI registers
64  */
65 
66 #define	RECA_ADDR		(devc->base+0x00)
67 #define	RECA_SIZE		(devc->base+0x04)
68 #define	RECA_FRAG		(devc->base+0x06)
69 #define	RECB_ADDR		(devc->base+0x08)
70 #define	RECB_SIZE		(devc->base+0x0C)
71 #define	RECB_FRAG		(devc->base+0x0E)
72 #define	RECC_ADDR		(devc->base+0x10)
73 #define	RECC_SIZE		(devc->base+0x14)
74 #define	RECC_FRAG		(devc->base+0x16)
75 #define	SPDIF_ADDR		(devc->base+0x18)
76 #define	SPDIF_SIZE		(devc->base+0x1C)
77 #define	SPDIF_FRAG		(devc->base+0x1E)
78 #define	MULTICH_ADDR		(devc->base+0x20)
79 #define	MULTICH_SIZE		(devc->base+0x24)
80 #define	MULTICH_FRAG		(devc->base+0x28)
81 #define	FPOUT_ADDR		(devc->base+0x30)
82 #define	FPOUT_SIZE		(devc->base+0x34)
83 #define	FPOUT_FRAG		(devc->base+0x36)
84 
85 #define	DMA_START		(devc->base+0x40)
86 #define	CHAN_RESET		(devc->base+0x42)
87 #define	MULTICH_MODE		(devc->base+0x43)
88 #define	IRQ_MASK		(devc->base+0x44)
89 #define	IRQ_STAT		(devc->base+0x46)
90 #define	MISC_REG		(devc->base+0x48)
91 #define	REC_FORMAT		(devc->base+0x4A)
92 #define	PLAY_FORMAT		(devc->base+0x4B)
93 #define	REC_MODE		(devc->base+0x4C)
94 #define	FUNCTION		(devc->base+0x50)
95 
96 #define	I2S_MULTICH_DAC		(devc->base+0x60)
97 #define	I2S_ADC1		(devc->base+0x62)
98 #define	I2S_ADC2		(devc->base+0x64)
99 #define	I2S_ADC3		(devc->base+0x66)
100 
101 #define	SPDIF_FUNC		(devc->base+0x70)
102 #define	SPDIFOUT_CHAN_STAT	(devc->base+0x74)
103 #define	SPDIFIN_CHAN_STAT	(devc->base+0x78)
104 
105 #define	TWO_WIRE_ADDR		(devc->base+0x90)
106 #define	TWO_WIRE_MAP		(devc->base+0x91)
107 #define	TWO_WIRE_DATA		(devc->base+0x92)
108 #define	TWO_WIRE_CTRL		(devc->base+0x94)
109 
110 #define	SPI_CONTROL		(devc->base+0x98)
111 #define	SPI_DATA		(devc->base+0x99)
112 
113 #define	MPU401_DATA		(devc->base+0xA0)
114 #define	MPU401_COMMAND		(devc->base+0xA1)
115 #define	MPU401_CONTROL		(devc->base+0xA2)
116 
117 #define	GPI_DATA		(devc->base+0xA4)
118 #define	GPI_IRQ_MASK		(devc->base+0xA5)
119 #define	GPIO_DATA		(devc->base+0xA6)
120 #define	GPIO_CONTROL		(devc->base+0xA8)
121 #define	GPIO_IRQ_MASK		(devc->base+0xAA)
122 #define	DEVICE_SENSE		(devc->base+0xAC)
123 
124 #define	PLAY_ROUTING		(devc->base+0xC0)
125 #define	REC_ROUTING		(devc->base+0xC2)
126 #define	REC_MONITOR		(devc->base+0xC3)
127 #define	MONITOR_ROUTING		(devc->base+0xC4)
128 
129 #define	AC97_CTRL		(devc->base+0xD0)
130 #define	AC97_INTR_MASK		(devc->base+0xD2)
131 #define	AC97_INTR_STAT		(devc->base+0xD3)
132 #define	AC97_OUT_CHAN_CONFIG	(devc->base+0xD4)
133 #define	AC97_IN_CHAN_CONFIG	(devc->base+0xD8)
134 #define	AC97_CMD_DATA		(devc->base+0xDC)
135 
136 #define	CODEC_VERSION		(devc->base+0xE4)
137 #define	CTRL_VERSION		(devc->base+0xE6)
138 
139 /* Device IDs */
140 #define	ASUS_VENDOR_ID		0x1043
141 #define	SUBID_XONAR_D2		0x8269
142 #define	SUBID_XONAR_D2X		0x82b7
143 #define	SUBID_XONAR_D1		0x834f
144 #define	SUBID_XONAR_DX		0x8275
145 #define	SUBID_XONAR_STX		0x835c
146 #define	SUBID_XONAR_DS		0x838e
147 
148 
149 #define	SUBID_GENERIC		0x0000
150 
151 /* Xonar specific */
152 #define	XONAR_DX_FRONTDAC	0x9e
153 #define	XONAR_DX_SURRDAC	0x30
154 #define	XONAR_STX_FRONTDAC	0x98
155 #define	XONAR_DS_FRONTDAC	0x1
156 #define	XONAR_DS_SURRDAC	0x0
157 
158 /* defs for AKM 4396 DAC */
159 #define	AK4396_CTL1		0x00
160 #define	AK4396_CTL2		0x01
161 #define	AK4396_CTL3		0x02
162 #define	AK4396_LchATTCtl	0x03
163 #define	AK4396_RchATTCtl	0x04
164 
165 /* defs for CS4398 DAC */
166 #define	CS4398_CHIP_ID		0x01
167 #define	CS4398_MODE_CTRL	0x02
168 #define	CS4398_MIXING		0x03
169 #define	CS4398_MUTE_CTRL	0x04
170 #define	CS4398_VOLA		0x05
171 #define	CS4398_VOLB		0x06
172 #define	CS4398_RAMP_CTRL	0x07
173 #define	CS4398_MISC_CTRL	0x08
174 #define	CS4398_MISC2_CTRL	0x09
175 #define	CS4398_POWER_DOWN	(1<<7)	/* Obvious */
176 #define	CS4398_CPEN		(1<<6)  /* Control Port Enable */
177 #define	CS4398_FREEZE		(1<<5)	/* Freezes registers, unfreeze to */
178 					/* accept changed registers */
179 #define	CS4398_MCLKDIV2		(1<<4)	/* Divide MCLK by 2 */
180 #define	CS4398_MCLKDIV3		(1<<3)	/* Divive MCLK by 3 */
181 #define	CS4398_I2S		(1<<4)	/* Set I2S mode */
182 
183 /* defs for CS4362A DAC */
184 #define	CS4362A_MODE1_CTRL	0x01
185 #define	CS4362A_MODE2_CTRL	0x02
186 #define	CS4362A_MODE3_CTRL	0x03
187 #define	CS4362A_FILTER_CTRL	0x04
188 #define	CS4362A_INVERT_CTRL	0x05
189 #define	CS4362A_MIX1_CTRL	0x06
190 #define	CS4362A_VOLA_1		0x07
191 #define	CS4362A_VOLB_1		0x08
192 #define	CS4362A_MIX2_CTRL	0x09
193 #define	CS4362A_VOLA_2		0x0A
194 #define	CS4362A_VOLB_2		0x0B
195 #define	CS4362A_MIX3_CTRL	0x0C
196 #define	CS4362A_VOLA_3		0x0D
197 #define	CS4362A_VOLB_3		0x0E
198 #define	CS4362A_CHIP_REV	0x12
199 
200 /* CS4362A Reg 01h */
201 #define	CS4362A_CPEN		(1<<7)
202 #define	CS4362A_FREEZE		(1<<6)
203 #define	CS4362A_MCLKDIV		(1<<5)
204 #define	CS4362A_DAC3_ENABLE	(1<<3)
205 #define	CS4362A_DAC2_ENABLE	(1<<2)
206 #define	CS4362A_DAC1_ENABLE	(1<<1)
207 #define	CS4362A_POWER_DOWN	(1)
208 
209 /* CS4362A Reg 02h */
210 #define	CS4362A_DIF_LJUST	0x00
211 #define	CS4362A_DIF_I2S		0x10
212 #define	CS4362A_DIF_RJUST16	0x20
213 #define	CS4362A_DIF_RJUST24	0x30
214 #define	CS4362A_DIF_RJUST20	0x40
215 #define	CS4362A_DIF_RJUST18	0x50
216 
217 /* CS4362A Reg 03h */
218 #define	CS4362A_RAMP_IMMEDIATE	0x00
219 #define	CS4362A_RAMP_ZEROCROSS	0x40
220 #define	CS4362A_RAMP_SOFT	0x80
221 #define	CS4362A_RAMP_SOFTZERO	0xC0
222 #define	CS4362A_SINGLE_VOL	0x20
223 #define	CS4362A_RAMP_ERROR	0x10
224 #define	CS4362A_MUTEC_POL	0x08
225 #define	CS4362A_AUTOMUTE	0x04
226 #define	CS4362A_SIX_MUTE	0x00
227 #define	CS4362A_ONE_MUTE	0x01
228 #define	CS4362A_THREE_MUTE	0x03
229 
230 /* CS4362A Reg 04h */
231 #define	CS4362A_FILT_SEL	0x10
232 #define	CS4362A_DEM_NONE	0x00
233 #define	CS4362A_DEM_44KHZ	0x02
234 #define	CS4362A_DEM_48KHZ	0x04
235 #define	CS4362A_DEM_32KHZ	0x06
236 #define	CS4362A_RAMPDOWN	0x01
237 
238 
239 /* CS4362A Reg 05h */
240 #define	CS4362A_INV_A3		(1<<4)
241 #define	CS4362A_INV_B3		(1<<5)
242 #define	CS4362A_INV_A2		(1<<2)
243 #define	CS4362A_INV_B2		(1<<3)
244 #define	CS4362A_INV_A1		(1)
245 #define	CS4362A_INV_B1		(1<<1)
246 
247 /* CS4362A Reg 06h, 09h, 0Ch */
248 /* ATAPI crap, does anyone still use analog CD playback? */
249 
250 /* CS4362A Reg 07h, 08h, 0Ah, 0Bh, 0Dh, 0Eh */
251 /* Volume registers */
252 #define	CS4362A_VOL_MUTE	0x80
253 
254 /* 0-100. Start at -96dB. */
255 #define	CS4398_VOL(x) \
256 	((x) == 0 ? 0xFF : (0xC0 - ((x)*192/100)))
257 /* 0-100. Start at -96dB. Bit 7 is mute. */
258 #define	CS4362A_VOL(x) \
259 	(char)((x) == 0 ? 0xFF : (0x60 - ((x)*96/100)))
260 
261 /* Xonar D2/D2X codec remap */
262 static const char xd2_codec_map[4] = {
263 	0, 1, 2, 4
264 };
265 
266 
267 typedef struct _cmediahd_devc_t cmediahd_devc_t;
268 typedef struct _cmediahd_portc_t cmediahd_portc_t;
269 
270 typedef enum {
271 	CTL_VOLUME = 0,
272 	CTL_FRONT,
273 	CTL_REAR,
274 	CTL_CENTER,
275 	CTL_LFE,
276 	CTL_SURROUND,
277 	CTL_MONITOR,
278 	CTL_RECSRC,
279 	CTL_RECGAIN,
280 	CTL_MICVOL,
281 	CTL_AUXVOL,
282 	CTL_CDVOL,
283 	CTL_LOOP,
284 	CTL_SPREAD,
285 	CTL_NUM		/* must be last */
286 } cmediahd_ctrl_num_t;
287 
288 typedef struct cmediahd_ctrl
289 {
290 	cmediahd_devc_t		*devc;
291 	audio_ctrl_t		*ctrl;
292 	cmediahd_ctrl_num_t	num;
293 	uint64_t		val;
294 } cmediahd_ctrl_t;
295 
296 typedef struct cmediahd_regs
297 {
298 	caddr_t addr;	/* base address */
299 	caddr_t size;	/* current count */
300 	caddr_t frag;	/* terminal count */
301 	caddr_t i2s;    /* i2s reg */
302 	int chan; 	/* rec a/b/c, play spdif/multi/front */
303 #define	REC_A 0
304 #define	REC_B 1
305 #define	REC_C 2
306 #define	PLAY_SPDIF 3
307 #define	PLAY_MULTI 4
308 #define	PLAY_FRONT 5
309 } cmediahd_regs_t;
310 
311 struct _cmediahd_portc_t
312 {
313 	cmediahd_devc_t *devc;
314 	audio_engine_t *engine;
315 
316 	int			chans;
317 	int			direction;
318 
319 	ddi_dma_handle_t	buf_dmah;	/* dma for buffers */
320 	ddi_acc_handle_t	buf_acch;
321 	uint32_t		paddr;
322 	caddr_t			kaddr;
323 	size_t			buf_size;
324 	size_t			buf_frames;	/* Buffer size in frames */
325 	unsigned		fragfr;
326 	unsigned		nfrags;
327 	unsigned		nframes;
328 	unsigned		bufsz;
329 	size_t			offset;
330 	uint64_t		count;
331 	int			syncdir;
332 };
333 
334 struct _cmediahd_devc_t
335 {
336 	dev_info_t		*dip;
337 	audio_dev_t		*adev;
338 	boolean_t		has_ac97, has_fp_ac97;
339 	int			model;
340 	ac97_t			*ac97, *fp_ac97;
341 
342 	boolean_t		suspended;
343 	ddi_acc_handle_t	pcih;
344 	ddi_acc_handle_t	regsh;
345 	caddr_t			base;
346 	kmutex_t		mutex;		/* For normal locking */
347 	kmutex_t		low_mutex;	/* For low level routines */
348 	cmediahd_regs_t		rec_eng;	/* which rec engine to use */
349 	cmediahd_portc_t 	*portc[CMEDIAHD_NUM_PORTC];
350 	int			gpio_mic, gpio_out, gpio_codec, gpio_alt;
351 	cmediahd_ctrl_t		controls[CTL_NUM];
352 };
353 
354 #define	INB(devc, reg)		ddi_get8(devc->regsh, (void *)(reg))
355 #define	OUTB(devc, val, reg)	ddi_put8(devc->regsh, (void *)(reg), (val))
356 
357 #define	INW(devc, reg)		ddi_get16(devc->regsh, (void *)(reg))
358 #define	OUTW(devc, val, reg)	ddi_put16(devc->regsh, (void *)(reg), (val))
359 
360 #define	INL(devc, reg)		ddi_get32(devc->regsh, (void *)(reg))
361 #define	OUTL(devc, val, reg)	ddi_put32(devc->regsh, (void *)(reg), (val))
362 
363 #endif /* CMEDIAHD_H */
364