vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / kernel / drivers / audio / ac97 / ich / ac97.c
blob69763fa0150a7553b69cdb00e3eaa8b86fc1b11d
1 /*
2 * BeOS Driver for Intel ICH AC'97 Link interface
4 * Copyright (c) 2002, Marcus Overhagen <marcus@overhagen.de>
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:
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.
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.
28 #include <OS.h>
29 #include <stdio.h>
30 #include <malloc.h>
31 #include <MediaDefs.h>
32 #include "ac97.h"
33 #include "debug.h"
35 #define B_UTF8_REGISTERED "\xC2\xAE"
37 bool ac97_reg_is_valid(ac97_dev *dev, uint8 reg);
38 void ac97_amp_enable(ac97_dev *dev, bool onoff);
39 void ac97_dump_capabilities(ac97_dev *dev);
40 void ac97_detect_capabilities(ac97_dev *dev);
41 void ac97_detect_rates(ac97_dev *dev);
42 void ac97_update_register_cache(ac97_dev *dev);
44 const char * stereo_enhancement_technique[] =
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)"
80 void default_init(ac97_dev *dev);
81 void ad1819_init(ac97_dev *dev);
82 void ad1881_init(ac97_dev *dev);
83 void ad1885_init(ac97_dev *dev);
84 void ad1886_init(ac97_dev *dev);
85 void ad1980_init(ac97_dev *dev);
86 void alc650_init(ac97_dev *dev);
87 void stac9708_init(ac97_dev *dev);
88 void stac9721_init(ac97_dev *dev);
89 void stac9744_init(ac97_dev *dev);
90 void stac9756_init(ac97_dev *dev);
91 void tr28028_init(ac97_dev *dev);
92 void wm9701_init(ac97_dev *dev);
93 void wm9703_init(ac97_dev *dev);
94 void wm9704_init(ac97_dev *dev);
96 bool ad1819_set_rate(ac97_dev *dev, uint8 reg, uint32 rate);
97 bool ad1819_get_rate(ac97_dev *dev, uint8 reg, uint32 *rate);
99 typedef struct
101 uint32 id;
102 uint32 mask;
103 codec_init init;
104 const char *info;
105 } codec_table;
107 codec_table codecs[] =
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 */
180 codec_table *find_codec_table(uint32 codecid);
182 codec_table *
183 find_codec_table(uint32 codecid)
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;
192 void
193 ac97_attach(ac97_dev **_dev, codec_reg_read reg_read, codec_reg_write reg_write, void *cookie)
195 ac97_dev *dev;
196 codec_table *codec;
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;
213 /* reset the codec */
214 LOG(("codec reset\n"));
215 ac97_reg_uncached_write(dev, AC97_RESET, 0x0000);
216 snooze(50000); // 50 ms
218 /* setup register cache */
219 ac97_update_register_cache(dev);
221 dev->codec_3d_stereo_enhancement = stereo_enhancement_technique[(ac97_reg_cached_read(dev, AC97_RESET) >> 10) & 31];
222 dev->capabilities = 0;
224 ac97_reg_update_bits(dev, AC97_EXTENDED_STAT_CTRL, 1, 1); // enable variable rate audio
226 ac97_detect_capabilities(dev);
228 dev->init(dev);
229 ac97_amp_enable(dev, true);
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 */
241 ac97_dump_capabilities(dev);
244 void
245 ac97_detach(ac97_dev *dev)
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);
257 free(dev);
260 void
261 ac97_suspend(ac97_dev *dev)
263 ac97_amp_enable(dev, false);
266 void
267 ac97_resume(ac97_dev *dev)
269 ac97_amp_enable(dev, true);
272 void
273 ac97_reg_cached_write(ac97_dev *dev, uint8 reg, uint16 value)
275 if (!ac97_reg_is_valid(dev, reg))
276 return;
277 dev->reg_write(dev->cookie, reg, value);
278 dev->reg_cache[reg] = value;
281 uint16
282 ac97_reg_cached_read(ac97_dev *dev, uint8 reg)
284 if (!ac97_reg_is_valid(dev, reg))
285 return 0;
286 return dev->reg_cache[reg];
289 void
290 ac97_reg_uncached_write(ac97_dev *dev, uint8 reg, uint16 value)
292 if (!ac97_reg_is_valid(dev, reg))
293 return;
294 dev->reg_write(dev->cookie, reg, value);
297 uint16
298 ac97_reg_uncached_read(ac97_dev *dev, uint8 reg)
300 if (!ac97_reg_is_valid(dev, reg))
301 return 0;
302 return dev->reg_read(dev->cookie, reg);
305 bool
306 ac97_reg_update(ac97_dev *dev, uint8 reg, uint16 value)
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;
316 bool
317 ac97_reg_update_bits(ac97_dev *dev, uint8 reg, uint16 mask, uint16 value)
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;
331 void
332 ac97_update_register_cache(ac97_dev *dev)
334 int reg;
335 for (reg = 0; reg <= 0x7e; reg += 2)
336 dev->reg_cache[reg] = ac97_reg_uncached_read(dev, reg);
339 bool
340 ac97_set_rate(ac97_dev *dev, uint8 reg, uint32 rate)
342 uint32 value;
343 uint32 old;
345 if (dev->set_rate)
346 return dev->set_rate(dev, reg, rate);
348 value = (uint32)((rate * 48000ULL) / dev->clock); /* need 64 bit calculation for rates 96000 or higher */
350 LOG(("ac97_set_rate: clock = %d, rate = %d, value = %d\n", dev->clock, rate, value));
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;
356 if (value < dev->min_vsr || value > dev->max_vsr)
357 return false;
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;
366 LOG(("ac97_set_rate done\n"));
367 return true;
370 bool
371 ac97_get_rate(ac97_dev *dev, uint8 reg, uint32 *rate)
373 uint32 value;
375 if (dev->get_rate)
376 return dev->get_rate(dev, reg, rate);
378 value = ac97_reg_cached_read(dev, reg);
379 if (value == 0)
380 return false;
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;
386 *rate = (uint32)((value * (uint64)dev->clock) / 48000); /* need 64 bit calculation to avoid overflow*/
387 return true;
390 void
391 ac97_set_clock(ac97_dev *dev, uint32 clock)
393 LOG(("ac97_set_clock: clock = %d\n", clock));
394 dev->clock = clock;
395 ac97_detect_rates(dev);
396 ac97_dump_capabilities(dev);
399 void
400 ac97_detect_capabilities(ac97_dev *dev)
402 uint16 val;
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;
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;
450 ac97_detect_rates(dev);
453 void
454 ac97_detect_rates(ac97_dev *dev)
456 uint32 oldrate;
458 dev->capabilities &= ~CAP_PCM_RATE_MASK;
460 if (!ac97_get_rate(dev, AC97_PCM_FRONT_DAC_RATE, &oldrate))
461 oldrate = 48000;
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;
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);
496 ac97_set_rate(dev, AC97_PCM_FRONT_DAC_RATE, oldrate);
499 void
500 ac97_dump_capabilities(ac97_dev *dev)
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"));
569 bool
570 ac97_has_capability(ac97_dev *dev, uint64 cap)
572 // return (dev->capabilities & cap); // does not work because of 64 bit to integer trucation
573 return (dev->capabilities & cap) != 0;
576 /*************************************************
577 * Codec specific initialization, etc.
580 bool
581 ac97_reg_is_valid(ac97_dev *dev, uint8 reg)
583 if (reg & 1)
584 return false;
585 if (reg > 0x7e)
586 return false;
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;
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;
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;
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;
621 default:
622 return true;
626 void ac97_amp_enable(ac97_dev *dev, bool yesno)
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;
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;
653 bool
654 ad1819_set_rate(ac97_dev *dev, uint8 reg, uint32 rate)
656 uint32 value;
658 value = (uint32)((rate * 48000ULL) / dev->clock); /* need 64 bit calculation for rates 96000 or higher */
660 LOG(("ad1819_set_rate: clock = %d, rate = %d, value = %d\n", dev->clock, rate, value));
662 if (value < 0x1B58 || value > 0xBB80)
663 return false;
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;
670 case AC97_PCM_L_R_ADC_RATE:
671 ac97_reg_cached_write(dev, AC97_AD_SAMPLE_RATE_1, value);
672 return true;
674 default:
675 return false;
679 bool
680 ad1819_get_rate(ac97_dev *dev, uint8 reg, uint32 *rate)
682 uint32 value;
684 switch (reg) {
685 case AC97_PCM_FRONT_DAC_RATE:
686 value = ac97_reg_cached_read(dev, AC97_AD_SAMPLE_RATE_0);
687 break;
689 case AC97_PCM_L_R_ADC_RATE:
690 value = ac97_reg_cached_read(dev, AC97_AD_SAMPLE_RATE_1);
691 break;
693 default:
694 return false;
697 *rate = (uint32)((value * (uint64)dev->clock) / 48000); /* need 64 bit calculation to avoid overflow*/
698 return true;
702 void default_init(ac97_dev *dev)
704 LOG(("default_init\n"));
707 void ad1819_init(ac97_dev *dev)
709 LOG(("ad1819_init\n"));
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);
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
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);
729 void ad1881_init(ac97_dev *dev)
731 LOG(("ad1881_init\n"));
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);
738 /* Setup DAC and ADC rate generator assignments compatible with AC97 */
739 ac97_reg_cached_write(dev, AC97_AD_MISC_CONTROL, 0x0404);
741 /* Setup variable frame rate limits */
742 dev->min_vsr = 0x1B58; /* 7kHz */
743 dev->max_vsr = 0xBB80; /* 48kHz */
746 void ad1885_init(ac97_dev *dev)
748 LOG(("ad1885_init\n"));
749 ad1881_init(dev);
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);
755 void ad1886_init(ac97_dev *dev)
757 LOG(("ad1886_init\n"));
758 ad1881_init(dev);
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);
766 void ad1980_init(ac97_dev *dev)
768 LOG(("ad1980_init\n"));
770 /* Select only master codec,
771 * SPDIF and DAC are linked
773 ac97_reg_cached_write(dev, AC97_AD_SERIAL_CONFIG, 0x1001);
774 ac97_update_register_cache(dev);
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
781 ac97_reg_cached_write(dev, AC97_AD_MISC_CONTROL, 0x0400);
784 void alc650_init(ac97_dev *dev)
786 LOG(("alc650_init\n"));
788 /* Enable Surround, LFE and Center downmix into Line-out,
789 * Set Surround-out as duplicated Line-out.
791 ac97_reg_cached_write(dev, AC97_ALC650_MULTI_CHAN_CTRL, 0x0007);
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)
797 ac97_reg_cached_write(dev, AC97_ALC650_SURR_VOLUME, 0x0808);
798 ac97_reg_cached_write(dev, AC97_ALC650_CEN_LFE_VOLUME, 0x0808);
801 void stac9708_init(ac97_dev *dev)
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.
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);
815 void stac9721_init(ac97_dev *dev)
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);
832 void stac9744_init(ac97_dev *dev)
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);
849 void stac9756_init(ac97_dev *dev)
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);
866 void tr28028_init(ac97_dev *dev)
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);
875 void wm9701_init(ac97_dev *dev)
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
883 /* DVD noise patch (?) */
884 ac97_reg_cached_write(dev, 0x5a, 0x0200);
887 void wm9703_init(ac97_dev *dev)
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);
896 void wm9704_init(ac97_dev *dev)
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);