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