xref: /haiku/src/add-ons/kernel/drivers/audio/ac97/ac97.c (revision 26a211b054229a851c77227be4cec5b6347466b1)
1 /*
2  * AC97 interface
3  *
4  * Copyright (c) 2002, Marcus Overhagen <marcus@overhagen.de>
5  * Copyright (c) 2008-2013, Jérôme Duval
6  *
7  * All rights reserved.
8  * Redistribution and use in source and binary forms, with or without modification,
9  * are permitted provided that the following conditions are met:
10  *
11  * - Redistributions of source code must retain the above copyright notice,
12  *   this list of conditions and the following disclaimer.
13  * - Redistributions in binary form must reproduce the above copyright notice,
14  *   this list of conditions and the following disclaimer in the documentation
15  *   and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
21  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
23  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  */
29 
30 
31 #include <KernelExport.h>
32 #include <OS.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <MediaDefs.h>
37 #include "ac97.h"
38 
39 #define LOG(x)	dprintf x
40 
41 #define B_UTF8_REGISTERED	"\xC2\xAE"
42 
43 bool ac97_reg_is_valid(ac97_dev *dev, uint8 reg);
44 void ac97_amp_enable(ac97_dev *dev, bool onoff);
45 void ac97_dump_capabilities(ac97_dev *dev);
46 void ac97_detect_capabilities(ac97_dev *dev);
47 void ac97_detect_rates(ac97_dev *dev);
48 void ac97_update_register_cache(ac97_dev *dev);
49 
50 
51 const char * stereo_enhancement_technique[] =
52 {
53 	"No 3D Stereo Enhancement",
54 	"Analog Devices",
55 	"Creative Technology",
56 	"National Semiconductor",
57 	"Yamaha",
58 	"BBE Sound",
59 	"Crystal Semiconductor",
60 	"Qsound Labs",
61 	"Spatializer Audio Laboratories",
62 	"SRS Labs",
63 	"Platform Tech",
64 	"AKM Semiconductor",
65 	"Aureal",
66 	"Aztech Labs",
67 	"Binaura",
68 	"ESS Technology",
69 	"Harman International",
70 	"Nvidea",
71 	"Philips",
72 	"Texas Instruments",
73 	"VLSI Technology",
74 	"TriTech",
75 	"Realtek",
76 	"Samsung",
77 	"Wolfson Microelectronics",
78 	"Delta Integration",
79 	"SigmaTel",
80 	"KS Waves",
81 	"Rockwell",
82 	"Unknown (29)",
83 	"Unknown (30)",
84 	"Unknown (31)"
85 };
86 
87 
88 static void default_init(ac97_dev *dev);
89 static void ad1819_init(ac97_dev *dev);
90 static void ad1881_init(ac97_dev *dev);
91 static void ad1885_init(ac97_dev *dev);
92 static void ad1886_init(ac97_dev *dev);
93 static void ad1980_init(ac97_dev *dev);
94 static void ad1981b_init(ac97_dev *dev);
95 static void alc203_init(ac97_dev *dev);
96 static void alc650_init(ac97_dev *dev);
97 static void alc655_init(ac97_dev *dev);
98 static void alc850_init(ac97_dev *dev);
99 static void stac9708_init(ac97_dev *dev);
100 static void stac9721_init(ac97_dev *dev);
101 static void stac9744_init(ac97_dev *dev);
102 static void stac9756_init(ac97_dev *dev);
103 static void stac9758_init(ac97_dev *dev);
104 static void tr28028_init(ac97_dev *dev);
105 static void wm9701_init(ac97_dev *dev);
106 static void wm9703_init(ac97_dev *dev);
107 static void wm9704_init(ac97_dev *dev);
108 
109 bool ad1819_set_rate(ac97_dev *dev, uint8 reg, uint32 rate);
110 bool ad1819_get_rate(ac97_dev *dev, uint8 reg, uint32 *rate);
111 
112 
113 typedef struct
114 {
115 	uint32 id;
116 	uint32 mask;
117 	codec_init init;
118 	const char *info;
119 } codec_table;
120 
121 
122 codec_table codecs[] =
123 {
124 	{ CODEC_ID_AD1819,	0xffffffff, ad1819_init,	"Analog Devices AD1819A, AD1819B SoundPort" B_UTF8_REGISTERED },
125 	{ CODEC_ID_AD1881,	0xffffffff, ad1881_init,	"Analog Devices AD1881 SoundMAX" B_UTF8_REGISTERED },
126 	{ CODEC_ID_AD1881A,	0xffffffff, ad1881_init,	"Analog Devices AD1881A SoundMAX" B_UTF8_REGISTERED },
127 	{ CODEC_ID_AD1885,	0xffffffff, ad1885_init,	"Analog Devices AD1885 SoundMAX" B_UTF8_REGISTERED },
128 	{ CODEC_ID_AD1886,	0xffffffff, ad1886_init,	"Analog Devices AD1886 SoundMAX" B_UTF8_REGISTERED },
129 	{ CODEC_ID_AD1886A,	0xffffffff, ad1881_init,	"Analog Devices AD1886A SoundMAX" B_UTF8_REGISTERED },
130 	{ CODEC_ID_AD1887,	0xffffffff, ad1881_init,	"Analog Devices AD1887 SoundMAX" B_UTF8_REGISTERED },
131 	{ CODEC_ID_AD1888,	0xffffffff, ad1881_init,	"Analog Devices AD1888 SoundMAX" B_UTF8_REGISTERED },
132 	{ CODEC_ID_AD1980,	0xffffffff, ad1980_init,	"Analog Devices AD1980 SoundMAX" B_UTF8_REGISTERED },
133 	{ 0x41445371,		0xffffffff, default_init,	"Analog Devices 0x41445371 (\?\?\?)" },
134 	{ 0x41445372,		0xffffffff, default_init,	"Analog Devices AD1981A SoundMAX" B_UTF8_REGISTERED },
135 	{ CODEC_ID_AD1981B,	0xffffffff, ad1981b_init,	"Analog Devices AD1981B SoundMAX" B_UTF8_REGISTERED },
136 	{ CODEC_ID_AD1985,	0xffffffff, default_init,	"Analog Devices AD1985 SoundMAX" B_UTF8_REGISTERED },
137 	{ CODEC_ID_AD1986,	0xffffffff, default_init,	"Analog Devices AD1986 SoundMAX" B_UTF8_REGISTERED },
138 	{ CODEC_ID_AK4540,	0xffffffff, default_init,	"Asahi Kasei AK4540" },
139 	{ CODEC_ID_AK4542,	0xffffffff, default_init,	"Asahi Kasei AK4542" },
140 	{ CODEC_ID_AK4543,	0xffffffff, default_init,	"Asahi Kasei AK4543" },
141 	{ 0x414b4d06,		0xffffffff, default_init,	"Asahi Kasei AK4544A" },
142 	{ 0x414b4d07,		0xffffffff, default_init,	"Asahi Kasei AK4545" },
143 	{ 0x414c4300, 		0xffffff00, default_init,	"Avance Logic (Realtek) ALC100" }, /* 0x4300 = ALC100 */
144 	{ 0x414c4320,		0xfffffff0, default_init,	"Avance Logic (Realtek) ALC100/ALC100P, RL5383/RL5522" },
145 	{ CODEC_ID_ALC201A, 0xfffffff0, default_init,	"Avance Logic (Realtek) ALC200/ALC200A, ALC201/ALC201A" }, /* 0x4710 = ALC201A */
146 	{ 0x414c4720,		0xffffffff, alc650_init,	"Avance Logic (Realtek) ALC650" }, /* 0x4720 = ALC650 */
147 	{ 0x414c4730, 		0xffffffff, default_init,	"Avance Logic (Realtek) ALC101" },
148 	{ 0x414c4740,		0xfffffff0, default_init,	"Avance Logic (Realtek) ALC202/ALC202A" },
149 	{ 0x414c4750,		0xfffffff0, default_init,	"Avance Logic (Realtek) ALC250" },
150 	{ 0x414c4760,		0xfffffff0, alc655_init,	"Avance Logic (Realtek) ALC655" }, /* 0x4760 = ALC655 */
151 	{ 0x414c4770,		0xfffffff0, alc203_init,	"Avance Logic (Realtek) ALC203" },
152 	{ 0x414c4780,		0xffffffff, alc655_init,	"Avance Logic (Realtek) ALC658" },
153 	{ 0x414c4790,		0xfffffff0, alc850_init,	"Avance Logic (Realtek) ALC850" },
154 	{ 0x434d4941,		0xffffffff, default_init,	"C-Media CMI9738" },
155 	{ 0x434d4961,		0xffffffff, default_init,	"C-Media CMI9739" },
156 	{ 0x43525900,		0xffffffff, default_init,	"Cirrus Logic CS4297" },
157 	{ 0x43525903,		0xffffffff, default_init,	"Cirrus Logic CS4297" },
158 	{ 0x43525913,		0xffffffff, default_init,	"Cirrus Logic CS4297A" },
159 	{ 0x43525914,		0xffffffff, default_init,	"Cirrus Logic CS4297B" },
160 	{ 0x43525923,		0xffffffff, default_init,	"Cirrus Logic CS4294C" },
161 	{ 0x4352592b,		0xffffffff, default_init,	"Cirrus Logic CS4298C" },
162 	{ CODEC_ID_CS4299A,	0xffffffff, default_init,	"Cirrus Logic CS4299A" },
163 	{ CODEC_ID_CS4299C,	0xffffffff, default_init,	"Cirrus Logic CS4299C" },
164 	{ CODEC_ID_CS4299D,	0xffffffff, default_init,	"Cirrus Logic CS4299D" },
165 	{ 0x43525941,		0xffffffff, default_init,	"Cirrus Logic CS4201A" },
166 	{ 0x43525951,		0xffffffff, default_init,	"Cirrus Logic CS4205A" },
167 	{ 0x43525961,		0xffffffff, default_init,	"Cirrus Logic CS4291A" },
168 	{ 0x43585421,		0xffffffff, default_init,	"HSD11246" },
169 	{ 0x44543031,		0xffffffff, default_init,	"DT0398" },
170 	{ 0x454d4328,		0xffffffff, default_init,	"EM28028" },
171 	{ 0x45838308,		0xffffffff, default_init,	"ESS Technology ES1921" },
172 	{ 0x49434501,		0xffffffff, default_init,	"ICEnsemble ICE1230" },
173 	{ 0x49434511,		0xffffffff, default_init,	"ICEnsemble ICE1232" },
174 	{ 0x49434514,		0xffffffff, default_init,	"ICEnsemble ICE1232A" },
175 	{ 0x49434551,		0xffffffff, default_init,	"Via Technologies VT1616" }, /* rebranded from ICEnsemble */
176 	{ 0x49544520,		0xffffffff, default_init,	"Integrated Technology Express ITE2226E" },
177 	{ 0x49544560,		0xffffffff, default_init,	"Integrated Technology Express ITE2646E" },
178 	{ 0x4e534331,		0xffffffff, default_init,	"National Semiconductor LM4549" },
179 	{ CODEC_ID_STAC9700,0xffffffff, default_init,	"SigmaTel STAC9700/9783/9784" },
180 	{ CODEC_ID_STAC9704,0xffffffff, default_init,	"SigmaTel STAC9701/03, STAC9704/07, STAC9705 (\?\?\?)" },
181 	{ CODEC_ID_STAC9705,0xffffffff, default_init,	"SigmaTel STAC9704 (\?\?\?)" },
182 	{ CODEC_ID_STAC9708,0xffffffff, stac9708_init,	"SigmaTel STAC9708/9711" },
183 	{ CODEC_ID_STAC9721,0xffffffff, stac9721_init,	"SigmaTel STAC9721/9723" },
184 	{ CODEC_ID_STAC9744,0xffffffff, stac9744_init,	"SigmaTel STAC9744" },
185 	{ CODEC_ID_STAC9750,0xffffffff, default_init,	"SigmaTel STAC9750/51" },
186 	{ CODEC_ID_STAC9752,0xffffffff, default_init,	"SigmaTel STAC9752/53" },
187 	{ CODEC_ID_STAC9756,0xffffffff, stac9756_init,	"SigmaTel STAC9756/9757" },
188 	{ CODEC_ID_STAC9758,0xffffffff, stac9758_init,	"SigmaTel STAC9758/59" },
189 	{ CODEC_ID_STAC9766,0xffffffff, default_init,	"SigmaTel STAC9766/67" },
190 	{ 0x53494c22,		0xffffffff, default_init,	"Silicon Laboratory Si3036" },
191 	{ 0x53494c23,		0xffffffff, default_init,	"Silicon Laboratory Si3038" },
192 	{ 0x53544d02,		0xffffffff, default_init,	"ST7597" },
193 	{ 0x54524103,		0xffffffff, default_init,	"TriTech TR28023" },
194 	{ 0x54524106,		0xffffffff, default_init,	"TriTech TR28026" },
195 	{ 0x54524108,		0xffffffff, tr28028_init,	"TriTech TR28028" },
196 	{ 0x54524123,		0xffffffff, default_init,	"TriTech TR28602" },
197 	{ 0x56494161,		0xffffffff, default_init,	"Via Technologies VIA1612A" },
198 	{ 0x56494170,		0xffffffff, default_init,	"Via Technologies VIA1617A" },
199 	{ 0x574d4c00,		0xffffffff, wm9701_init,	"Wolfson WM9701A" },
200 	{ 0x574d4c03,		0xffffffff, wm9703_init,	"Wolfson WM9703/9704" },
201 	{ 0x574d4c04,		0xffffffff, wm9704_init,	"Wolfson WM9704 (quad)" },
202 	{ 0x574d4c05,		0xffffffff, wm9703_init,	"Wolfson WM9705/WM9710" },
203 	{ 0x574d4d09,		0xffffffff, default_init,	"Wolfson WM9709" },
204 	{ 0x574d4c12,		0xffffffff, default_init,	"Wolfson WM9711/12" },
205 	{ 0x574d4c13,		0xffffffff, default_init,	"Wolfson WM9713/14" },
206 	{ 0x57454301,		0xffffffff, default_init,	"Wolfson W83971D" },
207 	/* Vendors only: */
208 	{ 0x41445300,		0xffffff00, default_init,	"Analog Devices" },
209 	{ 0x414b4d00,		0xffffff00, default_init,	"Asahi Kasei" },
210 	{ 0x414c4700,		0xffffff00, default_init,	"Avance Logic (Realtek)" },
211 	{ 0x434d4900,		0xffffff00, default_init,	"C-Media" },
212 	{ 0x43525900,		0xffffff00, default_init,	"Cirrus Logic" },
213 	{ 0x45838300,		0xffffff00, default_init,	"ESS Technology" },
214 	{ 0x49434500,		0xffffff00, default_init,	"ICEnsemble" },
215 	{ 0x49544500,		0xffffff00, default_init,	"ITE, Inc." },
216 	{ 0x4e534300,		0xffffff00, default_init,	"National Semiconductor" },
217 	{ 0x83847600,		0xffffff00, default_init,	"SigmaTel" },
218 	{ 0x53494c00,		0xffffff00, default_init,	"Silicon Laboratory" },
219 	{ 0x54524100,		0xffffff00, default_init,	"TriTech" },
220 	{ 0x54584e00,		0xffffff00, default_init,	"Texas Instruments" },
221 	{ 0x56494100,		0xffffff00, default_init,	"VIA Technologies" },
222 	{ 0x574d4c00,		0xffffff00, default_init,	"Wolfson" },
223 	{ 0x594d4800,		0xffffff00, default_init,	"Yamaha" },
224 	{ 0x00000000,		0x00000000, default_init,	"Unknown" } /* must be last one, matches every codec */
225 };
226 
227 
228 static codec_table *
find_codec_table(uint32 codecid)229 find_codec_table(uint32 codecid)
230 {
231 	codec_table *codec;
232 	for (codec = codecs; codec->id; codec++)
233 		if ((codec->id & codec->mask) == (codecid & codec->mask))
234 			break;
235 	return codec;
236 }
237 
238 
239 void
ac97_attach(ac97_dev ** _dev,codec_reg_read reg_read,codec_reg_write reg_write,void * cookie,ushort subvendor_id,ushort subsystem_id)240 ac97_attach(ac97_dev **_dev, codec_reg_read reg_read, codec_reg_write reg_write, void *cookie,
241 	ushort subvendor_id, ushort subsystem_id)
242 {
243 	ac97_dev *dev;
244 	codec_table *codec;
245 	int i;
246 
247 	*_dev = dev = (ac97_dev *) malloc(sizeof(ac97_dev));
248 	memset(dev->reg_cache, 0, sizeof(dev->reg_cache));
249 	dev->cookie = cookie;
250 	dev->reg_read = reg_read;
251 	dev->reg_write = reg_write;
252 	dev->set_rate = 0;
253 	dev->get_rate = 0;
254 	dev->clock = 48000; /* default clock on non-broken motherboards */
255 	dev->min_vsr = 0x0001;
256 	dev->max_vsr = 0xffff;
257 	dev->reversed_eamp_polarity = false;
258 	dev->capabilities = 0;
259 
260 	dev->subsystem = (subvendor_id << 16) | subsystem_id;
261 
262 	if (dev->subsystem == 0x161f202f
263 		|| dev->subsystem == 0x161f203a
264 		|| dev->subsystem == 0x161f203e
265 		|| dev->subsystem == 0x161f204c
266 		|| dev->subsystem == 0x104d8144
267 		|| dev->subsystem == 0x104d8197
268 		|| dev->subsystem == 0x104d81c0
269 		|| dev->subsystem == 0x104d81c5
270 		|| dev->subsystem == 0x103c3089
271 		|| dev->subsystem == 0x103c309a
272 		|| dev->subsystem == 0x10338213
273 		|| dev->subsystem == 0x103382be) {
274 		dev->reversed_eamp_polarity = true;
275 	}
276 
277 	/* reset the codec */
278 	LOG(("codec reset\n"));
279 	ac97_reg_uncached_write(dev, AC97_RESET, 0x0000);
280 	for (i = 0; i < 500; i++) {
281 		if ((ac97_reg_uncached_read(dev, AC97_POWERDOWN) & 0xf) == 0xf)
282 			break;
283 		snooze(1000);
284 	}
285 
286 	dev->codec_id = ((uint32)reg_read(cookie, AC97_VENDOR_ID1) << 16) | reg_read(cookie, AC97_VENDOR_ID2);
287 	codec = find_codec_table(dev->codec_id);
288 	dev->codec_info = codec->info;
289 	dev->init = codec->init;
290 
291 	dev->codec_3d_stereo_enhancement = stereo_enhancement_technique[(ac97_reg_cached_read(dev, AC97_RESET) >> 10) & 31];
292 
293 	/* setup register cache */
294 	ac97_update_register_cache(dev);
295 
296 	ac97_reg_update_bits(dev, AC97_EXTENDED_STAT_CTRL, 1, 1); // enable variable rate audio
297 
298 	ac97_detect_capabilities(dev);
299 
300 	dev->init(dev);
301 	ac97_amp_enable(dev, true);
302 
303 	/* set mixer defaults, enabled Line-out sources are PCM-out, CD-in, Line-in */
304 	ac97_reg_update(dev, AC97_CENTER_LFE_VOLUME, 0x0000);	/* set LFE & center volume 0dB */
305 	ac97_reg_update(dev, AC97_SURR_VOLUME, 0x0000);			/* set surround volume 0dB */
306 	ac97_reg_update(dev, AC97_MASTER_VOLUME, 0x0000);		/* set master output 0dB */
307 	ac97_reg_update(dev, AC97_AUX_OUT_VOLUME, 0x0000);		/* set aux output 0dB */
308 	ac97_reg_update(dev, AC97_MONO_VOLUME, 0x0000);			/* set mono output 0dB */
309 	ac97_reg_update(dev, AC97_PCM_OUT_VOLUME, 0x0808);		/* enable pcm-out */
310 	ac97_reg_update(dev, AC97_CD_VOLUME, 0x0808);			/* enable cd-in */
311 	ac97_reg_update(dev, AC97_LINE_IN_VOLUME, 0x0808);		/* enable line-in */
312 
313 	/* set record line in */
314 	ac97_reg_update(dev, AC97_RECORD_SELECT, 0x0404);
315 
316 	LOG(("codec vendor id      = %#08" B_PRIx32 "\n", dev->codec_id));
317 	LOG(("codec description     = %s\n", dev->codec_info));
318 	LOG(("codec 3d enhancement = %s\n", dev->codec_3d_stereo_enhancement));
319 
320 	ac97_dump_capabilities(dev);
321 }
322 
323 
324 void
ac97_detach(ac97_dev * dev)325 ac97_detach(ac97_dev *dev)
326 {
327 	/* Mute everything */
328 	ac97_reg_update_bits(dev, AC97_CENTER_LFE_VOLUME, 0x8000, 0x8000);
329 	ac97_reg_update_bits(dev, AC97_SURR_VOLUME, 0x8000, 0x8000);
330 	ac97_reg_update_bits(dev, AC97_MASTER_VOLUME, 0x8000, 0x8000);
331 	ac97_reg_update_bits(dev, AC97_AUX_OUT_VOLUME, 0x8000, 0x8000);
332 	ac97_reg_update_bits(dev, AC97_MONO_VOLUME, 0x8000, 0x8000);
333 	ac97_reg_update_bits(dev, AC97_PCM_OUT_VOLUME, 0x8000, 0x8000);
334 	ac97_reg_update_bits(dev, AC97_CD_VOLUME, 0x8000, 0x8000);
335 	ac97_reg_update_bits(dev, AC97_LINE_IN_VOLUME, 0x8000, 0x8000);
336 
337 	ac97_amp_enable(dev, false);
338 
339 	free(dev);
340 }
341 
342 
343 void
ac97_suspend(ac97_dev * dev)344 ac97_suspend(ac97_dev *dev)
345 {
346 	ac97_amp_enable(dev, false);
347 }
348 
349 
350 void
ac97_resume(ac97_dev * dev)351 ac97_resume(ac97_dev *dev)
352 {
353 	ac97_amp_enable(dev, true);
354 }
355 
356 
357 void
ac97_reg_cached_write(ac97_dev * dev,uint8 reg,uint16 value)358 ac97_reg_cached_write(ac97_dev *dev, uint8 reg, uint16 value)
359 {
360 	if (!ac97_reg_is_valid(dev, reg))
361 		return;
362 	dev->reg_write(dev->cookie, reg, value);
363 	dev->reg_cache[reg] = value;
364 }
365 
366 
367 uint16
ac97_reg_cached_read(ac97_dev * dev,uint8 reg)368 ac97_reg_cached_read(ac97_dev *dev, uint8 reg)
369 {
370 	if (!ac97_reg_is_valid(dev, reg))
371 		return 0;
372 	return dev->reg_cache[reg];
373 }
374 
375 void
ac97_reg_uncached_write(ac97_dev * dev,uint8 reg,uint16 value)376 ac97_reg_uncached_write(ac97_dev *dev, uint8 reg, uint16 value)
377 {
378 	if (!ac97_reg_is_valid(dev, reg))
379 		return;
380 	dev->reg_write(dev->cookie, reg, value);
381 }
382 
383 
384 uint16
ac97_reg_uncached_read(ac97_dev * dev,uint8 reg)385 ac97_reg_uncached_read(ac97_dev *dev, uint8 reg)
386 {
387 	if (!ac97_reg_is_valid(dev, reg))
388 		return 0;
389 	return dev->reg_read(dev->cookie, reg);
390 }
391 
392 
393 bool
ac97_reg_update(ac97_dev * dev,uint8 reg,uint16 value)394 ac97_reg_update(ac97_dev *dev, uint8 reg, uint16 value)
395 {
396 	if (!ac97_reg_is_valid(dev, reg))
397 		return false;
398 	if (ac97_reg_cached_read(dev, reg) == value)
399 		return false;
400 	ac97_reg_cached_write(dev, reg, value);
401 	return true;
402 }
403 
404 
405 bool
ac97_reg_update_bits(ac97_dev * dev,uint8 reg,uint16 mask,uint16 value)406 ac97_reg_update_bits(ac97_dev *dev, uint8 reg, uint16 mask, uint16 value)
407 {
408 	uint16 old;
409 	if (!ac97_reg_is_valid(dev, reg))
410 		return false;
411 	old = ac97_reg_cached_read(dev, reg);
412 	value &= mask;
413 	value |= (old & ~mask);
414 	if (old == value)
415 		return false;
416 	ac97_reg_cached_write(dev, reg, value);
417 	return true;
418 }
419 
420 
421 void
ac97_update_register_cache(ac97_dev * dev)422 ac97_update_register_cache(ac97_dev *dev)
423 {
424 	int reg;
425 	for (reg = 0; reg <= 0x7e; reg += 2)
426 		dev->reg_cache[reg] = ac97_reg_uncached_read(dev, reg);
427 }
428 
429 
430 bool
ac97_set_rate(ac97_dev * dev,uint8 reg,uint32 rate)431 ac97_set_rate(ac97_dev *dev, uint8 reg, uint32 rate)
432 {
433 	uint32 value;
434 	uint32 old;
435 
436 	if (dev->set_rate)
437 		return dev->set_rate(dev, reg, rate);
438 
439 	value = (uint32)((rate * 48000ULL) / dev->clock); /* need 64 bit calculation for rates 96000 or higher */
440 
441 	LOG(("ac97_set_rate: clock = %" B_PRIu32 ", "
442 		"rate = %" B_PRIu32 ", "
443 		"value = %" B_PRIu32 "\n",
444 		dev->clock, rate, value));
445 
446 	/* if double rate audio is currently enabled, divide value by 2 */
447 	if (ac97_reg_cached_read(dev, AC97_EXTENDED_STAT_CTRL) & 0x0002)
448 		value /= 2;
449 
450 	if (value < dev->min_vsr || value > dev->max_vsr)
451 		return false;
452 
453 	old = ac97_reg_cached_read(dev, reg);
454 	ac97_reg_cached_write(dev, reg, value);
455 	if (value != ac97_reg_uncached_read(dev, reg)) {
456 		LOG(("ac97_set_rate failed, new rate %d\n", ac97_reg_uncached_read(dev, reg)));
457 		ac97_reg_cached_write(dev, reg, old);
458 		return false;
459 	}
460 	LOG(("ac97_set_rate done\n"));
461 	return true;
462 }
463 
464 
465 bool
ac97_get_rate(ac97_dev * dev,uint8 reg,uint32 * rate)466 ac97_get_rate(ac97_dev *dev, uint8 reg, uint32 *rate)
467 {
468 	uint32 value;
469 
470 	if (dev->get_rate)
471 		return dev->get_rate(dev, reg, rate);
472 
473 	value = ac97_reg_cached_read(dev, reg);
474 	if (value == 0)
475 		return false;
476 
477 	/* if double rate audio is currently enabled, multiply value by 2 */
478 	if (ac97_reg_cached_read(dev, AC97_EXTENDED_STAT_CTRL) & 0x0002)
479 		value *= 2;
480 
481 	*rate = (uint32)((value * (uint64)dev->clock) / 48000); /* need 64 bit calculation to avoid overflow*/
482 	return true;
483 }
484 
485 
486 void
ac97_set_clock(ac97_dev * dev,uint32 clock)487 ac97_set_clock(ac97_dev *dev, uint32 clock)
488 {
489 	LOG(("ac97_set_clock: clock = %" B_PRIu32 "\n", clock));
490 	dev->clock = clock;
491 	ac97_detect_rates(dev);
492 	ac97_dump_capabilities(dev);
493 }
494 
495 
496 void
ac97_detect_capabilities(ac97_dev * dev)497 ac97_detect_capabilities(ac97_dev *dev)
498 {
499 	uint16 val;
500 
501 	val = ac97_reg_cached_read(dev, AC97_RESET);
502 	if (val & 0x0001)
503 		dev->capabilities |= CAP_PCM_MIC;
504 	if (val & 0x0004)
505 		dev->capabilities |= CAP_BASS_TREBLE_CTRL;
506 	if (val & 0x0008)
507 		dev->capabilities |= CAP_SIMULATED_STEREO;
508 	if (val & 0x0010)
509 		dev->capabilities |= CAP_HEADPHONE_OUT;
510 	if (val & 0x0020)
511 		dev->capabilities |= CAP_LAUDNESS;
512 	if (val & 0x0040)
513 		dev->capabilities |= CAP_DAC_18BIT;
514 	if (val & 0x0080)
515 		dev->capabilities |= CAP_DAC_20BIT;
516 	if (val & 0x0100)
517 		dev->capabilities |= CAP_ADC_18BIT;
518 	if (val & 0x0200)
519 		dev->capabilities |= CAP_ADC_20BIT;
520 	if (val & 0x7C00)
521 		dev->capabilities |= CAP_3D_ENHANCEMENT;
522 
523 	val = ac97_reg_cached_read(dev, AC97_EXTENDED_ID);
524 	if (val & EXID_VRA)
525 		dev->capabilities |= CAP_VARIABLE_PCM;
526 	if (val & EXID_DRA)
527 		dev->capabilities |= CAP_DOUBLE_PCM;
528 	if (val & EXID_SPDIF)
529 		dev->capabilities |= CAP_SPDIF;
530 	if (val & EXID_VRM)
531 		dev->capabilities |= CAP_VARIABLE_MIC;
532 	if (val & EXID_CDAC)
533 		dev->capabilities |= CAP_CENTER_DAC;
534 	if (val & EXID_SDAC)
535 		dev->capabilities |= CAP_SURR_DAC;
536 	if (val & EXID_LDAC)
537 		dev->capabilities |= CAP_LFE_DAC;
538 	if (val & EXID_AMAP)
539 		dev->capabilities |= CAP_AMAP;
540 	if ((val & (EXID_REV0 | EXID_REV1)) == 0)
541 		dev->capabilities |= CAP_REV21;
542 	if ((val & (EXID_REV0 | EXID_REV1)) == EXID_REV0)
543 		dev->capabilities |= CAP_REV22;
544 	if ((val & (EXID_REV0 | EXID_REV1)) == EXID_REV1)
545 		dev->capabilities |= CAP_REV23;
546 
547 	ac97_detect_rates(dev);
548 }
549 
550 void
ac97_detect_rates(ac97_dev * dev)551 ac97_detect_rates(ac97_dev *dev)
552 {
553 	uint32 oldrate;
554 
555 	dev->capabilities &= ~CAP_PCM_RATE_MASK;
556 
557 	if (!ac97_get_rate(dev, AC97_PCM_FRONT_DAC_RATE, &oldrate))
558 		oldrate = 48000;
559 
560 	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 20000))
561 		dev->capabilities |= CAP_PCM_RATE_CONTINUOUS;
562 	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 8000))
563 		dev->capabilities |= CAP_PCM_RATE_8000;
564 	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 11025))
565 		dev->capabilities |= CAP_PCM_RATE_11025;
566 	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 12000))
567 		dev->capabilities |= CAP_PCM_RATE_12000;
568 	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 16000))
569 		dev->capabilities |= CAP_PCM_RATE_16000;
570 	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 22050))
571 		dev->capabilities |= CAP_PCM_RATE_22050;
572 	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 24000))
573 		dev->capabilities |= CAP_PCM_RATE_24000;
574 	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 32000))
575 		dev->capabilities |= CAP_PCM_RATE_32000;
576 	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 44100))
577 		dev->capabilities |= CAP_PCM_RATE_44100;
578 	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 48000))
579 		dev->capabilities |= CAP_PCM_RATE_48000;
580 
581 	if (dev->capabilities & CAP_DOUBLE_PCM) {
582 		// enable double rate mode
583 		if (ac97_reg_update_bits(dev, AC97_EXTENDED_STAT_CTRL, 0x0002, 0x0002)) {
584 			if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 88200))
585 				dev->capabilities |= CAP_PCM_RATE_88200;
586 			if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 96000))
587 				dev->capabilities |= CAP_PCM_RATE_96000;
588 			// disable double rate mode
589 			ac97_reg_update_bits(dev, AC97_EXTENDED_STAT_CTRL, 0x0002, 0x0000);
590 		}
591 	}
592 
593 	ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, oldrate);
594 }
595 
596 
597 void
ac97_dump_capabilities(ac97_dev * dev)598 ac97_dump_capabilities(ac97_dev *dev)
599 {
600 	LOG(("AC97 capabilities:\n"));
601 	if (ac97_has_capability(dev, CAP_PCM_MIC))
602 		LOG(("CAP_PCM_MIC\n"));
603 	if (ac97_has_capability(dev, CAP_BASS_TREBLE_CTRL))
604 		LOG(("CAP_BASS_TREBLE_CTRL\n"));
605 	if (ac97_has_capability(dev, CAP_SIMULATED_STEREO))
606 		LOG(("CAP_SIMULATED_STEREO\n"));
607 	if (ac97_has_capability(dev, CAP_HEADPHONE_OUT))
608 		LOG(("CAP_HEADPHONE_OUT\n"));
609 	if (ac97_has_capability(dev, CAP_LAUDNESS))
610 		LOG(("CAP_LAUDNESS\n"));
611 	if (ac97_has_capability(dev, CAP_DAC_18BIT))
612 		LOG(("CAP_DAC_18BIT\n"));
613 	if (ac97_has_capability(dev, CAP_DAC_20BIT))
614 		LOG(("CAP_DAC_20BIT\n"));
615 	if (ac97_has_capability(dev, CAP_ADC_18BIT))
616 		LOG(("CAP_ADC_18BIT\n"));
617 	if (ac97_has_capability(dev, CAP_ADC_20BIT))
618 		LOG(("CAP_ADC_20BIT\n"));
619 	if (ac97_has_capability(dev, CAP_3D_ENHANCEMENT))
620 		LOG(("CAP_3D_ENHANCEMENT\n"));
621 	if (ac97_has_capability(dev, CAP_VARIABLE_PCM))
622 		LOG(("CAP_VARIABLE_PCM\n"));
623 	if (ac97_has_capability(dev, CAP_DOUBLE_PCM))
624 		LOG(("CAP_DOUBLE_PCM\n"));
625 	if (ac97_has_capability(dev, CAP_VARIABLE_MIC))
626 		LOG(("CAP_VARIABLE_MIC\n"));
627 	if (ac97_has_capability(dev, CAP_CENTER_DAC))
628 		LOG(("CAP_CENTER_DAC\n"));
629 	if (ac97_has_capability(dev, CAP_SURR_DAC))
630 		LOG(("CAP_SURR_DAC\n"));
631 	if (ac97_has_capability(dev, CAP_LFE_DAC))
632 		LOG(("CAP_LFE_DAC\n"));
633 	if (ac97_has_capability(dev, CAP_AMAP))
634 		LOG(("CAP_AMAP\n"));
635 	if (ac97_has_capability(dev, CAP_REV21))
636 		LOG(("CAP_REV21\n"));
637 	if (ac97_has_capability(dev, CAP_REV22))
638 		LOG(("CAP_REV22\n"));
639 	if (ac97_has_capability(dev, CAP_REV23))
640 		LOG(("CAP_REV23\n"));
641 	if (ac97_has_capability(dev, CAP_PCM_RATE_CONTINUOUS))
642 		LOG(("CAP_PCM_RATE_CONTINUOUS\n"));
643 	if (ac97_has_capability(dev, CAP_PCM_RATE_8000))
644 		LOG(("CAP_PCM_RATE_8000\n"));
645 	if (ac97_has_capability(dev, CAP_PCM_RATE_11025))
646 		LOG(("CAP_PCM_RATE_11025\n"));
647 	if (ac97_has_capability(dev, CAP_PCM_RATE_12000))
648 		LOG(("CAP_PCM_RATE_12000\n"));
649 	if (ac97_has_capability(dev, CAP_PCM_RATE_16000))
650 		LOG(("CAP_PCM_RATE_16000\n"));
651 	if (ac97_has_capability(dev, CAP_PCM_RATE_22050))
652 		LOG(("CAP_PCM_RATE_22050\n"));
653 	if (ac97_has_capability(dev, CAP_PCM_RATE_24000))
654 		LOG(("CAP_PCM_RATE_24000\n"));
655 	if (ac97_has_capability(dev, CAP_PCM_RATE_32000))
656 		LOG(("CAP_PCM_RATE_32000\n"));
657 	if (ac97_has_capability(dev, CAP_PCM_RATE_44100))
658 		LOG(("CAP_PCM_RATE_44100\n"));
659 	if (ac97_has_capability(dev, CAP_PCM_RATE_48000))
660 		LOG(("CAP_PCM_RATE_48000\n"));
661 	if (ac97_has_capability(dev, CAP_PCM_RATE_88200))
662 		LOG(("CAP_PCM_RATE_88200\n"));
663 	if (ac97_has_capability(dev, CAP_PCM_RATE_96000))
664 		LOG(("CAP_PCM_RATE_96000\n"));
665 }
666 
667 
668 bool
ac97_has_capability(ac97_dev * dev,uint64 cap)669 ac97_has_capability(ac97_dev *dev, uint64 cap)
670 {
671 	// return (dev->capabilities & cap); // does not work because of 64 bit to integer trucation
672 	return (dev->capabilities & cap) != 0;
673 }
674 
675 /*************************************************
676  * Codec specific initialization, etc.
677  */
678 
679 bool
ac97_reg_is_valid(ac97_dev * dev,uint8 reg)680 ac97_reg_is_valid(ac97_dev *dev, uint8 reg)
681 {
682 	if (reg & 1)
683 		return false;
684 	if (reg > 0x7e)
685 		return false;
686 
687 	switch (dev->codec_id) {
688 		case CODEC_ID_AK4540:
689 		case CODEC_ID_AK4542:
690 			if (reg < 0x1e || reg == 0x20 || reg == 0x26 || reg > 0x7a)
691 				return true;
692 			return false;
693 
694 		case CODEC_ID_AD1819:
695 		case CODEC_ID_AD1881:
696 		case CODEC_ID_AD1881A:
697 			if (reg < 0x3a || reg > 0x6e)
698 				return true;
699 			return false;
700 
701 		case CODEC_ID_AD1885:
702 		case CODEC_ID_AD1886:
703 		case CODEC_ID_AD1886A:
704 		case CODEC_ID_AD1887:
705 			if (reg < 0x3c || reg == 0x5a || reg > 0x6e)
706 				return true;
707 			return false;
708 
709 		case CODEC_ID_STAC9700:
710 		case CODEC_ID_STAC9704:
711 		case CODEC_ID_STAC9705:
712 		case CODEC_ID_STAC9708:
713 		case CODEC_ID_STAC9721:
714 		case CODEC_ID_STAC9744:
715 		case CODEC_ID_STAC9756:
716 			if (reg < 0x3c || reg > 0x58)
717 				return true;
718 			return false;
719 
720 		default:
721 			return true;
722 	}
723 }
724 
725 
726 void
ac97_amp_enable(ac97_dev * dev,bool yesno)727 ac97_amp_enable(ac97_dev *dev, bool yesno)
728 {
729 	switch (dev->codec_id) {
730 		case CODEC_ID_CS4299A:
731 		case CODEC_ID_CS4299C:
732 		case CODEC_ID_CS4299D:
733 			LOG(("cs4299_amp_enable\n"));
734 			if (yesno)
735 				ac97_reg_cached_write(dev, 0x68, 0x8004);
736 			else
737 				ac97_reg_cached_write(dev, 0x68, 0);
738 			break;
739 
740 		default:
741 			LOG(("ac97_amp_enable, reverse eamp = %d\n", dev->reversed_eamp_polarity));
742 			LOG(("powerdown register was = %#04x\n", ac97_reg_uncached_read(dev, AC97_POWERDOWN)));
743 			if (dev->reversed_eamp_polarity)
744 				yesno = !yesno;
745 			if (yesno)
746 				ac97_reg_cached_write(dev, AC97_POWERDOWN, ac97_reg_uncached_read(dev, AC97_POWERDOWN) & ~0x8000); /* switch on (low active) */
747 			else
748 				ac97_reg_cached_write(dev, AC97_POWERDOWN, ac97_reg_uncached_read(dev, AC97_POWERDOWN) | 0x8000); /* switch off */
749 			LOG(("powerdown register is = %#04x\n", ac97_reg_uncached_read(dev, AC97_POWERDOWN)));
750 		break;
751 	}
752 }
753 
754 
755 bool
ad1819_set_rate(ac97_dev * dev,uint8 reg,uint32 rate)756 ad1819_set_rate(ac97_dev *dev, uint8 reg, uint32 rate)
757 {
758 	uint32 value;
759 
760 	value = (uint32)((rate * 48000ULL) / dev->clock); /* need 64 bit calculation for rates 96000 or higher */
761 
762 	LOG(("ad1819_set_rate: clock = %" B_PRIu32 ", "
763 		"rate = %" B_PRIu32 ", "
764 		"value = %" B_PRIu32 "\n",
765 		dev->clock, rate, value));
766 
767 	if (value < 0x1B58 || value > 0xBB80)
768 		return false;
769 
770 	switch (reg) {
771 		case AC97_PCM_FRONT_DAC_RATE:
772 			ac97_reg_cached_write(dev, AC97_AD_SAMPLE_RATE_0, value);
773 			return true;
774 
775 		case AC97_PCM_L_R_ADC_RATE:
776 			ac97_reg_cached_write(dev, AC97_AD_SAMPLE_RATE_1, value);
777 			return true;
778 
779 		default:
780 			return false;
781 	}
782 }
783 
784 
785 bool
ad1819_get_rate(ac97_dev * dev,uint8 reg,uint32 * rate)786 ad1819_get_rate(ac97_dev *dev, uint8 reg, uint32 *rate)
787 {
788 	uint32 value;
789 
790 	switch (reg) {
791 		case AC97_PCM_FRONT_DAC_RATE:
792 			value = ac97_reg_cached_read(dev, AC97_AD_SAMPLE_RATE_0);
793 			break;
794 
795 		case AC97_PCM_L_R_ADC_RATE:
796 			value = ac97_reg_cached_read(dev, AC97_AD_SAMPLE_RATE_1);
797 			break;
798 
799 		default:
800 			return false;
801 	}
802 
803 	*rate = (uint32)((value * (uint64)dev->clock) / 48000); /* need 64 bit calculation to avoid overflow*/
804 	return true;
805 }
806 
807 
808 void
default_init(ac97_dev * dev)809 default_init(ac97_dev *dev)
810 {
811 	LOG(("default_init\n"));
812 }
813 
814 
815 void
ad1819_init(ac97_dev * dev)816 ad1819_init(ac97_dev *dev)
817 {
818 	LOG(("ad1819_init\n"));
819 
820 	/* Default config for system with single AD1819 codec */
821 	ac97_reg_cached_write(dev, AC97_AD_SERIAL_CONFIG, 0x7000);
822 	ac97_update_register_cache(dev);
823 
824 	/* The AD1819 chip has proprietary  sample rate controls
825 	 * Setup sample rate 0 generator for DAC,
826 	 * Setup sample rate 1 generator for ADC,
827 	 * ARSR=1, DRSR=0, ALSR=1, DLSR=0
828 	 */
829 	ac97_reg_cached_write(dev, AC97_AD_MISC_CONTROL, 0x0101);
830 	/* connect special rate set/get functions */
831 	dev->set_rate = ad1819_set_rate;
832 	dev->get_rate = ad1819_get_rate;
833 	ac97_detect_rates(dev);
834 	ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 48000);
835 	ac97_set_rate(dev, AC97_PCM_L_R_ADC_RATE, 48000);
836 }
837 
838 
839 void
ad1881_init(ac97_dev * dev)840 ad1881_init(ac97_dev *dev)
841 {
842 	LOG(("ad1881_init\n"));
843 
844 	/* Default config for system with single AD1819 codec,
845 	 * BROKEN on systems with master & slave codecs */
846 	ac97_reg_cached_write(dev, AC97_AD_SERIAL_CONFIG, 0x7000);
847 	ac97_update_register_cache(dev);
848 
849 	/* Setup DAC and ADC rate generator assignments compatible with AC97 */
850 	ac97_reg_cached_write(dev, AC97_AD_MISC_CONTROL, 0x0404);
851 
852 	/* Setup variable frame rate limits */
853 	dev->min_vsr = 0x1B58;	/*  7kHz */
854 	dev->max_vsr = 0xBB80;	/* 48kHz */
855 }
856 
857 
858 void
ad1885_init(ac97_dev * dev)859 ad1885_init(ac97_dev *dev)
860 {
861 	LOG(("ad1885_init\n"));
862 	ad1881_init(dev);
863 
864 	/* disable jack sense 0 and 1 (JS0, JS1) to turn off automatic mute */
865 	ac97_reg_cached_write(dev, AC97_AD_JACK_SENSE, ac97_reg_cached_read(dev, AC97_AD_JACK_SENSE) | 0x0300);
866 }
867 
868 
869 void
ad1886_init(ac97_dev * dev)870 ad1886_init(ac97_dev *dev)
871 {
872 	LOG(("ad1886_init\n"));
873 	ad1881_init(dev);
874 
875 	/* change jack sense to always activate outputs*/
876 	ac97_reg_cached_write(dev, AC97_AD_JACK_SENSE, 0x0010);
877 	/* change SPDIF to a valid value */
878 	ac97_reg_cached_write(dev, AC97_SPDIF_CONTROL, 0x2a20);
879 }
880 
881 
882 void
ad1980_init(ac97_dev * dev)883 ad1980_init(ac97_dev *dev)
884 {
885 	LOG(("ad1980_init\n"));
886 
887 	/* Select only master codec,
888 	 * SPDIF and DAC are linked
889 	 */
890 	ac97_reg_cached_write(dev, AC97_AD_SERIAL_CONFIG, 0x1001);
891 	ac97_update_register_cache(dev);
892 
893 	/* Select Line-out driven with mixer data (not surround data)
894 	 * Select Headphone-out driven with mixer data (not surround data),
895 	 * LOSEL = 0, HPSEL = 1
896 	 * XXX this one needs to be changed to support surround	out
897 	 */
898 	ac97_reg_cached_write(dev, AC97_AD_MISC_CONTROL, 0x0400);
899 }
900 
901 
902 void
ad1981b_init(ac97_dev * dev)903 ad1981b_init(ac97_dev *dev)
904 {
905 	LOG(("ad1981b_init\n"));
906 	if (dev->subsystem == 0x0e11005a
907 		|| dev->subsystem == 0x103c006d
908 		|| dev->subsystem == 0x103c088c
909 		|| dev->subsystem == 0x103c0890
910 		|| dev->subsystem == 0x103c0934
911 		|| dev->subsystem == 0x103c0938
912 		|| dev->subsystem == 0x103c0944
913 		|| dev->subsystem == 0x103c099c
914 		|| dev->subsystem == 0x101402d9) {
915 		ac97_reg_cached_write(dev, AC97_AD_JACK_SENSE,
916 				ac97_reg_cached_read(dev, AC97_AD_JACK_SENSE) | 0x0800);
917 	}
918 }
919 
920 
921 void
alc203_init(ac97_dev * dev)922 alc203_init(ac97_dev *dev)
923 {
924 	LOG(("alc203_init\n"));
925 
926 	ac97_reg_update_bits(dev, AC97_ALC650_CLOCK_SOURCE, 0x400, 0x400);
927 }
928 
929 
930 void
alc650_init(ac97_dev * dev)931 alc650_init(ac97_dev *dev)
932 {
933 	LOG(("alc650_init\n"));
934 
935 	/* Enable Surround, LFE and Center downmix into Line-out,
936 	 * Set Surround-out as duplicated Line-out.
937 	 */
938 	ac97_reg_cached_write(dev, AC97_ALC650_MULTI_CHAN_CTRL, 0x0007);
939 
940 	/* Set Surround DAC Volume to 0dB
941 	 * Set Center/LFE DAC Volume to 0dB
942 	 * (but both should already be set, as these are hardware reset defaults)
943 	 */
944 	ac97_reg_cached_write(dev, AC97_ALC650_SURR_VOLUME, 0x0808);
945 	ac97_reg_cached_write(dev, AC97_ALC650_CEN_LFE_VOLUME, 0x0808);
946 }
947 
948 
949 void
alc655_init(ac97_dev * dev)950 alc655_init(ac97_dev *dev)
951 {
952 	uint16 val;
953 	LOG(("alc655_init\n"));
954 
955 	ac97_reg_update_bits(dev, AC97_PAGING, 0xf, 0);
956 
957 	val = ac97_reg_cached_read(dev, AC97_ALC650_CLOCK_SOURCE);
958 	// TODO update bits for specific devices
959 	val &= ~0x1000;
960 	ac97_reg_cached_write(dev, AC97_ALC650_CLOCK_SOURCE, val);
961 
962 	ac97_reg_cached_write(dev, AC97_ALC650_MULTI_CHAN_CTRL, 0x8000);
963 	ac97_reg_cached_write(dev, AC97_ALC650_SURR_VOLUME, 0x808);
964 	ac97_reg_cached_write(dev, AC97_ALC650_CEN_LFE_VOLUME, 0x808);
965 
966 	if (dev->codec_id == 0x414c4781)
967 		ac97_reg_update_bits(dev, AC97_ALC650_MISC_CONTROL, 0x800, 0x800);
968 }
969 
970 
971 void
alc850_init(ac97_dev * dev)972 alc850_init(ac97_dev *dev)
973 {
974 	LOG(("alc850_init\n"));
975 
976 	ac97_reg_update_bits(dev, AC97_PAGING, 0xf, 0);
977 
978 	ac97_reg_cached_write(dev, AC97_ALC650_MULTI_CHAN_CTRL, 0x8000);
979 	ac97_reg_cached_write(dev, AC97_ALC650_CLOCK_SOURCE, 0x20d2);
980 	ac97_reg_cached_write(dev, AC97_ALC650_GPIO_SETUP, 0x8a90);
981 	ac97_reg_cached_write(dev, AC97_ALC650_SURR_VOLUME, 0x808);
982 	ac97_reg_cached_write(dev, AC97_ALC650_CEN_LFE_VOLUME, 0x808);
983 }
984 
985 
986 void
stac9708_init(ac97_dev * dev)987 stac9708_init(ac97_dev *dev)
988 {
989 	LOG(("stac9708_init\n"));
990 	/* ALSA initializes some registers that according to the
991 	 * documentation for this codec do not exist. If the
992 	 * following doesn't work, we may need to do that, too.
993 	 */
994 	/* The Analog Special reg is at 0x6C, other codecs have it at 0x6E */
995 	/* Set Analog Special to default (DAC/ADC -6dB disabled) */
996 	ac97_reg_cached_write(dev, 0x6C, 0x0000);
997 	/* Set Multi Channel to default */
998 	ac97_reg_cached_write(dev, 0x74, 0x0000);
999 }
1000 
1001 
1002 void
stac9721_init(ac97_dev * dev)1003 stac9721_init(ac97_dev *dev)
1004 {
1005 	LOG(("stac9721_init\n"));
1006 	/* Set Analog Special to default (DAC/ADC -6dB disabled) */
1007 	ac97_reg_cached_write(dev, 0x6E, 0x0000);
1008 	/* Enable register 0x72 */
1009 	ac97_reg_cached_write(dev, 0x70, 0xabba);
1010 	/* Set Analog Current to -50% */
1011 	ac97_reg_cached_write(dev, 0x72, 0x0002);
1012 	/* Set Multi Channel to default */
1013 	ac97_reg_cached_write(dev, 0x74, 0x0000);
1014 	/* Enable register 0x78 */
1015 	ac97_reg_cached_write(dev, 0x76, 0xabba);
1016 	/* Set Clock Access to default */
1017 	ac97_reg_cached_write(dev, 0x78, 0x0000);
1018 }
1019 
1020 
1021 void
stac9744_init(ac97_dev * dev)1022 stac9744_init(ac97_dev *dev)
1023 {
1024 	LOG(("stac9744_init\n"));
1025 	/* Set Analog Special to default (DAC/ADC -6dB disabled) */
1026 	ac97_reg_cached_write(dev, 0x6E, 0x0000);
1027 	/* Enable register 0x72 */
1028 	ac97_reg_cached_write(dev, 0x70, 0xabba);
1029 	/* Set Analog Current to -50% */
1030 	ac97_reg_cached_write(dev, 0x72, 0x0002);
1031 	/* Set Multi Channel to default */
1032 	ac97_reg_cached_write(dev, 0x74, 0x0000);
1033 	/* Enable register 0x78 */
1034 	ac97_reg_cached_write(dev, 0x76, 0xabba);
1035 	/* Set Clock Access to default */
1036 	ac97_reg_cached_write(dev, 0x78, 0x0000);
1037 }
1038 
1039 
1040 void
stac9756_init(ac97_dev * dev)1041 stac9756_init(ac97_dev *dev)
1042 {
1043 	LOG(("stac9756_init\n"));
1044 	/* Set Analog Special to default (AC97 all-mix, DAC/ADC -6dB disabled) */
1045 	ac97_reg_cached_write(dev, 0x6E, 0x1000);
1046 	/* Enable register 0x72 */
1047 	ac97_reg_cached_write(dev, 0x70, 0xabba);
1048 	/* Set Analog Current to -50% */
1049 	ac97_reg_cached_write(dev, 0x72, 0x0002);
1050 	/* Set Multi Channel to default */
1051 	ac97_reg_cached_write(dev, 0x74, 0x0000);
1052 	/* Enable register 0x78 */
1053 	ac97_reg_cached_write(dev, 0x76, 0xabba);
1054 	/* Set Clock Access to default */
1055 	ac97_reg_cached_write(dev, 0x78, 0x0000);
1056 }
1057 
1058 
1059 
1060 void
stac9758_init(ac97_dev * dev)1061 stac9758_init(ac97_dev *dev)
1062 {
1063 	LOG(("stac9758_init\n"));
1064 
1065 	ac97_reg_update_bits(dev, AC97_PAGING, 0xf, 0);
1066 
1067 	if (dev->subsystem == 0x107b0601) {
1068 		ac97_reg_cached_write(dev, 0x64, 0xfc70);
1069 		ac97_reg_cached_write(dev, 0x68, 0x2102);
1070 		ac97_reg_cached_write(dev, 0x66, 0x0203);
1071 		ac97_reg_cached_write(dev, 0x72, 0x0041);
1072 	} else {
1073 		ac97_reg_cached_write(dev, 0x64, 0xd794);
1074 		ac97_reg_cached_write(dev, 0x68, 0x2001);
1075 		ac97_reg_cached_write(dev, 0x66, 0x0201);
1076 		ac97_reg_cached_write(dev, 0x72, 0x0040);
1077 	}
1078 }
1079 
1080 
1081 void
tr28028_init(ac97_dev * dev)1082 tr28028_init(ac97_dev *dev)
1083 {
1084 	LOG(("tr28028_init\n"));
1085 	ac97_reg_cached_write(dev, AC97_POWERDOWN, 0x0300);
1086 	ac97_reg_cached_write(dev, AC97_POWERDOWN, 0x0000);
1087 	ac97_reg_cached_write(dev, AC97_SURR_VOLUME, 0x0000);
1088 	ac97_reg_cached_write(dev, AC97_SPDIF_CONTROL, 0x0000);
1089 }
1090 
1091 
1092 void
wm9701_init(ac97_dev * dev)1093 wm9701_init(ac97_dev *dev)
1094 {
1095 	LOG(("wm9701_init\n"));
1096 	/* ALSA writes some of these registers, but the codec
1097 	 * documentation states explicitly that 0x38 and 0x70 to 0x74
1098 	 * are not used in the WM9701A
1099 	 */
1100 
1101 	/* DVD noise patch (?) */
1102 	ac97_reg_cached_write(dev, 0x5a, 0x0200);
1103 }
1104 
1105 
1106 void
wm9703_init(ac97_dev * dev)1107 wm9703_init(ac97_dev *dev)
1108 {
1109 	LOG(("wm9703_init\n"));
1110 	/* Set front mixer value to unmuted */
1111 	ac97_reg_cached_write(dev, 0x72, 0x0808);
1112 	/* Disable loopback, etc */
1113 	ac97_reg_cached_write(dev, AC97_GENERAL_PURPOSE, 0x8000);
1114 }
1115 
1116 
1117 void
wm9704_init(ac97_dev * dev)1118 wm9704_init(ac97_dev *dev)
1119 {
1120 	LOG(("wm9704_init\n"));
1121 	/* Set read DAC value to unmuted */
1122 	ac97_reg_cached_write(dev, 0x70, 0x0808);
1123 	/* Set front mixer value to unmuted */
1124 	ac97_reg_cached_write(dev, 0x72, 0x0808);
1125 	/* Set rear mixer value to unmuted */
1126 	ac97_reg_cached_write(dev, 0x74, 0x0808);
1127 	/* DVD noise patch (?) */
1128 	ac97_reg_cached_write(dev, 0x5a, 0x0200);
1129 }
1130 
1131 
1132 const ac97_source_info source_info[] = {
1133 	{ "Recording", B_MIX_GAIN|B_MIX_MUTE|B_MIX_STEREO|B_MIX_RECORDMUX, 100, AC97_RECORD_GAIN, 0x8000, 4, 0, 1, 0, 0.0, 22.5, 1.5 },
1134 	{ "Master", B_MIX_GAIN|B_MIX_MUTE|B_MIX_STEREO, 101, AC97_MASTER_VOLUME, 0x8000, 5, 0, 1, 1,-46.5, 0.0, 1.5 },
1135 	//{ "Bass/Treble", B_MIX_GAIN|B_MIX_STEREO, 102, AC97_MASTER_TONE, 0x0f0f, 4, 0, 1, 1,-12.0, 10.5, 1.5 },
1136 	//{ "Aux out", B_MIX_GAIN|B_MIX_MUTE|B_MIX_STEREO, 103, AC97_AUX_OUT_VOLUME, 0x8000, 5, 0, 1, 1,-46.5, 0.0, 1.5 },
1137 	{ "PCM out", B_MIX_GAIN|B_MIX_MUTE|B_MIX_STEREO, 104, AC97_PCM_OUT_VOLUME, 0x8808, 5, 0, 1, 1,-34.5, 12.0, 1.5 },
1138 	{ "CD", B_MIX_GAIN|B_MIX_MUTE|B_MIX_STEREO, 105, AC97_CD_VOLUME, 0x8808, 5, 0, 1, 1,-34.5, 12.0, 1.5 },
1139 	{ "Aux In", B_MIX_GAIN|B_MIX_MUTE|B_MIX_STEREO, 106, AC97_AUX_IN_VOLUME, 0x8808, 5, 0, 1, 1,-34.5, 12.0, 1.5 },
1140 	{ "TAD", B_MIX_GAIN|B_MIX_MUTE|B_MIX_MONO, 107, AC97_PHONE_VOLUME, 0x8008, 5, 0, 1, 1,-34.5, 12.0, 1.5 },
1141 	{ "Mic", B_MIX_GAIN|B_MIX_MUTE|B_MIX_MONO|B_MIX_MICBOOST, 108, AC97_MIC_VOLUME, 0x8008, 5, 0, 1, 1,-34.5, 12.0, 1.5 },
1142 	{ "Line in", B_MIX_GAIN|B_MIX_MUTE|B_MIX_STEREO, 109, AC97_LINE_IN_VOLUME, 0x8808, 5, 0, 1, 1,-34.5, 12.0, 1.5 },
1143 	//{ "Center/Lfe", B_MIX_GAIN|B_MIX_MUTE|B_MIX_STEREO, 111, AC97_CENTER_LFE_VOLUME, 0x8080, 5, 0, 1, 1,-46.5, 0.0, 1.5 },
1144 	{ "Center/Lfe" /* should be "Surround" but no */, B_MIX_GAIN|B_MIX_MUTE|B_MIX_STEREO, 110, AC97_SURR_VOLUME, 0x8080, 5, 0, 1, 1,-46.5, 0.0, 1.5 }
1145 };
1146 
1147 const int32 source_info_size = (sizeof(source_info)/sizeof(source_info[0]));
1148