audio810.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 * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#ifndef	_AUDIO810_H_
27#define	_AUDIO810_H_
28
29/*
30 * Header file for the audio810 device driver
31 */
32
33/*
34 * Driver supported configuration information
35 */
36#define	I810_NAME			"audio810"
37#define	I810_MOD_NAME			"audio810 audio driver"
38
39/*
40 * Misc. defines
41 */
42
43#define	I810_BD_NUMS			(32)
44#define	I810_NUM_PORTS			(2)
45#define	I810_MOD_SIZE			(16)
46
47#define	I810_ROUNDUP(x, algn)		(((x) + ((algn) - 1)) & ~((algn) - 1))
48
49/* The size of each entry of "reg" property is 5 integers */
50#define	I810_INTS_PER_REG_PROP		5
51
52/* offset from the base of specified DMA engine */
53#define	I810_OFFSET_BD_BASE		(0x00)
54#define	I810_OFFSET_CIV			(0x04)
55#define	I810_OFFSET_LVI			(0x05)
56#define	I810_OFFSET_SR			(0x06)
57#define	I810_OFFSET_PICB		(0x08)
58#define	I810_OFFSET_PIV			(0x0A)
59#define	I810_OFFSET_CR			(0x0B)
60
61/* DMA engine offset from base */
62#define	I810_BASE_PCM_IN		(0x00)
63#define	I810_BASE_PCM_OUT		(0x10)
64#define	I810_BASE_MIC			(0x20)
65
66#define	I810_REG_GCR			0x2C
67#define	I810_REG_GSR			0x30
68#define	I810_REG_CASR			0x34
69#define	I810_REG_SISCTL			0x4C	/* SiS 7012 control */
70
71/* bits of bus master status register */
72#define	I810_BM_SR_DCH			0x01
73#define	I810_BM_SR_CELV			0x02
74#define	I810_BM_SR_LVBCI		0x04
75#define	I810_BM_SR_BCIS			0x08
76#define	I810_BM_SR_FIFOE		0x10
77
78/* bits of bus master control register */
79#define	I810_BM_CR_RUN			0x01
80#define	I810_BM_CR_RST			0x02
81#define	I810_BM_CR_LVBIE		0x04
82#define	I810_BM_CR_FEIE			0x08
83#define	I810_BM_CR_IOCE			0x10
84
85#define	I810_BM_CR_PAUSE		0x00
86
87/*
88 * Global Control Register
89 */
90#define	I810_GCR_GPIE			0x00000001
91#define	I810_GCR_COLD_RST		0x00000002
92#define	I810_GCR_WARM_RST		0x00000004
93#define	I810_GCR_ACLINK_OFF		0x00000008
94#define	I810_GCR_PRI_INTR_ENABLE	0x00000010
95#define	I810_GCR_SEC_INTR_ENABLE	0x00000020
96
97/* For ICH2 or more, bit21:20 is the PCM 4/6-channel enable bits */
98#define	I810_GCR_2_CHANNELS		(0 << 20)
99#define	I810_GCR_4_CHANNELS		(1 << 20)
100#define	I810_GCR_6_CHANNELS		(2 << 20)
101#define	I810_GCR_CHANNELS_MASK		(3 << 20)
102/* SiS 7012 has its own flags here */
103#define	I810_GCR_SIS_2_CHANNELS		(0 << 6)
104#define	I810_GCR_SIS_4_CHANNELS		(1 << 6)
105#define	I810_GCR_SIS_6_CHANNELS		(2 << 6)
106#define	I810_GCR_SIS_CHANNELS_MASK	(3 << 6)
107
108
109/*
110 * Global Status Register
111 */
112#define	I810_GSR_TRI_READY		0x10000000	/* for ICH4/5 */
113#define	I810_GSR_CAP8CH			0x00400000
114#define	I810_GSR_CAP6CH			0x00200000
115#define	I810_GSR_CAP4CH			0x00100000
116#define	I810_GSR_READ_COMPL		0x00008000
117#define	I810_GSR_INTR_SEC_RESUME	0x00000800
118#define	I810_GSR_INTR_PRI_RESUME	0x00000400
119#define	I810_GSR_SEC_READY		0x00000200
120#define	I810_GSR_PRI_READY		0x00000100
121#define	I810_GSR_INTR_MIC		0x00000080
122#define	I810_GSR_INTR_POUT		0x00000040
123#define	I810_GSR_INTR_PIN		0x00000020
124#define	I810_GSR_INTR_MO		0x00000004
125#define	I810_GSR_INTR_MI		0x00000002
126#define	I810_GSR_INTR_GSI		0x00000001
127#define	I810_GSR_USE_INTR		0x00000060	/* PCM-IN ,PCM-OUT */
128
129/*
130 * SiS Control Register
131 */
132#define	I810_SISCTL_UNMUTE		0x01
133
134/*
135 * Macro for AD1980 codec
136 */
137#define	AD1980_VID1		0x4144
138#define	AD1980_VID2		0x5370
139#define	AD1985_VID2		0x5375
140#define	CODEC_AD_REG_MISC	0x76	/* offset of ad1980 misc control reg */
141#define	AD1980_MISC_LOSEL	0x0020	/* Line-out amplifier output selector */
142#define	AD1980_MISC_HPSEL	0x0400	/* HP-out amplifier output selector */
143#define	AD1980_SURR_MUTE	0x8080	/* Mute for surround volume register */
144
145#define	I810_PCM_IN		0
146#define	I810_PCM_OUT		1
147
148struct audio810_port {
149	struct audio810_state	*statep;
150	int			num;
151	ddi_dma_handle_t	samp_dmah;
152	ddi_acc_handle_t	samp_acch;
153	uint32_t		samp_frames;
154	size_t			samp_size;
155	caddr_t			samp_kaddr;
156	uint32_t		samp_paddr;
157
158	ddi_dma_handle_t	bdl_dmah;
159	ddi_acc_handle_t	bdl_acch;
160	size_t			bdl_size;
161	caddr_t			bdl_kaddr;
162	uint32_t		bdl_paddr;
163
164	uint32_t		offset;
165	uint64_t		count;
166	uint8_t			nchan;
167
168	uint8_t			regoff;
169	uint8_t			stsoff;		/* status offset */
170	uint8_t			picboff;	/* picb offset */
171	unsigned		sync_dir;
172
173	audio_engine_t		*engine;
174};
175typedef struct audio810_port audio810_port_t;
176
177/*
178 * buffer descripter list entry, sees datasheet
179 */
180struct i810_bd_entry {
181	uint32_t	buf_base;	/* the address of the buffer */
182	uint16_t	buf_len;	/* the number of samples */
183	uint16_t	buf_cmd;
184};
185typedef struct	i810_bd_entry	i810_bd_entry_t;
186#define	BUF_CMD_BUP	0x4000
187#define	BUF_CMD_IOC	0x8000
188
189typedef enum i810_quirk {
190	QUIRK_NONE = 0,
191	QUIRK_OLDICH,		/* likely emulated, needs deeper playahead */
192	QUIRK_SIS7012,		/* weird registers and such */
193} i810_quirk_t;
194
195/*
196 * audio810_state_t	-per instance state and operation data
197 */
198struct audio810_state {
199	dev_info_t		*dip;	/* used by audio810_getinfo() */
200	audio_dev_t		*adev;
201	ac97_t			*ac97;
202	audio810_port_t		*ports[2];
203
204	ddi_acc_handle_t	am_regs_handle;	/* for audio mixer register */
205	ddi_acc_handle_t	bm_regs_handle;	/* for bus master register */
206	caddr_t			am_regs_base;	/* base of audio mixer regs */
207	caddr_t			bm_regs_base;	/* base of bus master regs */
208
209	kstat_t			*ksp;		/* kernel statistics */
210
211	uint8_t			maxch;
212	i810_quirk_t		quirk;
213};
214typedef struct audio810_state	 audio810_state_t;
215
216/*
217 * Useful bit twiddlers
218 */
219#define	I810_BM_GET8(reg)	\
220	ddi_get8(statep->bm_regs_handle, \
221	(void *)((char *)statep->bm_regs_base + (reg)))
222
223#define	I810_BM_GET16(reg)	\
224	ddi_get16(statep->bm_regs_handle, \
225	(void *)((char *)statep->bm_regs_base + (reg)))
226
227#define	I810_BM_GET32(reg)	\
228	ddi_get32(statep->bm_regs_handle, \
229	(void *)((char *)statep->bm_regs_base + (reg)))
230
231#define	I810_BM_PUT8(reg, val)	\
232	ddi_put8(statep->bm_regs_handle, \
233	(void *)((char *)statep->bm_regs_base + (reg)), (val))
234
235#define	I810_BM_PUT16(reg, val)	\
236	ddi_put16(statep->bm_regs_handle, \
237	(void *)((char *)statep->bm_regs_base + (reg)), (val))
238
239#define	I810_BM_PUT32(reg, val)	\
240	ddi_put32(statep->bm_regs_handle, \
241	(void *)((char *)statep->bm_regs_base + (reg)), (val))
242
243#define	I810_AM_GET16(reg)	\
244	ddi_get16(statep->am_regs_handle, \
245	(void *)((char *)statep->am_regs_base + (reg)))
246
247#define	I810_AM_PUT16(reg, val)	\
248	ddi_put16(statep->am_regs_handle, \
249	(void *)((char *)statep->am_regs_base + (reg)), (val))
250
251#endif /* _AUDIO810_H_ */
252