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