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#include <OS.h>
29#include <stdio.h>
30#include <malloc.h>
31#include <MediaDefs.h>
32#include "ac97.h"
33#include "debug.h"
34
35#define B_UTF8_REGISTERED	"\xC2\xAE"
36
37bool ac97_reg_is_valid(ac97_dev *dev, uint8 reg);
38void ac97_amp_enable(ac97_dev *dev, bool onoff);
39void ac97_dump_capabilities(ac97_dev *dev);
40void ac97_detect_capabilities(ac97_dev *dev);
41void ac97_detect_rates(ac97_dev *dev);
42void ac97_update_register_cache(ac97_dev *dev);
43
44const char * stereo_enhancement_technique[] =
45{
46	"No 3D Stereo Enhancement",
47	"Analog Devices",
48	"Creative Technology",
49	"National Semiconductor",
50	"Yamaha",
51	"BBE Sound",
52	"Crystal Semiconductor",
53	"Qsound Labs",
54	"Spatializer Audio Laboratories",
55	"SRS Labs",
56	"Platform Tech",
57	"AKM Semiconductor",
58	"Aureal",
59	"Aztech Labs",
60	"Binaura",
61	"ESS Technology",
62	"Harman International",
63	"Nvidea",
64	"Philips"
65	"Texas Instruments",
66	"VLSI Technology",
67	"TriTech",
68	"Realtek",
69	"Samsung",
70	"Wolfson Microelectronics",
71	"Delta Integration",
72	"SigmaTel",
73	"KS Waves",
74	"Rockwell",
75	"Unknown (29)",
76	"Unknown (30)",
77	"Unknown (31)"
78};
79
80void default_init(ac97_dev *dev);
81void ad1819_init(ac97_dev *dev);
82void ad1881_init(ac97_dev *dev);
83void ad1885_init(ac97_dev *dev);
84void ad1886_init(ac97_dev *dev);
85void ad1980_init(ac97_dev *dev);
86void alc650_init(ac97_dev *dev);
87void stac9708_init(ac97_dev *dev);
88void stac9721_init(ac97_dev *dev);
89void stac9744_init(ac97_dev *dev);
90void stac9756_init(ac97_dev *dev);
91void tr28028_init(ac97_dev *dev);
92void wm9701_init(ac97_dev *dev);
93void wm9703_init(ac97_dev *dev);
94void wm9704_init(ac97_dev *dev);
95
96bool ad1819_set_rate(ac97_dev *dev, uint8 reg, uint32 rate);
97bool ad1819_get_rate(ac97_dev *dev, uint8 reg, uint32 *rate);
98
99typedef struct
100{
101	uint32 id;
102	uint32 mask;
103	codec_init init;
104	const char *info;
105} codec_table;
106
107codec_table codecs[] =
108{
109	{ CODEC_ID_AD1819,	0xffffffff, ad1819_init,	"Analog Devices AD1819A, AD1819B SoundPort"B_UTF8_REGISTERED },
110	{ CODEC_ID_AD1881,	0xffffffff, ad1881_init,	"Analog Devices AD1881 SoundMAX"B_UTF8_REGISTERED },
111	{ CODEC_ID_AD1881A,	0xffffffff, ad1881_init,	"Analog Devices AD1881A SoundMAX"B_UTF8_REGISTERED },
112	{ CODEC_ID_AD1885,	0xffffffff, ad1885_init,	"Analog Devices AD1885 SoundMAX"B_UTF8_REGISTERED },
113	{ CODEC_ID_AD1886,	0xffffffff, ad1886_init,	"Analog Devices AD1886 SoundMAX"B_UTF8_REGISTERED },
114	{ CODEC_ID_AD1886A,	0xffffffff, ad1881_init,	"Analog Devices AD1886A SoundMAX"B_UTF8_REGISTERED },
115	{ CODEC_ID_AD1887,	0xffffffff, ad1881_init,	"Analog Devices AD1887 SoundMAX"B_UTF8_REGISTERED },
116	{ CODEC_ID_AD1980,	0xffffffff, ad1980_init,	"Analog Devices AD1980 SoundMAX"B_UTF8_REGISTERED },
117	{ 0x41445371,		0xffffffff, default_init,	"Analog Devices 0x41445371 (???)" },
118	{ 0x41445372,		0xffffffff, default_init,	"Analog Devices AD1981A SoundMAX"B_UTF8_REGISTERED },
119	{ CODEC_ID_AD1981B,	0xffffffff, default_init,	"Analog Devices AD1981B SoundMAX"B_UTF8_REGISTERED },
120	{ CODEC_ID_AD1985,	0xffffffff, default_init,	"Analog Devices AD1985 SoundMAX"B_UTF8_REGISTERED },
121	{ CODEC_ID_AK4540,	0xffffffff, default_init,	"Asahi Kasei AK4540" },
122	{ CODEC_ID_AK4542,	0xffffffff, default_init,	"Asahi Kasei AK4542" },
123	{ 0x414b4d02,		0xffffffff, default_init,	"Asahi Kasei AK4543" },
124	{ 0x414c4320,		0xfffffff0, default_init,	"Avance Logic (Realtek) ALC100/ALC100P, RL5383/RL5522" },
125	{ 0x414c4730,		0xffffffff, default_init,	"Avance Logic (Realtek) ALC101" },
126	{ CODEC_ID_ALC201A,	0xffffffff, default_init,	"Avance Logic (Realtek) ALC200/ALC200A, ALC201/ALC201A" }, /* 0x4710 = ALC201A */
127	{ 0x414c4720,		0xffffffff, alc650_init,	"Avance Logic (Realtek) ALC650" }, /* 0x4720 = ALC650 */
128	{ 0x414c4740,		0xffffffff, default_init,	"Avance Logic (Realtek) ALC202/ALC202A" },
129	{ 0x434d4941,		0xffffffff, default_init,	"C-Media CMI9738" },
130	{ 0x434d4961,		0xffffffff, default_init,	"C-Media CMI9739" },
131	{ 0x43525900,		0xffffffff, default_init,	"Cirrus Logic CS4297" },
132	{ 0x43525903,		0xffffffff, default_init,	"Cirrus Logic CS4297" },
133	{ 0x43525913,		0xffffffff, default_init,	"Cirrus Logic CS4297A" },
134	{ 0x43525914,		0xffffffff, default_init,	"Cirrus Logic CS4297B" },
135	{ 0x43525923,		0xffffffff, default_init,	"Cirrus Logic CS4294C" },
136	{ 0x4352592b,		0xffffffff, default_init,	"Cirrus Logic CS4298C" },
137	{ CODEC_ID_CS4299A,	0xffffffff, default_init,	"Cirrus Logic CS4299A" },
138	{ CODEC_ID_CS4299C,	0xffffffff, default_init,	"Cirrus Logic CS4299C" },
139	{ CODEC_ID_CS4299D,	0xffffffff, default_init,	"Cirrus Logic CS4299D" },
140	{ 0x43525941,		0xffffffff, default_init,	"Cirrus Logic CS4201A" },
141	{ 0x43525951,		0xffffffff, default_init,	"Cirrus Logic CS4205A" },
142	{ 0x43525961,		0xffffffff, default_init,	"Cirrus Logic CS4291A" },
143	{ 0x45838308,		0xffffffff, default_init,	"ESS Technology ES1921" },
144	{ 0x49434511,		0xffffffff, default_init,	"ICEnsemble ICE1232" },
145	{ 0x4e534331,		0xffffffff, default_init,	"National Semiconductor LM4549" },
146	{ CODEC_ID_STAC9700,0xffffffff, default_init,	"SigmaTel STAC9700/9783/9784" },
147	{ CODEC_ID_STAC9704,0xffffffff, default_init,	"SigmaTel STAC9701/03, STAC9704/07, STAC9705 (???)" },
148	{ CODEC_ID_STAC9705,0xffffffff, default_init,	"SigmaTel STAC9704 (???)" },
149	{ CODEC_ID_STAC9708,0xffffffff, stac9708_init,	"SigmaTel STAC9708/9711" },
150	{ CODEC_ID_STAC9721,0xffffffff, stac9721_init,	"SigmaTel STAC9721/9723" },
151	{ CODEC_ID_STAC9744,0xffffffff, stac9744_init,	"SigmaTel STAC9744" },
152	{ CODEC_ID_STAC9752,0xffffffff, default_init,	"SigmaTel STAC9752/53" },
153	{ CODEC_ID_STAC9756,0xffffffff, stac9756_init,	"SigmaTel STAC9756/9757" },
154	{ CODEC_ID_STAC9766,0xffffffff, default_init,	"SigmaTel STAC9766/67" },
155	{ 0x53494c22,		0xffffffff, default_init,	"Silicon Laboratory Si3036" },
156	{ 0x53494c23,		0xffffffff, default_init,	"Silicon Laboratory Si3038" },
157	{ 0x54524103,		0xffffffff, default_init,	"TriTech TR?????" },
158	{ 0x54524106,		0xffffffff, default_init,	"TriTech TR28026" },
159	{ 0x54524108,		0xffffffff, tr28028_init,	"TriTech TR28028" },
160	{ 0x54524123,		0xffffffff, default_init,	"TriTech TR28602" },
161	{ 0x574d4c00,		0xffffffff, wm9701_init,	"Wolfson WM9701A" },
162	{ 0x574d4c03,		0xffffffff, wm9703_init,	"Wolfson WM9703/9704" },
163	{ 0x574d4c04,		0xffffffff, wm9704_init,	"Wolfson WM9704 (quad)" },
164	/* Vendors only: */
165	{ 0x41445300,		0xffffff00, default_init,	"Analog Devices" },
166	{ 0x414b4d00,		0xffffff00, default_init,	"Asahi Kasei" },
167	{ 0x414c4700,		0xffffff00, default_init,	"Avance Logic (Realtek)" },
168	{ 0x434d4900,		0xffffff00, default_init,	"C-Media" },
169	{ 0x43525900,		0xffffff00, default_init,	"Cirrus Logic" },
170	{ 0x45838300,		0xffffff00, default_init,	"ESS Technology" },
171	{ 0x49434500,		0xffffff00, default_init,	"ICEnsemble" },
172	{ 0x4e534300,		0xffffff00, default_init,	"National Semiconductor" },
173	{ 0x83847600,		0xffffff00, default_init,	"SigmaTel" },
174	{ 0x53494c00,		0xffffff00, default_init,	"Silicon Laboratory" },
175	{ 0x54524100,		0xffffff00, default_init,	"TriTech" },
176	{ 0x574d4c00,		0xffffff00, default_init,	"Wolfson" },
177	{ 0x00000000,		0x00000000, default_init,	"Unknown" } /* must be last one, matches every codec */
178};
179
180codec_table *find_codec_table(uint32 codecid);
181
182codec_table *
183find_codec_table(uint32 codecid)
184{
185	codec_table *codec;
186	for (codec = codecs; codec->id; codec++)
187		if ((codec->id & codec->mask) == (codecid & codec->mask))
188			break;
189	return codec;
190}
191
192void
193ac97_attach(ac97_dev **_dev, codec_reg_read reg_read, codec_reg_write reg_write, void *cookie)
194{
195	ac97_dev *dev;
196	codec_table *codec;
197
198	*_dev = dev = (ac97_dev *) malloc(sizeof(ac97_dev));
199	dev->cookie = cookie;
200	dev->reg_read = reg_read;
201	dev->reg_write = reg_write;
202	dev->codec_id = (reg_read(cookie, AC97_VENDOR_ID1) << 16) | reg_read(cookie, AC97_VENDOR_ID2);
203	codec = find_codec_table(dev->codec_id);
204	dev->codec_info = codec->info;
205	dev->init = codec->init;
206	dev->set_rate = 0;
207	dev->get_rate = 0;
208	dev->clock = 48000; /* default clock on non-broken motherboards */
209	dev->min_vsr = 0x0001;
210	dev->max_vsr = 0xffff;
211	dev->reversed_eamp_polarity = false;
212
213	/* reset the codec */
214	LOG(("codec reset\n"));
215	ac97_reg_uncached_write(dev, AC97_RESET, 0x0000);
216	snooze(50000); // 50 ms
217
218	/* setup register cache */
219	ac97_update_register_cache(dev);
220
221	dev->codec_3d_stereo_enhancement = stereo_enhancement_technique[(ac97_reg_cached_read(dev, AC97_RESET) >> 10) & 31];
222	dev->capabilities = 0;
223
224	ac97_reg_update_bits(dev, AC97_EXTENDED_STAT_CTRL, 1, 1); // enable variable rate audio
225
226	ac97_detect_capabilities(dev);
227
228	dev->init(dev);
229	ac97_amp_enable(dev, true);
230
231	/* set mixer defaults, enabled Line-out sources are PCM-out, CD-in, Line-in */
232	ac97_reg_update(dev, AC97_CENTER_LFE_VOLUME, 0x0000);	/* set LFE & center volume 0dB */
233	ac97_reg_update(dev, AC97_SURR_VOLUME, 0x0000);			/* set surround volume 0dB */
234	ac97_reg_update(dev, AC97_MASTER_VOLUME, 0x0000);		/* set master output 0dB */
235	ac97_reg_update(dev, AC97_AUX_OUT_VOLUME, 0x0000);		/* set aux output 0dB */
236	ac97_reg_update(dev, AC97_MONO_VOLUME, 0x0000);			/* set mono output 0dB */
237	ac97_reg_update(dev, AC97_PCM_OUT_VOLUME, 0x0808);		/* enable pcm-out */
238	ac97_reg_update(dev, AC97_CD_VOLUME, 0x0808);			/* enable cd-in */
239	ac97_reg_update(dev, AC97_LINE_IN_VOLUME, 0x0808);		/* enable line-in */
240
241	ac97_dump_capabilities(dev);
242}
243
244void
245ac97_detach(ac97_dev *dev)
246{
247	/* Mute everything */
248	ac97_reg_update_bits(dev, AC97_CENTER_LFE_VOLUME, 0x8000, 0x8000);
249	ac97_reg_update_bits(dev, AC97_SURR_VOLUME, 0x8000, 0x8000);
250	ac97_reg_update_bits(dev, AC97_MASTER_VOLUME, 0x8000, 0x8000);
251	ac97_reg_update_bits(dev, AC97_AUX_OUT_VOLUME, 0x8000, 0x8000);
252	ac97_reg_update_bits(dev, AC97_MONO_VOLUME, 0x8000, 0x8000);
253	ac97_reg_update_bits(dev, AC97_PCM_OUT_VOLUME, 0x8000, 0x8000);
254	ac97_reg_update_bits(dev, AC97_CD_VOLUME, 0x8000, 0x8000);
255	ac97_reg_update_bits(dev, AC97_LINE_IN_VOLUME, 0x8000, 0x8000);
256
257	free(dev);
258}
259
260void
261ac97_suspend(ac97_dev *dev)
262{
263	ac97_amp_enable(dev, false);
264}
265
266void
267ac97_resume(ac97_dev *dev)
268{
269	ac97_amp_enable(dev, true);
270}
271
272void
273ac97_reg_cached_write(ac97_dev *dev, uint8 reg, uint16 value)
274{
275	if (!ac97_reg_is_valid(dev, reg))
276		return;
277	dev->reg_write(dev->cookie, reg, value);
278	dev->reg_cache[reg] = value;
279}
280
281uint16
282ac97_reg_cached_read(ac97_dev *dev, uint8 reg)
283{
284	if (!ac97_reg_is_valid(dev, reg))
285		return 0;
286	return dev->reg_cache[reg];
287}
288
289void
290ac97_reg_uncached_write(ac97_dev *dev, uint8 reg, uint16 value)
291{
292	if (!ac97_reg_is_valid(dev, reg))
293		return;
294	dev->reg_write(dev->cookie, reg, value);
295}
296
297uint16
298ac97_reg_uncached_read(ac97_dev *dev, uint8 reg)
299{
300	if (!ac97_reg_is_valid(dev, reg))
301		return 0;
302	return dev->reg_read(dev->cookie, reg);
303}
304
305bool
306ac97_reg_update(ac97_dev *dev, uint8 reg, uint16 value)
307{
308	if (!ac97_reg_is_valid(dev, reg))
309		return false;
310	if (ac97_reg_cached_read(dev, reg) == value)
311		return false;
312	ac97_reg_cached_write(dev, reg, value);
313	return true;
314}
315
316bool
317ac97_reg_update_bits(ac97_dev *dev, uint8 reg, uint16 mask, uint16 value)
318{
319	uint16 old;
320	if (!ac97_reg_is_valid(dev, reg))
321		return false;
322	old = ac97_reg_cached_read(dev, reg);
323	value &= mask;
324	value |= (old & ~mask);
325	if (old == value)
326		return false;
327	ac97_reg_cached_write(dev, reg, value);
328	return true;
329}
330
331void
332ac97_update_register_cache(ac97_dev *dev)
333{
334	int reg;
335	for (reg = 0; reg <= 0x7e; reg += 2)
336		dev->reg_cache[reg] = ac97_reg_uncached_read(dev, reg);
337}
338
339bool
340ac97_set_rate(ac97_dev *dev, uint8 reg, uint32 rate)
341{
342	uint32 value;
343	uint32 old;
344
345	if (dev->set_rate)
346		return dev->set_rate(dev, reg, rate);
347
348	value = (uint32)((rate * 48000ULL) / dev->clock); /* need 64 bit calculation for rates 96000 or higher */
349
350	LOG(("ac97_set_rate: clock = %d, rate = %d, value = %d\n", dev->clock, rate, value));
351
352	/* if double rate audio is currently enabled, divide value by 2 */
353	if (ac97_reg_cached_read(dev, AC97_EXTENDED_STAT_CTRL) & 0x0002)
354		value /= 2;
355
356	if (value < dev->min_vsr || value > dev->max_vsr)
357		return false;
358
359	old = ac97_reg_cached_read(dev, reg);
360	ac97_reg_cached_write(dev, reg, value);
361	if (value != ac97_reg_uncached_read(dev, reg)) {
362		LOG(("ac97_set_rate failed, new rate %d\n", ac97_reg_uncached_read(dev, reg)));
363		ac97_reg_cached_write(dev, reg, old);
364		return false;
365	}
366	LOG(("ac97_set_rate done\n"));
367	return true;
368}
369
370bool
371ac97_get_rate(ac97_dev *dev, uint8 reg, uint32 *rate)
372{
373	uint32 value;
374
375	if (dev->get_rate)
376		return dev->get_rate(dev, reg, rate);
377
378	value = ac97_reg_cached_read(dev, reg);
379	if (value == 0)
380		return false;
381
382	/* if double rate audio is currently enabled, multiply value by 2 */
383	if (ac97_reg_cached_read(dev, AC97_EXTENDED_STAT_CTRL) & 0x0002)
384		value *= 2;
385
386	*rate = (uint32)((value * (uint64)dev->clock) / 48000); /* need 64 bit calculation to avoid overflow*/
387	return true;
388}
389
390void
391ac97_set_clock(ac97_dev *dev, uint32 clock)
392{
393	LOG(("ac97_set_clock: clock = %d\n", clock));
394	dev->clock = clock;
395	ac97_detect_rates(dev);
396	ac97_dump_capabilities(dev);
397}
398
399void
400ac97_detect_capabilities(ac97_dev *dev)
401{
402	uint16 val;
403
404	val = ac97_reg_cached_read(dev, AC97_RESET);
405	if (val & 0x0001)
406		dev->capabilities |= CAP_PCM_MIC;
407	if (val & 0x0004)
408		dev->capabilities |= CAP_BASS_TREBLE_CTRL;
409	if (val & 0x0008)
410		dev->capabilities |= CAP_SIMULATED_STEREO;
411	if (val & 0x0010)
412		dev->capabilities |= CAP_HEADPHONE_OUT;
413	if (val & 0x0020)
414		dev->capabilities |= CAP_LAUDNESS;
415	if (val & 0x0040)
416		dev->capabilities |= CAP_DAC_18BIT;
417	if (val & 0x0080)
418		dev->capabilities |= CAP_DAC_20BIT;
419	if (val & 0x0100)
420		dev->capabilities |= CAP_ADC_18BIT;
421	if (val & 0x0200)
422		dev->capabilities |= CAP_ADC_20BIT;
423	if (val & 0x7C00)
424		dev->capabilities |= CAP_3D_ENHANCEMENT;
425
426	val = ac97_reg_cached_read(dev, AC97_EXTENDED_ID);
427	if (val & EXID_VRA)
428		dev->capabilities |= CAP_VARIABLE_PCM;
429	if (val & EXID_DRA)
430		dev->capabilities |= CAP_DOUBLE_PCM;
431	if (val & EXID_SPDIF)
432		dev->capabilities |= CAP_SPDIF;
433	if (val & EXID_VRM)
434		dev->capabilities |= CAP_VARIABLE_MIC;
435	if (val & EXID_CDAC)
436		dev->capabilities |= CAP_CENTER_DAC;
437	if (val & EXID_SDAC)
438		dev->capabilities |= CAP_SURR_DAC;
439	if (val & EXID_LDAC)
440		dev->capabilities |= CAP_LFE_DAC;
441	if (val & EXID_AMAP)
442		dev->capabilities |= CAP_AMAP;
443	if ((val & (EXID_REV0 | EXID_REV1)) == 0)
444		dev->capabilities |= CAP_REV21;
445	if ((val & (EXID_REV0 | EXID_REV1)) == EXID_REV0)
446		dev->capabilities |= CAP_REV22;
447	if ((val & (EXID_REV0 | EXID_REV1)) == EXID_REV1)
448		dev->capabilities |= CAP_REV23;
449
450	ac97_detect_rates(dev);
451}
452
453void
454ac97_detect_rates(ac97_dev *dev)
455{
456	uint32 oldrate;
457
458	dev->capabilities &= ~CAP_PCM_RATE_MASK;
459
460	if (!ac97_get_rate(dev, AC97_PCM_FRONT_DAC_RATE, &oldrate))
461		oldrate = 48000;
462
463	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 20000))
464		dev->capabilities |= CAP_PCM_RATE_CONTINUOUS;
465	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 8000))
466		dev->capabilities |= CAP_PCM_RATE_8000;
467	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 11025))
468		dev->capabilities |= CAP_PCM_RATE_11025;
469	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 12000))
470		dev->capabilities |= CAP_PCM_RATE_12000;
471	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 16000))
472		dev->capabilities |= CAP_PCM_RATE_16000;
473	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 22050))
474		dev->capabilities |= CAP_PCM_RATE_22050;
475	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 24000))
476		dev->capabilities |= CAP_PCM_RATE_24000;
477	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 32000))
478		dev->capabilities |= CAP_PCM_RATE_32000;
479	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 44100))
480		dev->capabilities |= CAP_PCM_RATE_44100;
481	if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 48000))
482		dev->capabilities |= CAP_PCM_RATE_48000;
483
484	if (dev->capabilities & CAP_DOUBLE_PCM) {
485		// enable double rate mode
486		if (ac97_reg_update_bits(dev, AC97_EXTENDED_STAT_CTRL, 0x0002, 0x0002)) {
487			if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 88200))
488				dev->capabilities |= CAP_PCM_RATE_88200;
489			if (ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 96000))
490				dev->capabilities |= CAP_PCM_RATE_96000;
491			// disable double rate mode
492			ac97_reg_update_bits(dev, AC97_EXTENDED_STAT_CTRL, 0x0002, 0x0000);
493		}
494	}
495
496	ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, oldrate);
497}
498
499void
500ac97_dump_capabilities(ac97_dev *dev)
501{
502	LOG(("AC97 capabilities:\n"));
503	if (ac97_has_capability(dev, CAP_PCM_MIC))
504		LOG(("CAP_PCM_MIC\n"));
505	if (ac97_has_capability(dev, CAP_BASS_TREBLE_CTRL))
506		LOG(("CAP_BASS_TREBLE_CTRL\n"));
507	if (ac97_has_capability(dev, CAP_SIMULATED_STEREO))
508		LOG(("CAP_SIMULATED_STEREO\n"));
509	if (ac97_has_capability(dev, CAP_HEADPHONE_OUT))
510		LOG(("CAP_HEADPHONE_OUT\n"));
511	if (ac97_has_capability(dev, CAP_LAUDNESS))
512		LOG(("CAP_LAUDNESS\n"));
513	if (ac97_has_capability(dev, CAP_DAC_18BIT))
514		LOG(("CAP_DAC_18BIT\n"));
515	if (ac97_has_capability(dev, CAP_DAC_20BIT))
516		LOG(("CAP_DAC_20BIT\n"));
517	if (ac97_has_capability(dev, CAP_ADC_18BIT))
518		LOG(("CAP_ADC_18BIT\n"));
519	if (ac97_has_capability(dev, CAP_ADC_20BIT))
520		LOG(("CAP_ADC_20BIT\n"));
521	if (ac97_has_capability(dev, CAP_3D_ENHANCEMENT))
522		LOG(("CAP_3D_ENHANCEMENT\n"));
523	if (ac97_has_capability(dev, CAP_VARIABLE_PCM))
524		LOG(("CAP_VARIABLE_PCM\n"));
525	if (ac97_has_capability(dev, CAP_DOUBLE_PCM))
526		LOG(("CAP_DOUBLE_PCM\n"));
527	if (ac97_has_capability(dev, CAP_VARIABLE_MIC))
528		LOG(("CAP_VARIABLE_MIC\n"));
529	if (ac97_has_capability(dev, CAP_CENTER_DAC))
530		LOG(("CAP_CENTER_DAC\n"));
531	if (ac97_has_capability(dev, CAP_SURR_DAC))
532		LOG(("CAP_SURR_DAC\n"));
533	if (ac97_has_capability(dev, CAP_LFE_DAC))
534		LOG(("CAP_LFE_DAC\n"));
535	if (ac97_has_capability(dev, CAP_AMAP))
536		LOG(("CAP_AMAP\n"));
537	if (ac97_has_capability(dev, CAP_REV21))
538		LOG(("CAP_REV21\n"));
539	if (ac97_has_capability(dev, CAP_REV22))
540		LOG(("CAP_REV22\n"));
541	if (ac97_has_capability(dev, CAP_REV23))
542		LOG(("CAP_REV23\n"));
543	if (ac97_has_capability(dev, CAP_PCM_RATE_CONTINUOUS))
544		LOG(("CAP_PCM_RATE_CONTINUOUS\n"));
545	if (ac97_has_capability(dev, CAP_PCM_RATE_8000))
546		LOG(("CAP_PCM_RATE_8000\n"));
547	if (ac97_has_capability(dev, CAP_PCM_RATE_11025))
548		LOG(("CAP_PCM_RATE_11025\n"));
549	if (ac97_has_capability(dev, CAP_PCM_RATE_12000))
550		LOG(("CAP_PCM_RATE_12000\n"));
551	if (ac97_has_capability(dev, CAP_PCM_RATE_16000))
552		LOG(("CAP_PCM_RATE_16000\n"));
553	if (ac97_has_capability(dev, CAP_PCM_RATE_22050))
554		LOG(("CAP_PCM_RATE_22050\n"));
555	if (ac97_has_capability(dev, CAP_PCM_RATE_24000))
556		LOG(("CAP_PCM_RATE_24000\n"));
557	if (ac97_has_capability(dev, CAP_PCM_RATE_32000))
558		LOG(("CAP_PCM_RATE_32000\n"));
559	if (ac97_has_capability(dev, CAP_PCM_RATE_44100))
560		LOG(("CAP_PCM_RATE_44100\n"));
561	if (ac97_has_capability(dev, CAP_PCM_RATE_48000))
562		LOG(("CAP_PCM_RATE_48000\n"));
563	if (ac97_has_capability(dev, CAP_PCM_RATE_88200))
564		LOG(("CAP_PCM_RATE_88200\n"));
565	if (ac97_has_capability(dev, CAP_PCM_RATE_96000))
566		LOG(("CAP_PCM_RATE_96000\n"));
567}
568
569bool
570ac97_has_capability(ac97_dev *dev, uint64 cap)
571{
572	// return (dev->capabilities & cap); // does not work because of 64 bit to integer trucation
573	return (dev->capabilities & cap) != 0;
574}
575
576/*************************************************
577 * Codec specific initialization, etc.
578 */
579
580bool
581ac97_reg_is_valid(ac97_dev *dev, uint8 reg)
582{
583	if (reg & 1)
584		return false;
585	if (reg > 0x7e)
586		return false;
587
588	switch (dev->codec_id) {
589		case CODEC_ID_AK4540:
590		case CODEC_ID_AK4542:
591			if (reg < 0x1e || reg == 0x20 || reg == 0x26 || reg > 0x7a)
592				return true;
593			return false;
594
595		case CODEC_ID_AD1819:
596		case CODEC_ID_AD1881:
597		case CODEC_ID_AD1881A:
598			if (reg < 0x3a || reg > 0x6e)
599				return true;
600			return false;
601
602		case CODEC_ID_AD1885:
603		case CODEC_ID_AD1886:
604		case CODEC_ID_AD1886A:
605		case CODEC_ID_AD1887:
606			if (reg < 0x3c || reg == 0x5a || reg > 0x6e)
607				return true;
608			return false;
609
610		case CODEC_ID_STAC9700:
611		case CODEC_ID_STAC9704:
612		case CODEC_ID_STAC9705:
613		case CODEC_ID_STAC9708:
614		case CODEC_ID_STAC9721:
615		case CODEC_ID_STAC9744:
616		case CODEC_ID_STAC9756:
617			if (reg < 0x3c || reg > 0x58)
618				return true;
619			return false;
620
621		default:
622			return true;
623	}
624}
625
626void ac97_amp_enable(ac97_dev *dev, bool yesno)
627{
628	switch (dev->codec_id) {
629		case CODEC_ID_CS4299A:
630		case CODEC_ID_CS4299C:
631		case CODEC_ID_CS4299D:
632			LOG(("cs4299_amp_enable\n"));
633			if (yesno)
634				ac97_reg_cached_write(dev, 0x68, 0x8004);
635			else
636				ac97_reg_cached_write(dev, 0x68, 0);
637			break;
638
639		default:
640			LOG(("ac97_amp_enable, reverse eamp = %d\n", dev->reversed_eamp_polarity));
641			LOG(("powerdown register was = %#04x\n", ac97_reg_uncached_read(dev, AC97_POWERDOWN)));
642			if (dev->reversed_eamp_polarity)
643				yesno = !yesno;
644			if (yesno)
645				ac97_reg_cached_write(dev, AC97_POWERDOWN, ac97_reg_uncached_read(dev, AC97_POWERDOWN) & ~0x8000); /* switch on (low active) */
646			else
647				ac97_reg_cached_write(dev, AC97_POWERDOWN, ac97_reg_uncached_read(dev, AC97_POWERDOWN) | 0x8000); /* switch off */
648			LOG(("powerdown register is = %#04x\n", ac97_reg_uncached_read(dev, AC97_POWERDOWN)));
649		break;
650	}
651}
652
653bool
654ad1819_set_rate(ac97_dev *dev, uint8 reg, uint32 rate)
655{
656	uint32 value;
657
658	value = (uint32)((rate * 48000ULL) / dev->clock); /* need 64 bit calculation for rates 96000 or higher */
659
660	LOG(("ad1819_set_rate: clock = %d, rate = %d, value = %d\n", dev->clock, rate, value));
661
662	if (value < 0x1B58 || value > 0xBB80)
663		return false;
664
665	switch (reg) {
666		case AC97_PCM_FRONT_DAC_RATE:
667			ac97_reg_cached_write(dev, AC97_AD_SAMPLE_RATE_0, value);
668			return true;
669
670		case AC97_PCM_L_R_ADC_RATE:
671			ac97_reg_cached_write(dev, AC97_AD_SAMPLE_RATE_1, value);
672			return true;
673
674		default:
675			return false;
676	}
677}
678
679bool
680ad1819_get_rate(ac97_dev *dev, uint8 reg, uint32 *rate)
681{
682	uint32 value;
683
684	switch (reg) {
685		case AC97_PCM_FRONT_DAC_RATE:
686			value = ac97_reg_cached_read(dev, AC97_AD_SAMPLE_RATE_0);
687			break;
688
689		case AC97_PCM_L_R_ADC_RATE:
690			value = ac97_reg_cached_read(dev, AC97_AD_SAMPLE_RATE_1);
691			break;
692
693		default:
694			return false;
695	}
696
697	*rate = (uint32)((value * (uint64)dev->clock) / 48000); /* need 64 bit calculation to avoid overflow*/
698	return true;
699}
700
701
702void default_init(ac97_dev *dev)
703{
704	LOG(("default_init\n"));
705}
706
707void ad1819_init(ac97_dev *dev)
708{
709	LOG(("ad1819_init\n"));
710
711	/* Default config for system with single AD1819 codec */
712	ac97_reg_cached_write(dev, AC97_AD_SERIAL_CONFIG, 0x7000);
713	ac97_update_register_cache(dev);
714
715	/* The AD1819 chip has proprietary  sample rate controls
716	 * Setup sample rate 0 generator for DAC,
717	 * Setup sample rate 1 generator for ADC,
718	 * ARSR=1, DRSR=0, ALSR=1, DLSR=0
719	 */
720	ac97_reg_cached_write(dev, AC97_AD_MISC_CONTROL, 0x0101);
721	/* connect special rate set/get functions */
722	dev->set_rate = ad1819_set_rate;
723	dev->get_rate = ad1819_get_rate;
724	ac97_detect_rates(dev);
725	ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, 48000);
726	ac97_set_rate(dev, AC97_PCM_L_R_ADC_RATE, 48000);
727}
728
729void ad1881_init(ac97_dev *dev)
730{
731	LOG(("ad1881_init\n"));
732
733	/* Default config for system with single AD1819 codec,
734	 * BROKEN on systems with master & slave codecs */
735	ac97_reg_cached_write(dev, AC97_AD_SERIAL_CONFIG, 0x7000);
736	ac97_update_register_cache(dev);
737
738	/* Setup DAC and ADC rate generator assignments compatible with AC97 */
739	ac97_reg_cached_write(dev, AC97_AD_MISC_CONTROL, 0x0404);
740
741	/* Setup variable frame rate limits */
742	dev->min_vsr = 0x1B58;	/*  7kHz */
743	dev->max_vsr = 0xBB80;	/* 48kHz */
744}
745
746void ad1885_init(ac97_dev *dev)
747{
748	LOG(("ad1885_init\n"));
749	ad1881_init(dev);
750
751	/* disable jack sense 0 and 1 (JS0, JS1) to turn off automatic mute */
752	ac97_reg_cached_write(dev, AC97_AD_JACK_SENSE, ac97_reg_cached_read(dev, AC97_AD_JACK_SENSE) | 0x0300);
753}
754
755void ad1886_init(ac97_dev *dev)
756{
757	LOG(("ad1886_init\n"));
758	ad1881_init(dev);
759
760	/* change jack sense to always activate outputs*/
761	ac97_reg_cached_write(dev, AC97_AD_JACK_SENSE, 0x0010);
762	/* change SPDIF to a valid value */
763	ac97_reg_cached_write(dev, AC97_SPDIF_CONTROL, 0x2a20);
764}
765
766void ad1980_init(ac97_dev *dev)
767{
768	LOG(("ad1980_init\n"));
769
770	/* Select only master codec,
771	 * SPDIF and DAC are linked
772	 */
773	ac97_reg_cached_write(dev, AC97_AD_SERIAL_CONFIG, 0x1001);
774	ac97_update_register_cache(dev);
775
776	/* Select Line-out driven with mixer data (not surround data)
777	 * Select Headphone-out driven with mixer data (not surround data),
778	 * LOSEL = 0, HPSEL = 1
779	 * XXX this one needs to be changed to support surround	out
780	 */
781	ac97_reg_cached_write(dev, AC97_AD_MISC_CONTROL, 0x0400);
782}
783
784void alc650_init(ac97_dev *dev)
785{
786	LOG(("alc650_init\n"));
787
788	/* Enable Surround, LFE and Center downmix into Line-out,
789	 * Set Surround-out as duplicated Line-out.
790	 */
791	ac97_reg_cached_write(dev, AC97_ALC650_MULTI_CHAN_CTRL, 0x0007);
792
793	/* Set Surround DAC Volume to 0dB
794	 * Set Center/LFE DAC Volume to 0dB
795	 * (but both should already be set, as these are hardware reset defaults)
796	 */
797	ac97_reg_cached_write(dev, AC97_ALC650_SURR_VOLUME, 0x0808);
798	ac97_reg_cached_write(dev, AC97_ALC650_CEN_LFE_VOLUME, 0x0808);
799}
800
801void stac9708_init(ac97_dev *dev)
802{
803	LOG(("stac9708_init\n"));
804	/* ALSA initializes some registers that according to the
805	 * documentation for this codec do not exist. If the
806	 * following doesn't work, we may need to do that, too.
807	 */
808	/* The Analog Special reg is at 0x6C, other codecs have it at 0x6E */
809	/* Set Analog Special to default (DAC/ADC -6dB disabled) */
810	ac97_reg_cached_write(dev, 0x6C, 0x0000);
811	/* Set Multi Channel to default */
812	ac97_reg_cached_write(dev, 0x74, 0x0000);
813}
814
815void stac9721_init(ac97_dev *dev)
816{
817	LOG(("stac9721_init\n"));
818	/* Set Analog Special to default (DAC/ADC -6dB disabled) */
819	ac97_reg_cached_write(dev, 0x6E, 0x0000);
820	/* Enable register 0x72 */
821	ac97_reg_cached_write(dev, 0x70, 0xabba);
822	/* Set Analog Current to -50% */
823	ac97_reg_cached_write(dev, 0x72, 0x0002);
824	/* Set Multi Channel to default */
825	ac97_reg_cached_write(dev, 0x74, 0x0000);
826	/* Enable register 0x78 */
827	ac97_reg_cached_write(dev, 0x76, 0xabba);
828	/* Set Clock Access to default */
829	ac97_reg_cached_write(dev, 0x78, 0x0000);
830}
831
832void stac9744_init(ac97_dev *dev)
833{
834	LOG(("stac9744_init\n"));
835	/* Set Analog Special to default (DAC/ADC -6dB disabled) */
836	ac97_reg_cached_write(dev, 0x6E, 0x0000);
837	/* Enable register 0x72 */
838	ac97_reg_cached_write(dev, 0x70, 0xabba);
839	/* Set Analog Current to -50% */
840	ac97_reg_cached_write(dev, 0x72, 0x0002);
841	/* Set Multi Channel to default */
842	ac97_reg_cached_write(dev, 0x74, 0x0000);
843	/* Enable register 0x78 */
844	ac97_reg_cached_write(dev, 0x76, 0xabba);
845	/* Set Clock Access to default */
846	ac97_reg_cached_write(dev, 0x78, 0x0000);
847}
848
849void stac9756_init(ac97_dev *dev)
850{
851	LOG(("stac9756_init\n"));
852	/* Set Analog Special to default (AC97 all-mix, DAC/ADC -6dB disabled) */
853	ac97_reg_cached_write(dev, 0x6E, 0x1000);
854	/* Enable register 0x72 */
855	ac97_reg_cached_write(dev, 0x70, 0xabba);
856	/* Set Analog Current to -50% */
857	ac97_reg_cached_write(dev, 0x72, 0x0002);
858	/* Set Multi Channel to default */
859	ac97_reg_cached_write(dev, 0x74, 0x0000);
860	/* Enable register 0x78 */
861	ac97_reg_cached_write(dev, 0x76, 0xabba);
862	/* Set Clock Access to default */
863	ac97_reg_cached_write(dev, 0x78, 0x0000);
864}
865
866void tr28028_init(ac97_dev *dev)
867{
868	LOG(("tr28028_init\n"));
869	ac97_reg_cached_write(dev, AC97_POWERDOWN, 0x0300);
870	ac97_reg_cached_write(dev, AC97_POWERDOWN, 0x0000);
871	ac97_reg_cached_write(dev, AC97_SURR_VOLUME, 0x0000);
872	ac97_reg_cached_write(dev, AC97_SPDIF_CONTROL, 0x0000);
873}
874
875void wm9701_init(ac97_dev *dev)
876{
877	LOG(("wm9701_init\n"));
878	/* ALSA writes some of these registers, but the codec
879	 * documentation states explicitly that 0x38 and 0x70 to 0x74
880	 * are not used in the WM9701A
881	 */
882
883	/* DVD noise patch (?) */
884	ac97_reg_cached_write(dev, 0x5a, 0x0200);
885}
886
887void wm9703_init(ac97_dev *dev)
888{
889	LOG(("wm9703_init\n"));
890	/* Set front mixer value to unmuted */
891	ac97_reg_cached_write(dev, 0x72, 0x0808);
892	/* Disable loopback, etc */
893	ac97_reg_cached_write(dev, AC97_GENERAL_PURPOSE, 0x8000);
894}
895
896void wm9704_init(ac97_dev *dev)
897{
898	LOG(("wm9704_init\n"));
899	/* Set read DAC value to unmuted */
900	ac97_reg_cached_write(dev, 0x70, 0x0808);
901	/* Set front mixer value to unmuted */
902	ac97_reg_cached_write(dev, 0x72, 0x0808);
903	/* Set rear mixer value to unmuted */
904	ac97_reg_cached_write(dev, 0x74, 0x0808);
905	/* DVD noise patch (?) */
906	ac97_reg_cached_write(dev, 0x5a, 0x0200);
907}
908