1/*
2 * BeOS Driver for Intel ICH AC'97 Link interface
3 *
4 * Copyright (c) 2002, Marcus Overhagen <marcus@overhagen.de>
5 *
6 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without modification,
8 * are permitted provided that the following conditions are met:
9 *
10 * - Redistributions of source code must retain the above copyright notice,
11 *   this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright notice,
13 *   this list of conditions and the following disclaimer in the documentation
14 *   and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
25 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28#ifndef _AC97_H_
29#define _AC97_H_
30
31enum AC97_REGISTER {
32	/* Baseline audio register set */
33	AC97_RESET				= 0x00,
34	AC97_MASTER_VOLUME		= 0x02,
35	AC97_AUX_OUT_VOLUME		= 0x04,
36	AC97_MONO_VOLUME		= 0x06,
37	AC97_MASTER_TONE		= 0x08,
38	AC97_PC_BEEP_VOLUME		= 0x0A,
39	AC97_PHONE_VOLUME		= 0x0C,
40	AC97_MIC_VOLUME			= 0x0E,
41	AC97_LINE_IN_VOLUME		= 0x10,
42	AC97_CD_VOLUME			= 0x12,
43	AC97_VIDEO_VOLUME		= 0x14,
44	AC97_AUX_IN_VOLUME		= 0x16,
45	AC97_PCM_OUT_VOLUME		= 0x18,
46	AC97_RECORD_SELECT		= 0x1A,
47	AC97_RECORD_GAIN		= 0x1C,
48	AC97_RECORD_GAIN_MIC	= 0x1E,
49	AC97_GENERAL_PURPOSE	= 0x20,
50	AC97_3D_CONTROL			= 0x22,
51	AC97_PAGING				= 0x24,
52	AC97_POWERDOWN			= 0x26,
53
54	/* Extended audio register set */
55	AC97_EXTENDED_ID		= 0x28,
56	AC97_EXTENDED_STAT_CTRL = 0x2A,
57	AC97_PCM_FRONT_DAC_RATE = 0x2C,
58	AC97_PCM_SURR_DAC_RATE	= 0x2E,
59	AC97_PCM_LFE_DAC_RATE	= 0x30,
60	AC97_PCM_L_R_ADC_RATE	= 0x32,
61	AC97_MIC_ADC_RATE		= 0x34,
62	AC97_CENTER_LFE_VOLUME	= 0x36,
63	AC97_SURR_VOLUME		= 0x38,
64	AC97_SPDIF_CONTROL		= 0x3A,
65
66	/* Vendor ID */
67	AC97_VENDOR_ID1			= 0x7C,
68	AC97_VENDOR_ID2			= 0x7E,
69
70	/* Analog Devices */
71	AC97_AD_JACK_SENSE		= 0x72,
72	AC97_AD_SERIAL_CONFIG	= 0x74,
73	AC97_AD_MISC_CONTROL	= 0x76,
74	AC97_AD_SAMPLE_RATE_0	= 0x78,
75	AC97_AD_SAMPLE_RATE_1	= 0x7a,
76
77	/* Realtek ALC650 */
78	AC97_ALC650_SPDIF_INPUT_CHAN_STATUS_LO = 0x60, /* only ALC650 Rev. E and later */
79	AC97_ALC650_SPDIF_INPUT_CHAN_STATUS_HI = 0x62, /* only ALC650 Rev. E and later */
80	AC97_ALC650_SURR_VOLUME		= 0x64,
81	AC97_ALC650_CEN_LFE_VOLUME	= 0x66,
82	AC97_ALC650_MULTI_CHAN_CTRL	= 0x6A,
83	AC97_ALC650_MISC_CONTROL	= 0x74,
84	AC97_ALC650_GPIO_SETUP		= 0x76,
85	AC97_ALC650_GPIO_STATUS		= 0x78,
86	AC97_ALC650_CLOCK_SOURCE	= 0x7A
87};
88
89// AC97_EXTENDED_ID bits
90enum {
91	EXID_VRA 	= 0x0001,
92	EXID_DRA 	= 0x0002,
93	EXID_SPDIF 	= 0x0004,
94	EXID_VRM 	= 0x0008,
95	EXID_DSA0 	= 0x0010,
96	EXID_DSA1 	= 0x0020,
97	EXID_CDAC 	= 0x0040,
98	EXID_SDAC 	= 0x0080,
99	EXID_LDAC 	= 0x0100,
100	EXID_AMAP 	= 0x0200,
101	EXID_REV0 	= 0x0400,
102	EXID_REV1 	= 0x0800,
103	EXID_bit12 	= 0x1000,
104	EXID_bit13 	= 0x2000,
105	EXID_ID0 	= 0x4000,
106	EXID_ID1 	= 0x8000
107};
108
109// some codec_ids
110enum {
111	CODEC_ID_ALC201A	= 0x414c4710,
112	CODEC_ID_AK4540		= 0x414b4d00,
113	CODEC_ID_AK4542		= 0x414b4d01,
114	CODEC_ID_AD1819 	= 0x41445303, // ok, AD1819A, AD1819B
115	CODEC_ID_AD1881		= 0x41445340, // ok, AD1881
116	CODEC_ID_AD1881A	= 0x41445348, // ok, AD1881A
117	CODEC_ID_AD1885		= 0x41445360, // ok, AD1885
118	CODEC_ID_AD1886		= 0x41445361, // ok, AD1886
119	CODEC_ID_AD1886A 	= 0x41445363, // ok, AD1886A
120	CODEC_ID_AD1887		= 0x41445362, // ok, AD1887
121	CODEC_ID_AD1980		= 0x41445370, // ok, AD1980
122	CODEC_ID_AD1981B	= 0x41445374, // ok, AD1981B
123	CODEC_ID_AD1985		= 0x41445375, // ok, AD1985
124	CODEC_ID_CS4299A	= 0x43525931,
125	CODEC_ID_CS4299C	= 0x43525933,
126	CODEC_ID_CS4299D	= 0x43525934,
127	CODEC_ID_STAC9700	= 0x83847600, // ok, STAC9700
128	CODEC_ID_STAC9704	= 0x83847604, // STAC9701/03, STAC9704/07, STAC9705 (???)
129	CODEC_ID_STAC9705	= 0x83847605, // ???
130	CODEC_ID_STAC9708	= 0x83847608, // ok, STAC9708/11
131	CODEC_ID_STAC9721	= 0x83847609, // ok, STAC9721/23
132	CODEC_ID_STAC9744	= 0x83847644, // ok, STAC9744
133	CODEC_ID_STAC9752	= 0x83847652, // ok, STAC9752/53
134	CODEC_ID_STAC9756	= 0x83847656, // ok, STAC9756/57
135	CODEC_ID_STAC9766	= 0x83847666, // ok, STAC9766/67
136};
137
138// capabilities
139enum ac97_capability {
140	CAP_PCM_MIC				= 0x0000000000000001ULL, /* dedicated mic PCM channel */
141	CAP_BASS_TREBLE_CTRL	= 0x0000000000000002ULL,
142	CAP_SIMULATED_STEREO	= 0x0000000000000004ULL,
143	CAP_HEADPHONE_OUT		= 0x0000000000000008ULL,
144	CAP_LAUDNESS			= 0x0000000000000010ULL,
145	CAP_DAC_18BIT			= 0x0000000000000020ULL,
146	CAP_DAC_20BIT			= 0x0000000000000040ULL,
147	CAP_ADC_18BIT			= 0x0000000000000080ULL,
148	CAP_ADC_20BIT			= 0x0000000000000100ULL,
149	CAP_3D_ENHANCEMENT		= 0x0000000000000200ULL,
150	CAP_VARIABLE_PCM		= 0x0000000000000400ULL, /* variable rate PCM */
151	CAP_DOUBLE_PCM			= 0x0000000000000800ULL, /* double rate PCM */
152	CAP_SPDIF				= 0x0000000000001000ULL,
153	CAP_VARIABLE_MIC		= 0x0000000000002000ULL, /* variable rate mic PCM */
154	CAP_CENTER_DAC			= 0x0000000000004000ULL,
155	CAP_SURR_DAC			= 0x0000000000008000ULL,
156	CAP_LFE_DAC				= 0x0000000000010000ULL,
157	CAP_AMAP				= 0x0000000000020000ULL,
158	CAP_REV21				= 0x0000000000040000ULL,
159	CAP_REV22				= 0x0000000000080000ULL,
160	CAP_REV23				= 0x0000000000100000ULL,
161	CAP_PCM_RATE_CONTINUOUS	= 0x0000000000200000ULL,
162	CAP_PCM_RATE_8000		= 0x0000000000400000ULL,
163	CAP_PCM_RATE_11025		= 0x0000000000800000ULL,
164	CAP_PCM_RATE_12000		= 0x0000000001000000ULL,
165	CAP_PCM_RATE_16000		= 0x0000000002000000ULL,
166	CAP_PCM_RATE_22050		= 0x0000000004000000ULL,
167	CAP_PCM_RATE_24000		= 0x0000000008000000ULL,
168	CAP_PCM_RATE_32000		= 0x0000000010000000ULL,
169	CAP_PCM_RATE_44100		= 0x0000000020000000ULL,
170	CAP_PCM_RATE_48000		= 0x0000000040000000ULL,
171	CAP_PCM_RATE_88200		= 0x0000000080000000ULL,
172	CAP_PCM_RATE_96000		= 0x0000000100000000ULL,
173	CAP_PCM_RATE_MASK		= ( CAP_PCM_RATE_CONTINUOUS | CAP_PCM_RATE_8000 | CAP_PCM_RATE_11025 |
174								CAP_PCM_RATE_12000 | CAP_PCM_RATE_16000 | CAP_PCM_RATE_22050 |
175								CAP_PCM_RATE_24000 | CAP_PCM_RATE_32000 | CAP_PCM_RATE_44100 |
176								CAP_PCM_RATE_48000 | CAP_PCM_RATE_88200 | CAP_PCM_RATE_96000)
177};
178
179
180struct ac97_dev;
181typedef struct ac97_dev ac97_dev;
182
183typedef void	(* codec_init)(ac97_dev * dev);
184typedef	uint16	(* codec_reg_read)(void * cookie, uint8 reg);
185typedef	void	(* codec_reg_write)(void * cookie, uint8 reg, uint16 value);
186typedef bool	(* codec_set_rate)(ac97_dev *dev, uint8 reg, uint32 rate);
187typedef bool	(* codec_get_rate)(ac97_dev *dev, uint8 reg, uint32 *rate);
188
189struct ac97_dev {
190	uint16				reg_cache[0x7f];
191
192	void *				cookie;
193
194	uint32				codec_id;
195	const char *		codec_info;
196	const char *		codec_3d_stereo_enhancement;
197
198	codec_init			init;
199	codec_reg_read		reg_read;
200	codec_reg_write		reg_write;
201	codec_set_rate		set_rate;
202	codec_get_rate		get_rate;
203
204	uint32				max_vsr;
205	uint32				min_vsr;
206	uint32 				clock;
207	uint64				capabilities;
208	bool				reversed_eamp_polarity;
209};
210
211
212void	ac97_attach(ac97_dev **dev, codec_reg_read reg_read, codec_reg_write reg_write, void *cookie);
213void	ac97_detach(ac97_dev *dev);
214void	ac97_suspend(ac97_dev *dev);
215void	ac97_resume(ac97_dev *dev);
216
217void	ac97_reg_cached_write(ac97_dev *dev, uint8 reg, uint16 value);
218uint16	ac97_reg_cached_read(ac97_dev *dev, uint8 reg);
219void	ac97_reg_uncached_write(ac97_dev *dev, uint8 reg, uint16 value);
220uint16	ac97_reg_uncached_read(ac97_dev *dev, uint8 reg);
221
222bool	ac97_reg_update(ac97_dev *dev, uint8 reg, uint16 value);
223bool	ac97_reg_update_bits(ac97_dev *dev, uint8 reg, uint16 mask, uint16 value);
224
225bool	ac97_set_rate(ac97_dev *dev, uint8 reg, uint32 rate);
226bool	ac97_get_rate(ac97_dev *dev, uint8 reg, uint32 *rate);
227
228bool	ac97_has_capability(ac97_dev *dev, uint64 cap);
229
230void	ac97_set_clock(ac97_dev *dev, uint32 clock);
231
232#endif
233