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