audioemu10k.h 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/*
23 * Copyright 2010 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
308typedef struct _emu10k_devc_t emu10k_devc_t;
309typedef struct _emu10k_portc_t emu10k_portc_t;
310
311
312typedef 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
339typedef 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
346typedef struct _emu10k_gpr {
347	boolean_t	valid;
348	uint32_t	value;
349} emu10k_gpr_t;
350
351struct _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		nframes;
366	unsigned		nfrags;
367	unsigned		fragsz;
368
369	ddi_dma_handle_t	buf_dmah;	/* dma for buffers */
370	ddi_acc_handle_t	buf_acch;
371	uint32_t		buf_paddr;
372	caddr_t			buf_kaddr;
373	size_t			buf_size;
374	/* Start of loop within the internal memory space */
375	uint32_t		memptr;
376	int			syncdir;
377	/* Position & timing */
378	uint64_t		count;
379	uint32_t		pos;
380	int		dopos;
381};
382
383struct _emu10k_devc_t {
384	dev_info_t		*dip;
385	audio_dev_t		*adev;
386	ddi_acc_handle_t	pcih;
387	ddi_acc_handle_t	regsh;
388	caddr_t			regs;
389	kmutex_t		mutex;
390
391	/*
392	 * Page table
393	 */
394	ddi_dma_handle_t	pt_dmah;	/* dma for page_tablefers */
395	ddi_acc_handle_t	pt_acch;
396	uint32_t		pt_paddr;
397	caddr_t			pt_kaddr;
398	uint32_t		*page_map;	/* up to 8k ptrs to 4k pages */
399
400
401	/*
402	 * Silent page used by voices that don't play anything.
403	 */
404	ddi_dma_handle_t	silence_dmah;	/* dma for silencefers */
405	ddi_acc_handle_t	silence_acch;
406	uint32_t		silence_paddr;
407	caddr_t			silence_kaddr;
408
409	/*
410	 * Device feature mask tells which kind of features are
411	 * supported by the hardware. Audigy2/2val have multiple bits
412	 * set while Live! has just the SB_LIVE bits. So Features of
413	 * Audigy will be reported by Audigy2/val too.
414	 */
415	int			feature_mask;
416	int			max_mem, max_pages, nr_pages;
417	/*
418	 * Mixer
419	 */
420	ac97_t			*ac97;
421	ac97_ctrl_t		*ac97_recsrc;
422	uint32_t		ac97_stereomix;
423	emu10k_gpr_t		gpr_shadow[MAX_GPR];
424	emu10k_ctrl_t		ctrls[CTL_MAX];
425
426	/*
427	 * Audio
428	 */
429
430	int			audio_memptr;
431	int			*silent_page;
432
433	emu10k_portc_t		*portc[EMU10K_NUM_PORTC];
434};
435
436#define	INB(devc, reg)		ddi_get8(devc->regsh, (void *)(reg))
437#define	OUTB(devc, val, reg)	ddi_put8(devc->regsh, (void *)(reg), (val))
438
439#define	INW(devc, reg)		ddi_get16(devc->regsh, (void *)(reg))
440#define	OUTW(devc, val, reg)	ddi_put16(devc->regsh, (void *)(reg), (val))
441
442#define	INL(devc, reg)		ddi_get32(devc->regsh, (void *)(reg))
443#define	OUTL(devc, val, reg)	ddi_put32(devc->regsh, (void *)(reg), (val))
444
445#endif	/* _KERNEL */
446
447#endif /* EMU10K_H */
448