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