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