1 /*- 2 * Copyright (c) 2006 Stephane E. Potvin <sepotvin@videotron.ca> 3 * Copyright (c) 2006 Ariff Abdullah <ariff@FreeBSD.org> 4 * Copyright (c) 2008-2012 Alexander Motin <mav@FreeBSD.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 /* 30 * Intel High Definition Audio (Audio function quirks) driver for FreeBSD. 31 */ 32 33 #ifdef HAVE_KERNEL_OPTION_HEADERS 34 #include "opt_snd.h" 35 #endif 36 37 #include <dev/sound/pcm/sound.h> 38 39 #include <sys/ctype.h> 40 41 #include <dev/sound/pci/hda/hdac.h> 42 #include <dev/sound/pci/hda/hdaa.h> 43 #include <dev/sound/pci/hda/hda_reg.h> 44 #include <dev/sound/pci/hda/hdaa_patches.h> 45 46 SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pci/hda/hdaa_patches.c 269158 2014-07-27 20:14:22Z adrian $"); 47 48 static const struct { 49 uint32_t model; 50 uint32_t id; 51 uint32_t subsystemid; 52 uint32_t set, unset; 53 uint32_t gpio; 54 } hdac_quirks[] = { 55 /* 56 * XXX Force stereo quirk. Monoural recording / playback 57 * on few codecs (especially ALC880) seems broken or 58 * perhaps unsupported. 59 */ 60 { HDA_MATCH_ALL, HDA_MATCH_ALL, HDA_MATCH_ALL, 61 HDAA_QUIRK_FORCESTEREO | HDAA_QUIRK_IVREF, 0, 62 0 }, 63 { ACER_ALL_SUBVENDOR, HDA_MATCH_ALL, HDA_MATCH_ALL, 64 0, 0, 65 HDAA_GPIO_SET(0) }, 66 { ASUS_G2K_SUBVENDOR, HDA_CODEC_ALC660, HDA_MATCH_ALL, 67 0, 0, 68 HDAA_GPIO_SET(0) }, 69 { ASUS_M5200_SUBVENDOR, HDA_CODEC_ALC880, HDA_MATCH_ALL, 70 0, 0, 71 HDAA_GPIO_SET(0) }, 72 { ASUS_A7M_SUBVENDOR, HDA_CODEC_ALC880, HDA_MATCH_ALL, 73 0, 0, 74 HDAA_GPIO_SET(0) }, 75 { ASUS_A7T_SUBVENDOR, HDA_CODEC_ALC882, HDA_MATCH_ALL, 76 0, 0, 77 HDAA_GPIO_SET(0) }, 78 { ASUS_W2J_SUBVENDOR, HDA_CODEC_ALC882, HDA_MATCH_ALL, 79 0, 0, 80 HDAA_GPIO_SET(0) }, 81 { ASUS_U5F_SUBVENDOR, HDA_CODEC_AD1986A, HDA_MATCH_ALL, 82 HDAA_QUIRK_EAPDINV, 0, 83 0 }, 84 { ASUS_A8X_SUBVENDOR, HDA_CODEC_AD1986A, HDA_MATCH_ALL, 85 HDAA_QUIRK_EAPDINV, 0, 86 0 }, 87 { ASUS_F3JC_SUBVENDOR, HDA_CODEC_ALC861, HDA_MATCH_ALL, 88 HDAA_QUIRK_OVREF, 0, 89 0 }, 90 { UNIWILL_9075_SUBVENDOR, HDA_CODEC_ALC861, HDA_MATCH_ALL, 91 HDAA_QUIRK_OVREF, 0, 92 0 }, 93 /*{ ASUS_M2N_SUBVENDOR, HDA_CODEC_AD1988, HDA_MATCH_ALL, 94 HDAA_QUIRK_IVREF80, HDAA_QUIRK_IVREF50 | HDAA_QUIRK_IVREF100, 95 0 },*/ 96 { MEDION_MD95257_SUBVENDOR, HDA_CODEC_ALC880, HDA_MATCH_ALL, 97 0, 0, 98 HDAA_GPIO_SET(1) }, 99 { LENOVO_3KN100_SUBVENDOR, HDA_CODEC_AD1986A, HDA_MATCH_ALL, 100 HDAA_QUIRK_EAPDINV | HDAA_QUIRK_SENSEINV, 0, 101 0 }, 102 { SAMSUNG_Q1_SUBVENDOR, HDA_CODEC_AD1986A, HDA_MATCH_ALL, 103 HDAA_QUIRK_EAPDINV, 0, 104 0 }, 105 { APPLE_MB3_SUBVENDOR, HDA_CODEC_ALC885, HDA_MATCH_ALL, 106 HDAA_QUIRK_OVREF50, 0, 107 HDAA_GPIO_SET(0) }, 108 { APPLE_INTEL_MAC, HDA_CODEC_STAC9221, HDA_MATCH_ALL, 109 0, 0, 110 HDAA_GPIO_SET(0) | HDAA_GPIO_SET(1) }, 111 { APPLE_MACBOOKAIR31, HDA_CODEC_CS4206, HDA_MATCH_ALL, 112 0, 0, 113 HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) }, 114 { APPLE_MACBOOKPRO55, HDA_CODEC_CS4206, HDA_MATCH_ALL, 115 0, 0, 116 HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) }, 117 { APPLE_MACBOOKPRO71, HDA_CODEC_CS4206, HDA_MATCH_ALL, 118 0, 0, 119 HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) }, 120 { HDA_INTEL_MACBOOKPRO92, HDA_CODEC_CS4206, HDA_MATCH_ALL, 121 0, 0, 122 HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) }, 123 { DELL_D630_SUBVENDOR, HDA_CODEC_STAC9205X, HDA_MATCH_ALL, 124 0, 0, 125 HDAA_GPIO_SET(0) }, 126 { DELL_V1400_SUBVENDOR, HDA_CODEC_STAC9228X, HDA_MATCH_ALL, 127 0, 0, 128 HDAA_GPIO_SET(2) }, 129 { DELL_V1500_SUBVENDOR, HDA_CODEC_STAC9205X, HDA_MATCH_ALL, 130 0, 0, 131 HDAA_GPIO_SET(0) }, 132 { HDA_MATCH_ALL, HDA_CODEC_AD1988, HDA_MATCH_ALL, 133 HDAA_QUIRK_IVREF80, HDAA_QUIRK_IVREF50 | HDAA_QUIRK_IVREF100, 134 0 }, 135 { HDA_MATCH_ALL, HDA_CODEC_AD1988B, HDA_MATCH_ALL, 136 HDAA_QUIRK_IVREF80, HDAA_QUIRK_IVREF50 | HDAA_QUIRK_IVREF100, 137 0 }, 138 { HDA_MATCH_ALL, HDA_CODEC_CX20549, HDA_MATCH_ALL, 139 0, HDAA_QUIRK_FORCESTEREO, 140 0 }, 141 /* Mac Pro 1,1 requires ovref for proper volume level. */ 142 { 0x00000000, HDA_CODEC_ALC885, 0x106b0c00, 143 0, HDAA_QUIRK_OVREF, 144 0 } 145 }; 146 147 static void 148 hdac_pin_patch(struct hdaa_widget *w) 149 { 150 const char *patch = NULL; 151 uint32_t config, orig, id, subid; 152 nid_t nid = w->nid; 153 154 config = orig = w->wclass.pin.config; 155 id = hdaa_codec_id(w->devinfo); 156 subid = hdaa_card_id(w->devinfo); 157 158 /* XXX: Old patches require complete review. 159 * Now they may create more problem then solve due to 160 * incorrect associations. 161 */ 162 if (id == HDA_CODEC_ALC880 && subid == LG_LW20_SUBVENDOR) { 163 switch (nid) { 164 case 26: 165 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK; 166 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN; 167 break; 168 case 27: 169 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK; 170 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT; 171 break; 172 default: 173 break; 174 } 175 } else if (id == HDA_CODEC_ALC880 && 176 (subid == CLEVO_D900T_SUBVENDOR || 177 subid == ASUS_M5200_SUBVENDOR)) { 178 /* 179 * Super broken BIOS 180 */ 181 switch (nid) { 182 case 24: /* MIC1 */ 183 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK; 184 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN; 185 break; 186 case 25: /* XXX MIC2 */ 187 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK; 188 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN; 189 break; 190 case 26: /* LINE1 */ 191 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK; 192 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN; 193 break; 194 case 27: /* XXX LINE2 */ 195 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK; 196 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN; 197 break; 198 case 28: /* CD */ 199 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK; 200 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_CD; 201 break; 202 } 203 } else if (id == HDA_CODEC_ALC883 && 204 (subid == MSI_MS034A_SUBVENDOR || 205 HDA_DEV_MATCH(ACER_ALL_SUBVENDOR, subid))) { 206 switch (nid) { 207 case 25: 208 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK | 209 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK); 210 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN | 211 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED); 212 break; 213 case 28: 214 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK | 215 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK); 216 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_CD | 217 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED); 218 break; 219 } 220 } else if (id == HDA_CODEC_CX20549 && subid == 221 HP_V3000_SUBVENDOR) { 222 switch (nid) { 223 case 18: 224 config &= ~HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK; 225 config |= HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE; 226 break; 227 case 20: 228 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK | 229 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK); 230 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN | 231 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED); 232 break; 233 case 21: 234 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK | 235 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK); 236 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_CD | 237 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED); 238 break; 239 } 240 } else if (id == HDA_CODEC_CX20551 && subid == 241 HP_DV5000_SUBVENDOR) { 242 switch (nid) { 243 case 20: 244 case 21: 245 config &= ~HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK; 246 config |= HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE; 247 break; 248 } 249 } else if (id == HDA_CODEC_ALC861 && subid == 250 ASUS_W6F_SUBVENDOR) { 251 switch (nid) { 252 case 11: 253 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK | 254 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK); 255 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_OUT | 256 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED); 257 break; 258 case 12: 259 case 14: 260 case 16: 261 case 31: 262 case 32: 263 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK | 264 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK); 265 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN | 266 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED); 267 break; 268 case 15: 269 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK | 270 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK); 271 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT | 272 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK); 273 break; 274 } 275 } else if (id == HDA_CODEC_ALC861 && subid == 276 UNIWILL_9075_SUBVENDOR) { 277 switch (nid) { 278 case 15: 279 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK | 280 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK); 281 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT | 282 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK); 283 break; 284 } 285 } 286 287 /* New patches */ 288 if (id == HDA_CODEC_ALC283 && (subid == ACER_C720_SUBVENDOR || 289 subid == ACER_C720_SUBVENDOR2)) { 290 switch (nid) { 291 case 20: 292 patch = "as=2 seq=0"; 293 break; 294 case 25: 295 patch = "as=1 seq=0"; 296 break; 297 case 27: 298 /* 299 patch = "device=Headphones conn=Fixed as=2 seq=15"; 300 w->enable = 1; 301 */ 302 break; 303 case 33: 304 break; 305 } 306 } else 307 if (id == HDA_CODEC_AD1984A && 308 subid == LENOVO_X300_SUBVENDOR) { 309 switch (nid) { 310 case 17: /* Headphones with redirection */ 311 patch = "as=1 seq=15"; 312 break; 313 case 20: /* Two mics together */ 314 patch = "as=2 seq=15"; 315 break; 316 } 317 } else if (id == HDA_CODEC_AD1986A && 318 (subid == ASUS_M2NPVMX_SUBVENDOR || 319 subid == ASUS_A8NVMCSM_SUBVENDOR || 320 subid == ASUS_P5PL2_SUBVENDOR)) { 321 switch (nid) { 322 case 26: /* Headphones with redirection */ 323 patch = "as=1 seq=15"; 324 break; 325 case 28: /* 5.1 out => 2.0 out + 1 input */ 326 patch = "device=Line-in as=8 seq=1"; 327 break; 328 case 29: /* Can't use this as input, as the only available mic 329 * preamplifier is busy by front panel mic (nid 31). 330 * If you want to use this rear connector as mic input, 331 * you have to disable the front panel one. */ 332 patch = "as=0"; 333 break; 334 case 31: /* Lot of inputs configured with as=15 and unusable */ 335 patch = "as=8 seq=3"; 336 break; 337 case 32: 338 patch = "as=8 seq=4"; 339 break; 340 case 34: 341 patch = "as=8 seq=5"; 342 break; 343 case 36: 344 patch = "as=8 seq=6"; 345 break; 346 } 347 } else if (id == HDA_CODEC_ALC260 && 348 HDA_DEV_MATCH(SONY_S5_SUBVENDOR, subid)) { 349 switch (nid) { 350 case 16: 351 patch = "seq=15 device=Headphones"; 352 break; 353 } 354 } else if (id == HDA_CODEC_ALC268) { 355 if (subid == ACER_T5320_SUBVENDOR) { 356 switch (nid) { 357 case 20: /* Headphones Jack */ 358 patch = "as=1 seq=15"; 359 break; 360 } 361 } 362 } else if (id == HDA_CODEC_CX20561 && 363 subid == LENOVO_B450_SUBVENDOR) { 364 switch (nid) { 365 case 22: 366 patch = "as=1 seq=15"; 367 break; 368 } 369 } else if (id == HDA_CODEC_CX20561 && 370 subid == LENOVO_T400_SUBVENDOR) { 371 switch (nid) { 372 case 22: 373 patch = "as=1 seq=15"; 374 break; 375 case 26: 376 patch = "as=1 seq=0"; 377 break; 378 } 379 } else if (id == HDA_CODEC_CX20590 && 380 (subid == LENOVO_X1_SUBVENDOR || 381 subid == LENOVO_X220_SUBVENDOR || 382 subid == LENOVO_T420_SUBVENDOR || 383 subid == LENOVO_T520_SUBVENDOR || 384 subid == LENOVO_G580_SUBVENDOR)) { 385 switch (nid) { 386 case 25: 387 patch = "as=1 seq=15"; 388 break; 389 /* 390 * Group onboard mic and headphone mic 391 * together. Fixes onboard mic. 392 */ 393 case 27: 394 patch = "as=2 seq=15"; 395 break; 396 case 35: 397 patch = "as=2"; 398 break; 399 } 400 } else if (id == HDA_CODEC_ALC269 && 401 (subid == LENOVO_X1CRBN_SUBVENDOR || 402 subid == LENOVO_T430_SUBVENDOR || 403 subid == LENOVO_T430S_SUBVENDOR || 404 subid == LENOVO_T530_SUBVENDOR)) { 405 switch (nid) { 406 case 21: 407 patch = "as=1 seq=15"; 408 break; 409 } 410 } else if (id == HDA_CODEC_ALC269 && 411 subid == ASUS_UX31A_SUBVENDOR) { 412 switch (nid) { 413 case 33: 414 patch = "as=1 seq=15"; 415 break; 416 } 417 } else if (id == HDA_CODEC_ALC892 && 418 subid == INTEL_DH87RL_SUBVENDOR) { 419 switch (nid) { 420 case 27: 421 patch = "as=1 seq=15"; 422 break; 423 } 424 } 425 426 if (patch != NULL) 427 config = hdaa_widget_pin_patch(config, patch); 428 HDA_BOOTVERBOSE( 429 if (config != orig) 430 device_printf(w->devinfo->dev, 431 "Patching pin config nid=%u 0x%08x -> 0x%08x\n", 432 nid, orig, config); 433 ); 434 w->wclass.pin.config = config; 435 } 436 437 static void 438 hdaa_widget_patch(struct hdaa_widget *w) 439 { 440 struct hdaa_devinfo *devinfo = w->devinfo; 441 uint32_t orig; 442 nid_t beeper = -1; 443 uint32_t id, subid; 444 445 id = hdaa_codec_id(devinfo); 446 subid = hdaa_card_id(devinfo); 447 448 orig = w->param.widget_cap; 449 /* On some codecs beeper is an input pin, but it is not recordable 450 alone. Also most of BIOSes does not declare beeper pin. 451 Change beeper pin node type to beeper to help parser. */ 452 switch (hdaa_codec_id(devinfo)) { 453 case HDA_CODEC_AD1882: 454 case HDA_CODEC_AD1883: 455 case HDA_CODEC_AD1984: 456 case HDA_CODEC_AD1984A: 457 case HDA_CODEC_AD1984B: 458 case HDA_CODEC_AD1987: 459 case HDA_CODEC_AD1988: 460 case HDA_CODEC_AD1988B: 461 case HDA_CODEC_AD1989B: 462 beeper = 26; 463 break; 464 case HDA_CODEC_ALC260: 465 beeper = 23; 466 break; 467 } 468 if (hda_get_vendor_id(devinfo->dev) == REALTEK_VENDORID && 469 hdaa_codec_id(devinfo) != HDA_CODEC_ALC260) 470 beeper = 29; 471 if (w->nid == beeper) { 472 w->param.widget_cap &= ~HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_MASK; 473 w->param.widget_cap |= HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET << 474 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT; 475 w->waspin = 1; 476 } 477 /* 478 * Clear "digital" flag from digital mic input, as its signal then goes 479 * to "analog" mixer and this separation just limits functionaity. 480 */ 481 if (hdaa_codec_id(devinfo) == HDA_CODEC_AD1984A && 482 w->nid == 23) 483 w->param.widget_cap &= ~HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL_MASK; 484 HDA_BOOTVERBOSE( 485 if (w->param.widget_cap != orig) { 486 device_printf(w->devinfo->dev, 487 "Patching widget caps nid=%u 0x%08x -> 0x%08x\n", 488 w->nid, orig, w->param.widget_cap); 489 } 490 ); 491 492 #if 1 493 /* 494 * Redirect the headphone plug sense (NID 33 -> redir to 12). 495 * 496 * Disable the remixer (NID 11). There was a comment in the linux 497 * driver that disabling the remixer removes low level whitenoise. 498 * this makes sense since the mixer's unconnected inputs might have 499 * noise on them that leaks through. 500 */ 501 if (id == HDA_CODEC_ALC283 && (subid == ACER_C720_SUBVENDOR || 502 subid == ACER_C720_SUBVENDOR2)) { 503 if (w->nid == 33) 504 w->senseredir = 12; 505 if (w->nid == 11) 506 w->enable = 0; 507 } 508 #endif 509 510 if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) 511 hdac_pin_patch(w); 512 } 513 514 void 515 hdaa_patch(struct hdaa_devinfo *devinfo) 516 { 517 struct hdaa_widget *w; 518 uint32_t id, subid, subsystemid; 519 int i; 520 521 id = hdaa_codec_id(devinfo); 522 subid = hdaa_card_id(devinfo); 523 subsystemid = hda_get_subsystem_id(devinfo->dev); 524 525 /* 526 * Quirks 527 */ 528 for (i = 0; i < nitems(hdac_quirks); i++) { 529 if (!(HDA_DEV_MATCH(hdac_quirks[i].model, subid) && 530 HDA_DEV_MATCH(hdac_quirks[i].id, id) && 531 HDA_DEV_MATCH(hdac_quirks[i].subsystemid, subsystemid))) 532 continue; 533 devinfo->quirks |= hdac_quirks[i].set; 534 devinfo->quirks &= ~(hdac_quirks[i].unset); 535 devinfo->gpio = hdac_quirks[i].gpio; 536 } 537 538 /* Apply per-widget patch. */ 539 for (i = devinfo->startnode; i < devinfo->endnode; i++) { 540 w = hdaa_widget_get(devinfo, i); 541 if (w == NULL) 542 continue; 543 hdaa_widget_patch(w); 544 } 545 546 switch (id) { 547 case HDA_CODEC_AD1983: 548 /* 549 * This CODEC has several possible usages, but none 550 * fit the parser best. Help parser to choose better. 551 */ 552 /* Disable direct unmixed playback to get pcm volume. */ 553 w = hdaa_widget_get(devinfo, 5); 554 if (w != NULL) 555 w->connsenable[0] = 0; 556 w = hdaa_widget_get(devinfo, 6); 557 if (w != NULL) 558 w->connsenable[0] = 0; 559 w = hdaa_widget_get(devinfo, 11); 560 if (w != NULL) 561 w->connsenable[0] = 0; 562 /* Disable mic and line selectors. */ 563 w = hdaa_widget_get(devinfo, 12); 564 if (w != NULL) 565 w->connsenable[1] = 0; 566 w = hdaa_widget_get(devinfo, 13); 567 if (w != NULL) 568 w->connsenable[1] = 0; 569 /* Disable recording from mono playback mix. */ 570 w = hdaa_widget_get(devinfo, 20); 571 if (w != NULL) 572 w->connsenable[3] = 0; 573 break; 574 case HDA_CODEC_AD1986A: 575 /* 576 * This CODEC has overcomplicated input mixing. 577 * Make some cleaning there. 578 */ 579 /* Disable input mono mixer. Not needed and not supported. */ 580 w = hdaa_widget_get(devinfo, 43); 581 if (w != NULL) 582 w->enable = 0; 583 /* Disable any with any input mixing mesh. Use separately. */ 584 w = hdaa_widget_get(devinfo, 39); 585 if (w != NULL) 586 w->enable = 0; 587 w = hdaa_widget_get(devinfo, 40); 588 if (w != NULL) 589 w->enable = 0; 590 w = hdaa_widget_get(devinfo, 41); 591 if (w != NULL) 592 w->enable = 0; 593 w = hdaa_widget_get(devinfo, 42); 594 if (w != NULL) 595 w->enable = 0; 596 /* Disable duplicate mixer node connector. */ 597 w = hdaa_widget_get(devinfo, 15); 598 if (w != NULL) 599 w->connsenable[3] = 0; 600 /* There is only one mic preamplifier, use it effectively. */ 601 w = hdaa_widget_get(devinfo, 31); 602 if (w != NULL) { 603 if ((w->wclass.pin.config & 604 HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) == 605 HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN) { 606 w = hdaa_widget_get(devinfo, 16); 607 if (w != NULL) 608 w->connsenable[2] = 0; 609 } else { 610 w = hdaa_widget_get(devinfo, 15); 611 if (w != NULL) 612 w->connsenable[0] = 0; 613 } 614 } 615 w = hdaa_widget_get(devinfo, 32); 616 if (w != NULL) { 617 if ((w->wclass.pin.config & 618 HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) == 619 HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN) { 620 w = hdaa_widget_get(devinfo, 16); 621 if (w != NULL) 622 w->connsenable[0] = 0; 623 } else { 624 w = hdaa_widget_get(devinfo, 15); 625 if (w != NULL) 626 w->connsenable[1] = 0; 627 } 628 } 629 630 if (subid == ASUS_A8X_SUBVENDOR) { 631 /* 632 * This is just plain ridiculous.. There 633 * are several A8 series that share the same 634 * pci id but works differently (EAPD). 635 */ 636 w = hdaa_widget_get(devinfo, 26); 637 if (w != NULL && w->type == 638 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX && 639 (w->wclass.pin.config & 640 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) != 641 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE) 642 devinfo->quirks &= 643 ~HDAA_QUIRK_EAPDINV; 644 } 645 break; 646 case HDA_CODEC_AD1981HD: 647 /* 648 * This CODEC has very unusual design with several 649 * points inappropriate for the present parser. 650 */ 651 /* Disable recording from mono playback mix. */ 652 w = hdaa_widget_get(devinfo, 21); 653 if (w != NULL) 654 w->connsenable[3] = 0; 655 /* Disable rear to front mic mixer, use separately. */ 656 w = hdaa_widget_get(devinfo, 31); 657 if (w != NULL) 658 w->enable = 0; 659 /* Disable direct playback, use mixer. */ 660 w = hdaa_widget_get(devinfo, 5); 661 if (w != NULL) 662 w->connsenable[0] = 0; 663 w = hdaa_widget_get(devinfo, 6); 664 if (w != NULL) 665 w->connsenable[0] = 0; 666 w = hdaa_widget_get(devinfo, 9); 667 if (w != NULL) 668 w->connsenable[0] = 0; 669 w = hdaa_widget_get(devinfo, 24); 670 if (w != NULL) 671 w->connsenable[0] = 0; 672 break; 673 case HDA_CODEC_ALC269: 674 /* 675 * ASUS EeePC 1001px has strange variant of ALC269 CODEC, 676 * that mutes speaker if unused mixer at NID 15 is muted. 677 * Probably CODEC incorrectly reports internal connections. 678 * Hide that muter from the driver. There are several CODECs 679 * sharing this ID and I have not enough information about 680 * them to implement more universal solution. 681 */ 682 if (subid == 0x84371043) { 683 w = hdaa_widget_get(devinfo, 15); 684 if (w != NULL) 685 w->param.inamp_cap = 0; 686 } 687 break; 688 case HDA_CODEC_CX20582: 689 case HDA_CODEC_CX20583: 690 case HDA_CODEC_CX20584: 691 case HDA_CODEC_CX20585: 692 case HDA_CODEC_CX20590: 693 /* 694 * These codecs have extra connectivity on record side 695 * too reach for the present parser. 696 */ 697 w = hdaa_widget_get(devinfo, 20); 698 if (w != NULL) 699 w->connsenable[1] = 0; 700 w = hdaa_widget_get(devinfo, 21); 701 if (w != NULL) 702 w->connsenable[1] = 0; 703 w = hdaa_widget_get(devinfo, 22); 704 if (w != NULL) 705 w->connsenable[0] = 0; 706 break; 707 case HDA_CODEC_VT1708S_0: 708 case HDA_CODEC_VT1708S_1: 709 case HDA_CODEC_VT1708S_2: 710 case HDA_CODEC_VT1708S_3: 711 case HDA_CODEC_VT1708S_4: 712 case HDA_CODEC_VT1708S_5: 713 case HDA_CODEC_VT1708S_6: 714 case HDA_CODEC_VT1708S_7: 715 /* 716 * These codecs have hidden mic boost controls. 717 */ 718 w = hdaa_widget_get(devinfo, 26); 719 if (w != NULL) 720 w->param.inamp_cap = 721 (40 << HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT) | 722 (3 << HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT) | 723 (0 << HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT); 724 w = hdaa_widget_get(devinfo, 30); 725 if (w != NULL) 726 w->param.inamp_cap = 727 (40 << HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT) | 728 (3 << HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT) | 729 (0 << HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT); 730 break; 731 } 732 } 733 734 void 735 hdaa_patch_direct(struct hdaa_devinfo *devinfo) 736 { 737 device_t dev = devinfo->dev; 738 uint32_t id, subid, val; 739 740 id = hdaa_codec_id(devinfo); 741 subid = hdaa_card_id(devinfo); 742 743 switch (id) { 744 case HDA_CODEC_VT1708S_0: 745 case HDA_CODEC_VT1708S_1: 746 case HDA_CODEC_VT1708S_2: 747 case HDA_CODEC_VT1708S_3: 748 case HDA_CODEC_VT1708S_4: 749 case HDA_CODEC_VT1708S_5: 750 case HDA_CODEC_VT1708S_6: 751 case HDA_CODEC_VT1708S_7: 752 /* Enable Mic Boost Volume controls. */ 753 hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid, 754 0xf98, 0x01)); 755 /* Fall though */ 756 case HDA_CODEC_VT1818S: 757 /* Don't bypass mixer. */ 758 hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid, 759 0xf88, 0xc0)); 760 break; 761 } 762 if (subid == APPLE_INTEL_MAC) 763 hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid, 764 0x7e7, 0)); 765 if (id == HDA_CODEC_ALC269) { 766 if (subid == 0x16e31043 || subid == 0x831a1043 || 767 subid == 0x834a1043 || subid == 0x83981043 || 768 subid == 0x83ce1043) { 769 /* 770 * The ditital mics on some Asus laptops produce 771 * differential signals instead of expected stereo. 772 * That results in silence if downmix it to mono. 773 * To workaround, make codec to handle signal as mono. 774 */ 775 hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, 0x20, 0x07)); 776 val = hda_command(dev, HDA_CMD_GET_PROCESSING_COEFF(0, 0x20)); 777 hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, 0x20, 0x07)); 778 hda_command(dev, HDA_CMD_SET_PROCESSING_COEFF(0, 0x20, val|0x80)); 779 } 780 } 781 if (id == HDA_CODEC_ALC283) { 782 if (subid == ACER_C720_SUBVENDOR || 783 subid == ACER_C720_SUBVENDOR2) 784 hdaa_patch_direct_acer_c720(devinfo); 785 } 786 } 787 788 /* XXX move me to a better place */ 789 uint32_t 790 hda_read_coef_idx(device_t dev, nid_t nid, unsigned int coef_idx) 791 { 792 uint32_t val; 793 794 hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, nid, coef_idx)); 795 val = hda_command(dev, HDA_CMD_GET_PROCESSING_COEFF(0, nid)); 796 return val; 797 } 798 799 void 800 hda_write_coef_idx(device_t dev, nid_t nid, unsigned int coef_idx, 801 unsigned coef_val) 802 { 803 hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, nid, coef_idx)); 804 hda_command(dev, HDA_CMD_SET_PROCESSING_COEFF(0, nid, coef_val)); 805 } 806