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