hdaa_patches.c revision 247911
151766Scg/*- 251766Scg * Copyright (c) 2006 Stephane E. Potvin <sepotvin@videotron.ca> 351766Scg * Copyright (c) 2006 Ariff Abdullah <ariff@FreeBSD.org> 451766Scg * Copyright (c) 2008-2012 Alexander Motin <mav@FreeBSD.org> 551766Scg * All rights reserved. 651766Scg * 751766Scg * Redistribution and use in source and binary forms, with or without 851766Scg * modification, are permitted provided that the following conditions 951766Scg * are met: 1051766Scg * 1. Redistributions of source code must retain the above copyright 1151766Scg * notice, this list of conditions and the following disclaimer. 1251766Scg * 2. Redistributions in binary form must reproduce the above copyright 1351766Scg * notice, this list of conditions and the following disclaimer in the 1451766Scg * documentation and/or other materials provided with the distribution. 1551766Scg * 1651766Scg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1751766Scg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1851766Scg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1951766Scg * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2051766Scg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2151766Scg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2251766Scg * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2351766Scg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2451766Scg * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2551766Scg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2651766Scg * SUCH DAMAGE. 2751766Scg */ 2851766Scg 2951766Scg/* 3051766Scg * Intel High Definition Audio (Audio function quirks) driver for FreeBSD. 3151766Scg */ 3251766Scg 3351766Scg#ifdef HAVE_KERNEL_OPTION_HEADERS 3451766Scg#include "opt_snd.h" 3551766Scg#endif 3651766Scg 3751766Scg#include <dev/sound/pcm/sound.h> 3851766Scg 3951766Scg#include <sys/ctype.h> 4051766Scg 4151766Scg#include <dev/sound/pci/hda/hdac.h> 4251766Scg#include <dev/sound/pci/hda/hdaa.h> 4351766Scg#include <dev/sound/pci/hda/hda_reg.h> 4451766Scg 4551766ScgSND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pci/hda/hdaa_patches.c 247911 2013-03-07 08:00:04Z glebius $"); 4651766Scg 4751766Scgstatic const struct { 4851766Scg uint32_t model; 4951766Scg uint32_t id; 5051766Scg uint32_t set, unset; 5151766Scg uint32_t gpio; 5251766Scg} hdac_quirks[] = { 5351766Scg /* 5451766Scg * XXX Force stereo quirk. Monoural recording / playback 5551766Scg * on few codecs (especially ALC880) seems broken or 5651766Scg * perhaps unsupported. 5751766Scg */ 5851766Scg { HDA_MATCH_ALL, HDA_MATCH_ALL, 5951766Scg HDAA_QUIRK_FORCESTEREO | HDAA_QUIRK_IVREF, 0, 6051766Scg 0 }, 6151766Scg { ACER_ALL_SUBVENDOR, HDA_MATCH_ALL, 6251766Scg 0, 0, 6351766Scg HDAA_GPIO_SET(0) }, 6451766Scg { ASUS_G2K_SUBVENDOR, HDA_CODEC_ALC660, 6551766Scg 0, 0, 6651766Scg HDAA_GPIO_SET(0) }, 6751766Scg { ASUS_M5200_SUBVENDOR, HDA_CODEC_ALC880, 6851766Scg 0, 0, 6951766Scg HDAA_GPIO_SET(0) }, 7051766Scg { ASUS_A7M_SUBVENDOR, HDA_CODEC_ALC880, 7151766Scg 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_MACBOOKPRO55, HDA_CODEC_CS4206, 110 0, 0, 111 HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) }, 112 { DELL_D630_SUBVENDOR, HDA_CODEC_STAC9205X, 113 0, 0, 114 HDAA_GPIO_SET(0) }, 115 { DELL_V1400_SUBVENDOR, HDA_CODEC_STAC9228X, 116 0, 0, 117 HDAA_GPIO_SET(2) }, 118 { DELL_V1500_SUBVENDOR, HDA_CODEC_STAC9205X, 119 0, 0, 120 HDAA_GPIO_SET(0) }, 121 { HDA_MATCH_ALL, HDA_CODEC_AD1988, 122 HDAA_QUIRK_IVREF80, HDAA_QUIRK_IVREF50 | HDAA_QUIRK_IVREF100, 123 0 }, 124 { HDA_MATCH_ALL, HDA_CODEC_AD1988B, 125 HDAA_QUIRK_IVREF80, HDAA_QUIRK_IVREF50 | HDAA_QUIRK_IVREF100, 126 0 }, 127 { HDA_MATCH_ALL, HDA_CODEC_CX20549, 128 0, HDAA_QUIRK_FORCESTEREO, 129 0 } 130}; 131#define HDAC_QUIRKS_LEN (sizeof(hdac_quirks) / sizeof(hdac_quirks[0])) 132 133static void 134hdac_pin_patch(struct hdaa_widget *w) 135{ 136 const char *patch = NULL; 137 uint32_t config, orig, id, subid; 138 nid_t nid = w->nid; 139 140 config = orig = w->wclass.pin.config; 141 id = hdaa_codec_id(w->devinfo); 142 subid = hdaa_card_id(w->devinfo); 143 144 /* XXX: Old patches require complete review. 145 * Now they may create more problem then solve due to 146 * incorrect associations. 147 */ 148 if (id == HDA_CODEC_ALC880 && subid == LG_LW20_SUBVENDOR) { 149 switch (nid) { 150 case 26: 151 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK; 152 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN; 153 break; 154 case 27: 155 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK; 156 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT; 157 break; 158 default: 159 break; 160 } 161 } else if (id == HDA_CODEC_ALC880 && 162 (subid == CLEVO_D900T_SUBVENDOR || 163 subid == ASUS_M5200_SUBVENDOR)) { 164 /* 165 * Super broken BIOS 166 */ 167 switch (nid) { 168 case 24: /* MIC1 */ 169 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK; 170 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN; 171 break; 172 case 25: /* XXX MIC2 */ 173 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK; 174 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN; 175 break; 176 case 26: /* LINE1 */ 177 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK; 178 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN; 179 break; 180 case 27: /* XXX LINE2 */ 181 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK; 182 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN; 183 break; 184 case 28: /* CD */ 185 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK; 186 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_CD; 187 break; 188 } 189 } else if (id == HDA_CODEC_ALC883 && 190 (subid == MSI_MS034A_SUBVENDOR || 191 HDA_DEV_MATCH(ACER_ALL_SUBVENDOR, subid))) { 192 switch (nid) { 193 case 25: 194 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK | 195 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK); 196 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN | 197 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED); 198 break; 199 case 28: 200 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK | 201 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK); 202 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_CD | 203 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED); 204 break; 205 } 206 } else if (id == HDA_CODEC_CX20549 && subid == 207 HP_V3000_SUBVENDOR) { 208 switch (nid) { 209 case 18: 210 config &= ~HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK; 211 config |= HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE; 212 break; 213 case 20: 214 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK | 215 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK); 216 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN | 217 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED); 218 break; 219 case 21: 220 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK | 221 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK); 222 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_CD | 223 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED); 224 break; 225 } 226 } else if (id == HDA_CODEC_CX20551 && subid == 227 HP_DV5000_SUBVENDOR) { 228 switch (nid) { 229 case 20: 230 case 21: 231 config &= ~HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK; 232 config |= HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE; 233 break; 234 } 235 } else if (id == HDA_CODEC_ALC861 && subid == 236 ASUS_W6F_SUBVENDOR) { 237 switch (nid) { 238 case 11: 239 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK | 240 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK); 241 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_OUT | 242 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED); 243 break; 244 case 12: 245 case 14: 246 case 16: 247 case 31: 248 case 32: 249 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK | 250 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK); 251 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN | 252 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED); 253 break; 254 case 15: 255 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK | 256 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK); 257 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT | 258 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK); 259 break; 260 } 261 } else if (id == HDA_CODEC_ALC861 && subid == 262 UNIWILL_9075_SUBVENDOR) { 263 switch (nid) { 264 case 15: 265 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK | 266 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK); 267 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT | 268 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK); 269 break; 270 } 271 } 272 273 /* New patches */ 274 if (id == HDA_CODEC_AD1984A && 275 subid == LENOVO_X300_SUBVENDOR) { 276 switch (nid) { 277 case 17: /* Headphones with redirection */ 278 patch = "as=1 seq=15"; 279 break; 280 case 20: /* Two mics together */ 281 patch = "as=2 seq=15"; 282 break; 283 } 284 } else if (id == HDA_CODEC_AD1986A && 285 (subid == ASUS_M2NPVMX_SUBVENDOR || 286 subid == ASUS_A8NVMCSM_SUBVENDOR || 287 subid == ASUS_P5PL2_SUBVENDOR)) { 288 switch (nid) { 289 case 26: /* Headphones with redirection */ 290 patch = "as=1 seq=15"; 291 break; 292 case 28: /* 5.1 out => 2.0 out + 1 input */ 293 patch = "device=Line-in as=8 seq=1"; 294 break; 295 case 29: /* Can't use this as input, as the only available mic 296 * preamplifier is busy by front panel mic (nid 31). 297 * If you want to use this rear connector as mic input, 298 * you have to disable the front panel one. */ 299 patch = "as=0"; 300 break; 301 case 31: /* Lot of inputs configured with as=15 and unusable */ 302 patch = "as=8 seq=3"; 303 break; 304 case 32: 305 patch = "as=8 seq=4"; 306 break; 307 case 34: 308 patch = "as=8 seq=5"; 309 break; 310 case 36: 311 patch = "as=8 seq=6"; 312 break; 313 } 314 } else if (id == HDA_CODEC_ALC260 && 315 HDA_DEV_MATCH(SONY_S5_SUBVENDOR, subid)) { 316 switch (nid) { 317 case 16: 318 patch = "seq=15 device=Headphones"; 319 break; 320 } 321 } else if (id == HDA_CODEC_ALC268) { 322 if (subid == ACER_T5320_SUBVENDOR) { 323 switch (nid) { 324 case 20: /* Headphones Jack */ 325 patch = "as=1 seq=15"; 326 break; 327 } 328 } 329 } else if (id == HDA_CODEC_CX20561 && 330 subid == LENOVO_B450_SUBVENDOR) { 331 switch (nid) { 332 case 22: 333 patch = "as=1 seq=15"; 334 break; 335 } 336 } else if (id == HDA_CODEC_CX20590 && 337 (subid == LENOVO_X1_SUBVENDOR || 338 subid == LENOVO_X220_SUBVENDOR || 339 subid == LENOVO_T420_SUBVENDOR || 340 subid == LENOVO_T520_SUBVENDOR)) { 341 switch (nid) { 342 case 25: 343 patch = "as=1 seq=15"; 344 break; 345 } 346 } else if (id == HDA_CODEC_ALC269 && 347 subid == LENOVO_X1CRBN_SUBVENDOR) { 348 switch (nid) { 349 case 21: 350 patch = "as=1 seq=15"; 351 break; 352 } 353 } 354 355 if (patch != NULL) 356 config = hdaa_widget_pin_patch(config, patch); 357 HDA_BOOTVERBOSE( 358 if (config != orig) 359 device_printf(w->devinfo->dev, 360 "Patching pin config nid=%u 0x%08x -> 0x%08x\n", 361 nid, orig, config); 362 ); 363 w->wclass.pin.config = config; 364} 365 366static void 367hdaa_widget_patch(struct hdaa_widget *w) 368{ 369 struct hdaa_devinfo *devinfo = w->devinfo; 370 uint32_t orig; 371 nid_t beeper = -1; 372 373 orig = w->param.widget_cap; 374 /* On some codecs beeper is an input pin, but it is not recordable 375 alone. Also most of BIOSes does not declare beeper pin. 376 Change beeper pin node type to beeper to help parser. */ 377 switch (hdaa_codec_id(devinfo)) { 378 case HDA_CODEC_AD1882: 379 case HDA_CODEC_AD1883: 380 case HDA_CODEC_AD1984: 381 case HDA_CODEC_AD1984A: 382 case HDA_CODEC_AD1984B: 383 case HDA_CODEC_AD1987: 384 case HDA_CODEC_AD1988: 385 case HDA_CODEC_AD1988B: 386 case HDA_CODEC_AD1989B: 387 beeper = 26; 388 break; 389 case HDA_CODEC_ALC260: 390 beeper = 23; 391 break; 392 } 393 if (hda_get_vendor_id(devinfo->dev) == REALTEK_VENDORID && 394 hdaa_codec_id(devinfo) != HDA_CODEC_ALC260) 395 beeper = 29; 396 if (w->nid == beeper) { 397 w->param.widget_cap &= ~HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_MASK; 398 w->param.widget_cap |= HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET << 399 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT; 400 w->waspin = 1; 401 } 402 /* 403 * Clear "digital" flag from digital mic input, as its signal then goes 404 * to "analog" mixer and this separation just limits functionaity. 405 */ 406 if (hdaa_codec_id(devinfo) == HDA_CODEC_AD1984A && 407 w->nid == 23) 408 w->param.widget_cap &= ~HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL_MASK; 409 HDA_BOOTVERBOSE( 410 if (w->param.widget_cap != orig) { 411 device_printf(w->devinfo->dev, 412 "Patching widget caps nid=%u 0x%08x -> 0x%08x\n", 413 w->nid, orig, w->param.widget_cap); 414 } 415 ); 416 417 if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) 418 hdac_pin_patch(w); 419} 420 421void 422hdaa_patch(struct hdaa_devinfo *devinfo) 423{ 424 struct hdaa_widget *w; 425 uint32_t id, subid; 426 int i; 427 428 id = hdaa_codec_id(devinfo); 429 subid = hdaa_card_id(devinfo); 430 431 /* 432 * Quirks 433 */ 434 for (i = 0; i < HDAC_QUIRKS_LEN; i++) { 435 if (!(HDA_DEV_MATCH(hdac_quirks[i].model, subid) && 436 HDA_DEV_MATCH(hdac_quirks[i].id, id))) 437 continue; 438 devinfo->quirks |= hdac_quirks[i].set; 439 devinfo->quirks &= ~(hdac_quirks[i].unset); 440 devinfo->gpio = hdac_quirks[i].gpio; 441 } 442 443 /* Apply per-widget patch. */ 444 for (i = devinfo->startnode; i < devinfo->endnode; i++) { 445 w = hdaa_widget_get(devinfo, i); 446 if (w == NULL) 447 continue; 448 hdaa_widget_patch(w); 449 } 450 451 switch (id) { 452 case HDA_CODEC_AD1983: 453 /* 454 * This CODEC has several possible usages, but none 455 * fit the parser best. Help parser to choose better. 456 */ 457 /* Disable direct unmixed playback to get pcm volume. */ 458 w = hdaa_widget_get(devinfo, 5); 459 if (w != NULL) 460 w->connsenable[0] = 0; 461 w = hdaa_widget_get(devinfo, 6); 462 if (w != NULL) 463 w->connsenable[0] = 0; 464 w = hdaa_widget_get(devinfo, 11); 465 if (w != NULL) 466 w->connsenable[0] = 0; 467 /* Disable mic and line selectors. */ 468 w = hdaa_widget_get(devinfo, 12); 469 if (w != NULL) 470 w->connsenable[1] = 0; 471 w = hdaa_widget_get(devinfo, 13); 472 if (w != NULL) 473 w->connsenable[1] = 0; 474 /* Disable recording from mono playback mix. */ 475 w = hdaa_widget_get(devinfo, 20); 476 if (w != NULL) 477 w->connsenable[3] = 0; 478 break; 479 case HDA_CODEC_AD1986A: 480 /* 481 * This CODEC has overcomplicated input mixing. 482 * Make some cleaning there. 483 */ 484 /* Disable input mono mixer. Not needed and not supported. */ 485 w = hdaa_widget_get(devinfo, 43); 486 if (w != NULL) 487 w->enable = 0; 488 /* Disable any with any input mixing mesh. Use separately. */ 489 w = hdaa_widget_get(devinfo, 39); 490 if (w != NULL) 491 w->enable = 0; 492 w = hdaa_widget_get(devinfo, 40); 493 if (w != NULL) 494 w->enable = 0; 495 w = hdaa_widget_get(devinfo, 41); 496 if (w != NULL) 497 w->enable = 0; 498 w = hdaa_widget_get(devinfo, 42); 499 if (w != NULL) 500 w->enable = 0; 501 /* Disable duplicate mixer node connector. */ 502 w = hdaa_widget_get(devinfo, 15); 503 if (w != NULL) 504 w->connsenable[3] = 0; 505 /* There is only one mic preamplifier, use it effectively. */ 506 w = hdaa_widget_get(devinfo, 31); 507 if (w != NULL) { 508 if ((w->wclass.pin.config & 509 HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) == 510 HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN) { 511 w = hdaa_widget_get(devinfo, 16); 512 if (w != NULL) 513 w->connsenable[2] = 0; 514 } else { 515 w = hdaa_widget_get(devinfo, 15); 516 if (w != NULL) 517 w->connsenable[0] = 0; 518 } 519 } 520 w = hdaa_widget_get(devinfo, 32); 521 if (w != NULL) { 522 if ((w->wclass.pin.config & 523 HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) == 524 HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN) { 525 w = hdaa_widget_get(devinfo, 16); 526 if (w != NULL) 527 w->connsenable[0] = 0; 528 } else { 529 w = hdaa_widget_get(devinfo, 15); 530 if (w != NULL) 531 w->connsenable[1] = 0; 532 } 533 } 534 535 if (subid == ASUS_A8X_SUBVENDOR) { 536 /* 537 * This is just plain ridiculous.. There 538 * are several A8 series that share the same 539 * pci id but works differently (EAPD). 540 */ 541 w = hdaa_widget_get(devinfo, 26); 542 if (w != NULL && w->type == 543 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX && 544 (w->wclass.pin.config & 545 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) != 546 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE) 547 devinfo->quirks &= 548 ~HDAA_QUIRK_EAPDINV; 549 } 550 break; 551 case HDA_CODEC_AD1981HD: 552 /* 553 * This CODEC has very unusual design with several 554 * points inappropriate for the present parser. 555 */ 556 /* Disable recording from mono playback mix. */ 557 w = hdaa_widget_get(devinfo, 21); 558 if (w != NULL) 559 w->connsenable[3] = 0; 560 /* Disable rear to front mic mixer, use separately. */ 561 w = hdaa_widget_get(devinfo, 31); 562 if (w != NULL) 563 w->enable = 0; 564 /* Disable direct playback, use mixer. */ 565 w = hdaa_widget_get(devinfo, 5); 566 if (w != NULL) 567 w->connsenable[0] = 0; 568 w = hdaa_widget_get(devinfo, 6); 569 if (w != NULL) 570 w->connsenable[0] = 0; 571 w = hdaa_widget_get(devinfo, 9); 572 if (w != NULL) 573 w->connsenable[0] = 0; 574 w = hdaa_widget_get(devinfo, 24); 575 if (w != NULL) 576 w->connsenable[0] = 0; 577 break; 578 case HDA_CODEC_ALC269: 579 /* 580 * ASUS EeePC 1001px has strange variant of ALC269 CODEC, 581 * that mutes speaker if unused mixer at NID 15 is muted. 582 * Probably CODEC incorrectly reports internal connections. 583 * Hide that muter from the driver. There are several CODECs 584 * sharing this ID and I have not enough information about 585 * them to implement more universal solution. 586 */ 587 if (subid == 0x84371043) { 588 w = hdaa_widget_get(devinfo, 15); 589 if (w != NULL) 590 w->param.inamp_cap = 0; 591 } 592 break; 593 case HDA_CODEC_CX20582: 594 case HDA_CODEC_CX20583: 595 case HDA_CODEC_CX20584: 596 case HDA_CODEC_CX20585: 597 case HDA_CODEC_CX20590: 598 /* 599 * These codecs have extra connectivity on record side 600 * too reach for the present parser. 601 */ 602 w = hdaa_widget_get(devinfo, 20); 603 if (w != NULL) 604 w->connsenable[1] = 0; 605 w = hdaa_widget_get(devinfo, 21); 606 if (w != NULL) 607 w->connsenable[1] = 0; 608 w = hdaa_widget_get(devinfo, 22); 609 if (w != NULL) 610 w->connsenable[0] = 0; 611 break; 612 case HDA_CODEC_VT1708S_0: 613 case HDA_CODEC_VT1708S_1: 614 case HDA_CODEC_VT1708S_2: 615 case HDA_CODEC_VT1708S_3: 616 case HDA_CODEC_VT1708S_4: 617 case HDA_CODEC_VT1708S_5: 618 case HDA_CODEC_VT1708S_6: 619 case HDA_CODEC_VT1708S_7: 620 /* 621 * These codecs have hidden mic boost controls. 622 */ 623 w = hdaa_widget_get(devinfo, 26); 624 if (w != NULL) 625 w->param.inamp_cap = 626 (40 << HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT) | 627 (3 << HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT) | 628 (0 << HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT); 629 w = hdaa_widget_get(devinfo, 30); 630 if (w != NULL) 631 w->param.inamp_cap = 632 (40 << HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT) | 633 (3 << HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT) | 634 (0 << HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT); 635 break; 636 } 637} 638 639void 640hdaa_patch_direct(struct hdaa_devinfo *devinfo) 641{ 642 device_t dev = devinfo->dev; 643 uint32_t id, subid, val; 644 645 id = hdaa_codec_id(devinfo); 646 subid = hdaa_card_id(devinfo); 647 648 switch (id) { 649 case HDA_CODEC_VT1708S_0: 650 case HDA_CODEC_VT1708S_1: 651 case HDA_CODEC_VT1708S_2: 652 case HDA_CODEC_VT1708S_3: 653 case HDA_CODEC_VT1708S_4: 654 case HDA_CODEC_VT1708S_5: 655 case HDA_CODEC_VT1708S_6: 656 case HDA_CODEC_VT1708S_7: 657 /* Enable Mic Boost Volume controls. */ 658 hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid, 659 0xf98, 0x01)); 660 /* Fall though */ 661 case HDA_CODEC_VT1818S: 662 /* Don't bypass mixer. */ 663 hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid, 664 0xf88, 0xc0)); 665 break; 666 } 667 if (subid == APPLE_INTEL_MAC) 668 hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid, 669 0x7e7, 0)); 670 if (id == HDA_CODEC_ALC269) { 671 if (subid == 0x16e31043 || subid == 0x831a1043 || 672 subid == 0x834a1043 || subid == 0x83981043 || 673 subid == 0x83ce1043) { 674 /* 675 * The ditital mics on some Asus laptops produce 676 * differential signals instead of expected stereo. 677 * That results in silence if downmix it to mono. 678 * To workaround, make codec to handle signal as mono. 679 */ 680 hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, 0x20, 0x07)); 681 val = hda_command(dev, HDA_CMD_GET_PROCESSING_COEFF(0, 0x20)); 682 hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, 0x20, 0x07)); 683 hda_command(dev, HDA_CMD_SET_PROCESSING_COEFF(0, 0x20, val|0x80)); 684 } 685 } 686} 687