1 // SPDX-License-Identifier: GPL-2.0-or-later 2 // 3 // Realtek HD-audio codec support code 4 // 5 6 #include <linux/init.h> 7 #include <linux/module.h> 8 #include "realtek.h" 9 10 static int __alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid, 11 unsigned int coef_idx) 12 { 13 unsigned int val; 14 15 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx); 16 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0); 17 return val; 18 } 19 20 int alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid, 21 unsigned int coef_idx) 22 { 23 guard(coef_mutex)(codec); 24 return __alc_read_coefex_idx(codec, nid, coef_idx); 25 } 26 EXPORT_SYMBOL_NS_GPL(alc_read_coefex_idx, "SND_HDA_CODEC_REALTEK"); 27 28 static void __alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid, 29 unsigned int coef_idx, unsigned int coef_val) 30 { 31 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx); 32 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF, coef_val); 33 } 34 35 void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid, 36 unsigned int coef_idx, unsigned int coef_val) 37 { 38 guard(coef_mutex)(codec); 39 __alc_write_coefex_idx(codec, nid, coef_idx, coef_val); 40 } 41 EXPORT_SYMBOL_NS_GPL(alc_write_coefex_idx, "SND_HDA_CODEC_REALTEK"); 42 43 static void __alc_update_coefex_idx(struct hda_codec *codec, hda_nid_t nid, 44 unsigned int coef_idx, unsigned int mask, 45 unsigned int bits_set) 46 { 47 unsigned int val = __alc_read_coefex_idx(codec, nid, coef_idx); 48 49 if (val != -1) 50 __alc_write_coefex_idx(codec, nid, coef_idx, 51 (val & ~mask) | bits_set); 52 } 53 54 void alc_update_coefex_idx(struct hda_codec *codec, hda_nid_t nid, 55 unsigned int coef_idx, unsigned int mask, 56 unsigned int bits_set) 57 { 58 guard(coef_mutex)(codec); 59 __alc_update_coefex_idx(codec, nid, coef_idx, mask, bits_set); 60 } 61 EXPORT_SYMBOL_NS_GPL(alc_update_coefex_idx, "SND_HDA_CODEC_REALTEK"); 62 63 /* a special bypass for COEF 0; read the cached value at the second time */ 64 unsigned int alc_get_coef0(struct hda_codec *codec) 65 { 66 struct alc_spec *spec = codec->spec; 67 68 if (!spec->coef0) 69 spec->coef0 = alc_read_coef_idx(codec, 0); 70 return spec->coef0; 71 } 72 EXPORT_SYMBOL_NS_GPL(alc_get_coef0, "SND_HDA_CODEC_REALTEK"); 73 74 void alc_process_coef_fw(struct hda_codec *codec, const struct coef_fw *fw) 75 { 76 guard(coef_mutex)(codec); 77 for (; fw->nid; fw++) { 78 if (fw->mask == (unsigned short)-1) 79 __alc_write_coefex_idx(codec, fw->nid, fw->idx, fw->val); 80 else 81 __alc_update_coefex_idx(codec, fw->nid, fw->idx, 82 fw->mask, fw->val); 83 } 84 } 85 EXPORT_SYMBOL_NS_GPL(alc_process_coef_fw, "SND_HDA_CODEC_REALTEK"); 86 87 /* 88 * GPIO setup tables, used in initialization 89 */ 90 91 /* Enable GPIO mask and set output */ 92 void alc_setup_gpio(struct hda_codec *codec, unsigned int mask) 93 { 94 struct alc_spec *spec = codec->spec; 95 96 spec->gpio_mask |= mask; 97 spec->gpio_dir |= mask; 98 spec->gpio_data |= mask; 99 } 100 EXPORT_SYMBOL_NS_GPL(alc_setup_gpio, "SND_HDA_CODEC_REALTEK"); 101 102 void alc_update_gpio_data(struct hda_codec *codec, unsigned int mask, 103 bool on) 104 { 105 struct alc_spec *spec = codec->spec; 106 unsigned int oldval = spec->gpio_data; 107 108 if (on) 109 spec->gpio_data |= mask; 110 else 111 spec->gpio_data &= ~mask; 112 if (oldval != spec->gpio_data) 113 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 114 spec->gpio_data); 115 } 116 EXPORT_SYMBOL_NS_GPL(alc_update_gpio_data, "SND_HDA_CODEC_REALTEK"); 117 118 static void alc_write_gpio(struct hda_codec *codec) 119 { 120 struct alc_spec *spec = codec->spec; 121 122 if (!spec->gpio_mask) 123 return; 124 125 snd_hda_codec_set_gpio(codec, spec->gpio_mask, spec->gpio_dir, 126 spec->gpio_data, 127 spec->gpio_write_delay ? 1 : 0); 128 } 129 130 void alc_fixup_gpio(struct hda_codec *codec, int action, unsigned int mask) 131 { 132 if (action == HDA_FIXUP_ACT_PRE_PROBE) 133 alc_setup_gpio(codec, mask); 134 } 135 EXPORT_SYMBOL_NS_GPL(alc_fixup_gpio, "SND_HDA_CODEC_REALTEK"); 136 137 void alc_fixup_gpio1(struct hda_codec *codec, 138 const struct hda_fixup *fix, int action) 139 { 140 alc_fixup_gpio(codec, action, 0x01); 141 } 142 EXPORT_SYMBOL_NS_GPL(alc_fixup_gpio1, "SND_HDA_CODEC_REALTEK"); 143 144 void alc_fixup_gpio2(struct hda_codec *codec, 145 const struct hda_fixup *fix, int action) 146 { 147 alc_fixup_gpio(codec, action, 0x02); 148 } 149 EXPORT_SYMBOL_NS_GPL(alc_fixup_gpio2, "SND_HDA_CODEC_REALTEK"); 150 151 void alc_fixup_gpio3(struct hda_codec *codec, 152 const struct hda_fixup *fix, int action) 153 { 154 alc_fixup_gpio(codec, action, 0x03); 155 } 156 EXPORT_SYMBOL_NS_GPL(alc_fixup_gpio3, "SND_HDA_CODEC_REALTEK"); 157 158 void alc_fixup_gpio4(struct hda_codec *codec, 159 const struct hda_fixup *fix, int action) 160 { 161 alc_fixup_gpio(codec, action, 0x04); 162 } 163 EXPORT_SYMBOL_NS_GPL(alc_fixup_gpio4, "SND_HDA_CODEC_REALTEK"); 164 165 void alc_fixup_micmute_led(struct hda_codec *codec, 166 const struct hda_fixup *fix, int action) 167 { 168 if (action == HDA_FIXUP_ACT_PRE_PROBE) 169 snd_hda_gen_add_micmute_led_cdev(codec, NULL); 170 } 171 EXPORT_SYMBOL_NS_GPL(alc_fixup_micmute_led, "SND_HDA_CODEC_REALTEK"); 172 173 /* 174 * Fix hardware PLL issue 175 * On some codecs, the analog PLL gating control must be off while 176 * the default value is 1. 177 */ 178 void alc_fix_pll(struct hda_codec *codec) 179 { 180 struct alc_spec *spec = codec->spec; 181 182 if (spec->pll_nid) 183 alc_update_coefex_idx(codec, spec->pll_nid, spec->pll_coef_idx, 184 1 << spec->pll_coef_bit, 0); 185 } 186 EXPORT_SYMBOL_NS_GPL(alc_fix_pll, "SND_HDA_CODEC_REALTEK"); 187 188 void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, 189 unsigned int coef_idx, unsigned int coef_bit) 190 { 191 struct alc_spec *spec = codec->spec; 192 spec->pll_nid = nid; 193 spec->pll_coef_idx = coef_idx; 194 spec->pll_coef_bit = coef_bit; 195 alc_fix_pll(codec); 196 } 197 EXPORT_SYMBOL_NS_GPL(alc_fix_pll_init, "SND_HDA_CODEC_REALTEK"); 198 199 /* update the master volume per volume-knob's unsol event */ 200 void alc_update_knob_master(struct hda_codec *codec, 201 struct hda_jack_callback *jack) 202 { 203 unsigned int val; 204 struct snd_kcontrol *kctl; 205 206 kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume"); 207 if (!kctl) 208 return; 209 210 struct snd_ctl_elem_value *uctl __free(kfree) = 211 kzalloc_obj(*uctl); 212 if (!uctl) 213 return; 214 val = snd_hda_codec_read(codec, jack->nid, 0, 215 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0); 216 val &= HDA_AMP_VOLMASK; 217 uctl->value.integer.value[0] = val; 218 uctl->value.integer.value[1] = val; 219 kctl->put(kctl, uctl); 220 } 221 EXPORT_SYMBOL_NS_GPL(alc_update_knob_master, "SND_HDA_CODEC_REALTEK"); 222 223 /* Change EAPD to verb control */ 224 void alc_fill_eapd_coef(struct hda_codec *codec) 225 { 226 int coef; 227 228 coef = alc_get_coef0(codec); 229 230 switch (codec->core.vendor_id) { 231 case 0x10ec0262: 232 alc_update_coef_idx(codec, 0x7, 0, 1<<5); 233 break; 234 case 0x10ec0267: 235 case 0x10ec0268: 236 alc_update_coef_idx(codec, 0x7, 0, 1<<13); 237 break; 238 case 0x10ec0269: 239 if ((coef & 0x00f0) == 0x0010) 240 alc_update_coef_idx(codec, 0xd, 0, 1<<14); 241 if ((coef & 0x00f0) == 0x0020) 242 alc_update_coef_idx(codec, 0x4, 1<<15, 0); 243 if ((coef & 0x00f0) == 0x0030) 244 alc_update_coef_idx(codec, 0x10, 1<<9, 0); 245 break; 246 case 0x10ec0280: 247 case 0x10ec0284: 248 case 0x10ec0290: 249 case 0x10ec0292: 250 alc_update_coef_idx(codec, 0x4, 1<<15, 0); 251 break; 252 case 0x10ec0225: 253 case 0x10ec0295: 254 case 0x10ec0299: 255 alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000); 256 fallthrough; 257 case 0x10ec0215: 258 case 0x10ec0236: 259 case 0x10ec0245: 260 case 0x10ec0256: 261 case 0x10ec0257: 262 case 0x10ec0285: 263 case 0x10ec0289: 264 alc_update_coef_idx(codec, 0x36, 1<<13, 0); 265 fallthrough; 266 case 0x10ec0230: 267 case 0x10ec0233: 268 case 0x10ec0235: 269 case 0x10ec0255: 270 case 0x19e58326: 271 case 0x10ec0282: 272 case 0x10ec0283: 273 case 0x10ec0286: 274 case 0x10ec0288: 275 case 0x10ec0298: 276 case 0x10ec0300: 277 alc_update_coef_idx(codec, 0x10, 1<<9, 0); 278 break; 279 case 0x10ec0275: 280 alc_update_coef_idx(codec, 0xe, 0, 1<<0); 281 break; 282 case 0x10ec0287: 283 alc_update_coef_idx(codec, 0x10, 1<<9, 0); 284 alc_write_coef_idx(codec, 0x8, 0x4ab7); 285 break; 286 case 0x10ec0293: 287 alc_update_coef_idx(codec, 0xa, 1<<13, 0); 288 break; 289 case 0x10ec0234: 290 case 0x10ec0274: 291 alc_write_coef_idx(codec, 0x6e, 0x0c25); 292 fallthrough; 293 case 0x10ec0294: 294 case 0x10ec0700: 295 case 0x10ec0701: 296 case 0x10ec0703: 297 case 0x10ec0711: 298 alc_update_coef_idx(codec, 0x10, 1<<15, 0); 299 break; 300 case 0x10ec0662: 301 if ((coef & 0x00f0) == 0x0030) 302 alc_update_coef_idx(codec, 0x4, 1<<10, 0); /* EAPD Ctrl */ 303 break; 304 case 0x10ec0272: 305 case 0x10ec0273: 306 case 0x10ec0663: 307 case 0x10ec0665: 308 case 0x10ec0670: 309 case 0x10ec0671: 310 case 0x10ec0672: 311 alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */ 312 break; 313 case 0x10ec0222: 314 case 0x10ec0623: 315 alc_update_coef_idx(codec, 0x19, 1<<13, 0); 316 break; 317 case 0x10ec0668: 318 alc_update_coef_idx(codec, 0x7, 3<<13, 0); 319 break; 320 case 0x10ec0867: 321 alc_update_coef_idx(codec, 0x4, 1<<10, 0); 322 break; 323 case 0x10ec0888: 324 if ((coef & 0x00f0) == 0x0020 || (coef & 0x00f0) == 0x0030) 325 alc_update_coef_idx(codec, 0x7, 1<<5, 0); 326 break; 327 case 0x10ec0892: 328 case 0x10ec0897: 329 alc_update_coef_idx(codec, 0x7, 1<<5, 0); 330 break; 331 case 0x10ec0899: 332 case 0x10ec0900: 333 case 0x10ec0b00: 334 case 0x10ec1168: 335 case 0x10ec1220: 336 alc_update_coef_idx(codec, 0x7, 1<<1, 0); 337 break; 338 } 339 } 340 EXPORT_SYMBOL_NS_GPL(alc_fill_eapd_coef, "SND_HDA_CODEC_REALTEK"); 341 342 /* turn on/off EAPD control (only if available) */ 343 static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on) 344 { 345 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) 346 return; 347 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD) 348 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, 349 on ? 2 : 0); 350 } 351 352 /* turn on/off EAPD controls of the codec */ 353 void alc_auto_setup_eapd(struct hda_codec *codec, bool on) 354 { 355 /* We currently only handle front, HP */ 356 static const hda_nid_t pins[] = { 357 0x0f, 0x10, 0x14, 0x15, 0x17, 0 358 }; 359 const hda_nid_t *p; 360 for (p = pins; *p; p++) 361 set_eapd(codec, *p, on); 362 } 363 EXPORT_SYMBOL_NS_GPL(alc_auto_setup_eapd, "SND_HDA_CODEC_REALTEK"); 364 365 /* Returns the nid of the external mic input pin, or 0 if it cannot be found. */ 366 int alc_find_ext_mic_pin(struct hda_codec *codec) 367 { 368 struct alc_spec *spec = codec->spec; 369 struct auto_pin_cfg *cfg = &spec->gen.autocfg; 370 hda_nid_t nid; 371 unsigned int defcfg; 372 int i; 373 374 for (i = 0; i < cfg->num_inputs; i++) { 375 if (cfg->inputs[i].type != AUTO_PIN_MIC) 376 continue; 377 nid = cfg->inputs[i].pin; 378 defcfg = snd_hda_codec_get_pincfg(codec, nid); 379 if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT) 380 continue; 381 return nid; 382 } 383 384 return 0; 385 } 386 EXPORT_SYMBOL_NS_GPL(alc_find_ext_mic_pin, "SND_HDA_CODEC_REALTEK"); 387 388 void alc_headset_mic_no_shutup(struct hda_codec *codec) 389 { 390 const struct hda_pincfg *pin; 391 int mic_pin = alc_find_ext_mic_pin(codec); 392 int i; 393 394 /* don't shut up pins when unloading the driver; otherwise it breaks 395 * the default pin setup at the next load of the driver 396 */ 397 if (codec->bus->shutdown) 398 return; 399 400 snd_array_for_each(&codec->init_pins, i, pin) { 401 if (pin->nid != mic_pin) 402 snd_hda_codec_write_sync(codec, pin->nid, 0, 403 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 404 } 405 406 codec->pins_shutup = 1; 407 } 408 EXPORT_SYMBOL_NS_GPL(alc_headset_mic_no_shutup, "SND_HDA_CODEC_REALTEK"); 409 410 void alc_shutup_pins(struct hda_codec *codec) 411 { 412 struct alc_spec *spec = codec->spec; 413 414 if (spec->no_shutup_pins) 415 return; 416 417 switch (codec->core.vendor_id) { 418 case 0x10ec0236: 419 case 0x10ec0256: 420 case 0x10ec0257: 421 case 0x19e58326: 422 case 0x10ec0283: 423 case 0x10ec0285: 424 case 0x10ec0286: 425 case 0x10ec0287: 426 case 0x10ec0288: 427 case 0x10ec0295: 428 case 0x10ec0298: 429 alc_headset_mic_no_shutup(codec); 430 break; 431 default: 432 snd_hda_shutup_pins(codec); 433 break; 434 } 435 } 436 EXPORT_SYMBOL_NS_GPL(alc_shutup_pins, "SND_HDA_CODEC_REALTEK"); 437 438 /* generic shutup callback; 439 * just turning off EAPD and a little pause for avoiding pop-noise 440 */ 441 void alc_eapd_shutup(struct hda_codec *codec) 442 { 443 struct alc_spec *spec = codec->spec; 444 445 alc_auto_setup_eapd(codec, false); 446 if (!spec->no_depop_delay) 447 msleep(200); 448 alc_shutup_pins(codec); 449 } 450 EXPORT_SYMBOL_NS_GPL(alc_eapd_shutup, "SND_HDA_CODEC_REALTEK"); 451 452 /* additional initialization for ALC888 variants */ 453 static void alc888_coef_init(struct hda_codec *codec) 454 { 455 switch (alc_get_coef0(codec) & 0x00f0) { 456 /* alc888-VA */ 457 case 0x00: 458 /* alc888-VB */ 459 case 0x10: 460 alc_update_coef_idx(codec, 7, 0, 0x2030); /* Turn EAPD to High */ 461 break; 462 } 463 } 464 465 /* generic EAPD initialization */ 466 void alc_auto_init_amp(struct hda_codec *codec, int type) 467 { 468 alc_auto_setup_eapd(codec, true); 469 alc_write_gpio(codec); 470 switch (type) { 471 case ALC_INIT_DEFAULT: 472 switch (codec->core.vendor_id) { 473 case 0x10ec0260: 474 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x2010); 475 break; 476 case 0x10ec0880: 477 case 0x10ec0882: 478 case 0x10ec0883: 479 case 0x10ec0885: 480 alc_update_coef_idx(codec, 7, 0, 0x2030); 481 break; 482 case 0x10ec0888: 483 alc888_coef_init(codec); 484 break; 485 } 486 break; 487 } 488 } 489 EXPORT_SYMBOL_NS_GPL(alc_auto_init_amp, "SND_HDA_CODEC_REALTEK"); 490 491 /* get a primary headphone pin if available */ 492 hda_nid_t alc_get_hp_pin(struct alc_spec *spec) 493 { 494 if (spec->gen.autocfg.hp_pins[0]) 495 return spec->gen.autocfg.hp_pins[0]; 496 if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT) 497 return spec->gen.autocfg.line_out_pins[0]; 498 return 0; 499 } 500 EXPORT_SYMBOL_NS_GPL(alc_get_hp_pin, "SND_HDA_CODEC_REALTEK"); 501 502 /* 503 * Realtek SSID verification 504 */ 505 506 /* Could be any non-zero and even value. When used as fixup, tells 507 * the driver to ignore any present sku defines. 508 */ 509 #define ALC_FIXUP_SKU_IGNORE (2) 510 511 void alc_fixup_sku_ignore(struct hda_codec *codec, 512 const struct hda_fixup *fix, int action) 513 { 514 struct alc_spec *spec = codec->spec; 515 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 516 spec->cdefine.fixup = 1; 517 spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE; 518 } 519 } 520 EXPORT_SYMBOL_NS_GPL(alc_fixup_sku_ignore, "SND_HDA_CODEC_REALTEK"); 521 522 void alc_fixup_no_depop_delay(struct hda_codec *codec, 523 const struct hda_fixup *fix, int action) 524 { 525 struct alc_spec *spec = codec->spec; 526 527 if (action == HDA_FIXUP_ACT_PROBE) { 528 spec->no_depop_delay = 1; 529 codec->depop_delay = 0; 530 } 531 } 532 EXPORT_SYMBOL_NS_GPL(alc_fixup_no_depop_delay, "SND_HDA_CODEC_REALTEK"); 533 534 int alc_auto_parse_customize_define(struct hda_codec *codec) 535 { 536 unsigned int ass, tmp, i; 537 unsigned nid = 0; 538 struct alc_spec *spec = codec->spec; 539 540 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */ 541 542 if (spec->cdefine.fixup) { 543 ass = spec->cdefine.sku_cfg; 544 if (ass == ALC_FIXUP_SKU_IGNORE) 545 return -1; 546 goto do_sku; 547 } 548 549 if (!codec->bus->pci) 550 return -1; 551 ass = codec->core.subsystem_id & 0xffff; 552 if (ass != codec->bus->pci->subsystem_device && (ass & 1)) 553 goto do_sku; 554 555 nid = 0x1d; 556 if (codec->core.vendor_id == 0x10ec0260) 557 nid = 0x17; 558 ass = snd_hda_codec_get_pincfg(codec, nid); 559 560 if (!(ass & 1)) { 561 codec_info(codec, "%s: SKU not ready 0x%08x\n", 562 codec->core.chip_name, ass); 563 return -1; 564 } 565 566 /* check sum */ 567 tmp = 0; 568 for (i = 1; i < 16; i++) { 569 if ((ass >> i) & 1) 570 tmp++; 571 } 572 if (((ass >> 16) & 0xf) != tmp) 573 return -1; 574 575 spec->cdefine.port_connectivity = ass >> 30; 576 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20; 577 spec->cdefine.check_sum = (ass >> 16) & 0xf; 578 spec->cdefine.customization = ass >> 8; 579 do_sku: 580 spec->cdefine.sku_cfg = ass; 581 spec->cdefine.external_amp = (ass & 0x38) >> 3; 582 spec->cdefine.platform_type = (ass & 0x4) >> 2; 583 spec->cdefine.swap = (ass & 0x2) >> 1; 584 spec->cdefine.override = ass & 0x1; 585 586 codec_dbg(codec, "SKU: Nid=0x%x sku_cfg=0x%08x\n", 587 nid, spec->cdefine.sku_cfg); 588 codec_dbg(codec, "SKU: port_connectivity=0x%x\n", 589 spec->cdefine.port_connectivity); 590 codec_dbg(codec, "SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep); 591 codec_dbg(codec, "SKU: check_sum=0x%08x\n", spec->cdefine.check_sum); 592 codec_dbg(codec, "SKU: customization=0x%08x\n", spec->cdefine.customization); 593 codec_dbg(codec, "SKU: external_amp=0x%x\n", spec->cdefine.external_amp); 594 codec_dbg(codec, "SKU: platform_type=0x%x\n", spec->cdefine.platform_type); 595 codec_dbg(codec, "SKU: swap=0x%x\n", spec->cdefine.swap); 596 codec_dbg(codec, "SKU: override=0x%x\n", spec->cdefine.override); 597 598 return 0; 599 } 600 EXPORT_SYMBOL_NS_GPL(alc_auto_parse_customize_define, "SND_HDA_CODEC_REALTEK"); 601 602 /* return the position of NID in the list, or -1 if not found */ 603 static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) 604 { 605 int i; 606 for (i = 0; i < nums; i++) 607 if (list[i] == nid) 608 return i; 609 return -1; 610 } 611 /* return true if the given NID is found in the list */ 612 static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) 613 { 614 return find_idx_in_nid_list(nid, list, nums) >= 0; 615 } 616 617 /* check subsystem ID and set up device-specific initialization; 618 * return 1 if initialized, 0 if invalid SSID 619 */ 620 /* 32-bit subsystem ID for BIOS loading in HD Audio codec. 621 * 31 ~ 16 : Manufacture ID 622 * 15 ~ 8 : SKU ID 623 * 7 ~ 0 : Assembly ID 624 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 625 */ 626 int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports) 627 { 628 unsigned int ass, tmp, i; 629 unsigned nid; 630 struct alc_spec *spec = codec->spec; 631 632 if (spec->cdefine.fixup) { 633 ass = spec->cdefine.sku_cfg; 634 if (ass == ALC_FIXUP_SKU_IGNORE) 635 return 0; 636 goto do_sku; 637 } 638 639 ass = codec->core.subsystem_id & 0xffff; 640 if (codec->bus->pci && 641 ass != codec->bus->pci->subsystem_device && (ass & 1)) 642 goto do_sku; 643 644 /* invalid SSID, check the special NID pin defcfg instead */ 645 /* 646 * 31~30 : port connectivity 647 * 29~21 : reserve 648 * 20 : PCBEEP input 649 * 19~16 : Check sum (15:1) 650 * 15~1 : Custom 651 * 0 : override 652 */ 653 nid = 0x1d; 654 if (codec->core.vendor_id == 0x10ec0260) 655 nid = 0x17; 656 ass = snd_hda_codec_get_pincfg(codec, nid); 657 codec_dbg(codec, 658 "realtek: No valid SSID, checking pincfg 0x%08x for NID 0x%x\n", 659 ass, nid); 660 if (!(ass & 1)) 661 return 0; 662 if ((ass >> 30) != 1) /* no physical connection */ 663 return 0; 664 665 /* check sum */ 666 tmp = 0; 667 for (i = 1; i < 16; i++) { 668 if ((ass >> i) & 1) 669 tmp++; 670 } 671 if (((ass >> 16) & 0xf) != tmp) 672 return 0; 673 do_sku: 674 codec_dbg(codec, "realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n", 675 ass & 0xffff, codec->core.vendor_id); 676 /* 677 * 0 : override 678 * 1 : Swap Jack 679 * 2 : 0 --> Desktop, 1 --> Laptop 680 * 3~5 : External Amplifier control 681 * 7~6 : Reserved 682 */ 683 tmp = (ass & 0x38) >> 3; /* external Amp control */ 684 if (spec->init_amp == ALC_INIT_UNDEFINED) { 685 switch (tmp) { 686 case 1: 687 alc_setup_gpio(codec, 0x01); 688 break; 689 case 3: 690 alc_setup_gpio(codec, 0x02); 691 break; 692 case 7: 693 alc_setup_gpio(codec, 0x04); 694 break; 695 case 5: 696 default: 697 spec->init_amp = ALC_INIT_DEFAULT; 698 break; 699 } 700 } 701 702 /* is laptop or Desktop and enable the function "Mute internal speaker 703 * when the external headphone out jack is plugged" 704 */ 705 if (!(ass & 0x8000)) 706 return 1; 707 /* 708 * 10~8 : Jack location 709 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered 710 * 14~13: Resvered 711 * 15 : 1 --> enable the function "Mute internal speaker 712 * when the external headphone out jack is plugged" 713 */ 714 if (!alc_get_hp_pin(spec)) { 715 hda_nid_t nid; 716 tmp = (ass >> 11) & 0x3; /* HP to chassis */ 717 nid = ports[tmp]; 718 if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins, 719 spec->gen.autocfg.line_outs)) 720 return 1; 721 spec->gen.autocfg.hp_pins[0] = nid; 722 } 723 return 1; 724 } 725 EXPORT_SYMBOL_NS_GPL(alc_subsystem_id, "SND_HDA_CODEC_REALTEK"); 726 727 /* Check the validity of ALC subsystem-id 728 * ports contains an array of 4 pin NIDs for port-A, E, D and I */ 729 void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports) 730 { 731 if (!alc_subsystem_id(codec, ports)) { 732 struct alc_spec *spec = codec->spec; 733 if (spec->init_amp == ALC_INIT_UNDEFINED) { 734 codec_dbg(codec, 735 "realtek: Enable default setup for auto mode as fallback\n"); 736 spec->init_amp = ALC_INIT_DEFAULT; 737 } 738 } 739 } 740 EXPORT_SYMBOL_NS_GPL(alc_ssid_check, "SND_HDA_CODEC_REALTEK"); 741 742 /* inverted digital-mic */ 743 void alc_fixup_inv_dmic(struct hda_codec *codec, 744 const struct hda_fixup *fix, int action) 745 { 746 struct alc_spec *spec = codec->spec; 747 748 spec->gen.inv_dmic_split = 1; 749 } 750 EXPORT_SYMBOL_NS_GPL(alc_fixup_inv_dmic, "SND_HDA_CODEC_REALTEK"); 751 752 int alc_build_controls(struct hda_codec *codec) 753 { 754 int err; 755 756 err = snd_hda_gen_build_controls(codec); 757 if (err < 0) 758 return err; 759 760 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD); 761 return 0; 762 } 763 EXPORT_SYMBOL_NS_GPL(alc_build_controls, "SND_HDA_CODEC_REALTEK"); 764 765 int alc_init(struct hda_codec *codec) 766 { 767 struct alc_spec *spec = codec->spec; 768 769 /* hibernation resume needs the full chip initialization */ 770 if (is_s4_resume(codec)) 771 alc_pre_init(codec); 772 773 if (spec->init_hook) 774 spec->init_hook(codec); 775 776 spec->gen.skip_verbs = 1; /* applied in below */ 777 snd_hda_gen_init(codec); 778 alc_fix_pll(codec); 779 alc_auto_init_amp(codec, spec->init_amp); 780 snd_hda_apply_verbs(codec); /* apply verbs here after own init */ 781 782 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT); 783 784 return 0; 785 } 786 EXPORT_SYMBOL_NS_GPL(alc_init, "SND_HDA_CODEC_REALTEK"); 787 788 void alc_shutup(struct hda_codec *codec) 789 { 790 struct alc_spec *spec = codec->spec; 791 792 if (!snd_hda_get_bool_hint(codec, "shutup")) 793 return; /* disabled explicitly by hints */ 794 795 if (spec && spec->shutup) 796 spec->shutup(codec); 797 else 798 alc_shutup_pins(codec); 799 } 800 EXPORT_SYMBOL_NS_GPL(alc_shutup, "SND_HDA_CODEC_REALTEK"); 801 802 void alc_power_eapd(struct hda_codec *codec) 803 { 804 alc_auto_setup_eapd(codec, false); 805 } 806 EXPORT_SYMBOL_NS_GPL(alc_power_eapd, "SND_HDA_CODEC_REALTEK"); 807 808 int alc_suspend(struct hda_codec *codec) 809 { 810 struct alc_spec *spec = codec->spec; 811 alc_shutup(codec); 812 if (spec && spec->power_hook) 813 spec->power_hook(codec); 814 return 0; 815 } 816 EXPORT_SYMBOL_NS_GPL(alc_suspend, "SND_HDA_CODEC_REALTEK"); 817 818 int alc_resume(struct hda_codec *codec) 819 { 820 struct alc_spec *spec = codec->spec; 821 822 if (!spec->no_depop_delay) 823 msleep(150); /* to avoid pop noise */ 824 snd_hda_codec_init(codec); 825 snd_hda_regmap_sync(codec); 826 hda_call_check_power_status(codec, 0x01); 827 return 0; 828 } 829 EXPORT_SYMBOL_NS_GPL(alc_resume, "SND_HDA_CODEC_REALTEK"); 830 831 /* 832 * Rename codecs appropriately from COEF value or subvendor id 833 */ 834 struct alc_codec_rename_table { 835 unsigned int vendor_id; 836 unsigned short coef_mask; 837 unsigned short coef_bits; 838 const char *name; 839 }; 840 841 struct alc_codec_rename_pci_table { 842 unsigned int codec_vendor_id; 843 unsigned short pci_subvendor; 844 unsigned short pci_subdevice; 845 const char *name; 846 }; 847 848 static const struct alc_codec_rename_table rename_tbl[] = { 849 { 0x10ec0221, 0xf00f, 0x1003, "ALC231" }, 850 { 0x10ec0269, 0xfff0, 0x3010, "ALC277" }, 851 { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" }, 852 { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" }, 853 { 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" }, 854 { 0x10ec0269, 0xffff, 0xa023, "ALC259" }, 855 { 0x10ec0269, 0xffff, 0x6023, "ALC281X" }, 856 { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" }, 857 { 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" }, 858 { 0x10ec0662, 0xffff, 0x4020, "ALC656" }, 859 { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" }, 860 { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" }, 861 { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" }, 862 { 0x10ec0899, 0x2000, 0x2000, "ALC899" }, 863 { 0x10ec0892, 0xffff, 0x8020, "ALC661" }, 864 { 0x10ec0892, 0xffff, 0x8011, "ALC661" }, 865 { 0x10ec0892, 0xffff, 0x4011, "ALC656" }, 866 { } /* terminator */ 867 }; 868 869 static const struct alc_codec_rename_pci_table rename_pci_tbl[] = { 870 { 0x10ec0280, 0x1028, 0, "ALC3220" }, 871 { 0x10ec0282, 0x1028, 0, "ALC3221" }, 872 { 0x10ec0283, 0x1028, 0, "ALC3223" }, 873 { 0x10ec0288, 0x1028, 0, "ALC3263" }, 874 { 0x10ec0292, 0x1028, 0, "ALC3226" }, 875 { 0x10ec0293, 0x1028, 0, "ALC3235" }, 876 { 0x10ec0255, 0x1028, 0, "ALC3234" }, 877 { 0x10ec0668, 0x1028, 0, "ALC3661" }, 878 { 0x10ec0275, 0x1028, 0, "ALC3260" }, 879 { 0x10ec0899, 0x1028, 0, "ALC3861" }, 880 { 0x10ec0298, 0x1028, 0, "ALC3266" }, 881 { 0x10ec0236, 0x1028, 0, "ALC3204" }, 882 { 0x10ec0256, 0x1028, 0, "ALC3246" }, 883 { 0x10ec0225, 0x1028, 0, "ALC3253" }, 884 { 0x10ec0295, 0x1028, 0, "ALC3254" }, 885 { 0x10ec0299, 0x1028, 0, "ALC3271" }, 886 { 0x10ec0670, 0x1025, 0, "ALC669X" }, 887 { 0x10ec0676, 0x1025, 0, "ALC679X" }, 888 { 0x10ec0282, 0x1043, 0, "ALC3229" }, 889 { 0x10ec0233, 0x1043, 0, "ALC3236" }, 890 { 0x10ec0280, 0x103c, 0, "ALC3228" }, 891 { 0x10ec0282, 0x103c, 0, "ALC3227" }, 892 { 0x10ec0286, 0x103c, 0, "ALC3242" }, 893 { 0x10ec0290, 0x103c, 0, "ALC3241" }, 894 { 0x10ec0668, 0x103c, 0, "ALC3662" }, 895 { 0x10ec0283, 0x17aa, 0, "ALC3239" }, 896 { 0x10ec0292, 0x17aa, 0, "ALC3232" }, 897 { 0x10ec0257, 0x12f0, 0, "ALC3328" }, 898 { } /* terminator */ 899 }; 900 901 static int alc_codec_rename_from_preset(struct hda_codec *codec) 902 { 903 const struct alc_codec_rename_table *p; 904 const struct alc_codec_rename_pci_table *q; 905 906 for (p = rename_tbl; p->vendor_id; p++) { 907 if (p->vendor_id != codec->core.vendor_id) 908 continue; 909 if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits) 910 return alc_codec_rename(codec, p->name); 911 } 912 913 if (!codec->bus->pci) 914 return 0; 915 for (q = rename_pci_tbl; q->codec_vendor_id; q++) { 916 if (q->codec_vendor_id != codec->core.vendor_id) 917 continue; 918 if (q->pci_subvendor != codec->bus->pci->subsystem_vendor) 919 continue; 920 if (!q->pci_subdevice || 921 q->pci_subdevice == codec->bus->pci->subsystem_device) 922 return alc_codec_rename(codec, q->name); 923 } 924 925 return 0; 926 } 927 928 /* 929 * Digital-beep handlers 930 */ 931 #ifdef CONFIG_SND_HDA_INPUT_BEEP 932 933 /* additional beep mixers; private_value will be overwritten */ 934 static const struct snd_kcontrol_new alc_beep_mixer[] = { 935 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT), 936 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT), 937 }; 938 939 /* set up and create beep controls */ 940 int alc_set_beep_amp(struct alc_spec *spec, hda_nid_t nid, int idx, int dir) 941 { 942 struct snd_kcontrol_new *knew; 943 unsigned int beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir); 944 int i; 945 946 for (i = 0; i < ARRAY_SIZE(alc_beep_mixer); i++) { 947 knew = snd_hda_gen_add_kctl(&spec->gen, NULL, 948 &alc_beep_mixer[i]); 949 if (!knew) 950 return -ENOMEM; 951 knew->private_value = beep_amp; 952 } 953 return 0; 954 } 955 EXPORT_SYMBOL_NS_GPL(alc_set_beep_amp, "SND_HDA_CODEC_REALTEK"); 956 957 static const struct snd_pci_quirk beep_allow_list[] = { 958 SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1), 959 SND_PCI_QUIRK(0x1043, 0x115d, "ASUS", 1), 960 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), 961 SND_PCI_QUIRK(0x1043, 0x8376, "EeePC", 1), 962 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1), 963 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1), 964 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1), 965 SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1), 966 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), 967 /* denylist -- no beep available */ 968 SND_PCI_QUIRK(0x17aa, 0x309e, "Lenovo ThinkCentre M73", 0), 969 SND_PCI_QUIRK(0x17aa, 0x30a3, "Lenovo ThinkCentre M93", 0), 970 {} 971 }; 972 973 int alc_has_cdefine_beep(struct hda_codec *codec) 974 { 975 struct alc_spec *spec = codec->spec; 976 const struct snd_pci_quirk *q; 977 q = snd_pci_quirk_lookup(codec->bus->pci, beep_allow_list); 978 if (q) 979 return q->value; 980 return spec->cdefine.enable_pcbeep; 981 } 982 EXPORT_SYMBOL_NS_GPL(alc_has_cdefine_beep, "SND_HDA_CODEC_REALTEK"); 983 984 #endif /* CONFIG_SND_HDA_INPUT_BEEP */ 985 986 /* parse the BIOS configuration and set up the alc_spec */ 987 /* return 1 if successful, 0 if the proper config is not found, 988 * or a negative error code 989 */ 990 int alc_parse_auto_config(struct hda_codec *codec, 991 const hda_nid_t *ignore_nids, 992 const hda_nid_t *ssid_nids) 993 { 994 struct alc_spec *spec = codec->spec; 995 struct auto_pin_cfg *cfg = &spec->gen.autocfg; 996 int err; 997 998 err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids, 999 spec->parse_flags); 1000 if (err < 0) 1001 return err; 1002 1003 if (ssid_nids) 1004 alc_ssid_check(codec, ssid_nids); 1005 1006 err = snd_hda_gen_parse_auto_config(codec, cfg); 1007 if (err < 0) 1008 return err; 1009 1010 return 1; 1011 } 1012 EXPORT_SYMBOL_NS_GPL(alc_parse_auto_config, "SND_HDA_CODEC_REALTEK"); 1013 1014 /* common preparation job for alc_spec */ 1015 int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid) 1016 { 1017 struct alc_spec *spec = kzalloc_obj(*spec); 1018 int err; 1019 1020 if (!spec) 1021 return -ENOMEM; 1022 codec->spec = spec; 1023 snd_hda_gen_spec_init(&spec->gen); 1024 spec->gen.mixer_nid = mixer_nid; 1025 spec->gen.own_eapd_ctl = 1; 1026 codec->single_adc_amp = 1; 1027 /* FIXME: do we need this for all Realtek codec models? */ 1028 codec->spdif_status_reset = 1; 1029 codec->forced_resume = 1; 1030 mutex_init(&spec->coef_mutex); 1031 1032 err = alc_codec_rename_from_preset(codec); 1033 if (err < 0) { 1034 kfree(spec); 1035 return err; 1036 } 1037 return 0; 1038 } 1039 EXPORT_SYMBOL_NS_GPL(alc_alloc_spec, "SND_HDA_CODEC_REALTEK"); 1040 1041 /* For dual-codec configuration, we need to disable some features to avoid 1042 * conflicts of kctls and PCM streams 1043 */ 1044 void alc_fixup_dual_codecs(struct hda_codec *codec, 1045 const struct hda_fixup *fix, int action) 1046 { 1047 struct alc_spec *spec = codec->spec; 1048 1049 if (action != HDA_FIXUP_ACT_PRE_PROBE) 1050 return; 1051 /* disable vmaster */ 1052 spec->gen.suppress_vmaster = 1; 1053 /* auto-mute and auto-mic switch don't work with multiple codecs */ 1054 spec->gen.suppress_auto_mute = 1; 1055 spec->gen.suppress_auto_mic = 1; 1056 /* disable aamix as well */ 1057 spec->gen.mixer_nid = 0; 1058 /* add location prefix to avoid conflicts */ 1059 codec->force_pin_prefix = 1; 1060 } 1061 EXPORT_SYMBOL_NS_GPL(alc_fixup_dual_codecs, "SND_HDA_CODEC_REALTEK"); 1062 1063 static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = { 1064 { .channels = 2, 1065 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } }, 1066 { .channels = 4, 1067 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, 1068 SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */ 1069 { } 1070 }; 1071 1072 /* override the 2.1 chmap */ 1073 void alc_fixup_bass_chmap(struct hda_codec *codec, 1074 const struct hda_fixup *fix, int action) 1075 { 1076 if (action == HDA_FIXUP_ACT_BUILD) { 1077 struct alc_spec *spec = codec->spec; 1078 spec->gen.pcm_rec[0]->stream[0].chmap = asus_pcm_2_1_chmaps; 1079 } 1080 } 1081 EXPORT_SYMBOL_NS_GPL(alc_fixup_bass_chmap, "SND_HDA_CODEC_REALTEK"); 1082 1083 /* exported as it's used by multiple codecs */ 1084 void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec, 1085 const struct hda_fixup *fix, 1086 int action) 1087 { 1088 alc_fixup_dual_codecs(codec, fix, action); 1089 switch (action) { 1090 case HDA_FIXUP_ACT_PRE_PROBE: 1091 /* override card longname to provide a unique UCM profile */ 1092 strscpy(codec->card->longname, "HDAudio-Gigabyte-ALC1220DualCodecs"); 1093 break; 1094 case HDA_FIXUP_ACT_BUILD: 1095 /* rename Capture controls depending on the codec */ 1096 rename_ctl(codec, "Capture Volume", 1097 codec->addr == 0 ? 1098 "Rear-Panel Capture Volume" : 1099 "Front-Panel Capture Volume"); 1100 rename_ctl(codec, "Capture Switch", 1101 codec->addr == 0 ? 1102 "Rear-Panel Capture Switch" : 1103 "Front-Panel Capture Switch"); 1104 break; 1105 } 1106 } 1107 EXPORT_SYMBOL_NS_GPL(alc1220_fixup_gb_dual_codecs, "SND_HDA_CODEC_REALTEK"); 1108 1109 void alc233_alc662_fixup_lenovo_dual_codecs(struct hda_codec *codec, 1110 const struct hda_fixup *fix, 1111 int action) 1112 { 1113 alc_fixup_dual_codecs(codec, fix, action); 1114 switch (action) { 1115 case HDA_FIXUP_ACT_PRE_PROBE: 1116 /* override card longname to provide a unique UCM profile */ 1117 strscpy(codec->card->longname, "HDAudio-Lenovo-DualCodecs"); 1118 break; 1119 case HDA_FIXUP_ACT_BUILD: 1120 /* rename Capture controls depending on the codec */ 1121 rename_ctl(codec, "Capture Volume", 1122 codec->addr == 0 ? 1123 "Rear-Panel Capture Volume" : 1124 "Front-Panel Capture Volume"); 1125 rename_ctl(codec, "Capture Switch", 1126 codec->addr == 0 ? 1127 "Rear-Panel Capture Switch" : 1128 "Front-Panel Capture Switch"); 1129 break; 1130 } 1131 } 1132 EXPORT_SYMBOL_NS_GPL(alc233_alc662_fixup_lenovo_dual_codecs, "SND_HDA_CODEC_REALTEK"); 1133 1134 static void alc_shutup_dell_xps13(struct hda_codec *codec) 1135 { 1136 struct alc_spec *spec = codec->spec; 1137 int hp_pin = alc_get_hp_pin(spec); 1138 1139 /* Prevent pop noises when headphones are plugged in */ 1140 snd_hda_codec_write(codec, hp_pin, 0, 1141 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); 1142 msleep(20); 1143 } 1144 1145 void alc_fixup_dell_xps13(struct hda_codec *codec, 1146 const struct hda_fixup *fix, int action) 1147 { 1148 struct alc_spec *spec = codec->spec; 1149 struct hda_input_mux *imux = &spec->gen.input_mux; 1150 int i; 1151 1152 switch (action) { 1153 case HDA_FIXUP_ACT_PRE_PROBE: 1154 /* mic pin 0x19 must be initialized with Vref Hi-Z, otherwise 1155 * it causes a click noise at start up 1156 */ 1157 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ); 1158 spec->shutup = alc_shutup_dell_xps13; 1159 break; 1160 case HDA_FIXUP_ACT_PROBE: 1161 /* Make the internal mic the default input source. */ 1162 for (i = 0; i < imux->num_items; i++) { 1163 if (spec->gen.imux_pins[i] == 0x12) { 1164 spec->gen.cur_mux[0] = i; 1165 break; 1166 } 1167 } 1168 break; 1169 } 1170 } 1171 EXPORT_SYMBOL_NS_GPL(alc_fixup_dell_xps13, "SND_HDA_CODEC_REALTEK"); 1172 1173 /* 1174 * headset handling 1175 */ 1176 1177 static void alc_hp_mute_disable(struct hda_codec *codec, unsigned int delay) 1178 { 1179 if (delay <= 0) 1180 delay = 75; 1181 snd_hda_codec_write(codec, 0x21, 0, 1182 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); 1183 msleep(delay); 1184 snd_hda_codec_write(codec, 0x21, 0, 1185 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); 1186 msleep(delay); 1187 } 1188 1189 static void alc_hp_enable_unmute(struct hda_codec *codec, unsigned int delay) 1190 { 1191 if (delay <= 0) 1192 delay = 75; 1193 snd_hda_codec_write(codec, 0x21, 0, 1194 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 1195 msleep(delay); 1196 snd_hda_codec_write(codec, 0x21, 0, 1197 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); 1198 msleep(delay); 1199 } 1200 1201 static const struct coef_fw alc225_pre_hsmode[] = { 1202 UPDATE_COEF(0x4a, 1<<8, 0), 1203 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), 1204 UPDATE_COEF(0x63, 3<<14, 3<<14), 1205 UPDATE_COEF(0x4a, 3<<4, 2<<4), 1206 UPDATE_COEF(0x4a, 3<<10, 3<<10), 1207 UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10), 1208 UPDATE_COEF(0x4a, 3<<10, 0), 1209 {} 1210 }; 1211 1212 static void alc_headset_mode_unplugged(struct hda_codec *codec) 1213 { 1214 struct alc_spec *spec = codec->spec; 1215 static const struct coef_fw coef0255[] = { 1216 WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */ 1217 WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */ 1218 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/ 1219 WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */ 1220 WRITE_COEFEX(0x57, 0x03, 0x8aa6), /* Direct Drive HP Amp control */ 1221 {} 1222 }; 1223 static const struct coef_fw coef0256[] = { 1224 WRITE_COEF(0x1b, 0x0c4b), /* LDO and MISC control */ 1225 WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */ 1226 WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */ 1227 WRITE_COEFEX(0x57, 0x03, 0x09a3), /* Direct Drive HP Amp control */ 1228 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/ 1229 {} 1230 }; 1231 static const struct coef_fw coef0233[] = { 1232 WRITE_COEF(0x1b, 0x0c0b), 1233 WRITE_COEF(0x45, 0xc429), 1234 UPDATE_COEF(0x35, 0x4000, 0), 1235 WRITE_COEF(0x06, 0x2104), 1236 WRITE_COEF(0x1a, 0x0001), 1237 WRITE_COEF(0x26, 0x0004), 1238 WRITE_COEF(0x32, 0x42a3), 1239 {} 1240 }; 1241 static const struct coef_fw coef0288[] = { 1242 UPDATE_COEF(0x4f, 0xfcc0, 0xc400), 1243 UPDATE_COEF(0x50, 0x2000, 0x2000), 1244 UPDATE_COEF(0x56, 0x0006, 0x0006), 1245 UPDATE_COEF(0x66, 0x0008, 0), 1246 UPDATE_COEF(0x67, 0x2000, 0), 1247 {} 1248 }; 1249 static const struct coef_fw coef0298[] = { 1250 UPDATE_COEF(0x19, 0x1300, 0x0300), 1251 {} 1252 }; 1253 static const struct coef_fw coef0292[] = { 1254 WRITE_COEF(0x76, 0x000e), 1255 WRITE_COEF(0x6c, 0x2400), 1256 WRITE_COEF(0x18, 0x7308), 1257 WRITE_COEF(0x6b, 0xc429), 1258 {} 1259 }; 1260 static const struct coef_fw coef0293[] = { 1261 UPDATE_COEF(0x10, 7<<8, 6<<8), /* SET Line1 JD to 0 */ 1262 UPDATE_COEFEX(0x57, 0x05, 1<<15|1<<13, 0x0), /* SET charge pump by verb */ 1263 UPDATE_COEFEX(0x57, 0x03, 1<<10, 1<<10), /* SET EN_OSW to 1 */ 1264 UPDATE_COEF(0x1a, 1<<3, 1<<3), /* Combo JD gating with LINE1-VREFO */ 1265 WRITE_COEF(0x45, 0xc429), /* Set to TRS type */ 1266 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */ 1267 {} 1268 }; 1269 static const struct coef_fw coef0668[] = { 1270 WRITE_COEF(0x15, 0x0d40), 1271 WRITE_COEF(0xb7, 0x802b), 1272 {} 1273 }; 1274 static const struct coef_fw coef0225[] = { 1275 UPDATE_COEF(0x63, 3<<14, 0), 1276 {} 1277 }; 1278 static const struct coef_fw coef0274[] = { 1279 UPDATE_COEF(0x4a, 0x0100, 0), 1280 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0), 1281 UPDATE_COEF(0x6b, 0xf000, 0x5000), 1282 UPDATE_COEF(0x4a, 0x0010, 0), 1283 UPDATE_COEF(0x4a, 0x0c00, 0x0c00), 1284 WRITE_COEF(0x45, 0x5289), 1285 UPDATE_COEF(0x4a, 0x0c00, 0), 1286 {} 1287 }; 1288 1289 if (spec->no_internal_mic_pin) { 1290 alc_update_coef_idx(codec, 0x45, 0xf<<12 | 1<<10, 5<<12); 1291 return; 1292 } 1293 1294 switch (codec->core.vendor_id) { 1295 case 0x10ec0255: 1296 alc_process_coef_fw(codec, coef0255); 1297 break; 1298 case 0x10ec0230: 1299 case 0x10ec0236: 1300 case 0x10ec0256: 1301 case 0x19e58326: 1302 alc_hp_mute_disable(codec, 75); 1303 alc_process_coef_fw(codec, coef0256); 1304 break; 1305 case 0x10ec0234: 1306 case 0x10ec0274: 1307 case 0x10ec0294: 1308 alc_process_coef_fw(codec, coef0274); 1309 break; 1310 case 0x10ec0233: 1311 case 0x10ec0283: 1312 alc_process_coef_fw(codec, coef0233); 1313 break; 1314 case 0x10ec0286: 1315 case 0x10ec0288: 1316 alc_process_coef_fw(codec, coef0288); 1317 break; 1318 case 0x10ec0298: 1319 alc_process_coef_fw(codec, coef0298); 1320 alc_process_coef_fw(codec, coef0288); 1321 break; 1322 case 0x10ec0292: 1323 alc_process_coef_fw(codec, coef0292); 1324 break; 1325 case 0x10ec0293: 1326 alc_process_coef_fw(codec, coef0293); 1327 break; 1328 case 0x10ec0668: 1329 alc_process_coef_fw(codec, coef0668); 1330 break; 1331 case 0x10ec0215: 1332 case 0x10ec0225: 1333 case 0x10ec0285: 1334 case 0x10ec0295: 1335 case 0x10ec0289: 1336 case 0x10ec0299: 1337 alc_hp_mute_disable(codec, 75); 1338 alc_process_coef_fw(codec, alc225_pre_hsmode); 1339 alc_process_coef_fw(codec, coef0225); 1340 break; 1341 case 0x10ec0867: 1342 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0); 1343 break; 1344 } 1345 codec_dbg(codec, "Headset jack set to unplugged mode.\n"); 1346 } 1347 1348 1349 static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, 1350 hda_nid_t mic_pin) 1351 { 1352 static const struct coef_fw coef0255[] = { 1353 WRITE_COEFEX(0x57, 0x03, 0x8aa6), 1354 WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */ 1355 {} 1356 }; 1357 static const struct coef_fw coef0256[] = { 1358 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14), /* Direct Drive HP Amp control(Set to verb control)*/ 1359 WRITE_COEFEX(0x57, 0x03, 0x09a3), 1360 WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */ 1361 {} 1362 }; 1363 static const struct coef_fw coef0233[] = { 1364 UPDATE_COEF(0x35, 0, 1<<14), 1365 WRITE_COEF(0x06, 0x2100), 1366 WRITE_COEF(0x1a, 0x0021), 1367 WRITE_COEF(0x26, 0x008c), 1368 {} 1369 }; 1370 static const struct coef_fw coef0288[] = { 1371 UPDATE_COEF(0x4f, 0x00c0, 0), 1372 UPDATE_COEF(0x50, 0x2000, 0), 1373 UPDATE_COEF(0x56, 0x0006, 0), 1374 UPDATE_COEF(0x4f, 0xfcc0, 0xc400), 1375 UPDATE_COEF(0x66, 0x0008, 0x0008), 1376 UPDATE_COEF(0x67, 0x2000, 0x2000), 1377 {} 1378 }; 1379 static const struct coef_fw coef0292[] = { 1380 WRITE_COEF(0x19, 0xa208), 1381 WRITE_COEF(0x2e, 0xacf0), 1382 {} 1383 }; 1384 static const struct coef_fw coef0293[] = { 1385 UPDATE_COEFEX(0x57, 0x05, 0, 1<<15|1<<13), /* SET charge pump by verb */ 1386 UPDATE_COEFEX(0x57, 0x03, 1<<10, 0), /* SET EN_OSW to 0 */ 1387 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */ 1388 {} 1389 }; 1390 static const struct coef_fw coef0688[] = { 1391 WRITE_COEF(0xb7, 0x802b), 1392 WRITE_COEF(0xb5, 0x1040), 1393 UPDATE_COEF(0xc3, 0, 1<<12), 1394 {} 1395 }; 1396 static const struct coef_fw coef0225[] = { 1397 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14), 1398 UPDATE_COEF(0x4a, 3<<4, 2<<4), 1399 UPDATE_COEF(0x63, 3<<14, 0), 1400 {} 1401 }; 1402 static const struct coef_fw coef0274[] = { 1403 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0x4000), 1404 UPDATE_COEF(0x4a, 0x0010, 0), 1405 UPDATE_COEF(0x6b, 0xf000, 0), 1406 {} 1407 }; 1408 1409 switch (codec->core.vendor_id) { 1410 case 0x10ec0255: 1411 alc_write_coef_idx(codec, 0x45, 0xc489); 1412 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); 1413 alc_process_coef_fw(codec, coef0255); 1414 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); 1415 break; 1416 case 0x10ec0230: 1417 case 0x10ec0236: 1418 case 0x10ec0256: 1419 case 0x19e58326: 1420 alc_write_coef_idx(codec, 0x45, 0xc489); 1421 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); 1422 alc_process_coef_fw(codec, coef0256); 1423 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); 1424 break; 1425 case 0x10ec0234: 1426 case 0x10ec0274: 1427 case 0x10ec0294: 1428 alc_write_coef_idx(codec, 0x45, 0x4689); 1429 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); 1430 alc_process_coef_fw(codec, coef0274); 1431 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); 1432 break; 1433 case 0x10ec0233: 1434 case 0x10ec0283: 1435 alc_write_coef_idx(codec, 0x45, 0xc429); 1436 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); 1437 alc_process_coef_fw(codec, coef0233); 1438 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); 1439 break; 1440 case 0x10ec0286: 1441 case 0x10ec0288: 1442 case 0x10ec0298: 1443 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); 1444 alc_process_coef_fw(codec, coef0288); 1445 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); 1446 break; 1447 case 0x10ec0292: 1448 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); 1449 alc_process_coef_fw(codec, coef0292); 1450 break; 1451 case 0x10ec0293: 1452 /* Set to TRS mode */ 1453 alc_write_coef_idx(codec, 0x45, 0xc429); 1454 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); 1455 alc_process_coef_fw(codec, coef0293); 1456 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); 1457 break; 1458 case 0x10ec0867: 1459 alc_update_coefex_idx(codec, 0x57, 0x5, 0, 1<<14); 1460 fallthrough; 1461 case 0x10ec0221: 1462 case 0x10ec0662: 1463 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); 1464 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); 1465 break; 1466 case 0x10ec0668: 1467 alc_write_coef_idx(codec, 0x11, 0x0001); 1468 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); 1469 alc_process_coef_fw(codec, coef0688); 1470 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); 1471 break; 1472 case 0x10ec0215: 1473 case 0x10ec0225: 1474 case 0x10ec0285: 1475 case 0x10ec0295: 1476 case 0x10ec0289: 1477 case 0x10ec0299: 1478 alc_process_coef_fw(codec, alc225_pre_hsmode); 1479 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10); 1480 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); 1481 alc_process_coef_fw(codec, coef0225); 1482 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); 1483 break; 1484 } 1485 codec_dbg(codec, "Headset jack set to mic-in mode.\n"); 1486 } 1487 1488 static void alc_headset_mode_default(struct hda_codec *codec) 1489 { 1490 static const struct coef_fw coef0225[] = { 1491 UPDATE_COEF(0x45, 0x3f<<10, 0x30<<10), 1492 UPDATE_COEF(0x45, 0x3f<<10, 0x31<<10), 1493 UPDATE_COEF(0x49, 3<<8, 0<<8), 1494 UPDATE_COEF(0x4a, 3<<4, 3<<4), 1495 UPDATE_COEF(0x63, 3<<14, 0), 1496 UPDATE_COEF(0x67, 0xf000, 0x3000), 1497 {} 1498 }; 1499 static const struct coef_fw coef0255[] = { 1500 WRITE_COEF(0x45, 0xc089), 1501 WRITE_COEF(0x45, 0xc489), 1502 WRITE_COEFEX(0x57, 0x03, 0x8ea6), 1503 WRITE_COEF(0x49, 0x0049), 1504 {} 1505 }; 1506 static const struct coef_fw coef0256[] = { 1507 WRITE_COEF(0x45, 0xc489), 1508 WRITE_COEFEX(0x57, 0x03, 0x0da3), 1509 WRITE_COEF(0x49, 0x0049), 1510 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/ 1511 WRITE_COEF(0x06, 0x6100), 1512 {} 1513 }; 1514 static const struct coef_fw coef0233[] = { 1515 WRITE_COEF(0x06, 0x2100), 1516 WRITE_COEF(0x32, 0x4ea3), 1517 {} 1518 }; 1519 static const struct coef_fw coef0288[] = { 1520 UPDATE_COEF(0x4f, 0xfcc0, 0xc400), /* Set to TRS type */ 1521 UPDATE_COEF(0x50, 0x2000, 0x2000), 1522 UPDATE_COEF(0x56, 0x0006, 0x0006), 1523 UPDATE_COEF(0x66, 0x0008, 0), 1524 UPDATE_COEF(0x67, 0x2000, 0), 1525 {} 1526 }; 1527 static const struct coef_fw coef0292[] = { 1528 WRITE_COEF(0x76, 0x000e), 1529 WRITE_COEF(0x6c, 0x2400), 1530 WRITE_COEF(0x6b, 0xc429), 1531 WRITE_COEF(0x18, 0x7308), 1532 {} 1533 }; 1534 static const struct coef_fw coef0293[] = { 1535 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */ 1536 WRITE_COEF(0x45, 0xC429), /* Set to TRS type */ 1537 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */ 1538 {} 1539 }; 1540 static const struct coef_fw coef0688[] = { 1541 WRITE_COEF(0x11, 0x0041), 1542 WRITE_COEF(0x15, 0x0d40), 1543 WRITE_COEF(0xb7, 0x802b), 1544 {} 1545 }; 1546 static const struct coef_fw coef0274[] = { 1547 WRITE_COEF(0x45, 0x4289), 1548 UPDATE_COEF(0x4a, 0x0010, 0x0010), 1549 UPDATE_COEF(0x6b, 0x0f00, 0), 1550 UPDATE_COEF(0x49, 0x0300, 0x0300), 1551 {} 1552 }; 1553 1554 switch (codec->core.vendor_id) { 1555 case 0x10ec0215: 1556 case 0x10ec0225: 1557 case 0x10ec0285: 1558 case 0x10ec0295: 1559 case 0x10ec0289: 1560 case 0x10ec0299: 1561 alc_process_coef_fw(codec, alc225_pre_hsmode); 1562 alc_process_coef_fw(codec, coef0225); 1563 alc_hp_enable_unmute(codec, 75); 1564 break; 1565 case 0x10ec0255: 1566 alc_process_coef_fw(codec, coef0255); 1567 break; 1568 case 0x10ec0230: 1569 case 0x10ec0236: 1570 case 0x10ec0256: 1571 case 0x19e58326: 1572 alc_write_coef_idx(codec, 0x1b, 0x0e4b); 1573 alc_write_coef_idx(codec, 0x45, 0xc089); 1574 msleep(50); 1575 alc_process_coef_fw(codec, coef0256); 1576 alc_hp_enable_unmute(codec, 75); 1577 break; 1578 case 0x10ec0234: 1579 case 0x10ec0274: 1580 case 0x10ec0294: 1581 alc_process_coef_fw(codec, coef0274); 1582 break; 1583 case 0x10ec0233: 1584 case 0x10ec0283: 1585 alc_process_coef_fw(codec, coef0233); 1586 break; 1587 case 0x10ec0286: 1588 case 0x10ec0288: 1589 case 0x10ec0298: 1590 alc_process_coef_fw(codec, coef0288); 1591 break; 1592 case 0x10ec0292: 1593 alc_process_coef_fw(codec, coef0292); 1594 break; 1595 case 0x10ec0293: 1596 alc_process_coef_fw(codec, coef0293); 1597 break; 1598 case 0x10ec0668: 1599 alc_process_coef_fw(codec, coef0688); 1600 break; 1601 case 0x10ec0867: 1602 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0); 1603 break; 1604 } 1605 codec_dbg(codec, "Headset jack set to headphone (default) mode.\n"); 1606 } 1607 1608 /* Iphone type */ 1609 static void alc_headset_mode_ctia(struct hda_codec *codec) 1610 { 1611 int val; 1612 1613 static const struct coef_fw coef0255[] = { 1614 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */ 1615 WRITE_COEF(0x1b, 0x0c2b), 1616 WRITE_COEFEX(0x57, 0x03, 0x8ea6), 1617 {} 1618 }; 1619 static const struct coef_fw coef0256[] = { 1620 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */ 1621 WRITE_COEF(0x1b, 0x0e6b), 1622 {} 1623 }; 1624 static const struct coef_fw coef0233[] = { 1625 WRITE_COEF(0x45, 0xd429), 1626 WRITE_COEF(0x1b, 0x0c2b), 1627 WRITE_COEF(0x32, 0x4ea3), 1628 {} 1629 }; 1630 static const struct coef_fw coef0288[] = { 1631 UPDATE_COEF(0x50, 0x2000, 0x2000), 1632 UPDATE_COEF(0x56, 0x0006, 0x0006), 1633 UPDATE_COEF(0x66, 0x0008, 0), 1634 UPDATE_COEF(0x67, 0x2000, 0), 1635 {} 1636 }; 1637 static const struct coef_fw coef0292[] = { 1638 WRITE_COEF(0x6b, 0xd429), 1639 WRITE_COEF(0x76, 0x0008), 1640 WRITE_COEF(0x18, 0x7388), 1641 {} 1642 }; 1643 static const struct coef_fw coef0293[] = { 1644 WRITE_COEF(0x45, 0xd429), /* Set to ctia type */ 1645 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */ 1646 {} 1647 }; 1648 static const struct coef_fw coef0688[] = { 1649 WRITE_COEF(0x11, 0x0001), 1650 WRITE_COEF(0x15, 0x0d60), 1651 WRITE_COEF(0xc3, 0x0000), 1652 {} 1653 }; 1654 static const struct coef_fw coef0225_1[] = { 1655 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10), 1656 UPDATE_COEF(0x63, 3<<14, 2<<14), 1657 {} 1658 }; 1659 static const struct coef_fw coef0225_2[] = { 1660 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10), 1661 UPDATE_COEF(0x63, 3<<14, 1<<14), 1662 {} 1663 }; 1664 1665 switch (codec->core.vendor_id) { 1666 case 0x10ec0255: 1667 alc_process_coef_fw(codec, coef0255); 1668 break; 1669 case 0x10ec0230: 1670 case 0x10ec0236: 1671 case 0x10ec0256: 1672 case 0x19e58326: 1673 alc_process_coef_fw(codec, coef0256); 1674 alc_hp_enable_unmute(codec, 75); 1675 break; 1676 case 0x10ec0234: 1677 case 0x10ec0274: 1678 case 0x10ec0294: 1679 alc_write_coef_idx(codec, 0x45, 0xd689); 1680 break; 1681 case 0x10ec0233: 1682 case 0x10ec0283: 1683 alc_process_coef_fw(codec, coef0233); 1684 break; 1685 case 0x10ec0298: 1686 val = alc_read_coef_idx(codec, 0x50); 1687 if (val & (1 << 12)) { 1688 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020); 1689 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400); 1690 msleep(300); 1691 } else { 1692 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010); 1693 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400); 1694 msleep(300); 1695 } 1696 break; 1697 case 0x10ec0286: 1698 case 0x10ec0288: 1699 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400); 1700 msleep(300); 1701 alc_process_coef_fw(codec, coef0288); 1702 break; 1703 case 0x10ec0292: 1704 alc_process_coef_fw(codec, coef0292); 1705 break; 1706 case 0x10ec0293: 1707 alc_process_coef_fw(codec, coef0293); 1708 break; 1709 case 0x10ec0668: 1710 alc_process_coef_fw(codec, coef0688); 1711 break; 1712 case 0x10ec0215: 1713 case 0x10ec0225: 1714 case 0x10ec0285: 1715 case 0x10ec0295: 1716 case 0x10ec0289: 1717 case 0x10ec0299: 1718 val = alc_read_coef_idx(codec, 0x45); 1719 if (val & (1 << 9)) 1720 alc_process_coef_fw(codec, coef0225_2); 1721 else 1722 alc_process_coef_fw(codec, coef0225_1); 1723 alc_hp_enable_unmute(codec, 75); 1724 break; 1725 case 0x10ec0867: 1726 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0); 1727 break; 1728 } 1729 codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n"); 1730 } 1731 1732 /* Nokia type */ 1733 static void alc_headset_mode_omtp(struct hda_codec *codec) 1734 { 1735 static const struct coef_fw coef0255[] = { 1736 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */ 1737 WRITE_COEF(0x1b, 0x0c2b), 1738 WRITE_COEFEX(0x57, 0x03, 0x8ea6), 1739 {} 1740 }; 1741 static const struct coef_fw coef0256[] = { 1742 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */ 1743 WRITE_COEF(0x1b, 0x0e6b), 1744 {} 1745 }; 1746 static const struct coef_fw coef0233[] = { 1747 WRITE_COEF(0x45, 0xe429), 1748 WRITE_COEF(0x1b, 0x0c2b), 1749 WRITE_COEF(0x32, 0x4ea3), 1750 {} 1751 }; 1752 static const struct coef_fw coef0288[] = { 1753 UPDATE_COEF(0x50, 0x2000, 0x2000), 1754 UPDATE_COEF(0x56, 0x0006, 0x0006), 1755 UPDATE_COEF(0x66, 0x0008, 0), 1756 UPDATE_COEF(0x67, 0x2000, 0), 1757 {} 1758 }; 1759 static const struct coef_fw coef0292[] = { 1760 WRITE_COEF(0x6b, 0xe429), 1761 WRITE_COEF(0x76, 0x0008), 1762 WRITE_COEF(0x18, 0x7388), 1763 {} 1764 }; 1765 static const struct coef_fw coef0293[] = { 1766 WRITE_COEF(0x45, 0xe429), /* Set to omtp type */ 1767 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */ 1768 {} 1769 }; 1770 static const struct coef_fw coef0688[] = { 1771 WRITE_COEF(0x11, 0x0001), 1772 WRITE_COEF(0x15, 0x0d50), 1773 WRITE_COEF(0xc3, 0x0000), 1774 {} 1775 }; 1776 static const struct coef_fw coef0225[] = { 1777 UPDATE_COEF(0x45, 0x3f<<10, 0x39<<10), 1778 UPDATE_COEF(0x63, 3<<14, 2<<14), 1779 {} 1780 }; 1781 1782 switch (codec->core.vendor_id) { 1783 case 0x10ec0255: 1784 alc_process_coef_fw(codec, coef0255); 1785 break; 1786 case 0x10ec0230: 1787 case 0x10ec0236: 1788 case 0x10ec0256: 1789 case 0x19e58326: 1790 alc_process_coef_fw(codec, coef0256); 1791 alc_hp_enable_unmute(codec, 75); 1792 break; 1793 case 0x10ec0234: 1794 case 0x10ec0274: 1795 case 0x10ec0294: 1796 alc_write_coef_idx(codec, 0x45, 0xe689); 1797 break; 1798 case 0x10ec0233: 1799 case 0x10ec0283: 1800 alc_process_coef_fw(codec, coef0233); 1801 break; 1802 case 0x10ec0298: 1803 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);/* Headset output enable */ 1804 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400); 1805 msleep(300); 1806 break; 1807 case 0x10ec0286: 1808 case 0x10ec0288: 1809 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400); 1810 msleep(300); 1811 alc_process_coef_fw(codec, coef0288); 1812 break; 1813 case 0x10ec0292: 1814 alc_process_coef_fw(codec, coef0292); 1815 break; 1816 case 0x10ec0293: 1817 alc_process_coef_fw(codec, coef0293); 1818 break; 1819 case 0x10ec0668: 1820 alc_process_coef_fw(codec, coef0688); 1821 break; 1822 case 0x10ec0215: 1823 case 0x10ec0225: 1824 case 0x10ec0285: 1825 case 0x10ec0295: 1826 case 0x10ec0289: 1827 case 0x10ec0299: 1828 alc_process_coef_fw(codec, coef0225); 1829 alc_hp_enable_unmute(codec, 75); 1830 break; 1831 } 1832 codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n"); 1833 } 1834 1835 static void alc_determine_headset_type(struct hda_codec *codec) 1836 { 1837 int val; 1838 bool is_ctia = false; 1839 struct alc_spec *spec = codec->spec; 1840 static const struct coef_fw coef0255[] = { 1841 WRITE_COEF(0x45, 0xd089), /* combo jack auto switch control(Check type)*/ 1842 WRITE_COEF(0x49, 0x0149), /* combo jack auto switch control(Vref 1843 conteol) */ 1844 {} 1845 }; 1846 static const struct coef_fw coef0288[] = { 1847 UPDATE_COEF(0x4f, 0xfcc0, 0xd400), /* Check Type */ 1848 {} 1849 }; 1850 static const struct coef_fw coef0298[] = { 1851 UPDATE_COEF(0x50, 0x2000, 0x2000), 1852 UPDATE_COEF(0x56, 0x0006, 0x0006), 1853 UPDATE_COEF(0x66, 0x0008, 0), 1854 UPDATE_COEF(0x67, 0x2000, 0), 1855 UPDATE_COEF(0x19, 0x1300, 0x1300), 1856 {} 1857 }; 1858 static const struct coef_fw coef0293[] = { 1859 UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */ 1860 WRITE_COEF(0x45, 0xD429), /* Set to ctia type */ 1861 {} 1862 }; 1863 static const struct coef_fw coef0688[] = { 1864 WRITE_COEF(0x11, 0x0001), 1865 WRITE_COEF(0xb7, 0x802b), 1866 WRITE_COEF(0x15, 0x0d60), 1867 WRITE_COEF(0xc3, 0x0c00), 1868 {} 1869 }; 1870 static const struct coef_fw coef0274[] = { 1871 UPDATE_COEF(0x4a, 0x0010, 0), 1872 UPDATE_COEF(0x4a, 0x8000, 0), 1873 WRITE_COEF(0x45, 0xd289), 1874 UPDATE_COEF(0x49, 0x0300, 0x0300), 1875 {} 1876 }; 1877 1878 if (spec->no_internal_mic_pin) { 1879 alc_update_coef_idx(codec, 0x45, 0xf<<12 | 1<<10, 5<<12); 1880 return; 1881 } 1882 1883 switch (codec->core.vendor_id) { 1884 case 0x10ec0255: 1885 alc_process_coef_fw(codec, coef0255); 1886 msleep(300); 1887 val = alc_read_coef_idx(codec, 0x46); 1888 is_ctia = (val & 0x0070) == 0x0070; 1889 break; 1890 case 0x10ec0230: 1891 case 0x10ec0236: 1892 case 0x10ec0256: 1893 case 0x19e58326: 1894 alc_write_coef_idx(codec, 0x1b, 0x0e4b); 1895 alc_write_coef_idx(codec, 0x06, 0x6104); 1896 alc_write_coefex_idx(codec, 0x57, 0x3, 0x09a3); 1897 1898 alc_process_coef_fw(codec, coef0255); 1899 msleep(300); 1900 val = alc_read_coef_idx(codec, 0x46); 1901 is_ctia = (val & 0x0070) == 0x0070; 1902 if (!is_ctia) { 1903 alc_write_coef_idx(codec, 0x45, 0xe089); 1904 msleep(100); 1905 val = alc_read_coef_idx(codec, 0x46); 1906 if ((val & 0x0070) == 0x0070) 1907 is_ctia = false; 1908 else 1909 is_ctia = true; 1910 } 1911 alc_write_coefex_idx(codec, 0x57, 0x3, 0x0da3); 1912 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0); 1913 break; 1914 case 0x10ec0234: 1915 case 0x10ec0274: 1916 case 0x10ec0294: 1917 alc_process_coef_fw(codec, coef0274); 1918 msleep(850); 1919 val = alc_read_coef_idx(codec, 0x46); 1920 is_ctia = (val & 0x00f0) == 0x00f0; 1921 break; 1922 case 0x10ec0233: 1923 case 0x10ec0283: 1924 alc_write_coef_idx(codec, 0x45, 0xd029); 1925 msleep(300); 1926 val = alc_read_coef_idx(codec, 0x46); 1927 is_ctia = (val & 0x0070) == 0x0070; 1928 break; 1929 case 0x10ec0298: 1930 snd_hda_codec_write(codec, 0x21, 0, 1931 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); 1932 msleep(100); 1933 snd_hda_codec_write(codec, 0x21, 0, 1934 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); 1935 msleep(200); 1936 1937 val = alc_read_coef_idx(codec, 0x50); 1938 if (val & (1 << 12)) { 1939 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020); 1940 alc_process_coef_fw(codec, coef0288); 1941 msleep(350); 1942 val = alc_read_coef_idx(codec, 0x50); 1943 is_ctia = (val & 0x0070) == 0x0070; 1944 } else { 1945 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010); 1946 alc_process_coef_fw(codec, coef0288); 1947 msleep(350); 1948 val = alc_read_coef_idx(codec, 0x50); 1949 is_ctia = (val & 0x0070) == 0x0070; 1950 } 1951 alc_process_coef_fw(codec, coef0298); 1952 snd_hda_codec_write(codec, 0x21, 0, 1953 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); 1954 msleep(75); 1955 snd_hda_codec_write(codec, 0x21, 0, 1956 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); 1957 break; 1958 case 0x10ec0286: 1959 case 0x10ec0288: 1960 alc_process_coef_fw(codec, coef0288); 1961 msleep(350); 1962 val = alc_read_coef_idx(codec, 0x50); 1963 is_ctia = (val & 0x0070) == 0x0070; 1964 break; 1965 case 0x10ec0292: 1966 alc_write_coef_idx(codec, 0x6b, 0xd429); 1967 msleep(300); 1968 val = alc_read_coef_idx(codec, 0x6c); 1969 is_ctia = (val & 0x001c) == 0x001c; 1970 break; 1971 case 0x10ec0293: 1972 alc_process_coef_fw(codec, coef0293); 1973 msleep(300); 1974 val = alc_read_coef_idx(codec, 0x46); 1975 is_ctia = (val & 0x0070) == 0x0070; 1976 break; 1977 case 0x10ec0668: 1978 alc_process_coef_fw(codec, coef0688); 1979 msleep(300); 1980 val = alc_read_coef_idx(codec, 0xbe); 1981 is_ctia = (val & 0x1c02) == 0x1c02; 1982 break; 1983 case 0x10ec0215: 1984 case 0x10ec0225: 1985 case 0x10ec0285: 1986 case 0x10ec0295: 1987 case 0x10ec0289: 1988 case 0x10ec0299: 1989 alc_process_coef_fw(codec, alc225_pre_hsmode); 1990 alc_update_coef_idx(codec, 0x67, 0xf000, 0x1000); 1991 val = alc_read_coef_idx(codec, 0x45); 1992 if (val & (1 << 9)) { 1993 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10); 1994 alc_update_coef_idx(codec, 0x49, 3<<8, 2<<8); 1995 msleep(800); 1996 val = alc_read_coef_idx(codec, 0x46); 1997 is_ctia = (val & 0x00f0) == 0x00f0; 1998 } else { 1999 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10); 2000 alc_update_coef_idx(codec, 0x49, 3<<8, 1<<8); 2001 msleep(800); 2002 val = alc_read_coef_idx(codec, 0x46); 2003 is_ctia = (val & 0x00f0) == 0x00f0; 2004 } 2005 if (!is_ctia) { 2006 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x38<<10); 2007 alc_update_coef_idx(codec, 0x49, 3<<8, 1<<8); 2008 msleep(100); 2009 val = alc_read_coef_idx(codec, 0x46); 2010 if ((val & 0x00f0) == 0x00f0) 2011 is_ctia = false; 2012 else 2013 is_ctia = true; 2014 } 2015 alc_update_coef_idx(codec, 0x4a, 7<<6, 7<<6); 2016 alc_update_coef_idx(codec, 0x4a, 3<<4, 3<<4); 2017 alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000); 2018 break; 2019 case 0x10ec0867: 2020 is_ctia = true; 2021 break; 2022 } 2023 2024 codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n", 2025 str_yes_no(is_ctia)); 2026 spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP; 2027 } 2028 2029 static void alc_update_headset_mode(struct hda_codec *codec) 2030 { 2031 struct alc_spec *spec = codec->spec; 2032 2033 hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]]; 2034 hda_nid_t hp_pin = alc_get_hp_pin(spec); 2035 2036 int new_headset_mode; 2037 2038 if (!snd_hda_jack_detect(codec, hp_pin)) 2039 new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED; 2040 else if (mux_pin == spec->headset_mic_pin) 2041 new_headset_mode = ALC_HEADSET_MODE_HEADSET; 2042 else if (mux_pin == spec->headphone_mic_pin) 2043 new_headset_mode = ALC_HEADSET_MODE_MIC; 2044 else 2045 new_headset_mode = ALC_HEADSET_MODE_HEADPHONE; 2046 2047 if (new_headset_mode == spec->current_headset_mode) { 2048 snd_hda_gen_update_outputs(codec); 2049 return; 2050 } 2051 2052 switch (new_headset_mode) { 2053 case ALC_HEADSET_MODE_UNPLUGGED: 2054 alc_headset_mode_unplugged(codec); 2055 spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN; 2056 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN; 2057 spec->gen.hp_jack_present = false; 2058 break; 2059 case ALC_HEADSET_MODE_HEADSET: 2060 if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN) 2061 alc_determine_headset_type(codec); 2062 if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA) 2063 alc_headset_mode_ctia(codec); 2064 else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP) 2065 alc_headset_mode_omtp(codec); 2066 spec->gen.hp_jack_present = true; 2067 break; 2068 case ALC_HEADSET_MODE_MIC: 2069 alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin); 2070 spec->gen.hp_jack_present = false; 2071 break; 2072 case ALC_HEADSET_MODE_HEADPHONE: 2073 alc_headset_mode_default(codec); 2074 spec->gen.hp_jack_present = true; 2075 break; 2076 } 2077 if (new_headset_mode != ALC_HEADSET_MODE_MIC) { 2078 snd_hda_set_pin_ctl_cache(codec, hp_pin, 2079 AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN); 2080 if (spec->headphone_mic_pin && spec->headphone_mic_pin != hp_pin) 2081 snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin, 2082 PIN_VREFHIZ); 2083 } 2084 spec->current_headset_mode = new_headset_mode; 2085 2086 snd_hda_gen_update_outputs(codec); 2087 } 2088 2089 static void alc_update_headset_mode_hook(struct hda_codec *codec, 2090 struct snd_kcontrol *kcontrol, 2091 struct snd_ctl_elem_value *ucontrol) 2092 { 2093 alc_update_headset_mode(codec); 2094 } 2095 2096 void alc_update_headset_jack_cb(struct hda_codec *codec, 2097 struct hda_jack_callback *jack) 2098 { 2099 snd_hda_gen_hp_automute(codec, jack); 2100 alc_update_headset_mode(codec); 2101 } 2102 EXPORT_SYMBOL_NS_GPL(alc_update_headset_jack_cb, "SND_HDA_CODEC_REALTEK"); 2103 2104 static void alc_probe_headset_mode(struct hda_codec *codec) 2105 { 2106 int i; 2107 struct alc_spec *spec = codec->spec; 2108 struct auto_pin_cfg *cfg = &spec->gen.autocfg; 2109 2110 /* Find mic pins */ 2111 for (i = 0; i < cfg->num_inputs; i++) { 2112 if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin) 2113 spec->headset_mic_pin = cfg->inputs[i].pin; 2114 if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin) 2115 spec->headphone_mic_pin = cfg->inputs[i].pin; 2116 } 2117 2118 WARN_ON(spec->gen.cap_sync_hook); 2119 spec->gen.cap_sync_hook = alc_update_headset_mode_hook; 2120 spec->gen.automute_hook = alc_update_headset_mode; 2121 spec->gen.hp_automute_hook = alc_update_headset_jack_cb; 2122 } 2123 2124 void alc_fixup_headset_mode(struct hda_codec *codec, 2125 const struct hda_fixup *fix, int action) 2126 { 2127 struct alc_spec *spec = codec->spec; 2128 2129 switch (action) { 2130 case HDA_FIXUP_ACT_PRE_PROBE: 2131 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC; 2132 break; 2133 case HDA_FIXUP_ACT_PROBE: 2134 alc_probe_headset_mode(codec); 2135 break; 2136 case HDA_FIXUP_ACT_INIT: 2137 if (is_s3_resume(codec) || is_s4_resume(codec)) { 2138 spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN; 2139 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN; 2140 } 2141 alc_update_headset_mode(codec); 2142 break; 2143 } 2144 } 2145 EXPORT_SYMBOL_NS_GPL(alc_fixup_headset_mode, "SND_HDA_CODEC_REALTEK"); 2146 2147 void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec, 2148 const struct hda_fixup *fix, int action) 2149 { 2150 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 2151 struct alc_spec *spec = codec->spec; 2152 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; 2153 } else 2154 alc_fixup_headset_mode(codec, fix, action); 2155 } 2156 EXPORT_SYMBOL_NS_GPL(alc_fixup_headset_mode_no_hp_mic, "SND_HDA_CODEC_REALTEK"); 2157 2158 void alc_fixup_headset_mic(struct hda_codec *codec, 2159 const struct hda_fixup *fix, int action) 2160 { 2161 struct alc_spec *spec = codec->spec; 2162 2163 if (action == HDA_FIXUP_ACT_PRE_PROBE) 2164 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; 2165 } 2166 EXPORT_SYMBOL_NS_GPL(alc_fixup_headset_mic, "SND_HDA_CODEC_REALTEK"); 2167 2168 /* update LED status via GPIO */ 2169 void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask, 2170 int polarity, bool enabled) 2171 { 2172 if (polarity) 2173 enabled = !enabled; 2174 alc_update_gpio_data(codec, mask, !enabled); /* muted -> LED on */ 2175 } 2176 EXPORT_SYMBOL_NS_GPL(alc_update_gpio_led, "SND_HDA_CODEC_REALTEK"); 2177 2178 /* turn on/off mic-mute LED via GPIO per capture hook */ 2179 static int micmute_led_set(struct led_classdev *led_cdev, 2180 enum led_brightness brightness) 2181 { 2182 struct hda_codec *codec = dev_to_hda_codec(led_cdev->dev->parent); 2183 struct alc_spec *spec = codec->spec; 2184 2185 alc_update_gpio_led(codec, spec->gpio_mic_led_mask, 2186 spec->micmute_led_polarity, !brightness); 2187 return 0; 2188 } 2189 2190 /* turn on/off mute LED via GPIO per vmaster hook */ 2191 static int gpio_mute_led_set(struct led_classdev *led_cdev, 2192 enum led_brightness brightness) 2193 { 2194 struct hda_codec *codec = dev_to_hda_codec(led_cdev->dev->parent); 2195 struct alc_spec *spec = codec->spec; 2196 2197 alc_update_gpio_led(codec, spec->gpio_mute_led_mask, 2198 spec->mute_led_polarity, !brightness); 2199 return 0; 2200 } 2201 2202 /* setup mute and mic-mute GPIO bits, add hooks appropriately */ 2203 void alc_fixup_hp_gpio_led(struct hda_codec *codec, 2204 int action, 2205 unsigned int mute_mask, 2206 unsigned int micmute_mask) 2207 { 2208 struct alc_spec *spec = codec->spec; 2209 2210 alc_fixup_gpio(codec, action, mute_mask | micmute_mask); 2211 2212 if (action != HDA_FIXUP_ACT_PRE_PROBE) 2213 return; 2214 if (mute_mask) { 2215 spec->gpio_mute_led_mask = mute_mask; 2216 snd_hda_gen_add_mute_led_cdev(codec, gpio_mute_led_set); 2217 } 2218 if (micmute_mask) { 2219 spec->gpio_mic_led_mask = micmute_mask; 2220 snd_hda_gen_add_micmute_led_cdev(codec, micmute_led_set); 2221 } 2222 } 2223 EXPORT_SYMBOL_NS_GPL(alc_fixup_hp_gpio_led, "SND_HDA_CODEC_REALTEK"); 2224 2225 /* suppress the jack-detection */ 2226 void alc_fixup_no_jack_detect(struct hda_codec *codec, 2227 const struct hda_fixup *fix, int action) 2228 { 2229 if (action == HDA_FIXUP_ACT_PRE_PROBE) 2230 codec->no_jack_detect = 1; 2231 } 2232 EXPORT_SYMBOL_NS_GPL(alc_fixup_no_jack_detect, "SND_HDA_CODEC_REALTEK"); 2233 2234 void alc_fixup_disable_aamix(struct hda_codec *codec, 2235 const struct hda_fixup *fix, int action) 2236 { 2237 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 2238 struct alc_spec *spec = codec->spec; 2239 /* Disable AA-loopback as it causes white noise */ 2240 spec->gen.mixer_nid = 0; 2241 } 2242 } 2243 EXPORT_SYMBOL_NS_GPL(alc_fixup_disable_aamix, "SND_HDA_CODEC_REALTEK"); 2244 2245 void alc_fixup_auto_mute_via_amp(struct hda_codec *codec, 2246 const struct hda_fixup *fix, int action) 2247 { 2248 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 2249 struct alc_spec *spec = codec->spec; 2250 spec->gen.auto_mute_via_amp = 1; 2251 } 2252 } 2253 EXPORT_SYMBOL_NS_GPL(alc_fixup_auto_mute_via_amp, "SND_HDA_CODEC_REALTEK"); 2254 2255 MODULE_IMPORT_NS("SND_HDA_SCODEC_COMPONENT"); 2256 MODULE_LICENSE("GPL"); 2257 MODULE_DESCRIPTION("Realtek HD-audio codec helper"); 2258