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