1 /*- 2 * Copyright (c) 1999 Cameron Grant <cg@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <dev/sound/pcm/sound.h> 28 #include <dev/sound/pcm/ac97.h> 29 #include <dev/sound/pcm/ac97_patch.h> 30 31 #include <dev/pci/pcivar.h> 32 33 #include "mixer_if.h" 34 35 SND_DECLARE_FILE("$FreeBSD$"); 36 37 MALLOC_DEFINE(M_AC97, "ac97", "ac97 codec"); 38 39 struct ac97mixtable_entry { 40 int reg:8; /* register index */ 41 /* reg < 0 if inverted polarity */ 42 unsigned bits:4; /* width of control field */ 43 unsigned ofs:4; /* offset (only if stereo=0) */ 44 unsigned stereo:1; /* set for stereo controls */ 45 unsigned mute:1; /* bit15 is MUTE */ 46 unsigned recidx:4; /* index in rec mux */ 47 unsigned mask:1; /* use only masked bits */ 48 unsigned enable:1; /* entry is enabled */ 49 }; 50 51 #define AC97_NAMELEN 16 52 struct ac97_info { 53 kobj_t methods; 54 device_t dev; 55 void *devinfo; 56 u_int32_t id; 57 u_int32_t subvendor; 58 unsigned count, caps, se, extcaps, extid, extstat, noext:1; 59 u_int32_t flags; 60 struct ac97mixtable_entry mix[32]; 61 char name[AC97_NAMELEN]; 62 struct mtx *lock; 63 }; 64 65 struct ac97_vendorid { 66 u_int32_t id; 67 const char *name; 68 }; 69 70 struct ac97_codecid { 71 u_int32_t id; 72 u_int8_t stepmask; 73 u_int8_t noext:1; 74 char *name; 75 ac97_patch patch; 76 }; 77 78 static const struct ac97mixtable_entry ac97mixtable_default[32] = { 79 /* [offset] reg bits of st mu re mk en */ 80 [SOUND_MIXER_VOLUME] = { AC97_MIX_MASTER, 5, 0, 1, 1, 6, 0, 1 }, 81 [SOUND_MIXER_OGAIN] = { AC97_MIX_AUXOUT, 5, 0, 1, 1, 0, 0, 0 }, 82 [SOUND_MIXER_PHONEOUT] = { AC97_MIX_MONO, 5, 0, 0, 1, 7, 0, 0 }, 83 [SOUND_MIXER_BASS] = { AC97_MIX_TONE, 4, 8, 0, 0, 0, 1, 0 }, 84 [SOUND_MIXER_TREBLE] = { AC97_MIX_TONE, 4, 0, 0, 0, 0, 1, 0 }, 85 [SOUND_MIXER_PCM] = { AC97_MIX_PCM, 5, 0, 1, 1, 0, 0, 1 }, 86 [SOUND_MIXER_SPEAKER] = { AC97_MIX_BEEP, 4, 1, 0, 1, 0, 0, 0 }, 87 [SOUND_MIXER_LINE] = { AC97_MIX_LINE, 5, 0, 1, 1, 5, 0, 1 }, 88 [SOUND_MIXER_PHONEIN] = { AC97_MIX_PHONE, 5, 0, 0, 1, 8, 0, 0 }, 89 [SOUND_MIXER_MIC] = { AC97_MIX_MIC, 5, 0, 0, 1, 1, 1, 1 }, 90 /* use igain for the mic 20dB boost */ 91 [SOUND_MIXER_IGAIN] = { -AC97_MIX_MIC, 1, 6, 0, 0, 0, 1, 1 }, 92 [SOUND_MIXER_CD] = { AC97_MIX_CD, 5, 0, 1, 1, 2, 0, 1 }, 93 [SOUND_MIXER_LINE1] = { AC97_MIX_AUX, 5, 0, 1, 1, 4, 0, 0 }, 94 [SOUND_MIXER_VIDEO] = { AC97_MIX_VIDEO, 5, 0, 1, 1, 3, 0, 0 }, 95 [SOUND_MIXER_RECLEV] = { -AC97_MIX_RGAIN, 4, 0, 1, 1, 0, 0, 1 } 96 }; 97 98 static const struct ac97_vendorid ac97vendorid[] = { 99 { 0x41445300, "Analog Devices" }, 100 { 0x414b4d00, "Asahi Kasei" }, 101 { 0x414c4300, "Realtek" }, 102 { 0x414c4700, "Avance Logic" }, 103 { 0x43525900, "Cirrus Logic" }, 104 { 0x434d4900, "C-Media Electronics" }, 105 { 0x43585400, "Conexant" }, 106 { 0x44543000, "Diamond Technology" }, 107 { 0x454d4300, "eMicro" }, 108 { 0x45838300, "ESS Technology" }, 109 { 0x48525300, "Intersil" }, 110 { 0x49434500, "ICEnsemble" }, 111 { 0x49544500, "ITE, Inc." }, 112 { 0x4e534300, "National Semiconductor" }, 113 { 0x50534300, "Philips Semiconductor" }, 114 { 0x83847600, "SigmaTel" }, 115 { 0x53494c00, "Silicon Laboratories" }, 116 { 0x54524100, "TriTech" }, 117 { 0x54584e00, "Texas Instruments" }, 118 { 0x56494100, "VIA Technologies" }, 119 { 0x57454300, "Winbond" }, 120 { 0x574d4c00, "Wolfson" }, 121 { 0x594d4800, "Yamaha" }, 122 /* 123 * XXX This is a fluke, really! The real vendor 124 * should be SigmaTel, not this! This should be 125 * removed someday! 126 */ 127 { 0x01408300, "Creative" }, 128 { 0x00000000, NULL } 129 }; 130 131 static struct ac97_codecid ac97codecid[] = { 132 { 0x41445303, 0x00, 0, "AD1819", 0 }, 133 { 0x41445340, 0x00, 0, "AD1881", 0 }, 134 { 0x41445348, 0x00, 0, "AD1881A", 0 }, 135 { 0x41445360, 0x00, 0, "AD1885", 0 }, 136 { 0x41445361, 0x00, 0, "AD1886", ad1886_patch }, 137 { 0x41445362, 0x00, 0, "AD1887", 0 }, 138 { 0x41445363, 0x00, 0, "AD1886A", 0 }, 139 { 0x41445368, 0x00, 0, "AD1888", ad198x_patch }, 140 { 0x41445370, 0x00, 0, "AD1980", ad198x_patch }, 141 { 0x41445372, 0x00, 0, "AD1981A", 0 }, 142 { 0x41445374, 0x00, 0, "AD1981B", ad1981b_patch }, 143 { 0x41445375, 0x00, 0, "AD1985", ad198x_patch }, 144 { 0x41445378, 0x00, 0, "AD1986", ad198x_patch }, 145 { 0x414b4d00, 0x00, 1, "AK4540", 0 }, 146 { 0x414b4d01, 0x00, 1, "AK4542", 0 }, 147 { 0x414b4d02, 0x00, 1, "AK4543", 0 }, 148 { 0x414b4d06, 0x00, 0, "AK4544A", 0 }, 149 { 0x454b4d07, 0x00, 0, "AK4545", 0 }, 150 { 0x414c4320, 0x0f, 0, "ALC100", 0 }, 151 { 0x414c4730, 0x0f, 0, "ALC101", 0 }, 152 { 0x414c4710, 0x0f, 0, "ALC200", 0 }, 153 { 0x414c4740, 0x0f, 0, "ALC202", 0 }, 154 { 0x414c4720, 0x0f, 0, "ALC650", 0 }, 155 { 0x414c4752, 0x0f, 0, "ALC250", 0 }, 156 { 0x414c4760, 0x0f, 0, "ALC655", alc655_patch }, 157 { 0x414c4770, 0x0f, 0, "ALC203", 0 }, 158 { 0x414c4780, 0x0f, 0, "ALC658", 0 }, 159 { 0x414c4790, 0x0f, 0, "ALC850", 0 }, 160 { 0x43525900, 0x07, 0, "CS4297", 0 }, 161 { 0x43525910, 0x07, 0, "CS4297A", 0 }, 162 { 0x43525920, 0x07, 0, "CS4294/98", 0 }, 163 { 0x4352592d, 0x07, 0, "CS4294", 0 }, 164 { 0x43525930, 0x07, 0, "CS4299", 0 }, 165 { 0x43525940, 0x07, 0, "CS4201", 0 }, 166 { 0x43525958, 0x07, 0, "CS4205", 0 }, 167 { 0x43525960, 0x07, 0, "CS4291A", 0 }, 168 { 0x434d4961, 0x00, 0, "CMI9739", cmi9739_patch }, 169 { 0x434d4941, 0x00, 0, "CMI9738", 0 }, 170 { 0x434d4978, 0x00, 0, "CMI9761", 0 }, 171 { 0x434d4982, 0x00, 0, "CMI9761", 0 }, 172 { 0x434d4983, 0x00, 0, "CMI9761", 0 }, 173 { 0x43585421, 0x00, 0, "HSD11246", 0 }, 174 { 0x43585428, 0x07, 0, "CX20468", 0 }, 175 { 0x43585430, 0x00, 0, "CX20468-21", 0 }, 176 { 0x44543000, 0x00, 0, "DT0398", 0 }, 177 { 0x454d4323, 0x00, 0, "EM28023", 0 }, 178 { 0x454d4328, 0x00, 0, "EM28028", 0 }, 179 { 0x45838308, 0x00, 0, "ES1988", 0 }, /* Formerly ES1921(?) */ 180 { 0x48525300, 0x00, 0, "HMP9701", 0 }, 181 { 0x49434501, 0x00, 0, "ICE1230", 0 }, 182 { 0x49434511, 0x00, 0, "ICE1232", 0 }, 183 { 0x49434514, 0x00, 0, "ICE1232A", 0 }, 184 { 0x49434551, 0x03, 0, "VT1616", 0 }, /* Via badged ICE */ 185 { 0x49544520, 0x00, 0, "ITE2226E", 0 }, 186 { 0x49544560, 0x07, 0, "ITE2646E", 0 }, /* XXX: patch needed */ 187 { 0x4e534340, 0x00, 0, "LM4540", 0 }, /* Spec blank on revid */ 188 { 0x4e534343, 0x00, 0, "LM4543", 0 }, /* Ditto */ 189 { 0x4e534346, 0x00, 0, "LM4546A", 0 }, 190 { 0x4e534348, 0x00, 0, "LM4548A", 0 }, 191 { 0x4e534331, 0x00, 0, "LM4549", 0 }, 192 { 0x4e534349, 0x00, 0, "LM4549A", 0 }, 193 { 0x4e534350, 0x00, 0, "LM4550", 0 }, 194 { 0x50534301, 0x00, 0, "UCB1510", 0 }, 195 { 0x50534304, 0x00, 0, "UCB1400", 0 }, 196 { 0x83847600, 0x00, 0, "STAC9700/83/84", 0 }, 197 { 0x83847604, 0x00, 0, "STAC9701/03/04/05", 0 }, 198 { 0x83847605, 0x00, 0, "STAC9704", 0 }, 199 { 0x83847608, 0x00, 0, "STAC9708/11", 0 }, 200 { 0x83847609, 0x00, 0, "STAC9721/23", 0 }, 201 { 0x83847644, 0x00, 0, "STAC9744/45", 0 }, 202 { 0x83847650, 0x00, 0, "STAC9750/51", 0 }, 203 { 0x83847652, 0x00, 0, "STAC9752/53", 0 }, 204 { 0x83847656, 0x00, 0, "STAC9756/57", 0 }, 205 { 0x83847658, 0x00, 0, "STAC9758/59", 0 }, 206 { 0x83847660, 0x00, 0, "STAC9760/61", 0 }, /* Extrapolated */ 207 { 0x83847662, 0x00, 0, "STAC9762/63", 0 }, /* Extrapolated */ 208 { 0x83847666, 0x00, 0, "STAC9766/67", 0 }, 209 { 0x53494c22, 0x00, 0, "Si3036", 0 }, 210 { 0x53494c23, 0x00, 0, "Si3038", 0 }, 211 { 0x54524103, 0x00, 0, "TR28023", 0 }, /* Extrapolated */ 212 { 0x54524106, 0x00, 0, "TR28026", 0 }, 213 { 0x54524108, 0x00, 0, "TR28028", 0 }, 214 { 0x54524123, 0x00, 0, "TR28602", 0 }, 215 { 0x54524e03, 0x07, 0, "TLV320AIC27", 0 }, 216 { 0x54584e20, 0x00, 0, "TLC320AD90", 0 }, 217 { 0x56494161, 0x00, 0, "VIA1612A", 0 }, 218 { 0x56494170, 0x00, 0, "VIA1617A", 0 }, 219 { 0x574d4c00, 0x00, 0, "WM9701A", 0 }, 220 { 0x574d4c03, 0x00, 0, "WM9703/4/7/8", 0 }, 221 { 0x574d4c04, 0x00, 0, "WM9704Q", 0 }, 222 { 0x574d4c05, 0x00, 0, "WM9705/10", 0 }, 223 { 0x574d4d09, 0x00, 0, "WM9709", 0 }, 224 { 0x574d4c12, 0x00, 0, "WM9711/12", 0 }, /* XXX: patch needed */ 225 { 0x57454301, 0x00, 0, "W83971D", 0 }, 226 { 0x594d4800, 0x00, 0, "YMF743", 0 }, 227 { 0x594d4802, 0x00, 0, "YMF752", 0 }, 228 { 0x594d4803, 0x00, 0, "YMF753", 0 }, 229 /* 230 * XXX This is a fluke, really! The real codec 231 * should be STAC9704, not this! This should be 232 * removed someday! 233 */ 234 { 0x01408384, 0x00, 0, "EV1938", 0 }, 235 { 0, 0, 0, NULL, 0 } 236 }; 237 238 static char *ac97enhancement[] = { 239 "no 3D Stereo Enhancement", 240 "Analog Devices Phat Stereo", 241 "Creative Stereo Enhancement", 242 "National Semi 3D Stereo Enhancement", 243 "Yamaha Ymersion", 244 "BBE 3D Stereo Enhancement", 245 "Crystal Semi 3D Stereo Enhancement", 246 "Qsound QXpander", 247 "Spatializer 3D Stereo Enhancement", 248 "SRS 3D Stereo Enhancement", 249 "Platform Tech 3D Stereo Enhancement", 250 "AKM 3D Audio", 251 "Aureal Stereo Enhancement", 252 "Aztech 3D Enhancement", 253 "Binaura 3D Audio Enhancement", 254 "ESS Technology Stereo Enhancement", 255 "Harman International VMAx", 256 "Nvidea 3D Stereo Enhancement", 257 "Philips Incredible Sound", 258 "Texas Instruments 3D Stereo Enhancement", 259 "VLSI Technology 3D Stereo Enhancement", 260 "TriTech 3D Stereo Enhancement", 261 "Realtek 3D Stereo Enhancement", 262 "Samsung 3D Stereo Enhancement", 263 "Wolfson Microelectronics 3D Enhancement", 264 "Delta Integration 3D Enhancement", 265 "SigmaTel 3D Enhancement", 266 "Reserved 27", 267 "Rockwell 3D Stereo Enhancement", 268 "Reserved 29", 269 "Reserved 30", 270 "Reserved 31" 271 }; 272 273 static char *ac97feature[] = { 274 "mic channel", 275 "reserved", 276 "tone", 277 "simulated stereo", 278 "headphone", 279 "bass boost", 280 "18 bit DAC", 281 "20 bit DAC", 282 "18 bit ADC", 283 "20 bit ADC" 284 }; 285 286 static char *ac97extfeature[] = { 287 "variable rate PCM", 288 "double rate PCM", 289 "reserved 1", 290 "variable rate mic", 291 "reserved 2", 292 "reserved 3", 293 "center DAC", 294 "surround DAC", 295 "LFE DAC", 296 "AMAP", 297 "reserved 4", 298 "reserved 5", 299 "reserved 6", 300 "reserved 7", 301 }; 302 303 u_int16_t 304 ac97_rdcd(struct ac97_info *codec, int reg) 305 { 306 if (codec->flags & AC97_F_RDCD_BUG) { 307 u_int16_t i[2], j = 100; 308 309 i[0] = AC97_READ(codec->methods, codec->devinfo, reg); 310 i[1] = AC97_READ(codec->methods, codec->devinfo, reg); 311 while (i[0] != i[1] && j) 312 i[j-- & 1] = AC97_READ(codec->methods, codec->devinfo, reg); 313 #if 0 314 if (j < 100) { 315 device_printf(codec->dev, "%s(): Inconsistent register value at" 316 " 0x%08x (retry: %d)\n", __func__, reg, 100 - j); 317 } 318 #endif 319 return i[!(j & 1)]; 320 } 321 return AC97_READ(codec->methods, codec->devinfo, reg); 322 } 323 324 void 325 ac97_wrcd(struct ac97_info *codec, int reg, u_int16_t val) 326 { 327 AC97_WRITE(codec->methods, codec->devinfo, reg, val); 328 } 329 330 static void 331 ac97_reset(struct ac97_info *codec) 332 { 333 u_int32_t i, ps; 334 ac97_wrcd(codec, AC97_REG_RESET, 0); 335 for (i = 0; i < 500; i++) { 336 ps = ac97_rdcd(codec, AC97_REG_POWER) & AC97_POWER_STATUS; 337 if (ps == AC97_POWER_STATUS) 338 return; 339 DELAY(1000); 340 } 341 device_printf(codec->dev, "AC97 reset timed out.\n"); 342 } 343 344 int 345 ac97_setrate(struct ac97_info *codec, int which, int rate) 346 { 347 u_int16_t v; 348 349 switch(which) { 350 case AC97_REGEXT_FDACRATE: 351 case AC97_REGEXT_SDACRATE: 352 case AC97_REGEXT_LDACRATE: 353 case AC97_REGEXT_LADCRATE: 354 case AC97_REGEXT_MADCRATE: 355 break; 356 357 default: 358 return -1; 359 } 360 361 snd_mtxlock(codec->lock); 362 if (rate != 0) { 363 v = rate; 364 if (codec->extstat & AC97_EXTCAP_DRA) 365 v >>= 1; 366 ac97_wrcd(codec, which, v); 367 } 368 v = ac97_rdcd(codec, which); 369 if (codec->extstat & AC97_EXTCAP_DRA) 370 v <<= 1; 371 snd_mtxunlock(codec->lock); 372 return v; 373 } 374 375 int 376 ac97_setextmode(struct ac97_info *codec, u_int16_t mode) 377 { 378 mode &= AC97_EXTCAPS; 379 if ((mode & ~codec->extcaps) != 0) { 380 device_printf(codec->dev, "ac97 invalid mode set 0x%04x\n", 381 mode); 382 return -1; 383 } 384 snd_mtxlock(codec->lock); 385 ac97_wrcd(codec, AC97_REGEXT_STAT, mode); 386 codec->extstat = ac97_rdcd(codec, AC97_REGEXT_STAT) & AC97_EXTCAPS; 387 snd_mtxunlock(codec->lock); 388 return (mode == codec->extstat)? 0 : -1; 389 } 390 391 u_int16_t 392 ac97_getextmode(struct ac97_info *codec) 393 { 394 return codec->extstat; 395 } 396 397 u_int16_t 398 ac97_getextcaps(struct ac97_info *codec) 399 { 400 return codec->extcaps; 401 } 402 403 u_int16_t 404 ac97_getcaps(struct ac97_info *codec) 405 { 406 return codec->caps; 407 } 408 409 u_int32_t 410 ac97_getsubvendor(struct ac97_info *codec) 411 { 412 return codec->subvendor; 413 } 414 415 static int 416 ac97_setrecsrc(struct ac97_info *codec, int channel) 417 { 418 struct ac97mixtable_entry *e = &codec->mix[channel]; 419 420 if (e->recidx > 0) { 421 int val = e->recidx - 1; 422 val |= val << 8; 423 snd_mtxlock(codec->lock); 424 ac97_wrcd(codec, AC97_REG_RECSEL, val); 425 snd_mtxunlock(codec->lock); 426 return 0; 427 } else 428 return -1; 429 } 430 431 static int 432 ac97_setmixer(struct ac97_info *codec, unsigned channel, unsigned left, unsigned right) 433 { 434 struct ac97mixtable_entry *e = &codec->mix[channel]; 435 436 if (e->reg && e->enable && e->bits) { 437 int mask, max, val, reg; 438 439 reg = (e->reg >= 0) ? e->reg : -e->reg; /* AC97 register */ 440 max = (1 << e->bits) - 1; /* actual range */ 441 mask = (max << 8) | max; /* bits of interest */ 442 443 if (!e->stereo) 444 right = left; 445 446 /* 447 * Invert the range if the polarity requires so, 448 * then scale to 0..max-1 to compute the value to 449 * write into the codec, and scale back to 0..100 450 * for the return value. 451 */ 452 if (e->reg > 0) { 453 left = 100 - left; 454 right = 100 - right; 455 } 456 457 left = (left * max) / 100; 458 right = (right * max) / 100; 459 460 val = (left << 8) | right; 461 462 left = (left * 100) / max; 463 right = (right * 100) / max; 464 465 if (e->reg > 0) { 466 left = 100 - left; 467 right = 100 - right; 468 } 469 470 /* 471 * For mono controls, trim val and mask, also taking 472 * care of e->ofs (offset of control field). 473 */ 474 if (e->ofs) { 475 val &= max; 476 val <<= e->ofs; 477 mask = (max << e->ofs); 478 } 479 480 /* 481 * If we have a mute bit, add it to the mask and 482 * update val and set mute if both channels require a 483 * zero volume. 484 */ 485 if (e->mute == 1) { 486 mask |= AC97_MUTE; 487 if (left == 0 && right == 0) 488 val = AC97_MUTE; 489 } 490 491 /* 492 * If the mask bit is set, do not alter the other bits. 493 */ 494 snd_mtxlock(codec->lock); 495 if (e->mask) { 496 int cur = ac97_rdcd(codec, reg); 497 val |= cur & ~(mask); 498 } 499 ac97_wrcd(codec, reg, val); 500 snd_mtxunlock(codec->lock); 501 return left | (right << 8); 502 } else { 503 #if 0 504 printf("ac97_setmixer: reg=%d, bits=%d, enable=%d\n", e->reg, e->bits, e->enable); 505 #endif 506 return -1; 507 } 508 } 509 510 static void 511 ac97_fix_auxout(struct ac97_info *codec) 512 { 513 int keep_ogain; 514 515 /* 516 * By default, The ac97 aux_out register (0x04) corresponds to OSS's 517 * OGAIN setting. 518 * 519 * We first check whether aux_out is a valid register. If not 520 * we may not want to keep ogain. 521 */ 522 keep_ogain = ac97_rdcd(codec, AC97_MIX_AUXOUT) & 0x8000; 523 524 /* 525 * Determine what AUX_OUT really means, it can be: 526 * 527 * 1. Headphone out. 528 * 2. 4-Channel Out 529 * 3. True line level out (effectively master volume). 530 * 531 * See Sections 5.2.1 and 5.27 for AUX_OUT Options in AC97r2.{2,3}. 532 */ 533 if (codec->extcaps & AC97_EXTCAP_SDAC && 534 ac97_rdcd(codec, AC97_MIXEXT_SURROUND) == 0x8080) { 535 codec->mix[SOUND_MIXER_OGAIN].reg = AC97_MIXEXT_SURROUND; 536 keep_ogain = 1; 537 } 538 539 if (keep_ogain == 0) { 540 bzero(&codec->mix[SOUND_MIXER_OGAIN], 541 sizeof(codec->mix[SOUND_MIXER_OGAIN])); 542 } 543 } 544 545 static void 546 ac97_fix_tone(struct ac97_info *codec) 547 { 548 /* 549 * YMF chips does not indicate tone and 3D enhancement capability 550 * in the AC97_REG_RESET register. 551 */ 552 switch (codec->id) { 553 case 0x594d4800: /* YMF743 */ 554 case 0x594d4803: /* YMF753 */ 555 codec->caps |= AC97_CAP_TONE; 556 codec->se |= 0x04; 557 break; 558 case 0x594d4802: /* YMF752 */ 559 codec->se |= 0x04; 560 break; 561 default: 562 break; 563 } 564 565 /* Hide treble and bass if they don't exist */ 566 if ((codec->caps & AC97_CAP_TONE) == 0) { 567 bzero(&codec->mix[SOUND_MIXER_BASS], 568 sizeof(codec->mix[SOUND_MIXER_BASS])); 569 bzero(&codec->mix[SOUND_MIXER_TREBLE], 570 sizeof(codec->mix[SOUND_MIXER_TREBLE])); 571 } 572 } 573 574 static const char* 575 ac97_hw_desc(u_int32_t id, const char* vname, const char* cname, char* buf) 576 { 577 if (cname == NULL) { 578 sprintf(buf, "Unknown AC97 Codec (id = 0x%08x)", id); 579 return buf; 580 } 581 582 if (vname == NULL) vname = "Unknown"; 583 584 if (bootverbose) { 585 sprintf(buf, "%s %s AC97 Codec (id = 0x%08x)", vname, cname, id); 586 } else { 587 sprintf(buf, "%s %s AC97 Codec", vname, cname); 588 } 589 return buf; 590 } 591 592 static unsigned 593 ac97_initmixer(struct ac97_info *codec) 594 { 595 ac97_patch codec_patch; 596 const char *cname, *vname; 597 char desc[80]; 598 u_int8_t model, step; 599 unsigned i, j, k, bit, old; 600 u_int32_t id; 601 int reg; 602 603 snd_mtxlock(codec->lock); 604 codec->count = AC97_INIT(codec->methods, codec->devinfo); 605 if (codec->count == 0) { 606 device_printf(codec->dev, "ac97 codec init failed\n"); 607 snd_mtxunlock(codec->lock); 608 return ENODEV; 609 } 610 611 ac97_wrcd(codec, AC97_REG_POWER, (codec->flags & AC97_F_EAPD_INV)? 0x8000 : 0x0000); 612 ac97_reset(codec); 613 ac97_wrcd(codec, AC97_REG_POWER, (codec->flags & AC97_F_EAPD_INV)? 0x8000 : 0x0000); 614 615 i = ac97_rdcd(codec, AC97_REG_RESET); 616 j = ac97_rdcd(codec, AC97_REG_RESET); 617 /* 618 * Let see if this codec can return consistent value. 619 * If not, turn on aggressive read workaround 620 * (STAC9704 comes in mind). 621 */ 622 if (i != j) { 623 codec->flags |= AC97_F_RDCD_BUG; 624 i = ac97_rdcd(codec, AC97_REG_RESET); 625 } 626 codec->caps = i & 0x03ff; 627 codec->se = (i & 0x7c00) >> 10; 628 629 id = (ac97_rdcd(codec, AC97_REG_ID1) << 16) | ac97_rdcd(codec, AC97_REG_ID2); 630 if (id == 0 || id == 0xffffffff) { 631 device_printf(codec->dev, "ac97 codec invalid or not present (id == %x)\n", id); 632 snd_mtxunlock(codec->lock); 633 return ENODEV; 634 } 635 636 codec->id = id; 637 codec->subvendor = (u_int32_t)pci_get_subdevice(codec->dev) << 16; 638 codec->subvendor |= (u_int32_t)pci_get_subvendor(codec->dev) & 639 0x0000ffff; 640 codec->noext = 0; 641 codec_patch = NULL; 642 643 cname = NULL; 644 model = step = 0; 645 for (i = 0; ac97codecid[i].id; i++) { 646 u_int32_t modelmask = 0xffffffff ^ ac97codecid[i].stepmask; 647 if ((ac97codecid[i].id & modelmask) == (id & modelmask)) { 648 codec->noext = ac97codecid[i].noext; 649 codec_patch = ac97codecid[i].patch; 650 cname = ac97codecid[i].name; 651 model = (id & modelmask) & 0xff; 652 step = (id & ~modelmask) & 0xff; 653 break; 654 } 655 } 656 657 vname = NULL; 658 for (i = 0; ac97vendorid[i].id; i++) { 659 if (ac97vendorid[i].id == (id & 0xffffff00)) { 660 vname = ac97vendorid[i].name; 661 break; 662 } 663 } 664 665 codec->extcaps = 0; 666 codec->extid = 0; 667 codec->extstat = 0; 668 if (!codec->noext) { 669 i = ac97_rdcd(codec, AC97_REGEXT_ID); 670 if (i != 0xffff) { 671 codec->extcaps = i & 0x3fff; 672 codec->extid = (i & 0xc000) >> 14; 673 codec->extstat = ac97_rdcd(codec, AC97_REGEXT_STAT) & AC97_EXTCAPS; 674 } 675 } 676 677 for (i = 0; i < 32; i++) { 678 codec->mix[i] = ac97mixtable_default[i]; 679 } 680 ac97_fix_auxout(codec); 681 ac97_fix_tone(codec); 682 if (codec_patch) 683 codec_patch(codec); 684 685 for (i = 0; i < 32; i++) { 686 k = codec->noext? codec->mix[i].enable : 1; 687 reg = codec->mix[i].reg; 688 if (reg < 0) 689 reg = -reg; 690 if (k && reg) { 691 j = old = ac97_rdcd(codec, reg); 692 /* 693 * Test for mute bit (except for AC97_MIX_TONE, 694 * where we simply assume it as available). 695 */ 696 if (codec->mix[i].mute) { 697 ac97_wrcd(codec, reg, j | 0x8000); 698 j = ac97_rdcd(codec, reg); 699 } else 700 j |= 0x8000; 701 if ((j & 0x8000)) { 702 /* 703 * Test whether the control width should be 704 * 4, 5 or 6 bit. For 5bit register, we should 705 * test it whether it's really 5 or 6bit. Leave 706 * 4bit register alone, because sometimes an 707 * attempt to write past 4th bit may cause 708 * incorrect result especially for AC97_MIX_BEEP 709 * (ac97 2.3). 710 */ 711 bit = codec->mix[i].bits; 712 if (bit == 5) 713 bit++; 714 j = ((1 << bit) - 1) << codec->mix[i].ofs; 715 ac97_wrcd(codec, reg, 716 j | (codec->mix[i].mute ? 0x8000 : 0)); 717 k = ac97_rdcd(codec, reg) & j; 718 k >>= codec->mix[i].ofs; 719 if (reg == AC97_MIX_TONE && 720 ((k & 0x0001) == 0x0000)) 721 k >>= 1; 722 for (j = 0; k >> j; j++) 723 ; 724 if (j != 0) { 725 #if 0 726 device_printf(codec->dev, "%2d: [ac97_rdcd() = %d] [Testbit = %d] %d -> %d\n", 727 i, k, bit, codec->mix[i].bits, j); 728 #endif 729 codec->mix[i].enable = 1; 730 codec->mix[i].bits = j; 731 } else if (reg == AC97_MIX_BEEP) { 732 /* 733 * Few codec such as CX20468-21 does 734 * have this control register, although 735 * the only usable part is the mute bit. 736 */ 737 codec->mix[i].enable = 1; 738 } else 739 codec->mix[i].enable = 0; 740 } else 741 codec->mix[i].enable = 0; 742 ac97_wrcd(codec, reg, old); 743 } 744 #if 0 745 printf("mixch %d, en=%d, b=%d\n", i, codec->mix[i].enable, codec->mix[i].bits); 746 #endif 747 } 748 749 device_printf(codec->dev, "<%s>\n", 750 ac97_hw_desc(codec->id, vname, cname, desc)); 751 752 if (bootverbose) { 753 if (codec->flags & AC97_F_RDCD_BUG) 754 device_printf(codec->dev, "Buggy AC97 Codec: aggressive ac97_rdcd() workaround enabled\n"); 755 device_printf(codec->dev, "Codec features "); 756 for (i = j = 0; i < 10; i++) 757 if (codec->caps & (1 << i)) 758 printf("%s%s", j++? ", " : "", ac97feature[i]); 759 printf("%s%d bit master volume", j++? ", " : "", codec->mix[SOUND_MIXER_VOLUME].bits); 760 printf("%s%s\n", j? ", " : "", ac97enhancement[codec->se]); 761 762 if (codec->extcaps != 0 || codec->extid) { 763 device_printf(codec->dev, "%s codec", 764 codec->extid? "Secondary" : "Primary"); 765 if (codec->extcaps) 766 printf(" extended features "); 767 for (i = j = 0; i < 14; i++) 768 if (codec->extcaps & (1 << i)) 769 printf("%s%s", j++? ", " : "", ac97extfeature[i]); 770 printf("\n"); 771 } 772 } 773 774 i = 0; 775 while ((ac97_rdcd(codec, AC97_REG_POWER) & 2) == 0) { 776 if (++i == 100) { 777 device_printf(codec->dev, "ac97 codec reports dac not ready\n"); 778 break; 779 } 780 DELAY(1000); 781 } 782 if (bootverbose) 783 device_printf(codec->dev, "ac97 codec dac ready count: %d\n", i); 784 snd_mtxunlock(codec->lock); 785 return 0; 786 } 787 788 static unsigned 789 ac97_reinitmixer(struct ac97_info *codec) 790 { 791 snd_mtxlock(codec->lock); 792 codec->count = AC97_INIT(codec->methods, codec->devinfo); 793 if (codec->count == 0) { 794 device_printf(codec->dev, "ac97 codec init failed\n"); 795 snd_mtxunlock(codec->lock); 796 return ENODEV; 797 } 798 799 ac97_wrcd(codec, AC97_REG_POWER, (codec->flags & AC97_F_EAPD_INV)? 0x8000 : 0x0000); 800 ac97_reset(codec); 801 ac97_wrcd(codec, AC97_REG_POWER, (codec->flags & AC97_F_EAPD_INV)? 0x8000 : 0x0000); 802 803 if (!codec->noext) { 804 ac97_wrcd(codec, AC97_REGEXT_STAT, codec->extstat); 805 if ((ac97_rdcd(codec, AC97_REGEXT_STAT) & AC97_EXTCAPS) 806 != codec->extstat) 807 device_printf(codec->dev, "ac97 codec failed to reset extended mode (%x, got %x)\n", 808 codec->extstat, 809 ac97_rdcd(codec, AC97_REGEXT_STAT) & 810 AC97_EXTCAPS); 811 } 812 813 if ((ac97_rdcd(codec, AC97_REG_POWER) & 2) == 0) 814 device_printf(codec->dev, "ac97 codec reports dac not ready\n"); 815 snd_mtxunlock(codec->lock); 816 return 0; 817 } 818 819 struct ac97_info * 820 ac97_create(device_t dev, void *devinfo, kobj_class_t cls) 821 { 822 struct ac97_info *codec; 823 int eapdinv; 824 825 codec = (struct ac97_info *)malloc(sizeof *codec, M_AC97, M_NOWAIT | M_ZERO); 826 if (codec == NULL) 827 return NULL; 828 829 snprintf(codec->name, AC97_NAMELEN, "%s:ac97", device_get_nameunit(dev)); 830 codec->lock = snd_mtxcreate(codec->name, "ac97 codec"); 831 codec->methods = kobj_create(cls, M_AC97, M_WAITOK | M_ZERO); 832 codec->dev = dev; 833 codec->devinfo = devinfo; 834 codec->flags = 0; 835 if (resource_int_value(device_get_name(dev), device_get_unit(dev), 836 "eapdinv", &eapdinv) == 0) { 837 if (eapdinv != 0) 838 codec->flags |= AC97_F_EAPD_INV; 839 } 840 return codec; 841 } 842 843 void 844 ac97_destroy(struct ac97_info *codec) 845 { 846 snd_mtxlock(codec->lock); 847 if (codec->methods != NULL) 848 kobj_delete(codec->methods, M_AC97); 849 snd_mtxfree(codec->lock); 850 free(codec, M_AC97); 851 } 852 853 void 854 ac97_setflags(struct ac97_info *codec, u_int32_t val) 855 { 856 codec->flags = val; 857 } 858 859 u_int32_t 860 ac97_getflags(struct ac97_info *codec) 861 { 862 return codec->flags; 863 } 864 865 /* -------------------------------------------------------------------- */ 866 867 #ifdef SND_DYNSYSCTL 868 static int 869 sysctl_hw_snd_ac97_eapd(SYSCTL_HANDLER_ARGS) 870 { 871 struct ac97_info *codec; 872 int ea, inv, err = 0; 873 u_int16_t val; 874 875 codec = oidp->oid_arg1; 876 if (codec == NULL || codec->id == 0 || codec->lock == NULL) 877 return EINVAL; 878 snd_mtxlock(codec->lock); 879 val = ac97_rdcd(codec, AC97_REG_POWER); 880 inv = (codec->flags & AC97_F_EAPD_INV) ? 0 : 1; 881 ea = (val >> 15) ^ inv; 882 snd_mtxunlock(codec->lock); 883 err = sysctl_handle_int(oidp, &ea, sizeof(ea), req); 884 if (err == 0 && req->newptr != NULL) { 885 if (ea != 0 && ea != 1) 886 return EINVAL; 887 if (ea != ((val >> 15) ^ inv)) { 888 snd_mtxlock(codec->lock); 889 ac97_wrcd(codec, AC97_REG_POWER, val ^ 0x8000); 890 snd_mtxunlock(codec->lock); 891 } 892 } 893 return err; 894 } 895 #endif 896 897 static void 898 ac97_init_sysctl(struct ac97_info *codec) 899 { 900 #ifdef SND_DYNSYSCTL 901 u_int16_t orig, val; 902 903 if (codec == NULL || codec->dev == NULL) 904 return; 905 snd_mtxlock(codec->lock); 906 orig = ac97_rdcd(codec, AC97_REG_POWER); 907 ac97_wrcd(codec, AC97_REG_POWER, orig ^ 0x8000); 908 val = ac97_rdcd(codec, AC97_REG_POWER); 909 ac97_wrcd(codec, AC97_REG_POWER, orig); 910 snd_mtxunlock(codec->lock); 911 if ((val & 0x8000) == (orig & 0x8000)) 912 return; 913 SYSCTL_ADD_PROC(device_get_sysctl_ctx(codec->dev), 914 SYSCTL_CHILDREN(device_get_sysctl_tree(codec->dev)), 915 OID_AUTO, "eapd", CTLTYPE_INT | CTLFLAG_RW, 916 codec, sizeof(codec), sysctl_hw_snd_ac97_eapd, 917 "I", "AC97 External Amplifier"); 918 #endif 919 } 920 921 static int 922 ac97mix_init(struct snd_mixer *m) 923 { 924 struct ac97_info *codec = mix_getdevinfo(m); 925 struct snddev_info *d; 926 u_int32_t i, mask; 927 928 if (codec == NULL) 929 return -1; 930 931 if (ac97_initmixer(codec)) 932 return -1; 933 934 switch (codec->id) { 935 case 0x41445374: /* AD1981B */ 936 if (codec->subvendor == 0x02d91014) { 937 /* 938 * IBM Thinkcentre: 939 * Tie "ogain" and "phone" to "vol" since its 940 * master volume is basically useless and can't 941 * control anything. 942 */ 943 mask = 0; 944 if (codec->mix[SOUND_MIXER_OGAIN].enable) 945 mask |= SOUND_MASK_OGAIN; 946 if (codec->mix[SOUND_MIXER_PHONEOUT].enable) 947 mask |= SOUND_MASK_PHONEOUT; 948 if (codec->mix[SOUND_MIXER_VOLUME].enable) 949 mix_setparentchild(m, SOUND_MIXER_VOLUME, 950 mask); 951 else { 952 mix_setparentchild(m, SOUND_MIXER_VOLUME, 953 mask); 954 mix_setrealdev(m, SOUND_MIXER_VOLUME, 955 SOUND_MIXER_NONE); 956 } 957 } 958 break; 959 case 0x434d4941: /* CMI9738 */ 960 case 0x434d4961: /* CMI9739 */ 961 case 0x434d4978: /* CMI9761 */ 962 case 0x434d4982: /* CMI9761 */ 963 case 0x434d4983: /* CMI9761 */ 964 ac97_wrcd(codec, AC97_MIX_PCM, 0); 965 bzero(&codec->mix[SOUND_MIXER_PCM], 966 sizeof(codec->mix[SOUND_MIXER_PCM])); 967 d = device_get_softc(codec->dev); 968 if (d != NULL) 969 d->flags |= SD_F_SOFTPCMVOL; 970 /* XXX How about master volume ? */ 971 break; 972 default: 973 break; 974 } 975 976 #if 0 977 /* XXX For the sake of debugging purposes */ 978 mix_setparentchild(m, SOUND_MIXER_VOLUME, 979 SOUND_MASK_PCM | SOUND_MASK_CD); 980 mix_setrealdev(m, SOUND_MIXER_VOLUME, SOUND_MIXER_NONE); 981 ac97_wrcd(codec, AC97_MIX_MASTER, 0); 982 #endif 983 984 mask = 0; 985 for (i = 0; i < 32; i++) 986 mask |= codec->mix[i].enable? 1 << i : 0; 987 mix_setdevs(m, mask); 988 989 mask = 0; 990 for (i = 0; i < 32; i++) 991 mask |= codec->mix[i].recidx? 1 << i : 0; 992 mix_setrecdevs(m, mask); 993 994 ac97_init_sysctl(codec); 995 996 return 0; 997 } 998 999 static int 1000 ac97mix_uninit(struct snd_mixer *m) 1001 { 1002 struct ac97_info *codec = mix_getdevinfo(m); 1003 1004 if (codec == NULL) 1005 return -1; 1006 /* 1007 if (ac97_uninitmixer(codec)) 1008 return -1; 1009 */ 1010 ac97_destroy(codec); 1011 return 0; 1012 } 1013 1014 static int 1015 ac97mix_reinit(struct snd_mixer *m) 1016 { 1017 struct ac97_info *codec = mix_getdevinfo(m); 1018 1019 if (codec == NULL) 1020 return -1; 1021 return ac97_reinitmixer(codec); 1022 } 1023 1024 static int 1025 ac97mix_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right) 1026 { 1027 struct ac97_info *codec = mix_getdevinfo(m); 1028 1029 if (codec == NULL) 1030 return -1; 1031 return ac97_setmixer(codec, dev, left, right); 1032 } 1033 1034 static int 1035 ac97mix_setrecsrc(struct snd_mixer *m, u_int32_t src) 1036 { 1037 int i; 1038 struct ac97_info *codec = mix_getdevinfo(m); 1039 1040 if (codec == NULL) 1041 return -1; 1042 for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) 1043 if ((src & (1 << i)) != 0) 1044 break; 1045 return (ac97_setrecsrc(codec, i) == 0)? 1 << i : -1; 1046 } 1047 1048 static kobj_method_t ac97mixer_methods[] = { 1049 KOBJMETHOD(mixer_init, ac97mix_init), 1050 KOBJMETHOD(mixer_uninit, ac97mix_uninit), 1051 KOBJMETHOD(mixer_reinit, ac97mix_reinit), 1052 KOBJMETHOD(mixer_set, ac97mix_set), 1053 KOBJMETHOD(mixer_setrecsrc, ac97mix_setrecsrc), 1054 { 0, 0 } 1055 }; 1056 MIXER_DECLARE(ac97mixer); 1057 1058 /* -------------------------------------------------------------------- */ 1059 1060 kobj_class_t 1061 ac97_getmixerclass(void) 1062 { 1063 return &ac97mixer_class; 1064 } 1065