xref: /illumos-gate/usr/src/uts/common/io/audio/drv/audioemu10k/audioemu10k.h (revision 46b592853d0f4f11781b6b0a7533f267c6aee132)
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 SB Live/Audigy driver
29  */
30 /*
31  * Copyright (C) 4Front Technologies 1996-2009.
32  */
33 #ifndef	EMU10K_H
34 #define	EMU10K_H
35 
36 #define	PCI_VENDOR_ID_CREATIVE		0x1102
37 #define	PCI_DEVICE_ID_SBLIVE		0x0002
38 #define	PCI_DEVICE_ID_AUDIGY		0x0004
39 #define	PCI_DEVICE_ID_AUDIGYVALUE	0x0008
40 
41 #define	SAMPLE_RATE		48000
42 
43 #define	EMU10K_NAME		"audioemu10k"
44 
45 #define	EMU10K_NUM_PORTC	2
46 #define	EMU10K_PLAY		0
47 #define	EMU10K_REC		1
48 
49 #define	EMU10K_NUM_FRAGS	(2*4)	/* Must be multiple of 2 */
50 
51 #define	EMU10K_MAX_INTRS	512
52 #define	EMU10K_MIN_INTRS	10
53 #define	EMU10K_INTRS		100
54 
55 #define	FRAGMENT_FRAMES		512
56 
57 #define	EMU10K1_MAGIC		0xe10001
58 #define	EMU10K2_MAGIC		0xe10002
59 
60 /* Audio */
61 
62 #define	DMABUF_SIZE		(256 * 1024)
63 
64 #define	AUDIO_MAXVOICE		(2*EMU10K_NUM_PORTC)
65 /* Audio buffer + silent page */
66 #define	AUDIO_MEMSIZE		(EMU10K_NUM_PORTC*DMABUF_SIZE+4096)
67 
68 /* Wall clock register */
69 #define	WC			0x10
70 
71 /* Hardware config register */
72 #define	HCFG			0x14
73 #define	HCFG_CODECFORMAT_MASK	0x00070000	/* CODEC format */
74 #define	HCFG_CODECFORMAT_AC97	0x00000000	/* AC97 CODEC format */
75 #define	HCFG_CODECFORMAT_I2S	0x00010000	/* I2S CODEC format */
76 #define	HCFG_GPINPUT0		0x00004000	/* External pin112 */
77 #define	HCFG_GPINPUT1		0x00002000	/* External pin110 */
78 #define	HCFG_GPOUTPUT_MASK	0x00001c00	/* Controllable pins */
79 #define	HCFG_GPOUT0		0x00001000	/* enable dig out on 5.1 */
80 #define	HCFG_GPOUT1		0x00000800	/* IR */
81 #define	HCFG_GPOUT2		0x00000400	/* IR */
82 #define	HCFG_JOYENABLE		0x00000200	/* Internal joystick enable */
83 #define	HCFG_PHASETRACKENABLE	0x00000100	/* Phase tracking enable */
84 #define	HCFG_AC3ENABLE_MASK	0x0x0000e0	/* AC3 async input control */
85 #define	HCFG_AC3ENABLE_ZVIDEO	0x00000080	/* Chan 0/1 replace ZVIDEO  */
86 #define	HCFG_AC3ENABLE_CDSPDIF	0x00000040	/* Chan 0/1 replace CDSPDIF */
87 #define	HCFG_AC3ENABLE_GPSPDIF	0x00000020	/* Chan 0/1 replace GPSPDIF */
88 #define	HCFG_AUTOMUTE		0x00000010
89 #define	HCFG_LOCKSOUNDCACHE	0x00000008
90 #define	HCFG_LOCKTANKCACHE_MASK	0x00000004
91 #define	HCFG_LOCKTANKCACHE	0x01020014
92 #define	HCFG_MUTEBUTTONENABLE	0x00000002	/* Mute can clear audioenable */
93 #define	HCFG_AUDIOENABLE	0x00000001	/* Codecs can send data */
94 #define	A_HCFG_VMUTE		0x00004000
95 #define	A_HCFG_AUTOMUTE		0x00008000
96 #define	A_HCFG_XM		0x00040000	/* Xtended address mode */
97 
98 /*
99  * GPIO bit definitions (global register 0x18) for Audigy.
100  */
101 
102 #define	A_IOCFG_GPOUT0		0x0044	/* analog/digital? */
103 #define	A_IOCFG_GPOUT1		0x0002	/* IR */
104 #define	A_IOCFG_GPOUT2		0x0001	/* IR */
105 
106 /* Status bits (read only) */
107 #define	GPIO_VERSAPLUGGED	0x2000	/* Center/LFE/digital */
108 #define	GPIO_FRONTPLUGGED	0x4000
109 #define	GPIO_REARPLUGGED	0x8000
110 #define	GPIO_HEADPHPLUGGED	0x0100
111 #define	GPIO_ANALOG_MUTE	0x0040
112 #define	GPIO_DIGITAL_ENABLE	0x0004	/* Cen/lfe (0) or digital (1) switch */
113 
114 #define	FILL_PAGE_MAP_ENTRY(e, v)					\
115 	ddi_put32(devc->pt_acch, devc->page_map + e, ((v) << 1) | (e));
116 
117 /*
118  * Audio block registers
119  */
120 
121 #define	CPF		0x000	/* DW:cnl   Current pitch and fraction */
122 #define	CPF_CURRENTPITCH_MASK		0xffff0000
123 #define	CPF_CURRENTPITCH		0x10100000
124 #define	CPF_STEREO_MASK			0x00008000
125 #define	CPF_STOP_MASK			0x00004000
126 #define	CPF_FRACADDRESS_MASK		0x00003fff
127 
128 
129 #define	PTAB		0x001	/* DW:cnl   Pitch target and sends A and B */
130 #define	PTRX_PITCHTARGET_MASK		0xffff0000
131 #define	PTRX_PITCHTARGET		0x10100001
132 #define	PTRX_FXSENDAMOUNT_A_MASK	0x0000ff00
133 #define	PTRX_FXSENDAMOUNT_A		0x08080001
134 #define	PTRX_FXSENDAMOUNT_B_MASK	0x000000ff
135 #define	PTRX_FXSENDAMOUNT_B		0x08000001
136 
137 
138 #define	CVCF		0x002	/* DW:cnl   Curr vol and curr filter cutoff */
139 #define	VTFT		0x003	/* DW:cnl   Volume tgt and filter cutoff tgt */
140 #define	Z2		0x004	/* DW:cnl   Filter delay memory 2 */
141 #define	Z1		0x005	/* DW:cnl   Filter delay memory 1 */
142 #define	SCSA		0x006	/* DW:cnl   Send C and Start addr */
143 #define	SDL		0x007	/* DW:cnl   Send D and Loop addr */
144 #define	QKBCA		0x008	/* DW:cnl   Filter Q, ROM, etc */
145 #define	CCR		0x009
146 #define	CCR_CACHEINVALIDSIZE		0x07190009
147 #define	CCR_CACHEINVALIDSIZE_MASK	0xfe000000
148 #define	CCR_CACHELOOPFLAG		0x01000000
149 #define	CCR_INTERLEAVEDSAMPLES		0x00800000
150 #define	CCR_WORDSIZEDSAMPLES		0x00400000
151 #define	CCR_READADDRESS			0x06100009
152 #define	CCR_READADDRESS_MASK		0x003f0000
153 #define	CCR_LOOPINVALSIZE		0x0000fe00
154 #define	CCR_LOOPFLAG			0x00000100
155 #define	CCR_CACHELOOPADDRHI		0x000000ff
156 
157 #define	CLP		0x00a
158 #define	SRHE		0x07c
159 #define	STHE		0x07d
160 #define	SRDA		0x07e
161 #define	STDA		0x07f
162 #define	L_FXRT		0x00b
163 #define	FXRT		0x00b	/* W:cnl */
164 #define	MAPA		0x00c
165 #define	MAPB		0x00d
166 #define	VEV		0x010	/* W:cnl */
167 #define	VEHA		0x011	/* W:cnl */
168 #define	VEDS		0x012	/* W:cnl */
169 #define	MLV		0x013	/* W:cnl */
170 #define	MEV		0x014	/* W:cnl */
171 #define	MEHA		0x015	/* W:cnl */
172 #define	MEDS		0x016	/* W:cnl */
173 #define	VLV		0x017	/* W:cnl */
174 #define	IP		0x018	/* W:cnl */
175 #define	IFA		0x019	/* W:cnl */
176 #define	PEFE		0x01a	/* W:cnl */
177 #define	PEFE_PITCHAMOUNT_MASK	0x0000ff00	/* Pitch envlope amount */
178 #define	PEFE_PITCHAMOUNT	0x0808001a
179 #define	PEFE_FILTERAMOUNT_MASK	0x000000ff	/* Filter envlope amount */
180 #define	PEFE_FILTERAMOUNT	0x0800001a
181 
182 #define	VFM		0x01b	/* W:cnl */
183 #define	TMFQ		0x01c	/* W:cnl */
184 #define	VVFQ		0x01d	/* W:cnl */
185 #define	TMPE		0x01e	/* W:cnl */
186 #define	CD0		0x020	/* DW:cnl (16 registers) */
187 #define	PTBA		0x040	/* DW:nocnl */
188 #define	TCBA		0x041	/* DW:nocnl */
189 #define	ADCSR		0x042	/* B:nocnl */
190 #define	FXWC		0x043	/* DW:nocnl */
191 #define	TCBS		0x044	/* B:nocnl */
192 #define	MBA		0x045	/* DW:nocnl */
193 #define	ADCBA		0x046	/* DW:nocnl */
194 #define	FXBA		0x047	/* DW:nocnl */
195 
196 #define	MBS		0x049	/* B:nocnl */
197 #define	ADCBS		0x04a	/* B:nocnl */
198 #define	FXBS		0x04b	/* B:nocnl */
199 #define	CSBA	0x4c
200 #define	CSDC	0x4d
201 #define	CSFE	0x4e
202 #define	CSHG	0x4f
203 #define	CDCS		0x050	/* DW:nocnl */
204 #define	GPSCS		0x051	/* DW:nocnl */
205 #define	DBG		0x052	/* DW:nocnl */
206 #define	AUDIGY_DBG	0x053	/* DW:nocnl */
207 #define	SCS0		0x054	/* DW:nocnl */
208 #define	SCS1		0x055	/* DW:nocnl */
209 #define	SCS2		0x056	/* DW:nocnl */
210 #define	CLIEL		0x058	/* DW:nocnl */
211 #define	CLIEH		0x059	/* DW:nocnl */
212 #define	CLIPL		0x05a	/* DW:nocnl */
213 #define	CLIPH		0x05b	/* DW:nocnl */
214 #define	SOLL		0x05c	/* DW:nocnl */
215 #define	SOLH		0x05d	/* DW:nocnl */
216 #define	SOC		0x05e	/* DW:nocnl */
217 #define	AC97SLOT	0x05f
218 #define	AC97SLOT_REAR_RIGHT	0x01
219 #define	AC97SLOT_REAR_LEFT	0x02
220 #define	AC97SLOT_CENTER		0x10
221 #define	AC97SLOT_LFE		0x20
222 #define	CDSRCS		0x060	/* DW:nocnl */
223 #define	GPSRCS		0x061	/* DW:nocnl */
224 #define	ZVSRCS		0x062	/* DW:nocnl */
225 #define	ADCIDX		0x063	/* W:nocnl */
226 #define	MIDX		0x064	/* W:nocnl */
227 #define	FXIDX		0x065	/* W:nocnl */
228 
229 /* Half loop interrupt registers (audigy only) */
230 #define	HLIEL		0x066	/* DW:nocnl */
231 #define	HLIEH		0x067	/* DW:nocnl */
232 #define	HLIPL		0x068	/* DW:nocnl */
233 #define	HLIPH		0x069	/* DW:nocnl */
234 #define	GPR0	((devc->feature_mask&SB_LIVE)? 0x100:0x400)	/* DW:nocnl */
235 #define	TMA0		0x300	/* Tank memory */
236 #define	UC0	((devc->feature_mask&SB_LIVE) ? 0x400:0x600)	/* DSM ucode */
237 
238 /* Interrupt pending register */
239 #define	INTPEND	0x08
240 #define		INT_VI		0x00100000
241 #define		INT_VD		0x00080000
242 #define		INT_MU		0x00040000
243 #define		INT_MF		0x00020000
244 #define		INT_MH		0x00010000
245 #define		INT_AF		0x00008000
246 #define		INT_AH		0x00004000
247 #define		INT_IT		0x00000200
248 #define		INT_TX		0x00000100
249 #define		INT_RX		0x00000080
250 #define		INT_CL		0x00000040
251 /* Interrupt enable register */
252 #define	IE	0x0c
253 #define		IE_VI		0x00000400
254 #define		IE_VD		0x00000200
255 #define		IE_MU		0x00000100
256 #define		IE_MB		0x00000080
257 #define		IE_AB		0x00000040
258 #define		IE_IT		0x00000004
259 #define		IE_TX		0x00000002
260 #define		IE_RX		0x00000001
261 
262 /* Interval timer register */
263 #define	TIMR		0x1a
264 
265 /* EMU10K2 MIDI UART */
266 #define	MUADAT		0x070
267 #define	MUACMD		0x071
268 #define	MUASTAT		MUACMD
269 
270 /* EMU10K2 S/PDIF recording buffer */
271 #define	SPRI		0x6a
272 #define	SPRA		0x6b
273 #define	SPRC		0x6c
274 
275 #define	EHC		0x76	/* Audigy 2 */
276 
277 #define	SRHE	0x07c
278 #define	STHE	0x07d
279 #define	SRDA	0x07e
280 
281 #define	ROM0		0x00000000	/* interpolation ROM 0 */
282 #define	ROM1		0x02000000	/* interpolation ROM 1 */
283 #define	ROM2		0x04000000	/* interpolation ROM 2 */
284 #define	ROM3		0x06000000	/* interpolation ROM 3 */
285 #define	ROM4		0x08000000	/* interpolation ROM 4 */
286 #define	ROM5		0x0A000000	/* interpolation ROM 5 */
287 #define	ROM6		0x0C000000	/* interpolation ROM 6 */
288 #define	ROM7		0x0E000000	/* interpolation ROM 7 */
289 #define	BYTESIZE	0x01000000	/* byte sound memory */
290 
291 #define	MAX_GPR	256
292 
293 /* See feature_mask below */
294 #define	SB_LIVE		1
295 #define	SB_AUDIGY	2
296 #define	SB_AUDIGY2	4
297 #define	SB_AUDIGY2VAL	8
298 #define	SB_51		0x10
299 #define	SB_71		0x20
300 #define	SB_INVSP	0x40	/* invert shared spdif switch */
301 #define	SB_NOEXP	0x80	/* no support for Live! Drive or expansion */
302 
303 #define	LEFT_CH		0
304 #define	RIGHT_CH	1
305 
306 #ifdef	_KERNEL
307 
308 typedef struct _emu10k_devc_t emu10k_devc_t;
309 typedef struct _emu10k_portc_t emu10k_portc_t;
310 
311 
312 typedef enum {
313 	CTL_VOLUME = 0,
314 	CTL_FRONT,
315 	CTL_SURROUND,
316 	CTL_CENTER,
317 	CTL_LFE,
318 	CTL_SIDE,
319 	CTL_HEADPH,
320 
321 	CTL_RECGAIN,
322 	CTL_RECSRC,
323 	CTL_AC97SRC,
324 
325 	/* monitor source values */
326 	CTL_AC97,
327 	CTL_DIGCD,
328 	CTL_SPD1,
329 	CTL_SPD2,
330 	CTL_LINE2,
331 	CTL_AUX2,
332 
333 	CTL_JACK3,
334 
335 	/* this one must be last */
336 	CTL_MAX,
337 } emu10k_ctrl_id_t;
338 
339 typedef struct _emu10k_ctrl {
340 	emu10k_devc_t	*devc;
341 	audio_ctrl_t	*ctrl;
342 	int		gpr_num;
343 	uint64_t	val;
344 } emu10k_ctrl_t;
345 
346 typedef struct _emu10k_gpr {
347 	boolean_t	valid;
348 	uint32_t	value;
349 } emu10k_gpr_t;
350 
351 struct _emu10k_portc_t {
352 	emu10k_devc_t		*devc;
353 	audio_engine_t		*engine;
354 
355 	/* Helper functions */
356 	void			(*update_port)(emu10k_portc_t *);
357 	void			(*reset_port)(emu10k_portc_t *);
358 	void			(*stop_port)(emu10k_portc_t *);
359 	void			(*start_port)(emu10k_portc_t *);
360 
361 	int			channels;
362 
363 	boolean_t		started;
364 	boolean_t		active;
365 	unsigned		fragfr;
366 	unsigned		nframes;
367 	unsigned		nfrags;
368 	unsigned		fragsz;
369 
370 	ddi_dma_handle_t	buf_dmah;	/* dma for buffers */
371 	ddi_acc_handle_t	buf_acch;
372 	uint32_t		buf_paddr;
373 	caddr_t			buf_kaddr;
374 	size_t			buf_size;
375 	/* Start of loop within the internal memory space */
376 	uint32_t		memptr;
377 	int			syncdir;
378 	/* Position & timing */
379 	uint64_t		count;
380 	uint32_t		pos;
381 	int		dopos;
382 };
383 
384 struct _emu10k_devc_t {
385 	dev_info_t		*dip;
386 	audio_dev_t		*adev;
387 	kstat_t			*ksp;
388 	boolean_t		suspended;
389 	ddi_acc_handle_t	pcih;
390 	ddi_acc_handle_t	regsh;
391 	caddr_t			regs;
392 	kmutex_t		mutex;
393 	ddi_intr_handle_t	ih;
394 
395 	/*
396 	 * Page table
397 	 */
398 	ddi_dma_handle_t	pt_dmah;	/* dma for page_tablefers */
399 	ddi_acc_handle_t	pt_acch;
400 	uint32_t		pt_paddr;
401 	caddr_t			pt_kaddr;
402 	uint32_t		*page_map;	/* up to 8k ptrs to 4k pages */
403 
404 
405 	/*
406 	 * Silent page used by voices that don't play anything.
407 	 */
408 	ddi_dma_handle_t	silence_dmah;	/* dma for silencefers */
409 	ddi_acc_handle_t	silence_acch;
410 	uint32_t		silence_paddr;
411 	caddr_t			silence_kaddr;
412 
413 	/*
414 	 * Device feature mask tells which kind of features are
415 	 * supported by the hardware. Audigy2/2val have multiple bits
416 	 * set while Live! has just the SB_LIVE bits. So Features of
417 	 * Audigy will be reported by Audigy2/val too.
418 	 */
419 	int			feature_mask;
420 	int			max_mem, max_pages, nr_pages;
421 	/*
422 	 * Mixer
423 	 */
424 	ac97_t			*ac97;
425 	ac97_ctrl_t		*ac97_recsrc;
426 	uint32_t		ac97_stereomix;
427 	emu10k_gpr_t		gpr_shadow[MAX_GPR];
428 	emu10k_ctrl_t		ctrls[CTL_MAX];
429 
430 	/*
431 	 * Audio
432 	 */
433 
434 	int			audio_memptr;
435 	int			*silent_page;
436 
437 	emu10k_portc_t		*portc[EMU10K_NUM_PORTC];
438 };
439 
440 #define	INB(devc, reg)		ddi_get8(devc->regsh, (void *)(reg))
441 #define	OUTB(devc, val, reg)	ddi_put8(devc->regsh, (void *)(reg), (val))
442 
443 #define	INW(devc, reg)		ddi_get16(devc->regsh, (void *)(reg))
444 #define	OUTW(devc, val, reg)	ddi_put16(devc->regsh, (void *)(reg), (val))
445 
446 #define	INL(devc, reg)		ddi_get32(devc->regsh, (void *)(reg))
447 #define	OUTL(devc, val, reg)	ddi_put32(devc->regsh, (void *)(reg), (val))
448 
449 #define	EMU10K_KIOP(X)	((kstat_intr_t *)(X->ksp->ks_data))
450 
451 #endif	/* _KERNEL */
452 
453 #endif /* EMU10K_H */
454