hdaa_patches.c revision 250797
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: head/sys/dev/sound/pci/hda/hdaa_patches.c 250797 2013-05-19 01:45:29Z sbruno $"); 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_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 138static void 139hdac_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 } 372 373 if (patch != NULL) 374 config = hdaa_widget_pin_patch(config, patch); 375 HDA_BOOTVERBOSE( 376 if (config != orig) 377 device_printf(w->devinfo->dev, 378 "Patching pin config nid=%u 0x%08x -> 0x%08x\n", 379 nid, orig, config); 380 ); 381 w->wclass.pin.config = config; 382} 383 384static void 385hdaa_widget_patch(struct hdaa_widget *w) 386{ 387 struct hdaa_devinfo *devinfo = w->devinfo; 388 uint32_t orig; 389 nid_t beeper = -1; 390 391 orig = w->param.widget_cap; 392 /* On some codecs beeper is an input pin, but it is not recordable 393 alone. Also most of BIOSes does not declare beeper pin. 394 Change beeper pin node type to beeper to help parser. */ 395 switch (hdaa_codec_id(devinfo)) { 396 case HDA_CODEC_AD1882: 397 case HDA_CODEC_AD1883: 398 case HDA_CODEC_AD1984: 399 case HDA_CODEC_AD1984A: 400 case HDA_CODEC_AD1984B: 401 case HDA_CODEC_AD1987: 402 case HDA_CODEC_AD1988: 403 case HDA_CODEC_AD1988B: 404 case HDA_CODEC_AD1989B: 405 beeper = 26; 406 break; 407 case HDA_CODEC_ALC260: 408 beeper = 23; 409 break; 410 } 411 if (hda_get_vendor_id(devinfo->dev) == REALTEK_VENDORID && 412 hdaa_codec_id(devinfo) != HDA_CODEC_ALC260) 413 beeper = 29; 414 if (w->nid == beeper) { 415 w->param.widget_cap &= ~HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_MASK; 416 w->param.widget_cap |= HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET << 417 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT; 418 w->waspin = 1; 419 } 420 /* 421 * Clear "digital" flag from digital mic input, as its signal then goes 422 * to "analog" mixer and this separation just limits functionaity. 423 */ 424 if (hdaa_codec_id(devinfo) == HDA_CODEC_AD1984A && 425 w->nid == 23) 426 w->param.widget_cap &= ~HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL_MASK; 427 HDA_BOOTVERBOSE( 428 if (w->param.widget_cap != orig) { 429 device_printf(w->devinfo->dev, 430 "Patching widget caps nid=%u 0x%08x -> 0x%08x\n", 431 w->nid, orig, w->param.widget_cap); 432 } 433 ); 434 435 if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) 436 hdac_pin_patch(w); 437} 438 439void 440hdaa_patch(struct hdaa_devinfo *devinfo) 441{ 442 struct hdaa_widget *w; 443 uint32_t id, subid, subsystemid; 444 int i; 445 446 id = hdaa_codec_id(devinfo); 447 subid = hdaa_card_id(devinfo); 448 subsystemid = hda_get_subsystem_id(devinfo->dev); 449 450 /* 451 * Quirks 452 */ 453 for (i = 0; i < HDAC_QUIRKS_LEN; i++) { 454 if (!(HDA_DEV_MATCH(hdac_quirks[i].model, subid) && 455 HDA_DEV_MATCH(hdac_quirks[i].id, id) && 456 HDA_DEV_MATCH(hdac_quirks[i].subsystemid, subsystemid))) 457 continue; 458 devinfo->quirks |= hdac_quirks[i].set; 459 devinfo->quirks &= ~(hdac_quirks[i].unset); 460 devinfo->gpio = hdac_quirks[i].gpio; 461 } 462 463 /* Apply per-widget patch. */ 464 for (i = devinfo->startnode; i < devinfo->endnode; i++) { 465 w = hdaa_widget_get(devinfo, i); 466 if (w == NULL) 467 continue; 468 hdaa_widget_patch(w); 469 } 470 471 switch (id) { 472 case HDA_CODEC_AD1983: 473 /* 474 * This CODEC has several possible usages, but none 475 * fit the parser best. Help parser to choose better. 476 */ 477 /* Disable direct unmixed playback to get pcm volume. */ 478 w = hdaa_widget_get(devinfo, 5); 479 if (w != NULL) 480 w->connsenable[0] = 0; 481 w = hdaa_widget_get(devinfo, 6); 482 if (w != NULL) 483 w->connsenable[0] = 0; 484 w = hdaa_widget_get(devinfo, 11); 485 if (w != NULL) 486 w->connsenable[0] = 0; 487 /* Disable mic and line selectors. */ 488 w = hdaa_widget_get(devinfo, 12); 489 if (w != NULL) 490 w->connsenable[1] = 0; 491 w = hdaa_widget_get(devinfo, 13); 492 if (w != NULL) 493 w->connsenable[1] = 0; 494 /* Disable recording from mono playback mix. */ 495 w = hdaa_widget_get(devinfo, 20); 496 if (w != NULL) 497 w->connsenable[3] = 0; 498 break; 499 case HDA_CODEC_AD1986A: 500 /* 501 * This CODEC has overcomplicated input mixing. 502 * Make some cleaning there. 503 */ 504 /* Disable input mono mixer. Not needed and not supported. */ 505 w = hdaa_widget_get(devinfo, 43); 506 if (w != NULL) 507 w->enable = 0; 508 /* Disable any with any input mixing mesh. Use separately. */ 509 w = hdaa_widget_get(devinfo, 39); 510 if (w != NULL) 511 w->enable = 0; 512 w = hdaa_widget_get(devinfo, 40); 513 if (w != NULL) 514 w->enable = 0; 515 w = hdaa_widget_get(devinfo, 41); 516 if (w != NULL) 517 w->enable = 0; 518 w = hdaa_widget_get(devinfo, 42); 519 if (w != NULL) 520 w->enable = 0; 521 /* Disable duplicate mixer node connector. */ 522 w = hdaa_widget_get(devinfo, 15); 523 if (w != NULL) 524 w->connsenable[3] = 0; 525 /* There is only one mic preamplifier, use it effectively. */ 526 w = hdaa_widget_get(devinfo, 31); 527 if (w != NULL) { 528 if ((w->wclass.pin.config & 529 HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) == 530 HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN) { 531 w = hdaa_widget_get(devinfo, 16); 532 if (w != NULL) 533 w->connsenable[2] = 0; 534 } else { 535 w = hdaa_widget_get(devinfo, 15); 536 if (w != NULL) 537 w->connsenable[0] = 0; 538 } 539 } 540 w = hdaa_widget_get(devinfo, 32); 541 if (w != NULL) { 542 if ((w->wclass.pin.config & 543 HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) == 544 HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN) { 545 w = hdaa_widget_get(devinfo, 16); 546 if (w != NULL) 547 w->connsenable[0] = 0; 548 } else { 549 w = hdaa_widget_get(devinfo, 15); 550 if (w != NULL) 551 w->connsenable[1] = 0; 552 } 553 } 554 555 if (subid == ASUS_A8X_SUBVENDOR) { 556 /* 557 * This is just plain ridiculous.. There 558 * are several A8 series that share the same 559 * pci id but works differently (EAPD). 560 */ 561 w = hdaa_widget_get(devinfo, 26); 562 if (w != NULL && w->type == 563 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX && 564 (w->wclass.pin.config & 565 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) != 566 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE) 567 devinfo->quirks &= 568 ~HDAA_QUIRK_EAPDINV; 569 } 570 break; 571 case HDA_CODEC_AD1981HD: 572 /* 573 * This CODEC has very unusual design with several 574 * points inappropriate for the present parser. 575 */ 576 /* Disable recording from mono playback mix. */ 577 w = hdaa_widget_get(devinfo, 21); 578 if (w != NULL) 579 w->connsenable[3] = 0; 580 /* Disable rear to front mic mixer, use separately. */ 581 w = hdaa_widget_get(devinfo, 31); 582 if (w != NULL) 583 w->enable = 0; 584 /* Disable direct playback, use mixer. */ 585 w = hdaa_widget_get(devinfo, 5); 586 if (w != NULL) 587 w->connsenable[0] = 0; 588 w = hdaa_widget_get(devinfo, 6); 589 if (w != NULL) 590 w->connsenable[0] = 0; 591 w = hdaa_widget_get(devinfo, 9); 592 if (w != NULL) 593 w->connsenable[0] = 0; 594 w = hdaa_widget_get(devinfo, 24); 595 if (w != NULL) 596 w->connsenable[0] = 0; 597 break; 598 case HDA_CODEC_ALC269: 599 /* 600 * ASUS EeePC 1001px has strange variant of ALC269 CODEC, 601 * that mutes speaker if unused mixer at NID 15 is muted. 602 * Probably CODEC incorrectly reports internal connections. 603 * Hide that muter from the driver. There are several CODECs 604 * sharing this ID and I have not enough information about 605 * them to implement more universal solution. 606 */ 607 if (subid == 0x84371043) { 608 w = hdaa_widget_get(devinfo, 15); 609 if (w != NULL) 610 w->param.inamp_cap = 0; 611 } 612 break; 613 case HDA_CODEC_CX20582: 614 case HDA_CODEC_CX20583: 615 case HDA_CODEC_CX20584: 616 case HDA_CODEC_CX20585: 617 case HDA_CODEC_CX20590: 618 /* 619 * These codecs have extra connectivity on record side 620 * too reach for the present parser. 621 */ 622 w = hdaa_widget_get(devinfo, 20); 623 if (w != NULL) 624 w->connsenable[1] = 0; 625 w = hdaa_widget_get(devinfo, 21); 626 if (w != NULL) 627 w->connsenable[1] = 0; 628 w = hdaa_widget_get(devinfo, 22); 629 if (w != NULL) 630 w->connsenable[0] = 0; 631 break; 632 case HDA_CODEC_VT1708S_0: 633 case HDA_CODEC_VT1708S_1: 634 case HDA_CODEC_VT1708S_2: 635 case HDA_CODEC_VT1708S_3: 636 case HDA_CODEC_VT1708S_4: 637 case HDA_CODEC_VT1708S_5: 638 case HDA_CODEC_VT1708S_6: 639 case HDA_CODEC_VT1708S_7: 640 /* 641 * These codecs have hidden mic boost controls. 642 */ 643 w = hdaa_widget_get(devinfo, 26); 644 if (w != NULL) 645 w->param.inamp_cap = 646 (40 << HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT) | 647 (3 << HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT) | 648 (0 << HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT); 649 w = hdaa_widget_get(devinfo, 30); 650 if (w != NULL) 651 w->param.inamp_cap = 652 (40 << HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT) | 653 (3 << HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT) | 654 (0 << HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT); 655 break; 656 } 657} 658 659void 660hdaa_patch_direct(struct hdaa_devinfo *devinfo) 661{ 662 device_t dev = devinfo->dev; 663 uint32_t id, subid, val; 664 665 id = hdaa_codec_id(devinfo); 666 subid = hdaa_card_id(devinfo); 667 668 switch (id) { 669 case HDA_CODEC_VT1708S_0: 670 case HDA_CODEC_VT1708S_1: 671 case HDA_CODEC_VT1708S_2: 672 case HDA_CODEC_VT1708S_3: 673 case HDA_CODEC_VT1708S_4: 674 case HDA_CODEC_VT1708S_5: 675 case HDA_CODEC_VT1708S_6: 676 case HDA_CODEC_VT1708S_7: 677 /* Enable Mic Boost Volume controls. */ 678 hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid, 679 0xf98, 0x01)); 680 /* Fall though */ 681 case HDA_CODEC_VT1818S: 682 /* Don't bypass mixer. */ 683 hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid, 684 0xf88, 0xc0)); 685 break; 686 } 687 if (subid == APPLE_INTEL_MAC) 688 hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid, 689 0x7e7, 0)); 690 if (id == HDA_CODEC_ALC269) { 691 if (subid == 0x16e31043 || subid == 0x831a1043 || 692 subid == 0x834a1043 || subid == 0x83981043 || 693 subid == 0x83ce1043) { 694 /* 695 * The ditital mics on some Asus laptops produce 696 * differential signals instead of expected stereo. 697 * That results in silence if downmix it to mono. 698 * To workaround, make codec to handle signal as mono. 699 */ 700 hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, 0x20, 0x07)); 701 val = hda_command(dev, HDA_CMD_GET_PROCESSING_COEFF(0, 0x20)); 702 hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, 0x20, 0x07)); 703 hda_command(dev, HDA_CMD_SET_PROCESSING_COEFF(0, 0x20, val|0x80)); 704 } 705 } 706} 707