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