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