1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2006 Stephane E. Potvin <sepotvin@videotron.ca> 5 * Copyright (c) 2006 Ariff Abdullah <ariff@FreeBSD.org> 6 * Copyright (c) 2008-2012 Alexander Motin <mav@FreeBSD.org> 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 /* 32 * Intel High Definition Audio (Audio function quirks) driver for FreeBSD. 33 */ 34 35 #ifdef HAVE_KERNEL_OPTION_HEADERS 36 #include "opt_snd.h" 37 #endif 38 39 #include <dev/sound/pcm/sound.h> 40 41 #include <sys/ctype.h> 42 43 #include <dev/sound/pci/hda/hdac.h> 44 #include <dev/sound/pci/hda/hdaa.h> 45 #include <dev/sound/pci/hda/hda_reg.h> 46 47 #include "pin_patch.h" 48 #include "pin_patch_realtek.h" 49 50 static const struct { 51 uint32_t model; 52 uint32_t id; 53 uint32_t subsystemid; 54 uint32_t set, unset; 55 uint32_t gpio; 56 } hdac_quirks[] = { 57 /* 58 * XXX Force stereo quirk. Monoural recording / playback 59 * on few codecs (especially ALC880) seems broken or 60 * perhaps unsupported. 61 */ 62 { HDA_MATCH_ALL, HDA_MATCH_ALL, HDA_MATCH_ALL, 63 HDAA_QUIRK_FORCESTEREO | HDAA_QUIRK_IVREF, 0, 64 0 }, 65 { ACER_ALL_SUBVENDOR, HDA_MATCH_ALL, HDA_MATCH_ALL, 66 0, 0, 67 HDAA_GPIO_SET(0) }, 68 { ASUS_G2K_SUBVENDOR, HDA_CODEC_ALC660, HDA_MATCH_ALL, 69 0, 0, 70 HDAA_GPIO_SET(0) }, 71 { ASUS_M5200_SUBVENDOR, HDA_CODEC_ALC880, HDA_MATCH_ALL, 72 0, 0, 73 HDAA_GPIO_SET(0) }, 74 { ASUS_A7M_SUBVENDOR, HDA_CODEC_ALC880, HDA_MATCH_ALL, 75 0, 0, 76 HDAA_GPIO_SET(0) }, 77 { ASUS_A7T_SUBVENDOR, HDA_CODEC_ALC882, HDA_MATCH_ALL, 78 0, 0, 79 HDAA_GPIO_SET(0) }, 80 { ASUS_W2J_SUBVENDOR, HDA_CODEC_ALC882, HDA_MATCH_ALL, 81 0, 0, 82 HDAA_GPIO_SET(0) }, 83 { ASUS_U5F_SUBVENDOR, HDA_CODEC_AD1986A, HDA_MATCH_ALL, 84 HDAA_QUIRK_EAPDINV, 0, 85 0 }, 86 { ASUS_A8X_SUBVENDOR, HDA_CODEC_AD1986A, HDA_MATCH_ALL, 87 HDAA_QUIRK_EAPDINV, 0, 88 0 }, 89 { ASUS_F3JC_SUBVENDOR, HDA_CODEC_ALC861, HDA_MATCH_ALL, 90 HDAA_QUIRK_OVREF, 0, 91 0 }, 92 { UNIWILL_9075_SUBVENDOR, HDA_CODEC_ALC861, HDA_MATCH_ALL, 93 HDAA_QUIRK_OVREF, 0, 94 0 }, 95 /*{ ASUS_M2N_SUBVENDOR, HDA_CODEC_AD1988, HDA_MATCH_ALL, 96 HDAA_QUIRK_IVREF80, HDAA_QUIRK_IVREF50 | HDAA_QUIRK_IVREF100, 97 0 },*/ 98 { MEDION_MD95257_SUBVENDOR, HDA_CODEC_ALC880, HDA_MATCH_ALL, 99 0, 0, 100 HDAA_GPIO_SET(1) }, 101 { LENOVO_3KN100_SUBVENDOR, HDA_CODEC_AD1986A, HDA_MATCH_ALL, 102 HDAA_QUIRK_EAPDINV | HDAA_QUIRK_SENSEINV, 0, 103 0 }, 104 { SAMSUNG_Q1_SUBVENDOR, HDA_CODEC_AD1986A, HDA_MATCH_ALL, 105 HDAA_QUIRK_EAPDINV, 0, 106 0 }, 107 { APPLE_MB3_SUBVENDOR, HDA_CODEC_ALC885, HDA_MATCH_ALL, 108 HDAA_QUIRK_OVREF50, 0, 109 HDAA_GPIO_SET(0) }, 110 { APPLE_INTEL_MAC, HDA_CODEC_STAC9221, HDA_MATCH_ALL, 111 0, 0, 112 HDAA_GPIO_SET(0) | HDAA_GPIO_SET(1) }, 113 { APPLE_MACBOOKAIR31, HDA_CODEC_CS4206, HDA_MATCH_ALL, 114 0, 0, 115 HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) }, 116 { APPLE_MACBOOKPRO55, HDA_CODEC_CS4206, HDA_MATCH_ALL, 117 0, 0, 118 HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) }, 119 { APPLE_MACBOOKPRO71, HDA_CODEC_CS4206, HDA_MATCH_ALL, 120 0, 0, 121 HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) }, 122 { HDA_INTEL_MACBOOKPRO92, HDA_CODEC_CS4206, HDA_MATCH_ALL, 123 0, 0, 124 HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) }, 125 { DELL_D630_SUBVENDOR, HDA_CODEC_STAC9205X, HDA_MATCH_ALL, 126 0, 0, 127 HDAA_GPIO_SET(0) }, 128 { DELL_V1400_SUBVENDOR, HDA_CODEC_STAC9228X, HDA_MATCH_ALL, 129 0, 0, 130 HDAA_GPIO_SET(2) }, 131 { DELL_V1500_SUBVENDOR, HDA_CODEC_STAC9205X, HDA_MATCH_ALL, 132 0, 0, 133 HDAA_GPIO_SET(0) }, 134 { HDA_MATCH_ALL, HDA_CODEC_AD1988, HDA_MATCH_ALL, 135 HDAA_QUIRK_IVREF80, HDAA_QUIRK_IVREF50 | HDAA_QUIRK_IVREF100, 136 0 }, 137 { HDA_MATCH_ALL, HDA_CODEC_AD1988B, HDA_MATCH_ALL, 138 HDAA_QUIRK_IVREF80, HDAA_QUIRK_IVREF50 | HDAA_QUIRK_IVREF100, 139 0 }, 140 { HDA_MATCH_ALL, HDA_CODEC_CX20549, HDA_MATCH_ALL, 141 0, HDAA_QUIRK_FORCESTEREO, 142 0 }, 143 /* Mac Pro 1,1 requires ovref for proper volume level. */ 144 { 0x00000000, HDA_CODEC_ALC885, 0x106b0c00, 145 0, HDAA_QUIRK_OVREF, 146 0 } 147 }; 148 149 static struct pin_patch_t * 150 match_pin_patches(int vendor_id, int vendor_subid) 151 { 152 for (int ci = 0; ci < nitems(realtek_model_pin_patches); ci++) { 153 struct hdaa_model_pin_patch_t *p = &realtek_model_pin_patches[ci]; 154 if (vendor_id != p->id) 155 continue; 156 for (struct model_pin_patch_t *pp = p->patches; pp->models; pp++) { 157 for (struct pin_machine_model_t *model = pp->models; model->id != 0; model++) { 158 if (HDA_DEV_MATCH(model->id, vendor_subid)) 159 return (pp->pin_patches); 160 } 161 } 162 } 163 164 return (0); 165 } 166 167 static void 168 hdac_pin_patch(struct hdaa_widget *w) 169 { 170 const char *patch_str = NULL; 171 uint32_t config, orig, id, subid; 172 nid_t nid = w->nid; 173 174 config = orig = w->wclass.pin.config; 175 id = hdaa_codec_id(w->devinfo); 176 subid = hdaa_card_id(w->devinfo); 177 178 if (id == HDA_CODEC_ALC883 && HDA_DEV_MATCH(ACER_ALL_SUBVENDOR, subid)) { 179 switch (nid) { 180 case 25: 181 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK | 182 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK); 183 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN | 184 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED); 185 break; 186 case 28: 187 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK | 188 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK); 189 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_CD | 190 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED); 191 break; 192 } 193 } else if (id == HDA_CODEC_CX20549 && subid == 194 HP_V3000_SUBVENDOR) { 195 switch (nid) { 196 case 18: 197 config &= ~HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK; 198 config |= HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE; 199 break; 200 case 20: 201 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK | 202 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK); 203 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN | 204 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED); 205 break; 206 case 21: 207 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK | 208 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK); 209 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_CD | 210 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED); 211 break; 212 } 213 } else if (id == HDA_CODEC_CX20551 && subid == 214 HP_DV5000_SUBVENDOR) { 215 switch (nid) { 216 case 20: 217 case 21: 218 config &= ~HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK; 219 config |= HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE; 220 break; 221 } 222 } 223 224 /* New patches */ 225 if (id == HDA_CODEC_AD1984A && 226 subid == LENOVO_X300_SUBVENDOR) { 227 switch (nid) { 228 case 17: /* Headphones with redirection */ 229 patch_str = "as=1 seq=15"; 230 break; 231 case 20: /* Two mics together */ 232 patch_str = "as=2 seq=15"; 233 break; 234 } 235 } else if (id == HDA_CODEC_AD1986A && 236 (subid == ASUS_M2NPVMX_SUBVENDOR || 237 subid == ASUS_A8NVMCSM_SUBVENDOR || 238 subid == ASUS_P5PL2_SUBVENDOR)) { 239 switch (nid) { 240 case 26: /* Headphones with redirection */ 241 patch_str = "as=1 seq=15"; 242 break; 243 case 28: /* 5.1 out => 2.0 out + 1 input */ 244 patch_str = "device=Line-in as=8 seq=1"; 245 break; 246 case 29: /* Can't use this as input, as the only available mic 247 * preamplifier is busy by front panel mic (nid 31). 248 * If you want to use this rear connector as mic input, 249 * you have to disable the front panel one. */ 250 patch_str = "as=0"; 251 break; 252 case 31: /* Lot of inputs configured with as=15 and unusable */ 253 patch_str = "as=8 seq=3"; 254 break; 255 case 32: 256 patch_str = "as=8 seq=4"; 257 break; 258 case 34: 259 patch_str = "as=8 seq=5"; 260 break; 261 case 36: 262 patch_str = "as=8 seq=6"; 263 break; 264 } 265 } else if (id == HDA_CODEC_CX20561 && 266 subid == LENOVO_B450_SUBVENDOR) { 267 switch (nid) { 268 case 22: 269 patch_str = "as=1 seq=15"; 270 break; 271 } 272 } else if (id == HDA_CODEC_CX20561 && 273 subid == LENOVO_T400_SUBVENDOR) { 274 switch (nid) { 275 case 22: 276 patch_str = "as=1 seq=15"; 277 break; 278 case 26: 279 patch_str = "as=1 seq=0"; 280 break; 281 } 282 } else if (id == HDA_CODEC_CX20590 && 283 (subid == LENOVO_X1_SUBVENDOR || 284 subid == LENOVO_X220_SUBVENDOR || 285 subid == LENOVO_T420_SUBVENDOR || 286 subid == LENOVO_T520_SUBVENDOR || 287 subid == LENOVO_G580_SUBVENDOR)) { 288 switch (nid) { 289 case 25: 290 patch_str = "as=1 seq=15"; 291 break; 292 /* 293 * Group onboard mic and headphone mic 294 * together. Fixes onboard mic. 295 */ 296 case 27: 297 patch_str = "as=2 seq=15"; 298 break; 299 case 35: 300 patch_str = "as=2"; 301 break; 302 } 303 } else if (id == HDA_CODEC_ALC235 && subid == ASUS_GL553VE_SUBVENDOR) { 304 switch (nid) { 305 case 33: 306 patch_str = "as=1 seq=15"; 307 break; 308 } 309 } else if (id == HDA_CODEC_ALC256 && (subid == DELL_I7577_SUBVENDOR || 310 subid == DELL_L7480_SUBVENDOR)) { 311 switch (nid) { 312 case 20: 313 patch_str = "as=1 seq=0"; 314 break; 315 case 33: 316 patch_str = "as=1 seq=15"; 317 break; 318 } 319 } else if (id == HDA_CODEC_ALC257 && 320 (subid == LENOVO_L5AMD_SUBVENDOR || 321 subid == LENOVO_L5INTEL_SUBVENDOR || 322 subid == LENOVO_IDEAPAD3_SUBVENDOR)) { 323 switch (nid) { 324 case 20: 325 patch_str = "as=1 seq=0"; 326 break; 327 case 33: 328 patch_str = "as=1 seq=15"; 329 break; 330 } 331 } else if (id == HDA_CODEC_IDT92HD95B && 332 (subid == FRAMEWORK_LAPTOP_0001_SUBVENDOR || 333 subid == FRAMEWORK_LAPTOP_0002_SUBVENDOR || 334 subid == FRAMEWORK_LAPTOP_0003_SUBVENDOR)) { 335 switch (nid) { 336 case 10: 337 patch_str = "as=1 seq=15 color=Black loc=Left"; 338 break; 339 case 11: 340 patch_str = "as=3 seq=15 color=Black loc=Left"; 341 break; 342 } 343 } else if (id == HDA_CODEC_ALC230 && 344 subid == LENOVO_IDEAPAD330_SUBVENDOR) { 345 switch (nid) { 346 case 20: 347 patch_str = "as=1 seq=0 device=Speaker"; 348 break; 349 case 33: 350 patch_str = "as=1 seq=15 device=Headphones"; 351 break; 352 } 353 } else if (id == HDA_CODEC_ALC269 && 354 subid == LENOVO_X230_SUBVENDOR) { 355 switch (nid) { 356 case 21: 357 patch_str = "as=1 seq=15"; 358 break; 359 case 24: 360 patch_str = "as=4 seq=15"; 361 break; 362 } 363 } else if (id == HDA_CODEC_ALC294 && 364 subid == ASUS_UX331_SUBVENDOR) { 365 switch (nid) { 366 case 25: 367 /* XXX You are not expected to understand this. */ 368 config = 0x01a1103c; 369 break; 370 case 33: 371 patch_str = "as=1 seq=15"; 372 break; 373 } 374 } else { 375 /* 376 * loop over hdaa_model_pin_patch 377 */ 378 struct pin_patch_t *pin_patches = NULL; 379 380 pin_patches = match_pin_patches(id, subid); 381 382 if (pin_patches != NULL) { 383 for (struct pin_patch_t *patch = pin_patches; patch->type; patch++) { 384 if (nid == patch->nid) { 385 switch (patch->type) { 386 case PIN_PATCH_TYPE_STRING: 387 patch_str = patch->patch.string; 388 break; 389 case PIN_PATCH_TYPE_MASK: 390 config &= ~patch->patch.mask[0]; 391 config |= patch->patch.mask[1]; 392 break; 393 case PIN_PATCH_TYPE_OVERRIDE: 394 config = patch->patch.override; 395 break; 396 default: 397 /* should panic hard */ 398 break; 399 } 400 break; 401 } 402 } 403 } 404 } 405 406 if (patch_str != NULL) 407 config = hdaa_widget_pin_patch(config, patch_str); 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 static uint32_t 693 hdaa_read_coef(device_t dev, nid_t nid, uint16_t idx) 694 { 695 696 hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, nid, idx)); 697 return (hda_command(dev, HDA_CMD_GET_PROCESSING_COEFF(0, nid))); 698 } 699 700 static uint32_t 701 hdaa_write_coef(device_t dev, nid_t nid, uint16_t idx, uint16_t val) 702 { 703 704 hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, nid, idx)); 705 return (hda_command(dev, HDA_CMD_SET_PROCESSING_COEFF(0, nid, val))); 706 } 707 708 void 709 hdaa_patch_direct(struct hdaa_devinfo *devinfo) 710 { 711 device_t dev = devinfo->dev; 712 uint32_t id, subid, val; 713 714 id = hdaa_codec_id(devinfo); 715 subid = hdaa_card_id(devinfo); 716 717 switch (id) { 718 case HDA_CODEC_VT1708S_0: 719 case HDA_CODEC_VT1708S_1: 720 case HDA_CODEC_VT1708S_2: 721 case HDA_CODEC_VT1708S_3: 722 case HDA_CODEC_VT1708S_4: 723 case HDA_CODEC_VT1708S_5: 724 case HDA_CODEC_VT1708S_6: 725 case HDA_CODEC_VT1708S_7: 726 /* Enable Mic Boost Volume controls. */ 727 hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid, 728 0xf98, 0x01)); 729 /* Fall though */ 730 case HDA_CODEC_VT1818S: 731 /* Don't bypass mixer. */ 732 hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid, 733 0xf88, 0xc0)); 734 break; 735 case HDA_CODEC_ALC1150: 736 if (subid == 0xd9781462) { 737 /* Too low volume on MSI H170 GAMING M3. */ 738 hdaa_write_coef(dev, 0x20, 0x07, 0x7cb); 739 } 740 break; 741 } 742 if (id == HDA_CODEC_ALC255 || id == HDA_CODEC_ALC256) { 743 val = hdaa_read_coef(dev, 0x20, 0x46); 744 hdaa_write_coef(dev, 0x20, 0x46, val|0x3000); 745 } 746 if (subid == APPLE_INTEL_MAC) 747 hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid, 748 0x7e7, 0)); 749 if (id == HDA_CODEC_ALC269) { 750 if (subid == 0x16e31043 || subid == 0x831a1043 || 751 subid == 0x834a1043 || subid == 0x83981043 || 752 subid == 0x83ce1043) { 753 /* 754 * The digital mics on some Asus laptops produce 755 * differential signals instead of expected stereo. 756 * That results in silence if downmixing to mono. 757 * To workaround, make codec handle the signal as mono. 758 */ 759 val = hdaa_read_coef(dev, 0x20, 0x07); 760 hdaa_write_coef(dev, 0x20, 0x07, val|0x80); 761 } 762 if (subid == 0x15171043) { 763 /* Increase output amp on ASUS UX31A by +5dB. */ 764 hdaa_write_coef(dev, 0x20, 0x12, 0x2800); 765 } 766 } 767 } 768