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 switch (nid) { 290 case 20: 291 patch = "as=2 seq=0"; 292 break; 293 case 25: 294 patch = "as=1 seq=0"; 295 break; 296 case 27: 297 /* 298 patch = "device=Headphones conn=Fixed as=2 seq=15"; 299 w->enable = 1; 300 */ 301 break; 302 case 33: 303 break; 304 } 305 } else 306 if (id == HDA_CODEC_AD1984A && 307 subid == LENOVO_X300_SUBVENDOR) { 308 switch (nid) { 309 case 17: /* Headphones with redirection */ 310 patch = "as=1 seq=15"; 311 break; 312 case 20: /* Two mics together */ 313 patch = "as=2 seq=15"; 314 break; 315 } 316 } else if (id == HDA_CODEC_AD1986A && 317 (subid == ASUS_M2NPVMX_SUBVENDOR || 318 subid == ASUS_A8NVMCSM_SUBVENDOR || 319 subid == ASUS_P5PL2_SUBVENDOR)) { 320 switch (nid) { 321 case 26: /* Headphones with redirection */ 322 patch = "as=1 seq=15"; 323 break; 324 case 28: /* 5.1 out => 2.0 out + 1 input */ 325 patch = "device=Line-in as=8 seq=1"; 326 break; 327 case 29: /* Can't use this as input, as the only available mic 328 * preamplifier is busy by front panel mic (nid 31). 329 * If you want to use this rear connector as mic input, 330 * you have to disable the front panel one. */ 331 patch = "as=0"; 332 break; 333 case 31: /* Lot of inputs configured with as=15 and unusable */ 334 patch = "as=8 seq=3"; 335 break; 336 case 32: 337 patch = "as=8 seq=4"; 338 break; 339 case 34: 340 patch = "as=8 seq=5"; 341 break; 342 case 36: 343 patch = "as=8 seq=6"; 344 break; 345 } 346 } else if (id == HDA_CODEC_ALC260 && 347 HDA_DEV_MATCH(SONY_S5_SUBVENDOR, subid)) { 348 switch (nid) { 349 case 16: 350 patch = "seq=15 device=Headphones"; 351 break; 352 } 353 } else if (id == HDA_CODEC_ALC268) { 354 if (subid == ACER_T5320_SUBVENDOR) { 355 switch (nid) { 356 case 20: /* Headphones Jack */ 357 patch = "as=1 seq=15"; 358 break; 359 } 360 } 361 } else if (id == HDA_CODEC_CX20561 && 362 subid == LENOVO_B450_SUBVENDOR) { 363 switch (nid) { 364 case 22: 365 patch = "as=1 seq=15"; 366 break; 367 } 368 } else if (id == HDA_CODEC_CX20561 && 369 subid == LENOVO_T400_SUBVENDOR) { 370 switch (nid) { 371 case 22: 372 patch = "as=1 seq=15"; 373 break; 374 case 26: 375 patch = "as=1 seq=0"; 376 break; 377 } 378 } else if (id == HDA_CODEC_CX20590 && 379 (subid == LENOVO_X1_SUBVENDOR || 380 subid == LENOVO_X220_SUBVENDOR || 381 subid == LENOVO_T420_SUBVENDOR || 382 subid == LENOVO_T520_SUBVENDOR || 383 subid == LENOVO_G580_SUBVENDOR)) { 384 switch (nid) { 385 case 25: 386 patch = "as=1 seq=15"; 387 break; 388 /* 389 * Group onboard mic and headphone mic 390 * together. Fixes onboard mic. 391 */ 392 case 27: 393 patch = "as=2 seq=15"; 394 break; 395 case 35: 396 patch = "as=2"; 397 break; 398 } 399 } else if (id == HDA_CODEC_ALC269 && 400 (subid == LENOVO_X1CRBN_SUBVENDOR || 401 subid == LENOVO_T430_SUBVENDOR || 402 subid == LENOVO_T430S_SUBVENDOR || 403 subid == LENOVO_T530_SUBVENDOR)) { 404 switch (nid) { 405 case 21: 406 patch = "as=1 seq=15"; 407 break; 408 } 409 } else if (id == HDA_CODEC_ALC269 && 410 subid == ASUS_UX31A_SUBVENDOR) { 411 switch (nid) { 412 case 33: 413 patch = "as=1 seq=15"; 414 break; 415 } 416 } else if (id == HDA_CODEC_ALC892 && 417 subid == INTEL_DH87RL_SUBVENDOR) { 418 switch (nid) { 419 case 27: 420 patch = "as=1 seq=15"; 421 break; 422 } 423 } 424 425 if (patch != NULL) 426 config = hdaa_widget_pin_patch(config, patch); 427 HDA_BOOTVERBOSE( 428 if (config != orig) 429 device_printf(w->devinfo->dev, 430 "Patching pin config nid=%u 0x%08x -> 0x%08x\n", 431 nid, orig, config); 432 ); 433 w->wclass.pin.config = config; 434 } 435 436 static void 437 hdaa_widget_patch(struct hdaa_widget *w) 438 { 439 struct hdaa_devinfo *devinfo = w->devinfo; 440 uint32_t orig; 441 nid_t beeper = -1; 442 uint32_t id, subid; 443 444 id = hdaa_codec_id(devinfo); 445 subid = hdaa_card_id(devinfo); 446 447 orig = w->param.widget_cap; 448 /* On some codecs beeper is an input pin, but it is not recordable 449 alone. Also most of BIOSes does not declare beeper pin. 450 Change beeper pin node type to beeper to help parser. */ 451 switch (hdaa_codec_id(devinfo)) { 452 case HDA_CODEC_AD1882: 453 case HDA_CODEC_AD1883: 454 case HDA_CODEC_AD1984: 455 case HDA_CODEC_AD1984A: 456 case HDA_CODEC_AD1984B: 457 case HDA_CODEC_AD1987: 458 case HDA_CODEC_AD1988: 459 case HDA_CODEC_AD1988B: 460 case HDA_CODEC_AD1989B: 461 beeper = 26; 462 break; 463 case HDA_CODEC_ALC260: 464 beeper = 23; 465 break; 466 } 467 if (hda_get_vendor_id(devinfo->dev) == REALTEK_VENDORID && 468 hdaa_codec_id(devinfo) != HDA_CODEC_ALC260) 469 beeper = 29; 470 if (w->nid == beeper) { 471 w->param.widget_cap &= ~HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_MASK; 472 w->param.widget_cap |= HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET << 473 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT; 474 w->waspin = 1; 475 } 476 /* 477 * Clear "digital" flag from digital mic input, as its signal then goes 478 * to "analog" mixer and this separation just limits functionaity. 479 */ 480 if (hdaa_codec_id(devinfo) == HDA_CODEC_AD1984A && 481 w->nid == 23) 482 w->param.widget_cap &= ~HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL_MASK; 483 HDA_BOOTVERBOSE( 484 if (w->param.widget_cap != orig) { 485 device_printf(w->devinfo->dev, 486 "Patching widget caps nid=%u 0x%08x -> 0x%08x\n", 487 w->nid, orig, w->param.widget_cap); 488 } 489 ); 490 491 #if 1 492 /* 493 * Redirect the headphone plug sense (NID 33 -> redir to 12). 494 * 495 * Disable the remixer (NID 11). There was a comment in the linux 496 * driver that disabling the remixer removes low level whitenoise. 497 * this makes sense since the mixer's unconnected inputs might have 498 * noise on them that leaks through. 499 */ 500 if (id == HDA_CODEC_ALC283 && subid == ACER_C720_SUBVENDOR) { 501 if (w->nid == 33) 502 w->senseredir = 12; 503 if (w->nid == 11) 504 w->enable = 0; 505 } 506 #endif 507 508 if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) 509 hdac_pin_patch(w); 510 } 511 512 void 513 hdaa_patch(struct hdaa_devinfo *devinfo) 514 { 515 struct hdaa_widget *w; 516 uint32_t id, subid, subsystemid; 517 int i; 518 519 id = hdaa_codec_id(devinfo); 520 subid = hdaa_card_id(devinfo); 521 subsystemid = hda_get_subsystem_id(devinfo->dev); 522 523 /* 524 * Quirks 525 */ 526 for (i = 0; i < nitems(hdac_quirks); i++) { 527 if (!(HDA_DEV_MATCH(hdac_quirks[i].model, subid) && 528 HDA_DEV_MATCH(hdac_quirks[i].id, id) && 529 HDA_DEV_MATCH(hdac_quirks[i].subsystemid, subsystemid))) 530 continue; 531 devinfo->quirks |= hdac_quirks[i].set; 532 devinfo->quirks &= ~(hdac_quirks[i].unset); 533 devinfo->gpio = hdac_quirks[i].gpio; 534 } 535 536 /* Apply per-widget patch. */ 537 for (i = devinfo->startnode; i < devinfo->endnode; i++) { 538 w = hdaa_widget_get(devinfo, i); 539 if (w == NULL) 540 continue; 541 hdaa_widget_patch(w); 542 } 543 544 switch (id) { 545 case HDA_CODEC_AD1983: 546 /* 547 * This CODEC has several possible usages, but none 548 * fit the parser best. Help parser to choose better. 549 */ 550 /* Disable direct unmixed playback to get pcm volume. */ 551 w = hdaa_widget_get(devinfo, 5); 552 if (w != NULL) 553 w->connsenable[0] = 0; 554 w = hdaa_widget_get(devinfo, 6); 555 if (w != NULL) 556 w->connsenable[0] = 0; 557 w = hdaa_widget_get(devinfo, 11); 558 if (w != NULL) 559 w->connsenable[0] = 0; 560 /* Disable mic and line selectors. */ 561 w = hdaa_widget_get(devinfo, 12); 562 if (w != NULL) 563 w->connsenable[1] = 0; 564 w = hdaa_widget_get(devinfo, 13); 565 if (w != NULL) 566 w->connsenable[1] = 0; 567 /* Disable recording from mono playback mix. */ 568 w = hdaa_widget_get(devinfo, 20); 569 if (w != NULL) 570 w->connsenable[3] = 0; 571 break; 572 case HDA_CODEC_AD1986A: 573 /* 574 * This CODEC has overcomplicated input mixing. 575 * Make some cleaning there. 576 */ 577 /* Disable input mono mixer. Not needed and not supported. */ 578 w = hdaa_widget_get(devinfo, 43); 579 if (w != NULL) 580 w->enable = 0; 581 /* Disable any with any input mixing mesh. Use separately. */ 582 w = hdaa_widget_get(devinfo, 39); 583 if (w != NULL) 584 w->enable = 0; 585 w = hdaa_widget_get(devinfo, 40); 586 if (w != NULL) 587 w->enable = 0; 588 w = hdaa_widget_get(devinfo, 41); 589 if (w != NULL) 590 w->enable = 0; 591 w = hdaa_widget_get(devinfo, 42); 592 if (w != NULL) 593 w->enable = 0; 594 /* Disable duplicate mixer node connector. */ 595 w = hdaa_widget_get(devinfo, 15); 596 if (w != NULL) 597 w->connsenable[3] = 0; 598 /* There is only one mic preamplifier, use it effectively. */ 599 w = hdaa_widget_get(devinfo, 31); 600 if (w != NULL) { 601 if ((w->wclass.pin.config & 602 HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) == 603 HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN) { 604 w = hdaa_widget_get(devinfo, 16); 605 if (w != NULL) 606 w->connsenable[2] = 0; 607 } else { 608 w = hdaa_widget_get(devinfo, 15); 609 if (w != NULL) 610 w->connsenable[0] = 0; 611 } 612 } 613 w = hdaa_widget_get(devinfo, 32); 614 if (w != NULL) { 615 if ((w->wclass.pin.config & 616 HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) == 617 HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN) { 618 w = hdaa_widget_get(devinfo, 16); 619 if (w != NULL) 620 w->connsenable[0] = 0; 621 } else { 622 w = hdaa_widget_get(devinfo, 15); 623 if (w != NULL) 624 w->connsenable[1] = 0; 625 } 626 } 627 628 if (subid == ASUS_A8X_SUBVENDOR) { 629 /* 630 * This is just plain ridiculous.. There 631 * are several A8 series that share the same 632 * pci id but works differently (EAPD). 633 */ 634 w = hdaa_widget_get(devinfo, 26); 635 if (w != NULL && w->type == 636 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX && 637 (w->wclass.pin.config & 638 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) != 639 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE) 640 devinfo->quirks &= 641 ~HDAA_QUIRK_EAPDINV; 642 } 643 break; 644 case HDA_CODEC_AD1981HD: 645 /* 646 * This CODEC has very unusual design with several 647 * points inappropriate for the present parser. 648 */ 649 /* Disable recording from mono playback mix. */ 650 w = hdaa_widget_get(devinfo, 21); 651 if (w != NULL) 652 w->connsenable[3] = 0; 653 /* Disable rear to front mic mixer, use separately. */ 654 w = hdaa_widget_get(devinfo, 31); 655 if (w != NULL) 656 w->enable = 0; 657 /* Disable direct playback, use mixer. */ 658 w = hdaa_widget_get(devinfo, 5); 659 if (w != NULL) 660 w->connsenable[0] = 0; 661 w = hdaa_widget_get(devinfo, 6); 662 if (w != NULL) 663 w->connsenable[0] = 0; 664 w = hdaa_widget_get(devinfo, 9); 665 if (w != NULL) 666 w->connsenable[0] = 0; 667 w = hdaa_widget_get(devinfo, 24); 668 if (w != NULL) 669 w->connsenable[0] = 0; 670 break; 671 case HDA_CODEC_ALC269: 672 /* 673 * ASUS EeePC 1001px has strange variant of ALC269 CODEC, 674 * that mutes speaker if unused mixer at NID 15 is muted. 675 * Probably CODEC incorrectly reports internal connections. 676 * Hide that muter from the driver. There are several CODECs 677 * sharing this ID and I have not enough information about 678 * them to implement more universal solution. 679 */ 680 if (subid == 0x84371043) { 681 w = hdaa_widget_get(devinfo, 15); 682 if (w != NULL) 683 w->param.inamp_cap = 0; 684 } 685 break; 686 case HDA_CODEC_CX20582: 687 case HDA_CODEC_CX20583: 688 case HDA_CODEC_CX20584: 689 case HDA_CODEC_CX20585: 690 case HDA_CODEC_CX20590: 691 /* 692 * These codecs have extra connectivity on record side 693 * too reach for the present parser. 694 */ 695 w = hdaa_widget_get(devinfo, 20); 696 if (w != NULL) 697 w->connsenable[1] = 0; 698 w = hdaa_widget_get(devinfo, 21); 699 if (w != NULL) 700 w->connsenable[1] = 0; 701 w = hdaa_widget_get(devinfo, 22); 702 if (w != NULL) 703 w->connsenable[0] = 0; 704 break; 705 case HDA_CODEC_VT1708S_0: 706 case HDA_CODEC_VT1708S_1: 707 case HDA_CODEC_VT1708S_2: 708 case HDA_CODEC_VT1708S_3: 709 case HDA_CODEC_VT1708S_4: 710 case HDA_CODEC_VT1708S_5: 711 case HDA_CODEC_VT1708S_6: 712 case HDA_CODEC_VT1708S_7: 713 /* 714 * These codecs have hidden mic boost controls. 715 */ 716 w = hdaa_widget_get(devinfo, 26); 717 if (w != NULL) 718 w->param.inamp_cap = 719 (40 << HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT) | 720 (3 << HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT) | 721 (0 << HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT); 722 w = hdaa_widget_get(devinfo, 30); 723 if (w != NULL) 724 w->param.inamp_cap = 725 (40 << HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT) | 726 (3 << HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT) | 727 (0 << HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT); 728 break; 729 } 730 } 731 732 void 733 hdaa_patch_direct(struct hdaa_devinfo *devinfo) 734 { 735 device_t dev = devinfo->dev; 736 uint32_t id, subid, val; 737 738 id = hdaa_codec_id(devinfo); 739 subid = hdaa_card_id(devinfo); 740 741 switch (id) { 742 case HDA_CODEC_VT1708S_0: 743 case HDA_CODEC_VT1708S_1: 744 case HDA_CODEC_VT1708S_2: 745 case HDA_CODEC_VT1708S_3: 746 case HDA_CODEC_VT1708S_4: 747 case HDA_CODEC_VT1708S_5: 748 case HDA_CODEC_VT1708S_6: 749 case HDA_CODEC_VT1708S_7: 750 /* Enable Mic Boost Volume controls. */ 751 hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid, 752 0xf98, 0x01)); 753 /* Fall though */ 754 case HDA_CODEC_VT1818S: 755 /* Don't bypass mixer. */ 756 hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid, 757 0xf88, 0xc0)); 758 break; 759 } 760 if (subid == APPLE_INTEL_MAC) 761 hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid, 762 0x7e7, 0)); 763 if (id == HDA_CODEC_ALC269) { 764 if (subid == 0x16e31043 || subid == 0x831a1043 || 765 subid == 0x834a1043 || subid == 0x83981043 || 766 subid == 0x83ce1043) { 767 /* 768 * The ditital mics on some Asus laptops produce 769 * differential signals instead of expected stereo. 770 * That results in silence if downmix it to mono. 771 * To workaround, make codec to handle signal as mono. 772 */ 773 hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, 0x20, 0x07)); 774 val = hda_command(dev, HDA_CMD_GET_PROCESSING_COEFF(0, 0x20)); 775 hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, 0x20, 0x07)); 776 hda_command(dev, HDA_CMD_SET_PROCESSING_COEFF(0, 0x20, val|0x80)); 777 } 778 } 779 if (id == HDA_CODEC_ALC283) { 780 if (subid == ACER_C720_SUBVENDOR) 781 hdaa_patch_direct_acer_c720(devinfo); 782 } 783 } 784 785 /* XXX move me to a better place */ 786 uint32_t 787 hda_read_coef_idx(device_t dev, nid_t nid, unsigned int coef_idx) 788 { 789 uint32_t val; 790 791 hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, nid, coef_idx)); 792 val = hda_command(dev, HDA_CMD_GET_PROCESSING_COEFF(0, nid)); 793 return val; 794 } 795 796 void 797 hda_write_coef_idx(device_t dev, nid_t nid, unsigned int coef_idx, 798 unsigned coef_val) 799 { 800 hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, nid, coef_idx)); 801 hda_command(dev, HDA_CMD_SET_PROCESSING_COEFF(0, nid, coef_val)); 802 } 803