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