2 * BeOS Driver for Intel ICH AC'97 Link interface
4 * Copyright (c) 2002, Marcus Overhagen <marcus@overhagen.de>
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.
31 #include <MediaDefs.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",
48 "Creative Technology",
49 "National Semiconductor",
52 "Crystal Semiconductor",
54 "Spatializer Audio Laboratories",
62 "Harman International",
70 "Wolfson Microelectronics",
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
);
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)" },
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
);
183 find_codec_table(uint32 codecid
)
186 for (codec
= codecs
; codec
->id
; codec
++)
187 if ((codec
->id
& codec
->mask
) == (codecid
& codec
->mask
))
193 ac97_attach(ac97_dev
**_dev
, codec_reg_read reg_read
, codec_reg_write reg_write
, void *cookie
)
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
;
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
);
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
);
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);
261 ac97_suspend(ac97_dev
*dev
)
263 ac97_amp_enable(dev
, false);
267 ac97_resume(ac97_dev
*dev
)
269 ac97_amp_enable(dev
, true);
273 ac97_reg_cached_write(ac97_dev
*dev
, uint8 reg
, uint16 value
)
275 if (!ac97_reg_is_valid(dev
, reg
))
277 dev
->reg_write(dev
->cookie
, reg
, value
);
278 dev
->reg_cache
[reg
] = value
;
282 ac97_reg_cached_read(ac97_dev
*dev
, uint8 reg
)
284 if (!ac97_reg_is_valid(dev
, reg
))
286 return dev
->reg_cache
[reg
];
290 ac97_reg_uncached_write(ac97_dev
*dev
, uint8 reg
, uint16 value
)
292 if (!ac97_reg_is_valid(dev
, reg
))
294 dev
->reg_write(dev
->cookie
, reg
, value
);
298 ac97_reg_uncached_read(ac97_dev
*dev
, uint8 reg
)
300 if (!ac97_reg_is_valid(dev
, reg
))
302 return dev
->reg_read(dev
->cookie
, reg
);
306 ac97_reg_update(ac97_dev
*dev
, uint8 reg
, uint16 value
)
308 if (!ac97_reg_is_valid(dev
, reg
))
310 if (ac97_reg_cached_read(dev
, reg
) == value
)
312 ac97_reg_cached_write(dev
, reg
, value
);
317 ac97_reg_update_bits(ac97_dev
*dev
, uint8 reg
, uint16 mask
, uint16 value
)
320 if (!ac97_reg_is_valid(dev
, reg
))
322 old
= ac97_reg_cached_read(dev
, reg
);
324 value
|= (old
& ~mask
);
327 ac97_reg_cached_write(dev
, reg
, value
);
332 ac97_update_register_cache(ac97_dev
*dev
)
335 for (reg
= 0; reg
<= 0x7e; reg
+= 2)
336 dev
->reg_cache
[reg
] = ac97_reg_uncached_read(dev
, reg
);
340 ac97_set_rate(ac97_dev
*dev
, uint8 reg
, uint32 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)
356 if (value
< dev
->min_vsr
|| value
> dev
->max_vsr
)
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
);
366 LOG(("ac97_set_rate done\n"));
371 ac97_get_rate(ac97_dev
*dev
, uint8 reg
, uint32
*rate
)
376 return dev
->get_rate(dev
, reg
, rate
);
378 value
= ac97_reg_cached_read(dev
, reg
);
382 /* if double rate audio is currently enabled, multiply value by 2 */
383 if (ac97_reg_cached_read(dev
, AC97_EXTENDED_STAT_CTRL
) & 0x0002)
386 *rate
= (uint32
)((value
* (uint64
)dev
->clock
) / 48000); /* need 64 bit calculation to avoid overflow*/
391 ac97_set_clock(ac97_dev
*dev
, uint32 clock
)
393 LOG(("ac97_set_clock: clock = %d\n", clock
));
395 ac97_detect_rates(dev
);
396 ac97_dump_capabilities(dev
);
400 ac97_detect_capabilities(ac97_dev
*dev
)
404 val
= ac97_reg_cached_read(dev
, AC97_RESET
);
406 dev
->capabilities
|= CAP_PCM_MIC
;
408 dev
->capabilities
|= CAP_BASS_TREBLE_CTRL
;
410 dev
->capabilities
|= CAP_SIMULATED_STEREO
;
412 dev
->capabilities
|= CAP_HEADPHONE_OUT
;
414 dev
->capabilities
|= CAP_LAUDNESS
;
416 dev
->capabilities
|= CAP_DAC_18BIT
;
418 dev
->capabilities
|= CAP_DAC_20BIT
;
420 dev
->capabilities
|= CAP_ADC_18BIT
;
422 dev
->capabilities
|= CAP_ADC_20BIT
;
424 dev
->capabilities
|= CAP_3D_ENHANCEMENT
;
426 val
= ac97_reg_cached_read(dev
, AC97_EXTENDED_ID
);
428 dev
->capabilities
|= CAP_VARIABLE_PCM
;
430 dev
->capabilities
|= CAP_DOUBLE_PCM
;
431 if (val
& EXID_SPDIF
)
432 dev
->capabilities
|= CAP_SPDIF
;
434 dev
->capabilities
|= CAP_VARIABLE_MIC
;
436 dev
->capabilities
|= CAP_CENTER_DAC
;
438 dev
->capabilities
|= CAP_SURR_DAC
;
440 dev
->capabilities
|= CAP_LFE_DAC
;
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
);
454 ac97_detect_rates(ac97_dev
*dev
)
458 dev
->capabilities
&= ~CAP_PCM_RATE_MASK
;
460 if (!ac97_get_rate(dev
, AC97_PCM_FRONT_DAC_RATE
, &oldrate
))
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
);
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
))
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"));
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.
581 ac97_reg_is_valid(ac97_dev
*dev
, uint8 reg
)
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)
595 case CODEC_ID_AD1819
:
596 case CODEC_ID_AD1881
:
597 case CODEC_ID_AD1881A
:
598 if (reg
< 0x3a || reg
> 0x6e)
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)
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)
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"));
634 ac97_reg_cached_write(dev
, 0x68, 0x8004);
636 ac97_reg_cached_write(dev
, 0x68, 0);
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
)
645 ac97_reg_cached_write(dev
, AC97_POWERDOWN
, ac97_reg_uncached_read(dev
, AC97_POWERDOWN
) & ~0x8000); /* switch on (low active) */
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
)));
654 ad1819_set_rate(ac97_dev
*dev
, uint8 reg
, uint32 rate
)
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)
666 case AC97_PCM_FRONT_DAC_RATE
:
667 ac97_reg_cached_write(dev
, AC97_AD_SAMPLE_RATE_0
, value
);
670 case AC97_PCM_L_R_ADC_RATE
:
671 ac97_reg_cached_write(dev
, AC97_AD_SAMPLE_RATE_1
, value
);
680 ad1819_get_rate(ac97_dev
*dev
, uint8 reg
, uint32
*rate
)
685 case AC97_PCM_FRONT_DAC_RATE
:
686 value
= ac97_reg_cached_read(dev
, AC97_AD_SAMPLE_RATE_0
);
689 case AC97_PCM_L_R_ADC_RATE
:
690 value
= ac97_reg_cached_read(dev
, AC97_AD_SAMPLE_RATE_1
);
697 *rate
= (uint32
)((value
* (uint64
)dev
->clock
) / 48000); /* need 64 bit calculation to avoid overflow*/
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"));
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"));
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);