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