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