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 Creative Audigy LS driver
29  */
30 /*
31  * This file is part of Open Sound System
32  *
33  * Copyright (C) 4Front Technologies 1996-2009.
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	AUDIGYLS_H
40 #define	AUDIGYLS_H
41 
42 #define	AUDIGYLS_NAME		"audiols"
43 
44 #define	AUDIGYLS_NUM_PORT	2
45 #define	AUDIGYLS_PLAY_PORT	0
46 #define	AUDIGYLS_REC_PORT	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	AUDIGYLS_NUM_FRAGS		(8*2)
54 
55 #define	PCI_VENDOR_ID_CREATIVE 		0x1102
56 #define	PCI_DEVICE_ID_CREATIVE_AUDIGYLS 0x0007
57 
58 #define	AUDIGYLS_MAX_INTRS		256
59 #define	AUDIGYLS_MIN_INTRS		24
60 #define	AUDIGYLS_INTRS			100
61 
62 /*
63  * PCI registers
64  */
65 
66 #define	PR 	0x00
67 #define	DR	0x04
68 #define	IPR	0x08
69 #define	IER	0x0C
70 #define		INTR_PCI	(1 << 0)
71 #define		INTR_TXA	(1 << 1)	/* midi-a tx */
72 #define		INTR_RXA	(1 << 2)	/* midi-a rx */
73 #define		INTR_IT2	(1 << 3)	/* timer 2, 44.1 kHz */
74 #define		INTR_IT1	(1 << 4)	/* timer 1, 192 kHz */
75 #define		INTR_SS_	(1 << 5)	/* spdif status */
76 #define		INTR_SRT	(1 << 6)	/* sample rate status */
77 #define		INTR_GP		(1 << 7)
78 #define		INTR_AI		(1 << 8)	/* audio pending interrupt */
79 #define		INTR_I2CDAC	(1 << 9)
80 #define		INTR_I2CEE	(1 << 10)
81 #define		INTR_SPI	(1 << 11)
82 #define		INTR_SPF	(1 << 12)
83 #define		INTR_SUO	(1 << 13)
84 #define		INTR_SUI	(1 << 14)
85 #define		INTR_TXB	(1 << 16)	/* midi-b tx */
86 #define		INTR_RXB	(1 << 17)	/* midi-b rx */
87 
88 #define	HC	0x14
89 #define		HC_PF		(1 << 11)	/* play fmt 1 = 32b, 0 = 16b */
90 #define		HC_RF		(1 << 10)	/* rec fmt 1 = 32b, 0 = 16b */
91 #define		HC_AC97		(1 << 3)
92 #define		HC_AEN		(1 << 0)	/* audio enable */
93 
94 #define	GPIO	0x18
95 #define	AC97D	0x1C
96 #define	AC97A	0x1E
97 /*
98  * Indirect registers
99  */
100 
101 #define	PTBA		0x000	/* gather play table base address */
102 #define	PTBS		0x001	/* gather play table buffer size */
103 #define	PTCA		0x002	/* gather play table current addr ptr */
104 #define	PFBA		0x004	/* play fifo base address */
105 #define	PFBS		0x005	/* play fifo buffer size */
106 #define	CPFA		0x006	/* current play fifo address */
107 #define	PFEA		0x007	/* play fifo end address */
108 #define	CPCAV		0x008	/* current play fifo offset/cache sz valid */
109 #define	RFBA		0x010	/* record fifo base address */
110 #define	RFBS		0x011	/* record fifo buffer size */
111 #define	CRFA		0x012	/* current record fifo address */
112 #define	CRCAV		0x013	/* current record fifo offset/cache sz valid */
113 #define	CDL		0x020	/* play fifo cache data, 0x20-0x2f */
114 #define	SA		0x040	/* start audio */
115 #define	SCS3		0x041
116 #define	SCS0		0x042
117 #define	SCS1		0x043
118 #define	SCS2		0x044
119 #define	SPC		0x045	/* spdif output control */
120 #define	WMARK		0x046	/* test purposes only */
121 #define	SPSC		0x049	/* spdif input control */
122 #define	RCD		0x050	/* record cache data, 0x50-0x5f */
123 #define	P17RECSEL	0x060	/* record fifo map address */
124 #define	P17RECVOLL	0x061	/* record fifo volume control (lo) */
125 #define	P17RECVOLH	0x062	/* record fifo volume control (hi) */
126 
127 #define	HMIXMAP_SPDIF	0x063	/* spdif router map address */
128 #define	SMIXMAP_SPDIF	0x064	/* spdif router map address */
129 #define	MIXCTL_SPDIF	0x065	/* spdif mixer control */
130 #define	MIXVOL_SPDIF	0x066	/* spdif mixer input volume control */
131 #define	HMIXMAP_I2S	0x067	/* i2s router map address */
132 #define	SMIXMAP_I2S	0x068	/* i2s router map address */
133 #define	MIXCTL_I2S	0x069	/* i2s mixer control */
134 #define	MIXVOL_I2S	0x06a	/* i2s mixer input volume control */
135 
136 /* MIDI UART */
137 #define	MUDATA		0x06c	/* midi uart a data */
138 #define	MUCMDA		0x06d	/* midi uart a command/status */
139 #define	MUDATB		0x06e	/* midi uart b data */
140 #define	MUCMDB		0x06f	/* midi uart b command/status */
141 
142 #define	SRT		0x070	/* sample rate tracker status */
143 #define	SRCTL		0x071	/* sample rate control */
144 #define	AUDCTL		0x072	/* audio output control */
145 #define	CHIP_ID		0x074	/* chip id */
146 #define	AIE		0x075	/* audio interrupt enable */
147 #define	AIP		0x076	/* audio interrupt */
148 #define	WALL192		0x077	/* wall clock @ 192 kHz */
149 #define	WALL441		0x078	/* wall clock @ 44.1 kHz */
150 #define	IT		0x079	/* interval timer */
151 #define	SPI		0x07a	/* spi interface */
152 #define	I2C_A		0x07b	/* i2c address */
153 #define	I2C_0		0x07c	/* i2c data */
154 #define	I2C_1		0x07d	/* i2c data */
155 
156 /*
157  * Audio interrupt bits
158  */
159 
160 #define	AI_PFH		0x00000001	/* playback fifo half loop */
161 #define	AI_PFF		0x00000010	/* playback fifo loop */
162 #define	AI_TFH		0x00000100	/* playback table half loop */
163 #define	AI_TFF		0x00001000	/* playback table loop */
164 #define	AI_RFH		0x00010000	/* capture table half loop */
165 #define	AI_RFF		0x00100000	/* capture fifo loop */
166 #define	AI_EAI		0x01000000	/* enables audio end interrupt */
167 
168 #define	SA_48K		0
169 #define	SA_44K		1
170 #define	SA_96K		2
171 #define	SA_192K		3
172 
173 #define	SA_MIX_OUT_EN(ch)	(1 << ((ch) + 28))
174 #define	SA_MIX_IN_EN(ch)	(1 << ((ch) + 24))
175 #define	SA_PLAY_RATE(ch, rate)	((rate) << (((ch) * 2) + 16))
176 #define	SA_PLAY_START(ch)	(1 << (ch))
177 #define	SA_RECORD_START(ch)	(1 << ((ch) + 8))
178 
179 #define	SA_SPA(ch)	(1U << (ch))
180 #define	SA_SRA(ch)	(1U << ((ch) + 8))
181 
182 #define	RECSEL_SPDIFOUT	0
183 #define	RECSEL_I2SOUT	1
184 #define	RECSEL_SPDIFIN	2
185 #define	RECSEL_I2SIN	3
186 #define	RECSEL_AC97	4
187 #define	RECSEL_SRC	5
188 
189 typedef struct _audigyls_dev_t audigyls_dev_t;
190 typedef struct _audigyls_port_t audigyls_port_t;
191 
192 typedef enum {
193 	CTL_FRONT = 0,
194 	CTL_SURROUND,
195 	CTL_CENTER,
196 	CTL_LFE,
197 	CTL_RECORDVOL,
198 	CTL_MONGAIN,
199 	CTL_RECSRC,
200 	CTL_SPREAD,
201 	CTL_LOOP,
202 	CTL_NUM		/* must be last */
203 } audigyls_ctrl_num_t;
204 
205 typedef struct audigyls_ctrl
206 {
207 	audigyls_dev_t		*dev;
208 	audio_ctrl_t		*ctrl;
209 	audigyls_ctrl_num_t	num;
210 	uint64_t		val;
211 } audigyls_ctrl_t;
212 
213 struct _audigyls_port_t
214 {
215 	audigyls_dev_t *dev;
216 	audio_engine_t *engine;
217 
218 	int			direction;
219 	int			started;
220 	boolean_t		active;
221 
222 	unsigned		fragfr;
223 	unsigned		fragsz;
224 	unsigned		nchan;
225 
226 	ddi_dma_handle_t	buf_dmah;	/* dma for buffers */
227 	ddi_acc_handle_t	buf_acch;
228 	uint32_t		buf_paddr;
229 	caddr_t			buf_kaddr;
230 	uint32_t		buf_size;
231 	uint32_t		buf_frames;	/* Buffer size in frames */
232 	uint32_t		offset;
233 	int			syncdir;
234 	uint64_t		count;
235 };
236 
237 struct _audigyls_dev_t
238 {
239 	dev_info_t		*dip;
240 	audio_dev_t		*adev;
241 	ac97_t			*ac97;
242 	kstat_t			*ksp;
243 	unsigned		intrs;
244 	unsigned		timer;
245 
246 	int			nactive;	/* Num active ports */
247 	char			digital_enable;	/* Orange combo-jack mode */
248 
249 	boolean_t		suspended;
250 	ddi_acc_handle_t	pcih;
251 	ddi_acc_handle_t	regsh;
252 	caddr_t			base;
253 	kmutex_t		mutex;		/* For normal locking */
254 	kmutex_t		low_mutex;	/* For low level routines */
255 	ddi_intr_handle_t	ih;
256 
257 	audigyls_port_t		*port[AUDIGYLS_NUM_PORT];
258 	audigyls_ctrl_t		controls[CTL_NUM];
259 
260 	ac97_ctrl_t		*ac97_recgain;
261 	ac97_ctrl_t		*ac97_recsrc;
262 	uint64_t		recmask;
263 };
264 
265 #define	INB(dev, reg)		\
266 	ddi_get8(dev->regsh, (void *)(dev->base + reg))
267 #define	OUTB(dev, reg, val)	\
268 	ddi_put8(dev->regsh, (void *)(dev->base + reg), (val))
269 
270 #define	INW(dev, reg)		\
271 	ddi_get16(dev->regsh, (void *)(dev->base + reg))
272 #define	OUTW(dev, reg, val)	\
273 	ddi_put16(dev->regsh, (void *)(dev->base + reg), (val))
274 
275 #define	INL(dev, reg)		\
276 	ddi_get32(dev->regsh, (void *)(dev->base + reg))
277 #define	OUTL(dev, reg, val)	\
278 	ddi_put32(dev->regsh, (void *)(dev->base + reg), (val))
279 
280 #define	AUDIGYLS_KIOP(X)	((kstat_intr_t *)(X->ksp->ks_data))
281 
282 #endif /* AUDIGYLS_H */
283