xref: /haiku/src/add-ons/kernel/drivers/audio/ac97/ac97.c (revision 4e3137c085bae361922078f123dceb92da700640)
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 *
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
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      = %#08lx\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
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
344 ac97_suspend(ac97_dev *dev)
345 {
346 	ac97_amp_enable(dev, false);
347 }
348 
349 
350 void
351 ac97_resume(ac97_dev *dev)
352 {
353 	ac97_amp_enable(dev, true);
354 }
355 
356 
357 void
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
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
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
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
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
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
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
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 = %ld, rate = %ld, value = %ld\n", dev->clock, rate, value));
442 
443 	/* if double rate audio is currently enabled, divide value by 2 */
444 	if (ac97_reg_cached_read(dev, AC97_EXTENDED_STAT_CTRL) & 0x0002)
445 		value /= 2;
446 
447 	if (value < dev->min_vsr || value > dev->max_vsr)
448 		return false;
449 
450 	old = ac97_reg_cached_read(dev, reg);
451 	ac97_reg_cached_write(dev, reg, value);
452 	if (value != ac97_reg_uncached_read(dev, reg)) {
453 		LOG(("ac97_set_rate failed, new rate %d\n", ac97_reg_uncached_read(dev, reg)));
454 		ac97_reg_cached_write(dev, reg, old);
455 		return false;
456 	}
457 	LOG(("ac97_set_rate done\n"));
458 	return true;
459 }
460 
461 
462 bool
463 ac97_get_rate(ac97_dev *dev, uint8 reg, uint32 *rate)
464 {
465 	uint32 value;
466 
467 	if (dev->get_rate)
468 		return dev->get_rate(dev, reg, rate);
469 
470 	value = ac97_reg_cached_read(dev, reg);
471 	if (value == 0)
472 		return false;
473 
474 	/* if double rate audio is currently enabled, multiply value by 2 */
475 	if (ac97_reg_cached_read(dev, AC97_EXTENDED_STAT_CTRL) & 0x0002)
476 		value *= 2;
477 
478 	*rate = (uint32)((value * (uint64)dev->clock) / 48000); /* need 64 bit calculation to avoid overflow*/
479 	return true;
480 }
481 
482 
483 void
484 ac97_set_clock(ac97_dev *dev, uint32 clock)
485 {
486 	LOG(("ac97_set_clock: clock = %ld\n", clock));
487 	dev->clock = clock;
488 	ac97_detect_rates(dev);
489 	ac97_dump_capabilities(dev);
490 }
491 
492 
493 void
494 ac97_detect_capabilities(ac97_dev *dev)
495 {
496 	uint16 val;
497 
498 	val = ac97_reg_cached_read(dev, AC97_RESET);
499 	if (val & 0x0001)
500 		dev->capabilities |= CAP_PCM_MIC;
501 	if (val & 0x0004)
502 		dev->capabilities |= CAP_BASS_TREBLE_CTRL;
503 	if (val & 0x0008)
504 		dev->capabilities |= CAP_SIMULATED_STEREO;
505 	if (val & 0x0010)
506 		dev->capabilities |= CAP_HEADPHONE_OUT;
507 	if (val & 0x0020)
508 		dev->capabilities |= CAP_LAUDNESS;
509 	if (val & 0x0040)
510 		dev->capabilities |= CAP_DAC_18BIT;
511 	if (val & 0x0080)
512 		dev->capabilities |= CAP_DAC_20BIT;
513 	if (val & 0x0100)
514 		dev->capabilities |= CAP_ADC_18BIT;
515 	if (val & 0x0200)
516 		dev->capabilities |= CAP_ADC_20BIT;
517 	if (val & 0x7C00)
518 		dev->capabilities |= CAP_3D_ENHANCEMENT;
519 
520 	val = ac97_reg_cached_read(dev, AC97_EXTENDED_ID);
521 	if (val & EXID_VRA)
522 		dev->capabilities |= CAP_VARIABLE_PCM;
523 	if (val & EXID_DRA)
524 		dev->capabilities |= CAP_DOUBLE_PCM;
525 	if (val & EXID_SPDIF)
526 		dev->capabilities |= CAP_SPDIF;
527 	if (val & EXID_VRM)
528 		dev->capabilities |= CAP_VARIABLE_MIC;
529 	if (val & EXID_CDAC)
530 		dev->capabilities |= CAP_CENTER_DAC;
531 	if (val & EXID_SDAC)
532 		dev->capabilities |= CAP_SURR_DAC;
533 	if (val & EXID_LDAC)
534 		dev->capabilities |= CAP_LFE_DAC;
535 	if (val & EXID_AMAP)
536 		dev->capabilities |= CAP_AMAP;
537 	if ((val & (EXID_REV0 | EXID_REV1)) == 0)
538 		dev->capabilities |= CAP_REV21;
539 	if ((val & (EXID_REV0 | EXID_REV1)) == EXID_REV0)
540 		dev->capabilities |= CAP_REV22;
541 	if ((val & (EXID_REV0 | EXID_REV1)) == EXID_REV1)
542 		dev->capabilities |= CAP_REV23;
543 
544 	ac97_detect_rates(dev);
545 }
546 
547 void
548 ac97_detect_rates(ac97_dev *dev)
549 {
550 	uint32 oldrate;
551 
552 	dev->capabilities &= ~CAP_PCM_RATE_MASK;
553 
554 	if (!ac97_get_rate(dev, AC97_PCM_FRONT_DAC_RATE, &oldrate))
555 		oldrate = 48000;
556 
557 	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 20000))
558 		dev->capabilities |= CAP_PCM_RATE_CONTINUOUS;
559 	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 8000))
560 		dev->capabilities |= CAP_PCM_RATE_8000;
561 	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 11025))
562 		dev->capabilities |= CAP_PCM_RATE_11025;
563 	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 12000))
564 		dev->capabilities |= CAP_PCM_RATE_12000;
565 	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 16000))
566 		dev->capabilities |= CAP_PCM_RATE_16000;
567 	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 22050))
568 		dev->capabilities |= CAP_PCM_RATE_22050;
569 	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 24000))
570 		dev->capabilities |= CAP_PCM_RATE_24000;
571 	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 32000))
572 		dev->capabilities |= CAP_PCM_RATE_32000;
573 	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 44100))
574 		dev->capabilities |= CAP_PCM_RATE_44100;
575 	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 48000))
576 		dev->capabilities |= CAP_PCM_RATE_48000;
577 
578 	if (dev->capabilities & CAP_DOUBLE_PCM) {
579 		// enable double rate mode
580 		if (ac97_reg_update_bits(dev, AC97_EXTENDED_STAT_CTRL, 0x0002, 0x0002)) {
581 			if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 88200))
582 				dev->capabilities |= CAP_PCM_RATE_88200;
583 			if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 96000))
584 				dev->capabilities |= CAP_PCM_RATE_96000;
585 			// disable double rate mode
586 			ac97_reg_update_bits(dev, AC97_EXTENDED_STAT_CTRL, 0x0002, 0x0000);
587 		}
588 	}
589 
590 	ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, oldrate);
591 }
592 
593 
594 void
595 ac97_dump_capabilities(ac97_dev *dev)
596 {
597 	LOG(("AC97 capabilities:\n"));
598 	if (ac97_has_capability(dev, CAP_PCM_MIC))
599 		LOG(("CAP_PCM_MIC\n"));
600 	if (ac97_has_capability(dev, CAP_BASS_TREBLE_CTRL))
601 		LOG(("CAP_BASS_TREBLE_CTRL\n"));
602 	if (ac97_has_capability(dev, CAP_SIMULATED_STEREO))
603 		LOG(("CAP_SIMULATED_STEREO\n"));
604 	if (ac97_has_capability(dev, CAP_HEADPHONE_OUT))
605 		LOG(("CAP_HEADPHONE_OUT\n"));
606 	if (ac97_has_capability(dev, CAP_LAUDNESS))
607 		LOG(("CAP_LAUDNESS\n"));
608 	if (ac97_has_capability(dev, CAP_DAC_18BIT))
609 		LOG(("CAP_DAC_18BIT\n"));
610 	if (ac97_has_capability(dev, CAP_DAC_20BIT))
611 		LOG(("CAP_DAC_20BIT\n"));
612 	if (ac97_has_capability(dev, CAP_ADC_18BIT))
613 		LOG(("CAP_ADC_18BIT\n"));
614 	if (ac97_has_capability(dev, CAP_ADC_20BIT))
615 		LOG(("CAP_ADC_20BIT\n"));
616 	if (ac97_has_capability(dev, CAP_3D_ENHANCEMENT))
617 		LOG(("CAP_3D_ENHANCEMENT\n"));
618 	if (ac97_has_capability(dev, CAP_VARIABLE_PCM))
619 		LOG(("CAP_VARIABLE_PCM\n"));
620 	if (ac97_has_capability(dev, CAP_DOUBLE_PCM))
621 		LOG(("CAP_DOUBLE_PCM\n"));
622 	if (ac97_has_capability(dev, CAP_VARIABLE_MIC))
623 		LOG(("CAP_VARIABLE_MIC\n"));
624 	if (ac97_has_capability(dev, CAP_CENTER_DAC))
625 		LOG(("CAP_CENTER_DAC\n"));
626 	if (ac97_has_capability(dev, CAP_SURR_DAC))
627 		LOG(("CAP_SURR_DAC\n"));
628 	if (ac97_has_capability(dev, CAP_LFE_DAC))
629 		LOG(("CAP_LFE_DAC\n"));
630 	if (ac97_has_capability(dev, CAP_AMAP))
631 		LOG(("CAP_AMAP\n"));
632 	if (ac97_has_capability(dev, CAP_REV21))
633 		LOG(("CAP_REV21\n"));
634 	if (ac97_has_capability(dev, CAP_REV22))
635 		LOG(("CAP_REV22\n"));
636 	if (ac97_has_capability(dev, CAP_REV23))
637 		LOG(("CAP_REV23\n"));
638 	if (ac97_has_capability(dev, CAP_PCM_RATE_CONTINUOUS))
639 		LOG(("CAP_PCM_RATE_CONTINUOUS\n"));
640 	if (ac97_has_capability(dev, CAP_PCM_RATE_8000))
641 		LOG(("CAP_PCM_RATE_8000\n"));
642 	if (ac97_has_capability(dev, CAP_PCM_RATE_11025))
643 		LOG(("CAP_PCM_RATE_11025\n"));
644 	if (ac97_has_capability(dev, CAP_PCM_RATE_12000))
645 		LOG(("CAP_PCM_RATE_12000\n"));
646 	if (ac97_has_capability(dev, CAP_PCM_RATE_16000))
647 		LOG(("CAP_PCM_RATE_16000\n"));
648 	if (ac97_has_capability(dev, CAP_PCM_RATE_22050))
649 		LOG(("CAP_PCM_RATE_22050\n"));
650 	if (ac97_has_capability(dev, CAP_PCM_RATE_24000))
651 		LOG(("CAP_PCM_RATE_24000\n"));
652 	if (ac97_has_capability(dev, CAP_PCM_RATE_32000))
653 		LOG(("CAP_PCM_RATE_32000\n"));
654 	if (ac97_has_capability(dev, CAP_PCM_RATE_44100))
655 		LOG(("CAP_PCM_RATE_44100\n"));
656 	if (ac97_has_capability(dev, CAP_PCM_RATE_48000))
657 		LOG(("CAP_PCM_RATE_48000\n"));
658 	if (ac97_has_capability(dev, CAP_PCM_RATE_88200))
659 		LOG(("CAP_PCM_RATE_88200\n"));
660 	if (ac97_has_capability(dev, CAP_PCM_RATE_96000))
661 		LOG(("CAP_PCM_RATE_96000\n"));
662 }
663 
664 
665 bool
666 ac97_has_capability(ac97_dev *dev, uint64 cap)
667 {
668 	// return (dev->capabilities & cap); // does not work because of 64 bit to integer trucation
669 	return (dev->capabilities & cap) != 0;
670 }
671 
672 /*************************************************
673  * Codec specific initialization, etc.
674  */
675 
676 bool
677 ac97_reg_is_valid(ac97_dev *dev, uint8 reg)
678 {
679 	if (reg & 1)
680 		return false;
681 	if (reg > 0x7e)
682 		return false;
683 
684 	switch (dev->codec_id) {
685 		case CODEC_ID_AK4540:
686 		case CODEC_ID_AK4542:
687 			if (reg < 0x1e || reg == 0x20 || reg == 0x26 || reg > 0x7a)
688 				return true;
689 			return false;
690 
691 		case CODEC_ID_AD1819:
692 		case CODEC_ID_AD1881:
693 		case CODEC_ID_AD1881A:
694 			if (reg < 0x3a || reg > 0x6e)
695 				return true;
696 			return false;
697 
698 		case CODEC_ID_AD1885:
699 		case CODEC_ID_AD1886:
700 		case CODEC_ID_AD1886A:
701 		case CODEC_ID_AD1887:
702 			if (reg < 0x3c || reg == 0x5a || reg > 0x6e)
703 				return true;
704 			return false;
705 
706 		case CODEC_ID_STAC9700:
707 		case CODEC_ID_STAC9704:
708 		case CODEC_ID_STAC9705:
709 		case CODEC_ID_STAC9708:
710 		case CODEC_ID_STAC9721:
711 		case CODEC_ID_STAC9744:
712 		case CODEC_ID_STAC9756:
713 			if (reg < 0x3c || reg > 0x58)
714 				return true;
715 			return false;
716 
717 		default:
718 			return true;
719 	}
720 }
721 
722 
723 void
724 ac97_amp_enable(ac97_dev *dev, bool yesno)
725 {
726 	switch (dev->codec_id) {
727 		case CODEC_ID_CS4299A:
728 		case CODEC_ID_CS4299C:
729 		case CODEC_ID_CS4299D:
730 			LOG(("cs4299_amp_enable\n"));
731 			if (yesno)
732 				ac97_reg_cached_write(dev, 0x68, 0x8004);
733 			else
734 				ac97_reg_cached_write(dev, 0x68, 0);
735 			break;
736 
737 		default:
738 			LOG(("ac97_amp_enable, reverse eamp = %d\n", dev->reversed_eamp_polarity));
739 			LOG(("powerdown register was = %#04x\n", ac97_reg_uncached_read(dev, AC97_POWERDOWN)));
740 			if (dev->reversed_eamp_polarity)
741 				yesno = !yesno;
742 			if (yesno)
743 				ac97_reg_cached_write(dev, AC97_POWERDOWN, ac97_reg_uncached_read(dev, AC97_POWERDOWN) & ~0x8000); /* switch on (low active) */
744 			else
745 				ac97_reg_cached_write(dev, AC97_POWERDOWN, ac97_reg_uncached_read(dev, AC97_POWERDOWN) | 0x8000); /* switch off */
746 			LOG(("powerdown register is = %#04x\n", ac97_reg_uncached_read(dev, AC97_POWERDOWN)));
747 		break;
748 	}
749 }
750 
751 
752 bool
753 ad1819_set_rate(ac97_dev *dev, uint8 reg, uint32 rate)
754 {
755 	uint32 value;
756 
757 	value = (uint32)((rate * 48000ULL) / dev->clock); /* need 64 bit calculation for rates 96000 or higher */
758 
759 	LOG(("ad1819_set_rate: clock = %ld, rate = %ld, value = %ld\n", dev->clock, rate, value));
760 
761 	if (value < 0x1B58 || value > 0xBB80)
762 		return false;
763 
764 	switch (reg) {
765 		case AC97_PCM_FRONT_DAC_RATE:
766 			ac97_reg_cached_write(dev, AC97_AD_SAMPLE_RATE_0, value);
767 			return true;
768 
769 		case AC97_PCM_L_R_ADC_RATE:
770 			ac97_reg_cached_write(dev, AC97_AD_SAMPLE_RATE_1, value);
771 			return true;
772 
773 		default:
774 			return false;
775 	}
776 }
777 
778 
779 bool
780 ad1819_get_rate(ac97_dev *dev, uint8 reg, uint32 *rate)
781 {
782 	uint32 value;
783 
784 	switch (reg) {
785 		case AC97_PCM_FRONT_DAC_RATE:
786 			value = ac97_reg_cached_read(dev, AC97_AD_SAMPLE_RATE_0);
787 			break;
788 
789 		case AC97_PCM_L_R_ADC_RATE:
790 			value = ac97_reg_cached_read(dev, AC97_AD_SAMPLE_RATE_1);
791 			break;
792 
793 		default:
794 			return false;
795 	}
796 
797 	*rate = (uint32)((value * (uint64)dev->clock) / 48000); /* need 64 bit calculation to avoid overflow*/
798 	return true;
799 }
800 
801 
802 void
803 default_init(ac97_dev *dev)
804 {
805 	LOG(("default_init\n"));
806 }
807 
808 
809 void
810 ad1819_init(ac97_dev *dev)
811 {
812 	LOG(("ad1819_init\n"));
813 
814 	/* Default config for system with single AD1819 codec */
815 	ac97_reg_cached_write(dev, AC97_AD_SERIAL_CONFIG, 0x7000);
816 	ac97_update_register_cache(dev);
817 
818 	/* The AD1819 chip has proprietary  sample rate controls
819 	 * Setup sample rate 0 generator for DAC,
820 	 * Setup sample rate 1 generator for ADC,
821 	 * ARSR=1, DRSR=0, ALSR=1, DLSR=0
822 	 */
823 	ac97_reg_cached_write(dev, AC97_AD_MISC_CONTROL, 0x0101);
824 	/* connect special rate set/get functions */
825 	dev->set_rate = ad1819_set_rate;
826 	dev->get_rate = ad1819_get_rate;
827 	ac97_detect_rates(dev);
828 	ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 48000);
829 	ac97_set_rate(dev, AC97_PCM_L_R_ADC_RATE, 48000);
830 }
831 
832 
833 void
834 ad1881_init(ac97_dev *dev)
835 {
836 	LOG(("ad1881_init\n"));
837 
838 	/* Default config for system with single AD1819 codec,
839 	 * BROKEN on systems with master & slave codecs */
840 	ac97_reg_cached_write(dev, AC97_AD_SERIAL_CONFIG, 0x7000);
841 	ac97_update_register_cache(dev);
842 
843 	/* Setup DAC and ADC rate generator assignments compatible with AC97 */
844 	ac97_reg_cached_write(dev, AC97_AD_MISC_CONTROL, 0x0404);
845 
846 	/* Setup variable frame rate limits */
847 	dev->min_vsr = 0x1B58;	/*  7kHz */
848 	dev->max_vsr = 0xBB80;	/* 48kHz */
849 }
850 
851 
852 void
853 ad1885_init(ac97_dev *dev)
854 {
855 	LOG(("ad1885_init\n"));
856 	ad1881_init(dev);
857 
858 	/* disable jack sense 0 and 1 (JS0, JS1) to turn off automatic mute */
859 	ac97_reg_cached_write(dev, AC97_AD_JACK_SENSE, ac97_reg_cached_read(dev, AC97_AD_JACK_SENSE) | 0x0300);
860 }
861 
862 
863 void
864 ad1886_init(ac97_dev *dev)
865 {
866 	LOG(("ad1886_init\n"));
867 	ad1881_init(dev);
868 
869 	/* change jack sense to always activate outputs*/
870 	ac97_reg_cached_write(dev, AC97_AD_JACK_SENSE, 0x0010);
871 	/* change SPDIF to a valid value */
872 	ac97_reg_cached_write(dev, AC97_SPDIF_CONTROL, 0x2a20);
873 }
874 
875 
876 void
877 ad1980_init(ac97_dev *dev)
878 {
879 	LOG(("ad1980_init\n"));
880 
881 	/* Select only master codec,
882 	 * SPDIF and DAC are linked
883 	 */
884 	ac97_reg_cached_write(dev, AC97_AD_SERIAL_CONFIG, 0x1001);
885 	ac97_update_register_cache(dev);
886 
887 	/* Select Line-out driven with mixer data (not surround data)
888 	 * Select Headphone-out driven with mixer data (not surround data),
889 	 * LOSEL = 0, HPSEL = 1
890 	 * XXX this one needs to be changed to support surround	out
891 	 */
892 	ac97_reg_cached_write(dev, AC97_AD_MISC_CONTROL, 0x0400);
893 }
894 
895 
896 void
897 ad1981b_init(ac97_dev *dev)
898 {
899 	LOG(("ad1981b_init\n"));
900 	if (dev->subsystem == 0x0e11005a
901 		|| dev->subsystem == 0x103c006d
902 		|| dev->subsystem == 0x103c088c
903 		|| dev->subsystem == 0x103c0890
904 		|| dev->subsystem == 0x103c0934
905 		|| dev->subsystem == 0x103c0938
906 		|| dev->subsystem == 0x103c0944
907 		|| dev->subsystem == 0x103c099c
908 		|| dev->subsystem == 0x101402d9) {
909 		ac97_reg_cached_write(dev, AC97_AD_JACK_SENSE,
910 				ac97_reg_cached_read(dev, AC97_AD_JACK_SENSE) | 0x0800);
911 	}
912 }
913 
914 
915 void
916 alc203_init(ac97_dev *dev)
917 {
918 	LOG(("alc203_init\n"));
919 
920 	ac97_reg_update_bits(dev, AC97_ALC650_CLOCK_SOURCE, 0x400, 0x400);
921 }
922 
923 
924 void
925 alc650_init(ac97_dev *dev)
926 {
927 	LOG(("alc650_init\n"));
928 
929 	/* Enable Surround, LFE and Center downmix into Line-out,
930 	 * Set Surround-out as duplicated Line-out.
931 	 */
932 	ac97_reg_cached_write(dev, AC97_ALC650_MULTI_CHAN_CTRL, 0x0007);
933 
934 	/* Set Surround DAC Volume to 0dB
935 	 * Set Center/LFE DAC Volume to 0dB
936 	 * (but both should already be set, as these are hardware reset defaults)
937 	 */
938 	ac97_reg_cached_write(dev, AC97_ALC650_SURR_VOLUME, 0x0808);
939 	ac97_reg_cached_write(dev, AC97_ALC650_CEN_LFE_VOLUME, 0x0808);
940 }
941 
942 
943 void
944 alc655_init(ac97_dev *dev)
945 {
946 	uint16 val;
947 	LOG(("alc655_init\n"));
948 
949 	ac97_reg_update_bits(dev, AC97_PAGING, 0xf, 0);
950 
951 	val = ac97_reg_cached_read(dev, AC97_ALC650_CLOCK_SOURCE);
952 	// TODO update bits for specific devices
953 	val &= ~0x1000;
954 	ac97_reg_cached_write(dev, AC97_ALC650_CLOCK_SOURCE, val);
955 
956 	ac97_reg_cached_write(dev, AC97_ALC650_MULTI_CHAN_CTRL, 0x8000);
957 	ac97_reg_cached_write(dev, AC97_ALC650_SURR_VOLUME, 0x808);
958 	ac97_reg_cached_write(dev, AC97_ALC650_CEN_LFE_VOLUME, 0x808);
959 
960 	if (dev->codec_id == 0x414c4781)
961 		ac97_reg_update_bits(dev, AC97_ALC650_MISC_CONTROL, 0x800, 0x800);
962 }
963 
964 
965 void
966 alc850_init(ac97_dev *dev)
967 {
968 	LOG(("alc850_init\n"));
969 
970 	ac97_reg_update_bits(dev, AC97_PAGING, 0xf, 0);
971 
972 	ac97_reg_cached_write(dev, AC97_ALC650_MULTI_CHAN_CTRL, 0x8000);
973 	ac97_reg_cached_write(dev, AC97_ALC650_CLOCK_SOURCE, 0x20d2);
974 	ac97_reg_cached_write(dev, AC97_ALC650_GPIO_SETUP, 0x8a90);
975 	ac97_reg_cached_write(dev, AC97_ALC650_SURR_VOLUME, 0x808);
976 	ac97_reg_cached_write(dev, AC97_ALC650_CEN_LFE_VOLUME, 0x808);
977 }
978 
979 
980 void
981 stac9708_init(ac97_dev *dev)
982 {
983 	LOG(("stac9708_init\n"));
984 	/* ALSA initializes some registers that according to the
985 	 * documentation for this codec do not exist. If the
986 	 * following doesn't work, we may need to do that, too.
987 	 */
988 	/* The Analog Special reg is at 0x6C, other codecs have it at 0x6E */
989 	/* Set Analog Special to default (DAC/ADC -6dB disabled) */
990 	ac97_reg_cached_write(dev, 0x6C, 0x0000);
991 	/* Set Multi Channel to default */
992 	ac97_reg_cached_write(dev, 0x74, 0x0000);
993 }
994 
995 
996 void
997 stac9721_init(ac97_dev *dev)
998 {
999 	LOG(("stac9721_init\n"));
1000 	/* Set Analog Special to default (DAC/ADC -6dB disabled) */
1001 	ac97_reg_cached_write(dev, 0x6E, 0x0000);
1002 	/* Enable register 0x72 */
1003 	ac97_reg_cached_write(dev, 0x70, 0xabba);
1004 	/* Set Analog Current to -50% */
1005 	ac97_reg_cached_write(dev, 0x72, 0x0002);
1006 	/* Set Multi Channel to default */
1007 	ac97_reg_cached_write(dev, 0x74, 0x0000);
1008 	/* Enable register 0x78 */
1009 	ac97_reg_cached_write(dev, 0x76, 0xabba);
1010 	/* Set Clock Access to default */
1011 	ac97_reg_cached_write(dev, 0x78, 0x0000);
1012 }
1013 
1014 
1015 void
1016 stac9744_init(ac97_dev *dev)
1017 {
1018 	LOG(("stac9744_init\n"));
1019 	/* Set Analog Special to default (DAC/ADC -6dB disabled) */
1020 	ac97_reg_cached_write(dev, 0x6E, 0x0000);
1021 	/* Enable register 0x72 */
1022 	ac97_reg_cached_write(dev, 0x70, 0xabba);
1023 	/* Set Analog Current to -50% */
1024 	ac97_reg_cached_write(dev, 0x72, 0x0002);
1025 	/* Set Multi Channel to default */
1026 	ac97_reg_cached_write(dev, 0x74, 0x0000);
1027 	/* Enable register 0x78 */
1028 	ac97_reg_cached_write(dev, 0x76, 0xabba);
1029 	/* Set Clock Access to default */
1030 	ac97_reg_cached_write(dev, 0x78, 0x0000);
1031 }
1032 
1033 
1034 void
1035 stac9756_init(ac97_dev *dev)
1036 {
1037 	LOG(("stac9756_init\n"));
1038 	/* Set Analog Special to default (AC97 all-mix, DAC/ADC -6dB disabled) */
1039 	ac97_reg_cached_write(dev, 0x6E, 0x1000);
1040 	/* Enable register 0x72 */
1041 	ac97_reg_cached_write(dev, 0x70, 0xabba);
1042 	/* Set Analog Current to -50% */
1043 	ac97_reg_cached_write(dev, 0x72, 0x0002);
1044 	/* Set Multi Channel to default */
1045 	ac97_reg_cached_write(dev, 0x74, 0x0000);
1046 	/* Enable register 0x78 */
1047 	ac97_reg_cached_write(dev, 0x76, 0xabba);
1048 	/* Set Clock Access to default */
1049 	ac97_reg_cached_write(dev, 0x78, 0x0000);
1050 }
1051 
1052 
1053 
1054 void
1055 stac9758_init(ac97_dev *dev)
1056 {
1057 	LOG(("stac9758_init\n"));
1058 
1059 	ac97_reg_update_bits(dev, AC97_PAGING, 0xf, 0);
1060 
1061 	if (dev->subsystem == 0x107b0601) {
1062 		ac97_reg_cached_write(dev, 0x64, 0xfc70);
1063 		ac97_reg_cached_write(dev, 0x68, 0x2102);
1064 		ac97_reg_cached_write(dev, 0x66, 0x0203);
1065 		ac97_reg_cached_write(dev, 0x72, 0x0041);
1066 	} else {
1067 		ac97_reg_cached_write(dev, 0x64, 0xd794);
1068 		ac97_reg_cached_write(dev, 0x68, 0x2001);
1069 		ac97_reg_cached_write(dev, 0x66, 0x0201);
1070 		ac97_reg_cached_write(dev, 0x72, 0x0040);
1071 	}
1072 }
1073 
1074 
1075 void
1076 tr28028_init(ac97_dev *dev)
1077 {
1078 	LOG(("tr28028_init\n"));
1079 	ac97_reg_cached_write(dev, AC97_POWERDOWN, 0x0300);
1080 	ac97_reg_cached_write(dev, AC97_POWERDOWN, 0x0000);
1081 	ac97_reg_cached_write(dev, AC97_SURR_VOLUME, 0x0000);
1082 	ac97_reg_cached_write(dev, AC97_SPDIF_CONTROL, 0x0000);
1083 }
1084 
1085 
1086 void
1087 wm9701_init(ac97_dev *dev)
1088 {
1089 	LOG(("wm9701_init\n"));
1090 	/* ALSA writes some of these registers, but the codec
1091 	 * documentation states explicitly that 0x38 and 0x70 to 0x74
1092 	 * are not used in the WM9701A
1093 	 */
1094 
1095 	/* DVD noise patch (?) */
1096 	ac97_reg_cached_write(dev, 0x5a, 0x0200);
1097 }
1098 
1099 
1100 void
1101 wm9703_init(ac97_dev *dev)
1102 {
1103 	LOG(("wm9703_init\n"));
1104 	/* Set front mixer value to unmuted */
1105 	ac97_reg_cached_write(dev, 0x72, 0x0808);
1106 	/* Disable loopback, etc */
1107 	ac97_reg_cached_write(dev, AC97_GENERAL_PURPOSE, 0x8000);
1108 }
1109 
1110 
1111 void
1112 wm9704_init(ac97_dev *dev)
1113 {
1114 	LOG(("wm9704_init\n"));
1115 	/* Set read DAC value to unmuted */
1116 	ac97_reg_cached_write(dev, 0x70, 0x0808);
1117 	/* Set front mixer value to unmuted */
1118 	ac97_reg_cached_write(dev, 0x72, 0x0808);
1119 	/* Set rear mixer value to unmuted */
1120 	ac97_reg_cached_write(dev, 0x74, 0x0808);
1121 	/* DVD noise patch (?) */
1122 	ac97_reg_cached_write(dev, 0x5a, 0x0200);
1123 }
1124 
1125 
1126 const ac97_source_info source_info[] = {
1127 	{ "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 },
1128 	{ "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 },
1129 	//{ "Bass/Treble", B_MIX_GAIN|B_MIX_STEREO, 102, AC97_MASTER_TONE, 0x0f0f, 4, 0, 1, 1,-12.0, 10.5, 1.5 },
1130 	//{ "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 },
1131 	{ "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 },
1132 	{ "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 },
1133 	{ "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 },
1134 	{ "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 },
1135 	{ "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 },
1136 	{ "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 },
1137 	//{ "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 },
1138 	{ "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 }
1139 };
1140 
1141 const int32 source_info_size = (sizeof(source_info)/sizeof(source_info[0]));
1142