1/* 2 * Universal Interface for Intel High Definition Audio Codec 3 * 4 * HD audio interface patch for Realtek ALC codecs 5 * 6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw> 7 * PeiSen Hou <pshou@realtek.com.tw> 8 * Takashi Iwai <tiwai@suse.de> 9 * Jonathan Woithe <jwoithe@just42.net> 10 * 11 * This driver is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 of the License, or 14 * (at your option) any later version. 15 * 16 * This driver is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 */ 25 26#include <linux/init.h> 27#include <linux/delay.h> 28#include <linux/slab.h> 29#include <linux/pci.h> 30#include <linux/dmi.h> 31#include <linux/module.h> 32#include <linux/input.h> 33#include <sound/core.h> 34#include <sound/jack.h> 35#include "hda_codec.h" 36#include "hda_local.h" 37#include "hda_auto_parser.h" 38#include "hda_jack.h" 39#include "hda_generic.h" 40 41/* keep halting ALC5505 DSP, for power saving */ 42#define HALT_REALTEK_ALC5505 43 44/* for GPIO Poll */ 45#define GPIO_MASK 0x03 46 47/* extra amp-initialization sequence types */ 48enum { 49 ALC_INIT_NONE, 50 ALC_INIT_DEFAULT, 51 ALC_INIT_GPIO1, 52 ALC_INIT_GPIO2, 53 ALC_INIT_GPIO3, 54}; 55 56enum { 57 ALC_HEADSET_MODE_UNKNOWN, 58 ALC_HEADSET_MODE_UNPLUGGED, 59 ALC_HEADSET_MODE_HEADSET, 60 ALC_HEADSET_MODE_MIC, 61 ALC_HEADSET_MODE_HEADPHONE, 62}; 63 64enum { 65 ALC_HEADSET_TYPE_UNKNOWN, 66 ALC_HEADSET_TYPE_CTIA, 67 ALC_HEADSET_TYPE_OMTP, 68}; 69 70struct alc_customize_define { 71 unsigned int sku_cfg; 72 unsigned char port_connectivity; 73 unsigned char check_sum; 74 unsigned char customization; 75 unsigned char external_amp; 76 unsigned int enable_pcbeep:1; 77 unsigned int platform_type:1; 78 unsigned int swap:1; 79 unsigned int override:1; 80 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */ 81}; 82 83struct alc_spec { 84 struct hda_gen_spec gen; /* must be at head */ 85 86 /* codec parameterization */ 87 const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 88 unsigned int num_mixers; 89 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ 90 91 struct alc_customize_define cdefine; 92 unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */ 93 94 /* mute LED for HP laptops, see alc269_fixup_mic_mute_hook() */ 95 int mute_led_polarity; 96 hda_nid_t mute_led_nid; 97 hda_nid_t cap_mute_led_nid; 98 99 unsigned int gpio_led; /* used for alc269_fixup_hp_gpio_led() */ 100 unsigned int gpio_mute_led_mask; 101 unsigned int gpio_mic_led_mask; 102 103 hda_nid_t headset_mic_pin; 104 hda_nid_t headphone_mic_pin; 105 int current_headset_mode; 106 int current_headset_type; 107 108 /* hooks */ 109 void (*init_hook)(struct hda_codec *codec); 110#ifdef CONFIG_PM 111 void (*power_hook)(struct hda_codec *codec); 112#endif 113 void (*shutup)(struct hda_codec *codec); 114 void (*reboot_notify)(struct hda_codec *codec); 115 116 int init_amp; 117 int codec_variant; /* flag for other variants */ 118 unsigned int has_alc5505_dsp:1; 119 unsigned int no_depop_delay:1; 120 121 /* for PLL fix */ 122 hda_nid_t pll_nid; 123 unsigned int pll_coef_idx, pll_coef_bit; 124 unsigned int coef0; 125 struct input_dev *kb_dev; 126}; 127 128/* 129 * COEF access helper functions 130 */ 131 132static int alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid, 133 unsigned int coef_idx) 134{ 135 unsigned int val; 136 137 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx); 138 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0); 139 return val; 140} 141 142#define alc_read_coef_idx(codec, coef_idx) \ 143 alc_read_coefex_idx(codec, 0x20, coef_idx) 144 145static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid, 146 unsigned int coef_idx, unsigned int coef_val) 147{ 148 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx); 149 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF, coef_val); 150} 151 152#define alc_write_coef_idx(codec, coef_idx, coef_val) \ 153 alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val) 154 155static void alc_update_coefex_idx(struct hda_codec *codec, hda_nid_t nid, 156 unsigned int coef_idx, unsigned int mask, 157 unsigned int bits_set) 158{ 159 unsigned int val = alc_read_coefex_idx(codec, nid, coef_idx); 160 161 if (val != -1) 162 alc_write_coefex_idx(codec, nid, coef_idx, 163 (val & ~mask) | bits_set); 164} 165 166#define alc_update_coef_idx(codec, coef_idx, mask, bits_set) \ 167 alc_update_coefex_idx(codec, 0x20, coef_idx, mask, bits_set) 168 169/* a special bypass for COEF 0; read the cached value at the second time */ 170static unsigned int alc_get_coef0(struct hda_codec *codec) 171{ 172 struct alc_spec *spec = codec->spec; 173 174 if (!spec->coef0) 175 spec->coef0 = alc_read_coef_idx(codec, 0); 176 return spec->coef0; 177} 178 179/* coef writes/updates batch */ 180struct coef_fw { 181 unsigned char nid; 182 unsigned char idx; 183 unsigned short mask; 184 unsigned short val; 185}; 186 187#define UPDATE_COEFEX(_nid, _idx, _mask, _val) \ 188 { .nid = (_nid), .idx = (_idx), .mask = (_mask), .val = (_val) } 189#define WRITE_COEFEX(_nid, _idx, _val) UPDATE_COEFEX(_nid, _idx, -1, _val) 190#define WRITE_COEF(_idx, _val) WRITE_COEFEX(0x20, _idx, _val) 191#define UPDATE_COEF(_idx, _mask, _val) UPDATE_COEFEX(0x20, _idx, _mask, _val) 192 193static void alc_process_coef_fw(struct hda_codec *codec, 194 const struct coef_fw *fw) 195{ 196 for (; fw->nid; fw++) { 197 if (fw->mask == (unsigned short)-1) 198 alc_write_coefex_idx(codec, fw->nid, fw->idx, fw->val); 199 else 200 alc_update_coefex_idx(codec, fw->nid, fw->idx, 201 fw->mask, fw->val); 202 } 203} 204 205/* 206 * Append the given mixer and verb elements for the later use 207 * The mixer array is referred in build_controls(), and init_verbs are 208 * called in init(). 209 */ 210static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix) 211{ 212 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers))) 213 return; 214 spec->mixers[spec->num_mixers++] = mix; 215} 216 217/* 218 * GPIO setup tables, used in initialization 219 */ 220/* Enable GPIO mask and set output */ 221static const struct hda_verb alc_gpio1_init_verbs[] = { 222 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 223 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 224 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 225 { } 226}; 227 228static const struct hda_verb alc_gpio2_init_verbs[] = { 229 {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, 230 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, 231 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, 232 { } 233}; 234 235static const struct hda_verb alc_gpio3_init_verbs[] = { 236 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 237 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 238 {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 239 { } 240}; 241 242/* 243 * Fix hardware PLL issue 244 * On some codecs, the analog PLL gating control must be off while 245 * the default value is 1. 246 */ 247static void alc_fix_pll(struct hda_codec *codec) 248{ 249 struct alc_spec *spec = codec->spec; 250 251 if (spec->pll_nid) 252 alc_update_coefex_idx(codec, spec->pll_nid, spec->pll_coef_idx, 253 1 << spec->pll_coef_bit, 0); 254} 255 256static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, 257 unsigned int coef_idx, unsigned int coef_bit) 258{ 259 struct alc_spec *spec = codec->spec; 260 spec->pll_nid = nid; 261 spec->pll_coef_idx = coef_idx; 262 spec->pll_coef_bit = coef_bit; 263 alc_fix_pll(codec); 264} 265 266/* update the master volume per volume-knob's unsol event */ 267static void alc_update_knob_master(struct hda_codec *codec, 268 struct hda_jack_callback *jack) 269{ 270 unsigned int val; 271 struct snd_kcontrol *kctl; 272 struct snd_ctl_elem_value *uctl; 273 274 kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume"); 275 if (!kctl) 276 return; 277 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); 278 if (!uctl) 279 return; 280 val = snd_hda_codec_read(codec, jack->nid, 0, 281 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0); 282 val &= HDA_AMP_VOLMASK; 283 uctl->value.integer.value[0] = val; 284 uctl->value.integer.value[1] = val; 285 kctl->put(kctl, uctl); 286 kfree(uctl); 287} 288 289static void alc880_unsol_event(struct hda_codec *codec, unsigned int res) 290{ 291 /* For some reason, the res given from ALC880 is broken. 292 Here we adjust it properly. */ 293 snd_hda_jack_unsol_event(codec, res >> 2); 294} 295 296/* Change EAPD to verb control */ 297static void alc_fill_eapd_coef(struct hda_codec *codec) 298{ 299 int coef; 300 301 coef = alc_get_coef0(codec); 302 303 switch (codec->core.vendor_id) { 304 case 0x10ec0262: 305 alc_update_coef_idx(codec, 0x7, 0, 1<<5); 306 break; 307 case 0x10ec0267: 308 case 0x10ec0268: 309 alc_update_coef_idx(codec, 0x7, 0, 1<<13); 310 break; 311 case 0x10ec0269: 312 if ((coef & 0x00f0) == 0x0010) 313 alc_update_coef_idx(codec, 0xd, 0, 1<<14); 314 if ((coef & 0x00f0) == 0x0020) 315 alc_update_coef_idx(codec, 0x4, 1<<15, 0); 316 if ((coef & 0x00f0) == 0x0030) 317 alc_update_coef_idx(codec, 0x10, 1<<9, 0); 318 break; 319 case 0x10ec0280: 320 case 0x10ec0284: 321 case 0x10ec0290: 322 case 0x10ec0292: 323 alc_update_coef_idx(codec, 0x4, 1<<15, 0); 324 break; 325 case 0x10ec0233: 326 case 0x10ec0255: 327 case 0x10ec0256: 328 case 0x10ec0282: 329 case 0x10ec0283: 330 case 0x10ec0286: 331 case 0x10ec0288: 332 case 0x10ec0298: 333 alc_update_coef_idx(codec, 0x10, 1<<9, 0); 334 break; 335 case 0x10ec0285: 336 case 0x10ec0293: 337 alc_update_coef_idx(codec, 0xa, 1<<13, 0); 338 break; 339 case 0x10ec0662: 340 if ((coef & 0x00f0) == 0x0030) 341 alc_update_coef_idx(codec, 0x4, 1<<10, 0); /* EAPD Ctrl */ 342 break; 343 case 0x10ec0272: 344 case 0x10ec0273: 345 case 0x10ec0663: 346 case 0x10ec0665: 347 case 0x10ec0670: 348 case 0x10ec0671: 349 case 0x10ec0672: 350 alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */ 351 break; 352 case 0x10ec0668: 353 alc_update_coef_idx(codec, 0x7, 3<<13, 0); 354 break; 355 case 0x10ec0867: 356 alc_update_coef_idx(codec, 0x4, 1<<10, 0); 357 break; 358 case 0x10ec0888: 359 if ((coef & 0x00f0) == 0x0020 || (coef & 0x00f0) == 0x0030) 360 alc_update_coef_idx(codec, 0x7, 1<<5, 0); 361 break; 362 case 0x10ec0892: 363 alc_update_coef_idx(codec, 0x7, 1<<5, 0); 364 break; 365 case 0x10ec0899: 366 case 0x10ec0900: 367 alc_update_coef_idx(codec, 0x7, 1<<1, 0); 368 break; 369 } 370} 371 372/* additional initialization for ALC888 variants */ 373static void alc888_coef_init(struct hda_codec *codec) 374{ 375 switch (alc_get_coef0(codec) & 0x00f0) { 376 /* alc888-VA */ 377 case 0x00: 378 /* alc888-VB */ 379 case 0x10: 380 alc_update_coef_idx(codec, 7, 0, 0x2030); /* Turn EAPD to High */ 381 break; 382 } 383} 384 385/* turn on/off EAPD control (only if available) */ 386static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on) 387{ 388 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) 389 return; 390 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD) 391 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, 392 on ? 2 : 0); 393} 394 395/* turn on/off EAPD controls of the codec */ 396static void alc_auto_setup_eapd(struct hda_codec *codec, bool on) 397{ 398 /* We currently only handle front, HP */ 399 static hda_nid_t pins[] = { 400 0x0f, 0x10, 0x14, 0x15, 0x17, 0 401 }; 402 hda_nid_t *p; 403 for (p = pins; *p; p++) 404 set_eapd(codec, *p, on); 405} 406 407/* generic shutup callback; 408 * just turning off EPAD and a little pause for avoiding pop-noise 409 */ 410static void alc_eapd_shutup(struct hda_codec *codec) 411{ 412 struct alc_spec *spec = codec->spec; 413 414 alc_auto_setup_eapd(codec, false); 415 if (!spec->no_depop_delay) 416 msleep(200); 417 snd_hda_shutup_pins(codec); 418} 419 420/* generic EAPD initialization */ 421static void alc_auto_init_amp(struct hda_codec *codec, int type) 422{ 423 alc_fill_eapd_coef(codec); 424 alc_auto_setup_eapd(codec, true); 425 switch (type) { 426 case ALC_INIT_GPIO1: 427 snd_hda_sequence_write(codec, alc_gpio1_init_verbs); 428 break; 429 case ALC_INIT_GPIO2: 430 snd_hda_sequence_write(codec, alc_gpio2_init_verbs); 431 break; 432 case ALC_INIT_GPIO3: 433 snd_hda_sequence_write(codec, alc_gpio3_init_verbs); 434 break; 435 case ALC_INIT_DEFAULT: 436 switch (codec->core.vendor_id) { 437 case 0x10ec0260: 438 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x2010); 439 break; 440 case 0x10ec0880: 441 case 0x10ec0882: 442 case 0x10ec0883: 443 case 0x10ec0885: 444 alc_update_coef_idx(codec, 7, 0, 0x2030); 445 break; 446 case 0x10ec0888: 447 alc888_coef_init(codec); 448 break; 449 } 450 break; 451 } 452} 453 454 455/* 456 * Realtek SSID verification 457 */ 458 459/* Could be any non-zero and even value. When used as fixup, tells 460 * the driver to ignore any present sku defines. 461 */ 462#define ALC_FIXUP_SKU_IGNORE (2) 463 464static void alc_fixup_sku_ignore(struct hda_codec *codec, 465 const struct hda_fixup *fix, int action) 466{ 467 struct alc_spec *spec = codec->spec; 468 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 469 spec->cdefine.fixup = 1; 470 spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE; 471 } 472} 473 474static void alc_fixup_no_depop_delay(struct hda_codec *codec, 475 const struct hda_fixup *fix, int action) 476{ 477 struct alc_spec *spec = codec->spec; 478 479 if (action == HDA_FIXUP_ACT_PROBE) { 480 spec->no_depop_delay = 1; 481 codec->depop_delay = 0; 482 } 483} 484 485static int alc_auto_parse_customize_define(struct hda_codec *codec) 486{ 487 unsigned int ass, tmp, i; 488 unsigned nid = 0; 489 struct alc_spec *spec = codec->spec; 490 491 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */ 492 493 if (spec->cdefine.fixup) { 494 ass = spec->cdefine.sku_cfg; 495 if (ass == ALC_FIXUP_SKU_IGNORE) 496 return -1; 497 goto do_sku; 498 } 499 500 if (!codec->bus->pci) 501 return -1; 502 ass = codec->core.subsystem_id & 0xffff; 503 if (ass != codec->bus->pci->subsystem_device && (ass & 1)) 504 goto do_sku; 505 506 nid = 0x1d; 507 if (codec->core.vendor_id == 0x10ec0260) 508 nid = 0x17; 509 ass = snd_hda_codec_get_pincfg(codec, nid); 510 511 if (!(ass & 1)) { 512 codec_info(codec, "%s: SKU not ready 0x%08x\n", 513 codec->core.chip_name, ass); 514 return -1; 515 } 516 517 /* check sum */ 518 tmp = 0; 519 for (i = 1; i < 16; i++) { 520 if ((ass >> i) & 1) 521 tmp++; 522 } 523 if (((ass >> 16) & 0xf) != tmp) 524 return -1; 525 526 spec->cdefine.port_connectivity = ass >> 30; 527 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20; 528 spec->cdefine.check_sum = (ass >> 16) & 0xf; 529 spec->cdefine.customization = ass >> 8; 530do_sku: 531 spec->cdefine.sku_cfg = ass; 532 spec->cdefine.external_amp = (ass & 0x38) >> 3; 533 spec->cdefine.platform_type = (ass & 0x4) >> 2; 534 spec->cdefine.swap = (ass & 0x2) >> 1; 535 spec->cdefine.override = ass & 0x1; 536 537 codec_dbg(codec, "SKU: Nid=0x%x sku_cfg=0x%08x\n", 538 nid, spec->cdefine.sku_cfg); 539 codec_dbg(codec, "SKU: port_connectivity=0x%x\n", 540 spec->cdefine.port_connectivity); 541 codec_dbg(codec, "SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep); 542 codec_dbg(codec, "SKU: check_sum=0x%08x\n", spec->cdefine.check_sum); 543 codec_dbg(codec, "SKU: customization=0x%08x\n", spec->cdefine.customization); 544 codec_dbg(codec, "SKU: external_amp=0x%x\n", spec->cdefine.external_amp); 545 codec_dbg(codec, "SKU: platform_type=0x%x\n", spec->cdefine.platform_type); 546 codec_dbg(codec, "SKU: swap=0x%x\n", spec->cdefine.swap); 547 codec_dbg(codec, "SKU: override=0x%x\n", spec->cdefine.override); 548 549 return 0; 550} 551 552/* return the position of NID in the list, or -1 if not found */ 553static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) 554{ 555 int i; 556 for (i = 0; i < nums; i++) 557 if (list[i] == nid) 558 return i; 559 return -1; 560} 561/* return true if the given NID is found in the list */ 562static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) 563{ 564 return find_idx_in_nid_list(nid, list, nums) >= 0; 565} 566 567/* check subsystem ID and set up device-specific initialization; 568 * return 1 if initialized, 0 if invalid SSID 569 */ 570/* 32-bit subsystem ID for BIOS loading in HD Audio codec. 571 * 31 ~ 16 : Manufacture ID 572 * 15 ~ 8 : SKU ID 573 * 7 ~ 0 : Assembly ID 574 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 575 */ 576static int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports) 577{ 578 unsigned int ass, tmp, i; 579 unsigned nid; 580 struct alc_spec *spec = codec->spec; 581 582 if (spec->cdefine.fixup) { 583 ass = spec->cdefine.sku_cfg; 584 if (ass == ALC_FIXUP_SKU_IGNORE) 585 return 0; 586 goto do_sku; 587 } 588 589 ass = codec->core.subsystem_id & 0xffff; 590 if (codec->bus->pci && 591 ass != codec->bus->pci->subsystem_device && (ass & 1)) 592 goto do_sku; 593 594 /* invalid SSID, check the special NID pin defcfg instead */ 595 /* 596 * 31~30 : port connectivity 597 * 29~21 : reserve 598 * 20 : PCBEEP input 599 * 19~16 : Check sum (15:1) 600 * 15~1 : Custom 601 * 0 : override 602 */ 603 nid = 0x1d; 604 if (codec->core.vendor_id == 0x10ec0260) 605 nid = 0x17; 606 ass = snd_hda_codec_get_pincfg(codec, nid); 607 codec_dbg(codec, 608 "realtek: No valid SSID, checking pincfg 0x%08x for NID 0x%x\n", 609 ass, nid); 610 if (!(ass & 1)) 611 return 0; 612 if ((ass >> 30) != 1) /* no physical connection */ 613 return 0; 614 615 /* check sum */ 616 tmp = 0; 617 for (i = 1; i < 16; i++) { 618 if ((ass >> i) & 1) 619 tmp++; 620 } 621 if (((ass >> 16) & 0xf) != tmp) 622 return 0; 623do_sku: 624 codec_dbg(codec, "realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n", 625 ass & 0xffff, codec->core.vendor_id); 626 /* 627 * 0 : override 628 * 1 : Swap Jack 629 * 2 : 0 --> Desktop, 1 --> Laptop 630 * 3~5 : External Amplifier control 631 * 7~6 : Reserved 632 */ 633 tmp = (ass & 0x38) >> 3; /* external Amp control */ 634 switch (tmp) { 635 case 1: 636 spec->init_amp = ALC_INIT_GPIO1; 637 break; 638 case 3: 639 spec->init_amp = ALC_INIT_GPIO2; 640 break; 641 case 7: 642 spec->init_amp = ALC_INIT_GPIO3; 643 break; 644 case 5: 645 default: 646 spec->init_amp = ALC_INIT_DEFAULT; 647 break; 648 } 649 650 /* is laptop or Desktop and enable the function "Mute internal speaker 651 * when the external headphone out jack is plugged" 652 */ 653 if (!(ass & 0x8000)) 654 return 1; 655 /* 656 * 10~8 : Jack location 657 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered 658 * 14~13: Resvered 659 * 15 : 1 --> enable the function "Mute internal speaker 660 * when the external headphone out jack is plugged" 661 */ 662 if (!spec->gen.autocfg.hp_pins[0] && 663 !(spec->gen.autocfg.line_out_pins[0] && 664 spec->gen.autocfg.line_out_type == AUTO_PIN_HP_OUT)) { 665 hda_nid_t nid; 666 tmp = (ass >> 11) & 0x3; /* HP to chassis */ 667 nid = ports[tmp]; 668 if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins, 669 spec->gen.autocfg.line_outs)) 670 return 1; 671 spec->gen.autocfg.hp_pins[0] = nid; 672 } 673 return 1; 674} 675 676/* Check the validity of ALC subsystem-id 677 * ports contains an array of 4 pin NIDs for port-A, E, D and I */ 678static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports) 679{ 680 if (!alc_subsystem_id(codec, ports)) { 681 struct alc_spec *spec = codec->spec; 682 codec_dbg(codec, 683 "realtek: Enable default setup for auto mode as fallback\n"); 684 spec->init_amp = ALC_INIT_DEFAULT; 685 } 686} 687 688/* 689 */ 690 691static void alc_fixup_inv_dmic(struct hda_codec *codec, 692 const struct hda_fixup *fix, int action) 693{ 694 struct alc_spec *spec = codec->spec; 695 696 spec->gen.inv_dmic_split = 1; 697} 698 699 700#ifdef CONFIG_SND_HDA_INPUT_BEEP 701/* additional beep mixers; the actual parameters are overwritten at build */ 702static const struct snd_kcontrol_new alc_beep_mixer[] = { 703 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT), 704 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT), 705 { } /* end */ 706}; 707#endif 708 709static int alc_build_controls(struct hda_codec *codec) 710{ 711 struct alc_spec *spec = codec->spec; 712 int i, err; 713 714 err = snd_hda_gen_build_controls(codec); 715 if (err < 0) 716 return err; 717 718 for (i = 0; i < spec->num_mixers; i++) { 719 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 720 if (err < 0) 721 return err; 722 } 723 724#ifdef CONFIG_SND_HDA_INPUT_BEEP 725 /* create beep controls if needed */ 726 if (spec->beep_amp) { 727 const struct snd_kcontrol_new *knew; 728 for (knew = alc_beep_mixer; knew->name; knew++) { 729 struct snd_kcontrol *kctl; 730 kctl = snd_ctl_new1(knew, codec); 731 if (!kctl) 732 return -ENOMEM; 733 kctl->private_value = spec->beep_amp; 734 err = snd_hda_ctl_add(codec, 0, kctl); 735 if (err < 0) 736 return err; 737 } 738 } 739#endif 740 741 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD); 742 return 0; 743} 744 745 746/* 747 * Common callbacks 748 */ 749 750static int alc_init(struct hda_codec *codec) 751{ 752 struct alc_spec *spec = codec->spec; 753 754 if (spec->init_hook) 755 spec->init_hook(codec); 756 757 alc_fix_pll(codec); 758 alc_auto_init_amp(codec, spec->init_amp); 759 760 snd_hda_gen_init(codec); 761 762 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT); 763 764 return 0; 765} 766 767static inline void alc_shutup(struct hda_codec *codec) 768{ 769 struct alc_spec *spec = codec->spec; 770 771 if (spec && spec->shutup) 772 spec->shutup(codec); 773 else 774 snd_hda_shutup_pins(codec); 775} 776 777static void alc_reboot_notify(struct hda_codec *codec) 778{ 779 struct alc_spec *spec = codec->spec; 780 781 if (spec && spec->reboot_notify) 782 spec->reboot_notify(codec); 783 else 784 alc_shutup(codec); 785} 786 787/* power down codec to D3 at reboot/shutdown; set as reboot_notify ops */ 788static void alc_d3_at_reboot(struct hda_codec *codec) 789{ 790 snd_hda_codec_set_power_to_all(codec, codec->core.afg, AC_PWRST_D3); 791 snd_hda_codec_write(codec, codec->core.afg, 0, 792 AC_VERB_SET_POWER_STATE, AC_PWRST_D3); 793 msleep(10); 794} 795 796#define alc_free snd_hda_gen_free 797 798#ifdef CONFIG_PM 799static void alc_power_eapd(struct hda_codec *codec) 800{ 801 alc_auto_setup_eapd(codec, false); 802} 803 804static int alc_suspend(struct hda_codec *codec) 805{ 806 struct alc_spec *spec = codec->spec; 807 alc_shutup(codec); 808 if (spec && spec->power_hook) 809 spec->power_hook(codec); 810 return 0; 811} 812#endif 813 814#ifdef CONFIG_PM 815static int alc_resume(struct hda_codec *codec) 816{ 817 struct alc_spec *spec = codec->spec; 818 819 if (!spec->no_depop_delay) 820 msleep(150); /* to avoid pop noise */ 821 codec->patch_ops.init(codec); 822 regcache_sync(codec->core.regmap); 823 hda_call_check_power_status(codec, 0x01); 824 return 0; 825} 826#endif 827 828/* 829 */ 830static const struct hda_codec_ops alc_patch_ops = { 831 .build_controls = alc_build_controls, 832 .build_pcms = snd_hda_gen_build_pcms, 833 .init = alc_init, 834 .free = alc_free, 835 .unsol_event = snd_hda_jack_unsol_event, 836#ifdef CONFIG_PM 837 .resume = alc_resume, 838 .suspend = alc_suspend, 839 .check_power_status = snd_hda_gen_check_power_status, 840#endif 841 .reboot_notify = alc_reboot_notify, 842}; 843 844 845/* replace the codec chip_name with the given string */ 846static int alc_codec_rename(struct hda_codec *codec, const char *name) 847{ 848 kfree(codec->core.chip_name); 849 codec->core.chip_name = kstrdup(name, GFP_KERNEL); 850 if (!codec->core.chip_name) { 851 alc_free(codec); 852 return -ENOMEM; 853 } 854 return 0; 855} 856 857/* 858 * Rename codecs appropriately from COEF value or subvendor id 859 */ 860struct alc_codec_rename_table { 861 unsigned int vendor_id; 862 unsigned short coef_mask; 863 unsigned short coef_bits; 864 const char *name; 865}; 866 867struct alc_codec_rename_pci_table { 868 unsigned int codec_vendor_id; 869 unsigned short pci_subvendor; 870 unsigned short pci_subdevice; 871 const char *name; 872}; 873 874static struct alc_codec_rename_table rename_tbl[] = { 875 { 0x10ec0221, 0xf00f, 0x1003, "ALC231" }, 876 { 0x10ec0269, 0xfff0, 0x3010, "ALC277" }, 877 { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" }, 878 { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" }, 879 { 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" }, 880 { 0x10ec0269, 0xffff, 0xa023, "ALC259" }, 881 { 0x10ec0269, 0xffff, 0x6023, "ALC281X" }, 882 { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" }, 883 { 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" }, 884 { 0x10ec0662, 0xffff, 0x4020, "ALC656" }, 885 { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" }, 886 { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" }, 887 { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" }, 888 { 0x10ec0899, 0x2000, 0x2000, "ALC899" }, 889 { 0x10ec0892, 0xffff, 0x8020, "ALC661" }, 890 { 0x10ec0892, 0xffff, 0x8011, "ALC661" }, 891 { 0x10ec0892, 0xffff, 0x4011, "ALC656" }, 892 { } /* terminator */ 893}; 894 895static struct alc_codec_rename_pci_table rename_pci_tbl[] = { 896 { 0x10ec0280, 0x1028, 0, "ALC3220" }, 897 { 0x10ec0282, 0x1028, 0, "ALC3221" }, 898 { 0x10ec0283, 0x1028, 0, "ALC3223" }, 899 { 0x10ec0288, 0x1028, 0, "ALC3263" }, 900 { 0x10ec0292, 0x1028, 0, "ALC3226" }, 901 { 0x10ec0293, 0x1028, 0, "ALC3235" }, 902 { 0x10ec0255, 0x1028, 0, "ALC3234" }, 903 { 0x10ec0668, 0x1028, 0, "ALC3661" }, 904 { 0x10ec0275, 0x1028, 0, "ALC3260" }, 905 { 0x10ec0899, 0x1028, 0, "ALC3861" }, 906 { 0x10ec0298, 0x1028, 0, "ALC3266" }, 907 { 0x10ec0256, 0x1028, 0, "ALC3246" }, 908 { 0x10ec0670, 0x1025, 0, "ALC669X" }, 909 { 0x10ec0676, 0x1025, 0, "ALC679X" }, 910 { 0x10ec0282, 0x1043, 0, "ALC3229" }, 911 { 0x10ec0233, 0x1043, 0, "ALC3236" }, 912 { 0x10ec0280, 0x103c, 0, "ALC3228" }, 913 { 0x10ec0282, 0x103c, 0, "ALC3227" }, 914 { 0x10ec0286, 0x103c, 0, "ALC3242" }, 915 { 0x10ec0290, 0x103c, 0, "ALC3241" }, 916 { 0x10ec0668, 0x103c, 0, "ALC3662" }, 917 { 0x10ec0283, 0x17aa, 0, "ALC3239" }, 918 { 0x10ec0292, 0x17aa, 0, "ALC3232" }, 919 { } /* terminator */ 920}; 921 922static int alc_codec_rename_from_preset(struct hda_codec *codec) 923{ 924 const struct alc_codec_rename_table *p; 925 const struct alc_codec_rename_pci_table *q; 926 927 for (p = rename_tbl; p->vendor_id; p++) { 928 if (p->vendor_id != codec->core.vendor_id) 929 continue; 930 if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits) 931 return alc_codec_rename(codec, p->name); 932 } 933 934 if (!codec->bus->pci) 935 return 0; 936 for (q = rename_pci_tbl; q->codec_vendor_id; q++) { 937 if (q->codec_vendor_id != codec->core.vendor_id) 938 continue; 939 if (q->pci_subvendor != codec->bus->pci->subsystem_vendor) 940 continue; 941 if (!q->pci_subdevice || 942 q->pci_subdevice == codec->bus->pci->subsystem_device) 943 return alc_codec_rename(codec, q->name); 944 } 945 946 return 0; 947} 948 949 950/* 951 * Digital-beep handlers 952 */ 953#ifdef CONFIG_SND_HDA_INPUT_BEEP 954#define set_beep_amp(spec, nid, idx, dir) \ 955 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) 956 957static const struct snd_pci_quirk beep_white_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 {} 968}; 969 970static inline int has_cdefine_beep(struct hda_codec *codec) 971{ 972 struct alc_spec *spec = codec->spec; 973 const struct snd_pci_quirk *q; 974 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list); 975 if (q) 976 return q->value; 977 return spec->cdefine.enable_pcbeep; 978} 979#else 980#define set_beep_amp(spec, nid, idx, dir) /* NOP */ 981#define has_cdefine_beep(codec) 0 982#endif 983 984/* parse the BIOS configuration and set up the alc_spec */ 985/* return 1 if successful, 0 if the proper config is not found, 986 * or a negative error code 987 */ 988static int alc_parse_auto_config(struct hda_codec *codec, 989 const hda_nid_t *ignore_nids, 990 const hda_nid_t *ssid_nids) 991{ 992 struct alc_spec *spec = codec->spec; 993 struct auto_pin_cfg *cfg = &spec->gen.autocfg; 994 int err; 995 996 err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids, 997 spec->parse_flags); 998 if (err < 0) 999 return err; 1000 1001 if (ssid_nids) 1002 alc_ssid_check(codec, ssid_nids); 1003 1004 err = snd_hda_gen_parse_auto_config(codec, cfg); 1005 if (err < 0) 1006 return err; 1007 1008 return 1; 1009} 1010 1011/* common preparation job for alc_spec */ 1012static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid) 1013{ 1014 struct alc_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL); 1015 int err; 1016 1017 if (!spec) 1018 return -ENOMEM; 1019 codec->spec = spec; 1020 snd_hda_gen_spec_init(&spec->gen); 1021 spec->gen.mixer_nid = mixer_nid; 1022 spec->gen.own_eapd_ctl = 1; 1023 codec->single_adc_amp = 1; 1024 /* FIXME: do we need this for all Realtek codec models? */ 1025 codec->spdif_status_reset = 1; 1026 1027 err = alc_codec_rename_from_preset(codec); 1028 if (err < 0) { 1029 kfree(spec); 1030 return err; 1031 } 1032 return 0; 1033} 1034 1035static int alc880_parse_auto_config(struct hda_codec *codec) 1036{ 1037 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 }; 1038 static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 }; 1039 return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids); 1040} 1041 1042/* 1043 * ALC880 fix-ups 1044 */ 1045enum { 1046 ALC880_FIXUP_GPIO1, 1047 ALC880_FIXUP_GPIO2, 1048 ALC880_FIXUP_MEDION_RIM, 1049 ALC880_FIXUP_LG, 1050 ALC880_FIXUP_LG_LW25, 1051 ALC880_FIXUP_W810, 1052 ALC880_FIXUP_EAPD_COEF, 1053 ALC880_FIXUP_TCL_S700, 1054 ALC880_FIXUP_VOL_KNOB, 1055 ALC880_FIXUP_FUJITSU, 1056 ALC880_FIXUP_F1734, 1057 ALC880_FIXUP_UNIWILL, 1058 ALC880_FIXUP_UNIWILL_DIG, 1059 ALC880_FIXUP_Z71V, 1060 ALC880_FIXUP_ASUS_W5A, 1061 ALC880_FIXUP_3ST_BASE, 1062 ALC880_FIXUP_3ST, 1063 ALC880_FIXUP_3ST_DIG, 1064 ALC880_FIXUP_5ST_BASE, 1065 ALC880_FIXUP_5ST, 1066 ALC880_FIXUP_5ST_DIG, 1067 ALC880_FIXUP_6ST_BASE, 1068 ALC880_FIXUP_6ST, 1069 ALC880_FIXUP_6ST_DIG, 1070 ALC880_FIXUP_6ST_AUTOMUTE, 1071}; 1072 1073/* enable the volume-knob widget support on NID 0x21 */ 1074static void alc880_fixup_vol_knob(struct hda_codec *codec, 1075 const struct hda_fixup *fix, int action) 1076{ 1077 if (action == HDA_FIXUP_ACT_PROBE) 1078 snd_hda_jack_detect_enable_callback(codec, 0x21, 1079 alc_update_knob_master); 1080} 1081 1082static const struct hda_fixup alc880_fixups[] = { 1083 [ALC880_FIXUP_GPIO1] = { 1084 .type = HDA_FIXUP_VERBS, 1085 .v.verbs = alc_gpio1_init_verbs, 1086 }, 1087 [ALC880_FIXUP_GPIO2] = { 1088 .type = HDA_FIXUP_VERBS, 1089 .v.verbs = alc_gpio2_init_verbs, 1090 }, 1091 [ALC880_FIXUP_MEDION_RIM] = { 1092 .type = HDA_FIXUP_VERBS, 1093 .v.verbs = (const struct hda_verb[]) { 1094 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, 1095 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 }, 1096 { } 1097 }, 1098 .chained = true, 1099 .chain_id = ALC880_FIXUP_GPIO2, 1100 }, 1101 [ALC880_FIXUP_LG] = { 1102 .type = HDA_FIXUP_PINS, 1103 .v.pins = (const struct hda_pintbl[]) { 1104 /* disable bogus unused pins */ 1105 { 0x16, 0x411111f0 }, 1106 { 0x18, 0x411111f0 }, 1107 { 0x1a, 0x411111f0 }, 1108 { } 1109 } 1110 }, 1111 [ALC880_FIXUP_LG_LW25] = { 1112 .type = HDA_FIXUP_PINS, 1113 .v.pins = (const struct hda_pintbl[]) { 1114 { 0x1a, 0x0181344f }, /* line-in */ 1115 { 0x1b, 0x0321403f }, /* headphone */ 1116 { } 1117 } 1118 }, 1119 [ALC880_FIXUP_W810] = { 1120 .type = HDA_FIXUP_PINS, 1121 .v.pins = (const struct hda_pintbl[]) { 1122 /* disable bogus unused pins */ 1123 { 0x17, 0x411111f0 }, 1124 { } 1125 }, 1126 .chained = true, 1127 .chain_id = ALC880_FIXUP_GPIO2, 1128 }, 1129 [ALC880_FIXUP_EAPD_COEF] = { 1130 .type = HDA_FIXUP_VERBS, 1131 .v.verbs = (const struct hda_verb[]) { 1132 /* change to EAPD mode */ 1133 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, 1134 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 }, 1135 {} 1136 }, 1137 }, 1138 [ALC880_FIXUP_TCL_S700] = { 1139 .type = HDA_FIXUP_VERBS, 1140 .v.verbs = (const struct hda_verb[]) { 1141 /* change to EAPD mode */ 1142 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, 1143 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, 1144 {} 1145 }, 1146 .chained = true, 1147 .chain_id = ALC880_FIXUP_GPIO2, 1148 }, 1149 [ALC880_FIXUP_VOL_KNOB] = { 1150 .type = HDA_FIXUP_FUNC, 1151 .v.func = alc880_fixup_vol_knob, 1152 }, 1153 [ALC880_FIXUP_FUJITSU] = { 1154 /* override all pins as BIOS on old Amilo is broken */ 1155 .type = HDA_FIXUP_PINS, 1156 .v.pins = (const struct hda_pintbl[]) { 1157 { 0x14, 0x0121401f }, /* HP */ 1158 { 0x15, 0x99030120 }, /* speaker */ 1159 { 0x16, 0x99030130 }, /* bass speaker */ 1160 { 0x17, 0x411111f0 }, /* N/A */ 1161 { 0x18, 0x411111f0 }, /* N/A */ 1162 { 0x19, 0x01a19950 }, /* mic-in */ 1163 { 0x1a, 0x411111f0 }, /* N/A */ 1164 { 0x1b, 0x411111f0 }, /* N/A */ 1165 { 0x1c, 0x411111f0 }, /* N/A */ 1166 { 0x1d, 0x411111f0 }, /* N/A */ 1167 { 0x1e, 0x01454140 }, /* SPDIF out */ 1168 { } 1169 }, 1170 .chained = true, 1171 .chain_id = ALC880_FIXUP_VOL_KNOB, 1172 }, 1173 [ALC880_FIXUP_F1734] = { 1174 /* almost compatible with FUJITSU, but no bass and SPDIF */ 1175 .type = HDA_FIXUP_PINS, 1176 .v.pins = (const struct hda_pintbl[]) { 1177 { 0x14, 0x0121401f }, /* HP */ 1178 { 0x15, 0x99030120 }, /* speaker */ 1179 { 0x16, 0x411111f0 }, /* N/A */ 1180 { 0x17, 0x411111f0 }, /* N/A */ 1181 { 0x18, 0x411111f0 }, /* N/A */ 1182 { 0x19, 0x01a19950 }, /* mic-in */ 1183 { 0x1a, 0x411111f0 }, /* N/A */ 1184 { 0x1b, 0x411111f0 }, /* N/A */ 1185 { 0x1c, 0x411111f0 }, /* N/A */ 1186 { 0x1d, 0x411111f0 }, /* N/A */ 1187 { 0x1e, 0x411111f0 }, /* N/A */ 1188 { } 1189 }, 1190 .chained = true, 1191 .chain_id = ALC880_FIXUP_VOL_KNOB, 1192 }, 1193 [ALC880_FIXUP_UNIWILL] = { 1194 /* need to fix HP and speaker pins to be parsed correctly */ 1195 .type = HDA_FIXUP_PINS, 1196 .v.pins = (const struct hda_pintbl[]) { 1197 { 0x14, 0x0121411f }, /* HP */ 1198 { 0x15, 0x99030120 }, /* speaker */ 1199 { 0x16, 0x99030130 }, /* bass speaker */ 1200 { } 1201 }, 1202 }, 1203 [ALC880_FIXUP_UNIWILL_DIG] = { 1204 .type = HDA_FIXUP_PINS, 1205 .v.pins = (const struct hda_pintbl[]) { 1206 /* disable bogus unused pins */ 1207 { 0x17, 0x411111f0 }, 1208 { 0x19, 0x411111f0 }, 1209 { 0x1b, 0x411111f0 }, 1210 { 0x1f, 0x411111f0 }, 1211 { } 1212 } 1213 }, 1214 [ALC880_FIXUP_Z71V] = { 1215 .type = HDA_FIXUP_PINS, 1216 .v.pins = (const struct hda_pintbl[]) { 1217 /* set up the whole pins as BIOS is utterly broken */ 1218 { 0x14, 0x99030120 }, /* speaker */ 1219 { 0x15, 0x0121411f }, /* HP */ 1220 { 0x16, 0x411111f0 }, /* N/A */ 1221 { 0x17, 0x411111f0 }, /* N/A */ 1222 { 0x18, 0x01a19950 }, /* mic-in */ 1223 { 0x19, 0x411111f0 }, /* N/A */ 1224 { 0x1a, 0x01813031 }, /* line-in */ 1225 { 0x1b, 0x411111f0 }, /* N/A */ 1226 { 0x1c, 0x411111f0 }, /* N/A */ 1227 { 0x1d, 0x411111f0 }, /* N/A */ 1228 { 0x1e, 0x0144111e }, /* SPDIF */ 1229 { } 1230 } 1231 }, 1232 [ALC880_FIXUP_ASUS_W5A] = { 1233 .type = HDA_FIXUP_PINS, 1234 .v.pins = (const struct hda_pintbl[]) { 1235 /* set up the whole pins as BIOS is utterly broken */ 1236 { 0x14, 0x0121411f }, /* HP */ 1237 { 0x15, 0x411111f0 }, /* N/A */ 1238 { 0x16, 0x411111f0 }, /* N/A */ 1239 { 0x17, 0x411111f0 }, /* N/A */ 1240 { 0x18, 0x90a60160 }, /* mic */ 1241 { 0x19, 0x411111f0 }, /* N/A */ 1242 { 0x1a, 0x411111f0 }, /* N/A */ 1243 { 0x1b, 0x411111f0 }, /* N/A */ 1244 { 0x1c, 0x411111f0 }, /* N/A */ 1245 { 0x1d, 0x411111f0 }, /* N/A */ 1246 { 0x1e, 0xb743111e }, /* SPDIF out */ 1247 { } 1248 }, 1249 .chained = true, 1250 .chain_id = ALC880_FIXUP_GPIO1, 1251 }, 1252 [ALC880_FIXUP_3ST_BASE] = { 1253 .type = HDA_FIXUP_PINS, 1254 .v.pins = (const struct hda_pintbl[]) { 1255 { 0x14, 0x01014010 }, /* line-out */ 1256 { 0x15, 0x411111f0 }, /* N/A */ 1257 { 0x16, 0x411111f0 }, /* N/A */ 1258 { 0x17, 0x411111f0 }, /* N/A */ 1259 { 0x18, 0x01a19c30 }, /* mic-in */ 1260 { 0x19, 0x0121411f }, /* HP */ 1261 { 0x1a, 0x01813031 }, /* line-in */ 1262 { 0x1b, 0x02a19c40 }, /* front-mic */ 1263 { 0x1c, 0x411111f0 }, /* N/A */ 1264 { 0x1d, 0x411111f0 }, /* N/A */ 1265 /* 0x1e is filled in below */ 1266 { 0x1f, 0x411111f0 }, /* N/A */ 1267 { } 1268 } 1269 }, 1270 [ALC880_FIXUP_3ST] = { 1271 .type = HDA_FIXUP_PINS, 1272 .v.pins = (const struct hda_pintbl[]) { 1273 { 0x1e, 0x411111f0 }, /* N/A */ 1274 { } 1275 }, 1276 .chained = true, 1277 .chain_id = ALC880_FIXUP_3ST_BASE, 1278 }, 1279 [ALC880_FIXUP_3ST_DIG] = { 1280 .type = HDA_FIXUP_PINS, 1281 .v.pins = (const struct hda_pintbl[]) { 1282 { 0x1e, 0x0144111e }, /* SPDIF */ 1283 { } 1284 }, 1285 .chained = true, 1286 .chain_id = ALC880_FIXUP_3ST_BASE, 1287 }, 1288 [ALC880_FIXUP_5ST_BASE] = { 1289 .type = HDA_FIXUP_PINS, 1290 .v.pins = (const struct hda_pintbl[]) { 1291 { 0x14, 0x01014010 }, /* front */ 1292 { 0x15, 0x411111f0 }, /* N/A */ 1293 { 0x16, 0x01011411 }, /* CLFE */ 1294 { 0x17, 0x01016412 }, /* surr */ 1295 { 0x18, 0x01a19c30 }, /* mic-in */ 1296 { 0x19, 0x0121411f }, /* HP */ 1297 { 0x1a, 0x01813031 }, /* line-in */ 1298 { 0x1b, 0x02a19c40 }, /* front-mic */ 1299 { 0x1c, 0x411111f0 }, /* N/A */ 1300 { 0x1d, 0x411111f0 }, /* N/A */ 1301 /* 0x1e is filled in below */ 1302 { 0x1f, 0x411111f0 }, /* N/A */ 1303 { } 1304 } 1305 }, 1306 [ALC880_FIXUP_5ST] = { 1307 .type = HDA_FIXUP_PINS, 1308 .v.pins = (const struct hda_pintbl[]) { 1309 { 0x1e, 0x411111f0 }, /* N/A */ 1310 { } 1311 }, 1312 .chained = true, 1313 .chain_id = ALC880_FIXUP_5ST_BASE, 1314 }, 1315 [ALC880_FIXUP_5ST_DIG] = { 1316 .type = HDA_FIXUP_PINS, 1317 .v.pins = (const struct hda_pintbl[]) { 1318 { 0x1e, 0x0144111e }, /* SPDIF */ 1319 { } 1320 }, 1321 .chained = true, 1322 .chain_id = ALC880_FIXUP_5ST_BASE, 1323 }, 1324 [ALC880_FIXUP_6ST_BASE] = { 1325 .type = HDA_FIXUP_PINS, 1326 .v.pins = (const struct hda_pintbl[]) { 1327 { 0x14, 0x01014010 }, /* front */ 1328 { 0x15, 0x01016412 }, /* surr */ 1329 { 0x16, 0x01011411 }, /* CLFE */ 1330 { 0x17, 0x01012414 }, /* side */ 1331 { 0x18, 0x01a19c30 }, /* mic-in */ 1332 { 0x19, 0x02a19c40 }, /* front-mic */ 1333 { 0x1a, 0x01813031 }, /* line-in */ 1334 { 0x1b, 0x0121411f }, /* HP */ 1335 { 0x1c, 0x411111f0 }, /* N/A */ 1336 { 0x1d, 0x411111f0 }, /* N/A */ 1337 /* 0x1e is filled in below */ 1338 { 0x1f, 0x411111f0 }, /* N/A */ 1339 { } 1340 } 1341 }, 1342 [ALC880_FIXUP_6ST] = { 1343 .type = HDA_FIXUP_PINS, 1344 .v.pins = (const struct hda_pintbl[]) { 1345 { 0x1e, 0x411111f0 }, /* N/A */ 1346 { } 1347 }, 1348 .chained = true, 1349 .chain_id = ALC880_FIXUP_6ST_BASE, 1350 }, 1351 [ALC880_FIXUP_6ST_DIG] = { 1352 .type = HDA_FIXUP_PINS, 1353 .v.pins = (const struct hda_pintbl[]) { 1354 { 0x1e, 0x0144111e }, /* SPDIF */ 1355 { } 1356 }, 1357 .chained = true, 1358 .chain_id = ALC880_FIXUP_6ST_BASE, 1359 }, 1360 [ALC880_FIXUP_6ST_AUTOMUTE] = { 1361 .type = HDA_FIXUP_PINS, 1362 .v.pins = (const struct hda_pintbl[]) { 1363 { 0x1b, 0x0121401f }, /* HP with jack detect */ 1364 { } 1365 }, 1366 .chained_before = true, 1367 .chain_id = ALC880_FIXUP_6ST_BASE, 1368 }, 1369}; 1370 1371static const struct snd_pci_quirk alc880_fixup_tbl[] = { 1372 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810), 1373 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS W5A", ALC880_FIXUP_ASUS_W5A), 1374 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V), 1375 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1), 1376 SND_PCI_QUIRK(0x147b, 0x1045, "ABit AA8XE", ALC880_FIXUP_6ST_AUTOMUTE), 1377 SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2), 1378 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF), 1379 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG), 1380 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734), 1381 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL), 1382 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB), 1383 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810), 1384 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM), 1385 SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST_AUTOMUTE), 1386 SND_PCI_QUIRK(0x1734, 0x107c, "FSC Amilo M1437", ALC880_FIXUP_FUJITSU), 1387 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU), 1388 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734), 1389 SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU), 1390 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG), 1391 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG), 1392 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG), 1393 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_FIXUP_LG_LW25), 1394 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700), 1395 1396 /* Below is the copied entries from alc880_quirks.c. 1397 * It's not quite sure whether BIOS sets the correct pin-config table 1398 * on these machines, thus they are kept to be compatible with 1399 * the old static quirks. Once when it's confirmed to work without 1400 * these overrides, it'd be better to remove. 1401 */ 1402 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG), 1403 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST), 1404 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG), 1405 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG), 1406 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG), 1407 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG), 1408 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG), 1409 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST), 1410 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG), 1411 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST), 1412 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST), 1413 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST), 1414 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST), 1415 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST), 1416 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG), 1417 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG), 1418 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG), 1419 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG), 1420 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG), 1421 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG), 1422 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG), 1423 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */ 1424 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG), 1425 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG), 1426 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG), 1427 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG), 1428 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG), 1429 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG), 1430 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG), 1431 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG), 1432 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG), 1433 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG), 1434 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG), 1435 /* default Intel */ 1436 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST), 1437 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG), 1438 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG), 1439 {} 1440}; 1441 1442static const struct hda_model_fixup alc880_fixup_models[] = { 1443 {.id = ALC880_FIXUP_3ST, .name = "3stack"}, 1444 {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"}, 1445 {.id = ALC880_FIXUP_5ST, .name = "5stack"}, 1446 {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"}, 1447 {.id = ALC880_FIXUP_6ST, .name = "6stack"}, 1448 {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"}, 1449 {.id = ALC880_FIXUP_6ST_AUTOMUTE, .name = "6stack-automute"}, 1450 {} 1451}; 1452 1453 1454/* 1455 * OK, here we have finally the patch for ALC880 1456 */ 1457static int patch_alc880(struct hda_codec *codec) 1458{ 1459 struct alc_spec *spec; 1460 int err; 1461 1462 err = alc_alloc_spec(codec, 0x0b); 1463 if (err < 0) 1464 return err; 1465 1466 spec = codec->spec; 1467 spec->gen.need_dac_fix = 1; 1468 spec->gen.beep_nid = 0x01; 1469 1470 snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl, 1471 alc880_fixups); 1472 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 1473 1474 /* automatic parse from the BIOS config */ 1475 err = alc880_parse_auto_config(codec); 1476 if (err < 0) 1477 goto error; 1478 1479 if (!spec->gen.no_analog) 1480 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 1481 1482 codec->patch_ops = alc_patch_ops; 1483 codec->patch_ops.unsol_event = alc880_unsol_event; 1484 1485 1486 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 1487 1488 return 0; 1489 1490 error: 1491 alc_free(codec); 1492 return err; 1493} 1494 1495 1496/* 1497 * ALC260 support 1498 */ 1499static int alc260_parse_auto_config(struct hda_codec *codec) 1500{ 1501 static const hda_nid_t alc260_ignore[] = { 0x17, 0 }; 1502 static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 }; 1503 return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids); 1504} 1505 1506/* 1507 * Pin config fixes 1508 */ 1509enum { 1510 ALC260_FIXUP_HP_DC5750, 1511 ALC260_FIXUP_HP_PIN_0F, 1512 ALC260_FIXUP_COEF, 1513 ALC260_FIXUP_GPIO1, 1514 ALC260_FIXUP_GPIO1_TOGGLE, 1515 ALC260_FIXUP_REPLACER, 1516 ALC260_FIXUP_HP_B1900, 1517 ALC260_FIXUP_KN1, 1518 ALC260_FIXUP_FSC_S7020, 1519 ALC260_FIXUP_FSC_S7020_JWSE, 1520 ALC260_FIXUP_VAIO_PINS, 1521}; 1522 1523static void alc260_gpio1_automute(struct hda_codec *codec) 1524{ 1525 struct alc_spec *spec = codec->spec; 1526 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 1527 spec->gen.hp_jack_present); 1528} 1529 1530static void alc260_fixup_gpio1_toggle(struct hda_codec *codec, 1531 const struct hda_fixup *fix, int action) 1532{ 1533 struct alc_spec *spec = codec->spec; 1534 if (action == HDA_FIXUP_ACT_PROBE) { 1535 /* although the machine has only one output pin, we need to 1536 * toggle GPIO1 according to the jack state 1537 */ 1538 spec->gen.automute_hook = alc260_gpio1_automute; 1539 spec->gen.detect_hp = 1; 1540 spec->gen.automute_speaker = 1; 1541 spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */ 1542 snd_hda_jack_detect_enable_callback(codec, 0x0f, 1543 snd_hda_gen_hp_automute); 1544 snd_hda_add_verbs(codec, alc_gpio1_init_verbs); 1545 } 1546} 1547 1548static void alc260_fixup_kn1(struct hda_codec *codec, 1549 const struct hda_fixup *fix, int action) 1550{ 1551 struct alc_spec *spec = codec->spec; 1552 static const struct hda_pintbl pincfgs[] = { 1553 { 0x0f, 0x02214000 }, /* HP/speaker */ 1554 { 0x12, 0x90a60160 }, /* int mic */ 1555 { 0x13, 0x02a19000 }, /* ext mic */ 1556 { 0x18, 0x01446000 }, /* SPDIF out */ 1557 /* disable bogus I/O pins */ 1558 { 0x10, 0x411111f0 }, 1559 { 0x11, 0x411111f0 }, 1560 { 0x14, 0x411111f0 }, 1561 { 0x15, 0x411111f0 }, 1562 { 0x16, 0x411111f0 }, 1563 { 0x17, 0x411111f0 }, 1564 { 0x19, 0x411111f0 }, 1565 { } 1566 }; 1567 1568 switch (action) { 1569 case HDA_FIXUP_ACT_PRE_PROBE: 1570 snd_hda_apply_pincfgs(codec, pincfgs); 1571 break; 1572 case HDA_FIXUP_ACT_PROBE: 1573 spec->init_amp = ALC_INIT_NONE; 1574 break; 1575 } 1576} 1577 1578static void alc260_fixup_fsc_s7020(struct hda_codec *codec, 1579 const struct hda_fixup *fix, int action) 1580{ 1581 struct alc_spec *spec = codec->spec; 1582 if (action == HDA_FIXUP_ACT_PROBE) 1583 spec->init_amp = ALC_INIT_NONE; 1584} 1585 1586static void alc260_fixup_fsc_s7020_jwse(struct hda_codec *codec, 1587 const struct hda_fixup *fix, int action) 1588{ 1589 struct alc_spec *spec = codec->spec; 1590 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 1591 spec->gen.add_jack_modes = 1; 1592 spec->gen.hp_mic = 1; 1593 } 1594} 1595 1596static const struct hda_fixup alc260_fixups[] = { 1597 [ALC260_FIXUP_HP_DC5750] = { 1598 .type = HDA_FIXUP_PINS, 1599 .v.pins = (const struct hda_pintbl[]) { 1600 { 0x11, 0x90130110 }, /* speaker */ 1601 { } 1602 } 1603 }, 1604 [ALC260_FIXUP_HP_PIN_0F] = { 1605 .type = HDA_FIXUP_PINS, 1606 .v.pins = (const struct hda_pintbl[]) { 1607 { 0x0f, 0x01214000 }, /* HP */ 1608 { } 1609 } 1610 }, 1611 [ALC260_FIXUP_COEF] = { 1612 .type = HDA_FIXUP_VERBS, 1613 .v.verbs = (const struct hda_verb[]) { 1614 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 }, 1615 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3040 }, 1616 { } 1617 }, 1618 }, 1619 [ALC260_FIXUP_GPIO1] = { 1620 .type = HDA_FIXUP_VERBS, 1621 .v.verbs = alc_gpio1_init_verbs, 1622 }, 1623 [ALC260_FIXUP_GPIO1_TOGGLE] = { 1624 .type = HDA_FIXUP_FUNC, 1625 .v.func = alc260_fixup_gpio1_toggle, 1626 .chained = true, 1627 .chain_id = ALC260_FIXUP_HP_PIN_0F, 1628 }, 1629 [ALC260_FIXUP_REPLACER] = { 1630 .type = HDA_FIXUP_VERBS, 1631 .v.verbs = (const struct hda_verb[]) { 1632 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 }, 1633 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3050 }, 1634 { } 1635 }, 1636 .chained = true, 1637 .chain_id = ALC260_FIXUP_GPIO1_TOGGLE, 1638 }, 1639 [ALC260_FIXUP_HP_B1900] = { 1640 .type = HDA_FIXUP_FUNC, 1641 .v.func = alc260_fixup_gpio1_toggle, 1642 .chained = true, 1643 .chain_id = ALC260_FIXUP_COEF, 1644 }, 1645 [ALC260_FIXUP_KN1] = { 1646 .type = HDA_FIXUP_FUNC, 1647 .v.func = alc260_fixup_kn1, 1648 }, 1649 [ALC260_FIXUP_FSC_S7020] = { 1650 .type = HDA_FIXUP_FUNC, 1651 .v.func = alc260_fixup_fsc_s7020, 1652 }, 1653 [ALC260_FIXUP_FSC_S7020_JWSE] = { 1654 .type = HDA_FIXUP_FUNC, 1655 .v.func = alc260_fixup_fsc_s7020_jwse, 1656 .chained = true, 1657 .chain_id = ALC260_FIXUP_FSC_S7020, 1658 }, 1659 [ALC260_FIXUP_VAIO_PINS] = { 1660 .type = HDA_FIXUP_PINS, 1661 .v.pins = (const struct hda_pintbl[]) { 1662 /* Pin configs are missing completely on some VAIOs */ 1663 { 0x0f, 0x01211020 }, 1664 { 0x10, 0x0001003f }, 1665 { 0x11, 0x411111f0 }, 1666 { 0x12, 0x01a15930 }, 1667 { 0x13, 0x411111f0 }, 1668 { 0x14, 0x411111f0 }, 1669 { 0x15, 0x411111f0 }, 1670 { 0x16, 0x411111f0 }, 1671 { 0x17, 0x411111f0 }, 1672 { 0x18, 0x411111f0 }, 1673 { 0x19, 0x411111f0 }, 1674 { } 1675 } 1676 }, 1677}; 1678 1679static const struct snd_pci_quirk alc260_fixup_tbl[] = { 1680 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1), 1681 SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF), 1682 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1), 1683 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750), 1684 SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900), 1685 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_FIXUP_VAIO_PINS), 1686 SND_PCI_QUIRK(0x104d, 0x81e2, "Sony VAIO TX", ALC260_FIXUP_HP_PIN_0F), 1687 SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020), 1688 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1), 1689 SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1), 1690 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER), 1691 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF), 1692 {} 1693}; 1694 1695static const struct hda_model_fixup alc260_fixup_models[] = { 1696 {.id = ALC260_FIXUP_GPIO1, .name = "gpio1"}, 1697 {.id = ALC260_FIXUP_COEF, .name = "coef"}, 1698 {.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"}, 1699 {.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"}, 1700 {} 1701}; 1702 1703/* 1704 */ 1705static int patch_alc260(struct hda_codec *codec) 1706{ 1707 struct alc_spec *spec; 1708 int err; 1709 1710 err = alc_alloc_spec(codec, 0x07); 1711 if (err < 0) 1712 return err; 1713 1714 spec = codec->spec; 1715 /* as quite a few machines require HP amp for speaker outputs, 1716 * it's easier to enable it unconditionally; even if it's unneeded, 1717 * it's almost harmless. 1718 */ 1719 spec->gen.prefer_hp_amp = 1; 1720 spec->gen.beep_nid = 0x01; 1721 1722 snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl, 1723 alc260_fixups); 1724 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 1725 1726 /* automatic parse from the BIOS config */ 1727 err = alc260_parse_auto_config(codec); 1728 if (err < 0) 1729 goto error; 1730 1731 if (!spec->gen.no_analog) 1732 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); 1733 1734 codec->patch_ops = alc_patch_ops; 1735 spec->shutup = alc_eapd_shutup; 1736 1737 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 1738 1739 return 0; 1740 1741 error: 1742 alc_free(codec); 1743 return err; 1744} 1745 1746 1747/* 1748 * ALC882/883/885/888/889 support 1749 * 1750 * ALC882 is almost identical with ALC880 but has cleaner and more flexible 1751 * configuration. Each pin widget can choose any input DACs and a mixer. 1752 * Each ADC is connected from a mixer of all inputs. This makes possible 1753 * 6-channel independent captures. 1754 * 1755 * In addition, an independent DAC for the multi-playback (not used in this 1756 * driver yet). 1757 */ 1758 1759/* 1760 * Pin config fixes 1761 */ 1762enum { 1763 ALC882_FIXUP_ABIT_AW9D_MAX, 1764 ALC882_FIXUP_LENOVO_Y530, 1765 ALC882_FIXUP_PB_M5210, 1766 ALC882_FIXUP_ACER_ASPIRE_7736, 1767 ALC882_FIXUP_ASUS_W90V, 1768 ALC889_FIXUP_CD, 1769 ALC889_FIXUP_FRONT_HP_NO_PRESENCE, 1770 ALC889_FIXUP_VAIO_TT, 1771 ALC888_FIXUP_EEE1601, 1772 ALC882_FIXUP_EAPD, 1773 ALC883_FIXUP_EAPD, 1774 ALC883_FIXUP_ACER_EAPD, 1775 ALC882_FIXUP_GPIO1, 1776 ALC882_FIXUP_GPIO2, 1777 ALC882_FIXUP_GPIO3, 1778 ALC889_FIXUP_COEF, 1779 ALC882_FIXUP_ASUS_W2JC, 1780 ALC882_FIXUP_ACER_ASPIRE_4930G, 1781 ALC882_FIXUP_ACER_ASPIRE_8930G, 1782 ALC882_FIXUP_ASPIRE_8930G_VERBS, 1783 ALC885_FIXUP_MACPRO_GPIO, 1784 ALC889_FIXUP_DAC_ROUTE, 1785 ALC889_FIXUP_MBP_VREF, 1786 ALC889_FIXUP_IMAC91_VREF, 1787 ALC889_FIXUP_MBA11_VREF, 1788 ALC889_FIXUP_MBA21_VREF, 1789 ALC889_FIXUP_MP11_VREF, 1790 ALC889_FIXUP_MP41_VREF, 1791 ALC882_FIXUP_INV_DMIC, 1792 ALC882_FIXUP_NO_PRIMARY_HP, 1793 ALC887_FIXUP_ASUS_BASS, 1794 ALC887_FIXUP_BASS_CHMAP, 1795}; 1796 1797static void alc889_fixup_coef(struct hda_codec *codec, 1798 const struct hda_fixup *fix, int action) 1799{ 1800 if (action != HDA_FIXUP_ACT_INIT) 1801 return; 1802 alc_update_coef_idx(codec, 7, 0, 0x2030); 1803} 1804 1805/* toggle speaker-output according to the hp-jack state */ 1806static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) 1807{ 1808 unsigned int gpiostate, gpiomask, gpiodir; 1809 1810 gpiostate = snd_hda_codec_read(codec, codec->core.afg, 0, 1811 AC_VERB_GET_GPIO_DATA, 0); 1812 1813 if (!muted) 1814 gpiostate |= (1 << pin); 1815 else 1816 gpiostate &= ~(1 << pin); 1817 1818 gpiomask = snd_hda_codec_read(codec, codec->core.afg, 0, 1819 AC_VERB_GET_GPIO_MASK, 0); 1820 gpiomask |= (1 << pin); 1821 1822 gpiodir = snd_hda_codec_read(codec, codec->core.afg, 0, 1823 AC_VERB_GET_GPIO_DIRECTION, 0); 1824 gpiodir |= (1 << pin); 1825 1826 1827 snd_hda_codec_write(codec, codec->core.afg, 0, 1828 AC_VERB_SET_GPIO_MASK, gpiomask); 1829 snd_hda_codec_write(codec, codec->core.afg, 0, 1830 AC_VERB_SET_GPIO_DIRECTION, gpiodir); 1831 1832 msleep(1); 1833 1834 snd_hda_codec_write(codec, codec->core.afg, 0, 1835 AC_VERB_SET_GPIO_DATA, gpiostate); 1836} 1837 1838/* set up GPIO at initialization */ 1839static void alc885_fixup_macpro_gpio(struct hda_codec *codec, 1840 const struct hda_fixup *fix, int action) 1841{ 1842 if (action != HDA_FIXUP_ACT_INIT) 1843 return; 1844 alc882_gpio_mute(codec, 0, 0); 1845 alc882_gpio_mute(codec, 1, 0); 1846} 1847 1848/* Fix the connection of some pins for ALC889: 1849 * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't 1850 * work correctly (bko#42740) 1851 */ 1852static void alc889_fixup_dac_route(struct hda_codec *codec, 1853 const struct hda_fixup *fix, int action) 1854{ 1855 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 1856 /* fake the connections during parsing the tree */ 1857 hda_nid_t conn1[2] = { 0x0c, 0x0d }; 1858 hda_nid_t conn2[2] = { 0x0e, 0x0f }; 1859 snd_hda_override_conn_list(codec, 0x14, 2, conn1); 1860 snd_hda_override_conn_list(codec, 0x15, 2, conn1); 1861 snd_hda_override_conn_list(codec, 0x18, 2, conn2); 1862 snd_hda_override_conn_list(codec, 0x1a, 2, conn2); 1863 } else if (action == HDA_FIXUP_ACT_PROBE) { 1864 /* restore the connections */ 1865 hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 }; 1866 snd_hda_override_conn_list(codec, 0x14, 5, conn); 1867 snd_hda_override_conn_list(codec, 0x15, 5, conn); 1868 snd_hda_override_conn_list(codec, 0x18, 5, conn); 1869 snd_hda_override_conn_list(codec, 0x1a, 5, conn); 1870 } 1871} 1872 1873/* Set VREF on HP pin */ 1874static void alc889_fixup_mbp_vref(struct hda_codec *codec, 1875 const struct hda_fixup *fix, int action) 1876{ 1877 struct alc_spec *spec = codec->spec; 1878 static hda_nid_t nids[3] = { 0x14, 0x15, 0x19 }; 1879 int i; 1880 1881 if (action != HDA_FIXUP_ACT_INIT) 1882 return; 1883 for (i = 0; i < ARRAY_SIZE(nids); i++) { 1884 unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]); 1885 if (get_defcfg_device(val) != AC_JACK_HP_OUT) 1886 continue; 1887 val = snd_hda_codec_get_pin_target(codec, nids[i]); 1888 val |= AC_PINCTL_VREF_80; 1889 snd_hda_set_pin_ctl(codec, nids[i], val); 1890 spec->gen.keep_vref_in_automute = 1; 1891 break; 1892 } 1893} 1894 1895static void alc889_fixup_mac_pins(struct hda_codec *codec, 1896 const hda_nid_t *nids, int num_nids) 1897{ 1898 struct alc_spec *spec = codec->spec; 1899 int i; 1900 1901 for (i = 0; i < num_nids; i++) { 1902 unsigned int val; 1903 val = snd_hda_codec_get_pin_target(codec, nids[i]); 1904 val |= AC_PINCTL_VREF_50; 1905 snd_hda_set_pin_ctl(codec, nids[i], val); 1906 } 1907 spec->gen.keep_vref_in_automute = 1; 1908} 1909 1910/* Set VREF on speaker pins on imac91 */ 1911static void alc889_fixup_imac91_vref(struct hda_codec *codec, 1912 const struct hda_fixup *fix, int action) 1913{ 1914 static hda_nid_t nids[2] = { 0x18, 0x1a }; 1915 1916 if (action == HDA_FIXUP_ACT_INIT) 1917 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids)); 1918} 1919 1920/* Set VREF on speaker pins on mba11 */ 1921static void alc889_fixup_mba11_vref(struct hda_codec *codec, 1922 const struct hda_fixup *fix, int action) 1923{ 1924 static hda_nid_t nids[1] = { 0x18 }; 1925 1926 if (action == HDA_FIXUP_ACT_INIT) 1927 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids)); 1928} 1929 1930/* Set VREF on speaker pins on mba21 */ 1931static void alc889_fixup_mba21_vref(struct hda_codec *codec, 1932 const struct hda_fixup *fix, int action) 1933{ 1934 static hda_nid_t nids[2] = { 0x18, 0x19 }; 1935 1936 if (action == HDA_FIXUP_ACT_INIT) 1937 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids)); 1938} 1939 1940/* Don't take HP output as primary 1941 * Strangely, the speaker output doesn't work on Vaio Z and some Vaio 1942 * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05 1943 */ 1944static void alc882_fixup_no_primary_hp(struct hda_codec *codec, 1945 const struct hda_fixup *fix, int action) 1946{ 1947 struct alc_spec *spec = codec->spec; 1948 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 1949 spec->gen.no_primary_hp = 1; 1950 spec->gen.no_multi_io = 1; 1951 } 1952} 1953 1954static void alc_fixup_bass_chmap(struct hda_codec *codec, 1955 const struct hda_fixup *fix, int action); 1956 1957static const struct hda_fixup alc882_fixups[] = { 1958 [ALC882_FIXUP_ABIT_AW9D_MAX] = { 1959 .type = HDA_FIXUP_PINS, 1960 .v.pins = (const struct hda_pintbl[]) { 1961 { 0x15, 0x01080104 }, /* side */ 1962 { 0x16, 0x01011012 }, /* rear */ 1963 { 0x17, 0x01016011 }, /* clfe */ 1964 { } 1965 } 1966 }, 1967 [ALC882_FIXUP_LENOVO_Y530] = { 1968 .type = HDA_FIXUP_PINS, 1969 .v.pins = (const struct hda_pintbl[]) { 1970 { 0x15, 0x99130112 }, /* rear int speakers */ 1971 { 0x16, 0x99130111 }, /* subwoofer */ 1972 { } 1973 } 1974 }, 1975 [ALC882_FIXUP_PB_M5210] = { 1976 .type = HDA_FIXUP_PINCTLS, 1977 .v.pins = (const struct hda_pintbl[]) { 1978 { 0x19, PIN_VREF50 }, 1979 {} 1980 } 1981 }, 1982 [ALC882_FIXUP_ACER_ASPIRE_7736] = { 1983 .type = HDA_FIXUP_FUNC, 1984 .v.func = alc_fixup_sku_ignore, 1985 }, 1986 [ALC882_FIXUP_ASUS_W90V] = { 1987 .type = HDA_FIXUP_PINS, 1988 .v.pins = (const struct hda_pintbl[]) { 1989 { 0x16, 0x99130110 }, /* fix sequence for CLFE */ 1990 { } 1991 } 1992 }, 1993 [ALC889_FIXUP_CD] = { 1994 .type = HDA_FIXUP_PINS, 1995 .v.pins = (const struct hda_pintbl[]) { 1996 { 0x1c, 0x993301f0 }, /* CD */ 1997 { } 1998 } 1999 }, 2000 [ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = { 2001 .type = HDA_FIXUP_PINS, 2002 .v.pins = (const struct hda_pintbl[]) { 2003 { 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */ 2004 { } 2005 }, 2006 .chained = true, 2007 .chain_id = ALC889_FIXUP_CD, 2008 }, 2009 [ALC889_FIXUP_VAIO_TT] = { 2010 .type = HDA_FIXUP_PINS, 2011 .v.pins = (const struct hda_pintbl[]) { 2012 { 0x17, 0x90170111 }, /* hidden surround speaker */ 2013 { } 2014 } 2015 }, 2016 [ALC888_FIXUP_EEE1601] = { 2017 .type = HDA_FIXUP_VERBS, 2018 .v.verbs = (const struct hda_verb[]) { 2019 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b }, 2020 { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 }, 2021 { } 2022 } 2023 }, 2024 [ALC882_FIXUP_EAPD] = { 2025 .type = HDA_FIXUP_VERBS, 2026 .v.verbs = (const struct hda_verb[]) { 2027 /* change to EAPD mode */ 2028 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, 2029 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 }, 2030 { } 2031 } 2032 }, 2033 [ALC883_FIXUP_EAPD] = { 2034 .type = HDA_FIXUP_VERBS, 2035 .v.verbs = (const struct hda_verb[]) { 2036 /* change to EAPD mode */ 2037 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, 2038 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, 2039 { } 2040 } 2041 }, 2042 [ALC883_FIXUP_ACER_EAPD] = { 2043 .type = HDA_FIXUP_VERBS, 2044 .v.verbs = (const struct hda_verb[]) { 2045 /* eanable EAPD on Acer laptops */ 2046 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, 2047 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, 2048 { } 2049 } 2050 }, 2051 [ALC882_FIXUP_GPIO1] = { 2052 .type = HDA_FIXUP_VERBS, 2053 .v.verbs = alc_gpio1_init_verbs, 2054 }, 2055 [ALC882_FIXUP_GPIO2] = { 2056 .type = HDA_FIXUP_VERBS, 2057 .v.verbs = alc_gpio2_init_verbs, 2058 }, 2059 [ALC882_FIXUP_GPIO3] = { 2060 .type = HDA_FIXUP_VERBS, 2061 .v.verbs = alc_gpio3_init_verbs, 2062 }, 2063 [ALC882_FIXUP_ASUS_W2JC] = { 2064 .type = HDA_FIXUP_VERBS, 2065 .v.verbs = alc_gpio1_init_verbs, 2066 .chained = true, 2067 .chain_id = ALC882_FIXUP_EAPD, 2068 }, 2069 [ALC889_FIXUP_COEF] = { 2070 .type = HDA_FIXUP_FUNC, 2071 .v.func = alc889_fixup_coef, 2072 }, 2073 [ALC882_FIXUP_ACER_ASPIRE_4930G] = { 2074 .type = HDA_FIXUP_PINS, 2075 .v.pins = (const struct hda_pintbl[]) { 2076 { 0x16, 0x99130111 }, /* CLFE speaker */ 2077 { 0x17, 0x99130112 }, /* surround speaker */ 2078 { } 2079 }, 2080 .chained = true, 2081 .chain_id = ALC882_FIXUP_GPIO1, 2082 }, 2083 [ALC882_FIXUP_ACER_ASPIRE_8930G] = { 2084 .type = HDA_FIXUP_PINS, 2085 .v.pins = (const struct hda_pintbl[]) { 2086 { 0x16, 0x99130111 }, /* CLFE speaker */ 2087 { 0x1b, 0x99130112 }, /* surround speaker */ 2088 { } 2089 }, 2090 .chained = true, 2091 .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS, 2092 }, 2093 [ALC882_FIXUP_ASPIRE_8930G_VERBS] = { 2094 /* additional init verbs for Acer Aspire 8930G */ 2095 .type = HDA_FIXUP_VERBS, 2096 .v.verbs = (const struct hda_verb[]) { 2097 /* Enable all DACs */ 2098 /* DAC DISABLE/MUTE 1? */ 2099 /* setting bits 1-5 disables DAC nids 0x02-0x06 2100 * apparently. Init=0x38 */ 2101 { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 }, 2102 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, 2103 /* DAC DISABLE/MUTE 2? */ 2104 /* some bit here disables the other DACs. 2105 * Init=0x4900 */ 2106 { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 }, 2107 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, 2108 /* DMIC fix 2109 * This laptop has a stereo digital microphone. 2110 * The mics are only 1cm apart which makes the stereo 2111 * useless. However, either the mic or the ALC889 2112 * makes the signal become a difference/sum signal 2113 * instead of standard stereo, which is annoying. 2114 * So instead we flip this bit which makes the 2115 * codec replicate the sum signal to both channels, 2116 * turning it into a normal mono mic. 2117 */ 2118 /* DMIC_CONTROL? Init value = 0x0001 */ 2119 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b }, 2120 { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 }, 2121 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, 2122 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, 2123 { } 2124 }, 2125 .chained = true, 2126 .chain_id = ALC882_FIXUP_GPIO1, 2127 }, 2128 [ALC885_FIXUP_MACPRO_GPIO] = { 2129 .type = HDA_FIXUP_FUNC, 2130 .v.func = alc885_fixup_macpro_gpio, 2131 }, 2132 [ALC889_FIXUP_DAC_ROUTE] = { 2133 .type = HDA_FIXUP_FUNC, 2134 .v.func = alc889_fixup_dac_route, 2135 }, 2136 [ALC889_FIXUP_MBP_VREF] = { 2137 .type = HDA_FIXUP_FUNC, 2138 .v.func = alc889_fixup_mbp_vref, 2139 .chained = true, 2140 .chain_id = ALC882_FIXUP_GPIO1, 2141 }, 2142 [ALC889_FIXUP_IMAC91_VREF] = { 2143 .type = HDA_FIXUP_FUNC, 2144 .v.func = alc889_fixup_imac91_vref, 2145 .chained = true, 2146 .chain_id = ALC882_FIXUP_GPIO1, 2147 }, 2148 [ALC889_FIXUP_MBA11_VREF] = { 2149 .type = HDA_FIXUP_FUNC, 2150 .v.func = alc889_fixup_mba11_vref, 2151 .chained = true, 2152 .chain_id = ALC889_FIXUP_MBP_VREF, 2153 }, 2154 [ALC889_FIXUP_MBA21_VREF] = { 2155 .type = HDA_FIXUP_FUNC, 2156 .v.func = alc889_fixup_mba21_vref, 2157 .chained = true, 2158 .chain_id = ALC889_FIXUP_MBP_VREF, 2159 }, 2160 [ALC889_FIXUP_MP11_VREF] = { 2161 .type = HDA_FIXUP_FUNC, 2162 .v.func = alc889_fixup_mba11_vref, 2163 .chained = true, 2164 .chain_id = ALC885_FIXUP_MACPRO_GPIO, 2165 }, 2166 [ALC889_FIXUP_MP41_VREF] = { 2167 .type = HDA_FIXUP_FUNC, 2168 .v.func = alc889_fixup_mbp_vref, 2169 .chained = true, 2170 .chain_id = ALC885_FIXUP_MACPRO_GPIO, 2171 }, 2172 [ALC882_FIXUP_INV_DMIC] = { 2173 .type = HDA_FIXUP_FUNC, 2174 .v.func = alc_fixup_inv_dmic, 2175 }, 2176 [ALC882_FIXUP_NO_PRIMARY_HP] = { 2177 .type = HDA_FIXUP_FUNC, 2178 .v.func = alc882_fixup_no_primary_hp, 2179 }, 2180 [ALC887_FIXUP_ASUS_BASS] = { 2181 .type = HDA_FIXUP_PINS, 2182 .v.pins = (const struct hda_pintbl[]) { 2183 {0x16, 0x99130130}, /* bass speaker */ 2184 {} 2185 }, 2186 .chained = true, 2187 .chain_id = ALC887_FIXUP_BASS_CHMAP, 2188 }, 2189 [ALC887_FIXUP_BASS_CHMAP] = { 2190 .type = HDA_FIXUP_FUNC, 2191 .v.func = alc_fixup_bass_chmap, 2192 }, 2193}; 2194 2195static const struct snd_pci_quirk alc882_fixup_tbl[] = { 2196 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD), 2197 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD), 2198 SND_PCI_QUIRK(0x1025, 0x0107, "Acer Aspire", ALC883_FIXUP_ACER_EAPD), 2199 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD), 2200 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD), 2201 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD), 2202 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD), 2203 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G", 2204 ALC882_FIXUP_ACER_ASPIRE_4930G), 2205 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G", 2206 ALC882_FIXUP_ACER_ASPIRE_4930G), 2207 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G", 2208 ALC882_FIXUP_ACER_ASPIRE_8930G), 2209 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G", 2210 ALC882_FIXUP_ACER_ASPIRE_8930G), 2211 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", 2212 ALC882_FIXUP_ACER_ASPIRE_4930G), 2213 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", 2214 ALC882_FIXUP_ACER_ASPIRE_4930G), 2215 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", 2216 ALC882_FIXUP_ACER_ASPIRE_4930G), 2217 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210), 2218 SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G", 2219 ALC882_FIXUP_ACER_ASPIRE_4930G), 2220 SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE), 2221 SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G), 2222 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736), 2223 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD), 2224 SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V), 2225 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC), 2226 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601), 2227 SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS), 2228 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT), 2229 SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP), 2230 SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP), 2231 SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP), 2232 2233 /* All Apple entries are in codec SSIDs */ 2234 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF), 2235 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF), 2236 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF), 2237 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF), 2238 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO), 2239 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO), 2240 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF), 2241 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF), 2242 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD), 2243 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF), 2244 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF), 2245 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF), 2246 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF), 2247 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO), 2248 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF), 2249 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF), 2250 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF), 2251 SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 4,1/5,1", ALC889_FIXUP_MP41_VREF), 2252 SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF), 2253 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF), 2254 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF), 2255 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_MBA11_VREF), 2256 2257 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD), 2258 SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD), 2259 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), 2260 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE), 2261 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), 2262 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), 2263 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), 2264 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530), 2265 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF), 2266 {} 2267}; 2268 2269static const struct hda_model_fixup alc882_fixup_models[] = { 2270 {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"}, 2271 {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"}, 2272 {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"}, 2273 {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"}, 2274 {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"}, 2275 {} 2276}; 2277 2278/* 2279 * BIOS auto configuration 2280 */ 2281/* almost identical with ALC880 parser... */ 2282static int alc882_parse_auto_config(struct hda_codec *codec) 2283{ 2284 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 }; 2285 static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 }; 2286 return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids); 2287} 2288 2289/* 2290 */ 2291static int patch_alc882(struct hda_codec *codec) 2292{ 2293 struct alc_spec *spec; 2294 int err; 2295 2296 err = alc_alloc_spec(codec, 0x0b); 2297 if (err < 0) 2298 return err; 2299 2300 spec = codec->spec; 2301 2302 switch (codec->core.vendor_id) { 2303 case 0x10ec0882: 2304 case 0x10ec0885: 2305 case 0x10ec0900: 2306 break; 2307 default: 2308 /* ALC883 and variants */ 2309 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 2310 break; 2311 } 2312 2313 snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl, 2314 alc882_fixups); 2315 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 2316 2317 alc_auto_parse_customize_define(codec); 2318 2319 if (has_cdefine_beep(codec)) 2320 spec->gen.beep_nid = 0x01; 2321 2322 /* automatic parse from the BIOS config */ 2323 err = alc882_parse_auto_config(codec); 2324 if (err < 0) 2325 goto error; 2326 2327 if (!spec->gen.no_analog && spec->gen.beep_nid) 2328 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 2329 2330 codec->patch_ops = alc_patch_ops; 2331 2332 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 2333 2334 return 0; 2335 2336 error: 2337 alc_free(codec); 2338 return err; 2339} 2340 2341 2342/* 2343 * ALC262 support 2344 */ 2345static int alc262_parse_auto_config(struct hda_codec *codec) 2346{ 2347 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 }; 2348 static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 }; 2349 return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids); 2350} 2351 2352/* 2353 * Pin config fixes 2354 */ 2355enum { 2356 ALC262_FIXUP_FSC_H270, 2357 ALC262_FIXUP_FSC_S7110, 2358 ALC262_FIXUP_HP_Z200, 2359 ALC262_FIXUP_TYAN, 2360 ALC262_FIXUP_LENOVO_3000, 2361 ALC262_FIXUP_BENQ, 2362 ALC262_FIXUP_BENQ_T31, 2363 ALC262_FIXUP_INV_DMIC, 2364 ALC262_FIXUP_INTEL_BAYLEYBAY, 2365}; 2366 2367static const struct hda_fixup alc262_fixups[] = { 2368 [ALC262_FIXUP_FSC_H270] = { 2369 .type = HDA_FIXUP_PINS, 2370 .v.pins = (const struct hda_pintbl[]) { 2371 { 0x14, 0x99130110 }, /* speaker */ 2372 { 0x15, 0x0221142f }, /* front HP */ 2373 { 0x1b, 0x0121141f }, /* rear HP */ 2374 { } 2375 } 2376 }, 2377 [ALC262_FIXUP_FSC_S7110] = { 2378 .type = HDA_FIXUP_PINS, 2379 .v.pins = (const struct hda_pintbl[]) { 2380 { 0x15, 0x90170110 }, /* speaker */ 2381 { } 2382 }, 2383 .chained = true, 2384 .chain_id = ALC262_FIXUP_BENQ, 2385 }, 2386 [ALC262_FIXUP_HP_Z200] = { 2387 .type = HDA_FIXUP_PINS, 2388 .v.pins = (const struct hda_pintbl[]) { 2389 { 0x16, 0x99130120 }, /* internal speaker */ 2390 { } 2391 } 2392 }, 2393 [ALC262_FIXUP_TYAN] = { 2394 .type = HDA_FIXUP_PINS, 2395 .v.pins = (const struct hda_pintbl[]) { 2396 { 0x14, 0x1993e1f0 }, /* int AUX */ 2397 { } 2398 } 2399 }, 2400 [ALC262_FIXUP_LENOVO_3000] = { 2401 .type = HDA_FIXUP_PINCTLS, 2402 .v.pins = (const struct hda_pintbl[]) { 2403 { 0x19, PIN_VREF50 }, 2404 {} 2405 }, 2406 .chained = true, 2407 .chain_id = ALC262_FIXUP_BENQ, 2408 }, 2409 [ALC262_FIXUP_BENQ] = { 2410 .type = HDA_FIXUP_VERBS, 2411 .v.verbs = (const struct hda_verb[]) { 2412 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, 2413 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, 2414 {} 2415 } 2416 }, 2417 [ALC262_FIXUP_BENQ_T31] = { 2418 .type = HDA_FIXUP_VERBS, 2419 .v.verbs = (const struct hda_verb[]) { 2420 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, 2421 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, 2422 {} 2423 } 2424 }, 2425 [ALC262_FIXUP_INV_DMIC] = { 2426 .type = HDA_FIXUP_FUNC, 2427 .v.func = alc_fixup_inv_dmic, 2428 }, 2429 [ALC262_FIXUP_INTEL_BAYLEYBAY] = { 2430 .type = HDA_FIXUP_FUNC, 2431 .v.func = alc_fixup_no_depop_delay, 2432 }, 2433}; 2434 2435static const struct snd_pci_quirk alc262_fixup_tbl[] = { 2436 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200), 2437 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110), 2438 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ), 2439 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN), 2440 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270), 2441 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000), 2442 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ), 2443 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31), 2444 SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY), 2445 {} 2446}; 2447 2448static const struct hda_model_fixup alc262_fixup_models[] = { 2449 {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"}, 2450 {} 2451}; 2452 2453/* 2454 */ 2455static int patch_alc262(struct hda_codec *codec) 2456{ 2457 struct alc_spec *spec; 2458 int err; 2459 2460 err = alc_alloc_spec(codec, 0x0b); 2461 if (err < 0) 2462 return err; 2463 2464 spec = codec->spec; 2465 spec->gen.shared_mic_vref_pin = 0x18; 2466 2467#if 0 2468 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is 2469 * under-run 2470 */ 2471 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x80); 2472#endif 2473 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 2474 2475 snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl, 2476 alc262_fixups); 2477 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 2478 2479 alc_auto_parse_customize_define(codec); 2480 2481 if (has_cdefine_beep(codec)) 2482 spec->gen.beep_nid = 0x01; 2483 2484 /* automatic parse from the BIOS config */ 2485 err = alc262_parse_auto_config(codec); 2486 if (err < 0) 2487 goto error; 2488 2489 if (!spec->gen.no_analog && spec->gen.beep_nid) 2490 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 2491 2492 codec->patch_ops = alc_patch_ops; 2493 spec->shutup = alc_eapd_shutup; 2494 2495 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 2496 2497 return 0; 2498 2499 error: 2500 alc_free(codec); 2501 return err; 2502} 2503 2504/* 2505 * ALC268 2506 */ 2507/* bind Beep switches of both NID 0x0f and 0x10 */ 2508static const struct hda_bind_ctls alc268_bind_beep_sw = { 2509 .ops = &snd_hda_bind_sw, 2510 .values = { 2511 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT), 2512 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT), 2513 0 2514 }, 2515}; 2516 2517static const struct snd_kcontrol_new alc268_beep_mixer[] = { 2518 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT), 2519 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw), 2520 { } 2521}; 2522 2523/* set PCBEEP vol = 0, mute connections */ 2524static const struct hda_verb alc268_beep_init_verbs[] = { 2525 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2526 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2527 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2528 { } 2529}; 2530 2531enum { 2532 ALC268_FIXUP_INV_DMIC, 2533 ALC268_FIXUP_HP_EAPD, 2534 ALC268_FIXUP_SPDIF, 2535}; 2536 2537static const struct hda_fixup alc268_fixups[] = { 2538 [ALC268_FIXUP_INV_DMIC] = { 2539 .type = HDA_FIXUP_FUNC, 2540 .v.func = alc_fixup_inv_dmic, 2541 }, 2542 [ALC268_FIXUP_HP_EAPD] = { 2543 .type = HDA_FIXUP_VERBS, 2544 .v.verbs = (const struct hda_verb[]) { 2545 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0}, 2546 {} 2547 } 2548 }, 2549 [ALC268_FIXUP_SPDIF] = { 2550 .type = HDA_FIXUP_PINS, 2551 .v.pins = (const struct hda_pintbl[]) { 2552 { 0x1e, 0x014b1180 }, /* enable SPDIF out */ 2553 {} 2554 } 2555 }, 2556}; 2557 2558static const struct hda_model_fixup alc268_fixup_models[] = { 2559 {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"}, 2560 {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"}, 2561 {} 2562}; 2563 2564static const struct snd_pci_quirk alc268_fixup_tbl[] = { 2565 SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF), 2566 SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC), 2567 /* below is codec SSID since multiple Toshiba laptops have the 2568 * same PCI SSID 1179:ff00 2569 */ 2570 SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD), 2571 {} 2572}; 2573 2574/* 2575 * BIOS auto configuration 2576 */ 2577static int alc268_parse_auto_config(struct hda_codec *codec) 2578{ 2579 static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 }; 2580 return alc_parse_auto_config(codec, NULL, alc268_ssids); 2581} 2582 2583/* 2584 */ 2585static int patch_alc268(struct hda_codec *codec) 2586{ 2587 struct alc_spec *spec; 2588 int err; 2589 2590 /* ALC268 has no aa-loopback mixer */ 2591 err = alc_alloc_spec(codec, 0); 2592 if (err < 0) 2593 return err; 2594 2595 spec = codec->spec; 2596 spec->gen.beep_nid = 0x01; 2597 2598 snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups); 2599 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 2600 2601 /* automatic parse from the BIOS config */ 2602 err = alc268_parse_auto_config(codec); 2603 if (err < 0) 2604 goto error; 2605 2606 if (err > 0 && !spec->gen.no_analog && 2607 spec->gen.autocfg.speaker_pins[0] != 0x1d) { 2608 add_mixer(spec, alc268_beep_mixer); 2609 snd_hda_add_verbs(codec, alc268_beep_init_verbs); 2610 if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) 2611 /* override the amp caps for beep generator */ 2612 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT, 2613 (0x0c << AC_AMPCAP_OFFSET_SHIFT) | 2614 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) | 2615 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) | 2616 (0 << AC_AMPCAP_MUTE_SHIFT)); 2617 } 2618 2619 codec->patch_ops = alc_patch_ops; 2620 spec->shutup = alc_eapd_shutup; 2621 2622 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 2623 2624 return 0; 2625 2626 error: 2627 alc_free(codec); 2628 return err; 2629} 2630 2631/* 2632 * ALC269 2633 */ 2634 2635static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = { 2636 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ 2637}; 2638 2639static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = { 2640 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ 2641}; 2642 2643/* different alc269-variants */ 2644enum { 2645 ALC269_TYPE_ALC269VA, 2646 ALC269_TYPE_ALC269VB, 2647 ALC269_TYPE_ALC269VC, 2648 ALC269_TYPE_ALC269VD, 2649 ALC269_TYPE_ALC280, 2650 ALC269_TYPE_ALC282, 2651 ALC269_TYPE_ALC283, 2652 ALC269_TYPE_ALC284, 2653 ALC269_TYPE_ALC285, 2654 ALC269_TYPE_ALC286, 2655 ALC269_TYPE_ALC298, 2656 ALC269_TYPE_ALC255, 2657 ALC269_TYPE_ALC256, 2658}; 2659 2660/* 2661 * BIOS auto configuration 2662 */ 2663static int alc269_parse_auto_config(struct hda_codec *codec) 2664{ 2665 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 }; 2666 static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 }; 2667 static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 }; 2668 struct alc_spec *spec = codec->spec; 2669 const hda_nid_t *ssids; 2670 2671 switch (spec->codec_variant) { 2672 case ALC269_TYPE_ALC269VA: 2673 case ALC269_TYPE_ALC269VC: 2674 case ALC269_TYPE_ALC280: 2675 case ALC269_TYPE_ALC284: 2676 case ALC269_TYPE_ALC285: 2677 ssids = alc269va_ssids; 2678 break; 2679 case ALC269_TYPE_ALC269VB: 2680 case ALC269_TYPE_ALC269VD: 2681 case ALC269_TYPE_ALC282: 2682 case ALC269_TYPE_ALC283: 2683 case ALC269_TYPE_ALC286: 2684 case ALC269_TYPE_ALC298: 2685 case ALC269_TYPE_ALC255: 2686 case ALC269_TYPE_ALC256: 2687 ssids = alc269_ssids; 2688 break; 2689 default: 2690 ssids = alc269_ssids; 2691 break; 2692 } 2693 2694 return alc_parse_auto_config(codec, alc269_ignore, ssids); 2695} 2696 2697static int find_ext_mic_pin(struct hda_codec *codec); 2698 2699static void alc286_shutup(struct hda_codec *codec) 2700{ 2701 int i; 2702 int mic_pin = find_ext_mic_pin(codec); 2703 /* don't shut up pins when unloading the driver; otherwise it breaks 2704 * the default pin setup at the next load of the driver 2705 */ 2706 if (codec->bus->shutdown) 2707 return; 2708 for (i = 0; i < codec->init_pins.used; i++) { 2709 struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i); 2710 /* use read here for syncing after issuing each verb */ 2711 if (pin->nid != mic_pin) 2712 snd_hda_codec_read(codec, pin->nid, 0, 2713 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 2714 } 2715 codec->pins_shutup = 1; 2716} 2717 2718static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up) 2719{ 2720 alc_update_coef_idx(codec, 0x04, 1 << 11, power_up ? (1 << 11) : 0); 2721} 2722 2723static void alc269_shutup(struct hda_codec *codec) 2724{ 2725 struct alc_spec *spec = codec->spec; 2726 2727 if (spec->codec_variant == ALC269_TYPE_ALC269VB) 2728 alc269vb_toggle_power_output(codec, 0); 2729 if (spec->codec_variant == ALC269_TYPE_ALC269VB && 2730 (alc_get_coef0(codec) & 0x00ff) == 0x018) { 2731 msleep(150); 2732 } 2733 snd_hda_shutup_pins(codec); 2734} 2735 2736static struct coef_fw alc282_coefs[] = { 2737 WRITE_COEF(0x03, 0x0002), /* Power Down Control */ 2738 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */ 2739 WRITE_COEF(0x07, 0x0200), /* DMIC control */ 2740 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */ 2741 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */ 2742 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */ 2743 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */ 2744 WRITE_COEF(0x0e, 0x6e00), /* LDO1/2/3, DAC/ADC */ 2745 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */ 2746 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */ 2747 WRITE_COEF(0x6f, 0x0), /* Class D test 4 */ 2748 UPDATE_COEF(0x0c, 0xfe00, 0), /* IO power down directly */ 2749 WRITE_COEF(0x34, 0xa0c0), /* ANC */ 2750 UPDATE_COEF(0x16, 0x0008, 0), /* AGC MUX */ 2751 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */ 2752 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */ 2753 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */ 2754 WRITE_COEF(0x63, 0x2902), /* PLL */ 2755 WRITE_COEF(0x68, 0xa080), /* capless control 2 */ 2756 WRITE_COEF(0x69, 0x3400), /* capless control 3 */ 2757 WRITE_COEF(0x6a, 0x2f3e), /* capless control 4 */ 2758 WRITE_COEF(0x6b, 0x0), /* capless control 5 */ 2759 UPDATE_COEF(0x6d, 0x0fff, 0x0900), /* class D test 2 */ 2760 WRITE_COEF(0x6e, 0x110a), /* class D test 3 */ 2761 UPDATE_COEF(0x70, 0x00f8, 0x00d8), /* class D test 5 */ 2762 WRITE_COEF(0x71, 0x0014), /* class D test 6 */ 2763 WRITE_COEF(0x72, 0xc2ba), /* classD OCP */ 2764 UPDATE_COEF(0x77, 0x0f80, 0), /* classD pure DC test */ 2765 WRITE_COEF(0x6c, 0xfc06), /* Class D amp control */ 2766 {} 2767}; 2768 2769static void alc282_restore_default_value(struct hda_codec *codec) 2770{ 2771 alc_process_coef_fw(codec, alc282_coefs); 2772} 2773 2774static void alc282_init(struct hda_codec *codec) 2775{ 2776 struct alc_spec *spec = codec->spec; 2777 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; 2778 bool hp_pin_sense; 2779 int coef78; 2780 2781 alc282_restore_default_value(codec); 2782 2783 if (!hp_pin) 2784 return; 2785 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); 2786 coef78 = alc_read_coef_idx(codec, 0x78); 2787 2788 /* Index 0x78 Direct Drive HP AMP LPM Control 1 */ 2789 /* Headphone capless set to high power mode */ 2790 alc_write_coef_idx(codec, 0x78, 0x9004); 2791 2792 if (hp_pin_sense) 2793 msleep(2); 2794 2795 snd_hda_codec_write(codec, hp_pin, 0, 2796 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); 2797 2798 if (hp_pin_sense) 2799 msleep(85); 2800 2801 snd_hda_codec_write(codec, hp_pin, 0, 2802 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 2803 2804 if (hp_pin_sense) 2805 msleep(100); 2806 2807 /* Headphone capless set to normal mode */ 2808 alc_write_coef_idx(codec, 0x78, coef78); 2809} 2810 2811static void alc282_shutup(struct hda_codec *codec) 2812{ 2813 struct alc_spec *spec = codec->spec; 2814 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; 2815 bool hp_pin_sense; 2816 int coef78; 2817 2818 if (!hp_pin) { 2819 alc269_shutup(codec); 2820 return; 2821 } 2822 2823 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); 2824 coef78 = alc_read_coef_idx(codec, 0x78); 2825 alc_write_coef_idx(codec, 0x78, 0x9004); 2826 2827 if (hp_pin_sense) 2828 msleep(2); 2829 2830 snd_hda_codec_write(codec, hp_pin, 0, 2831 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); 2832 2833 if (hp_pin_sense) 2834 msleep(85); 2835 2836 snd_hda_codec_write(codec, hp_pin, 0, 2837 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); 2838 2839 if (hp_pin_sense) 2840 msleep(100); 2841 2842 alc_auto_setup_eapd(codec, false); 2843 snd_hda_shutup_pins(codec); 2844 alc_write_coef_idx(codec, 0x78, coef78); 2845} 2846 2847static struct coef_fw alc283_coefs[] = { 2848 WRITE_COEF(0x03, 0x0002), /* Power Down Control */ 2849 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */ 2850 WRITE_COEF(0x07, 0x0200), /* DMIC control */ 2851 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */ 2852 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */ 2853 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */ 2854 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */ 2855 WRITE_COEF(0x0e, 0x6fc0), /* LDO1/2/3, DAC/ADC */ 2856 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */ 2857 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */ 2858 WRITE_COEF(0x3a, 0x0), /* Class D test 4 */ 2859 UPDATE_COEF(0x0c, 0xfe00, 0x0), /* IO power down directly */ 2860 WRITE_COEF(0x22, 0xa0c0), /* ANC */ 2861 UPDATE_COEFEX(0x53, 0x01, 0x000f, 0x0008), /* AGC MUX */ 2862 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */ 2863 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */ 2864 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */ 2865 WRITE_COEF(0x2e, 0x2902), /* PLL */ 2866 WRITE_COEF(0x33, 0xa080), /* capless control 2 */ 2867 WRITE_COEF(0x34, 0x3400), /* capless control 3 */ 2868 WRITE_COEF(0x35, 0x2f3e), /* capless control 4 */ 2869 WRITE_COEF(0x36, 0x0), /* capless control 5 */ 2870 UPDATE_COEF(0x38, 0x0fff, 0x0900), /* class D test 2 */ 2871 WRITE_COEF(0x39, 0x110a), /* class D test 3 */ 2872 UPDATE_COEF(0x3b, 0x00f8, 0x00d8), /* class D test 5 */ 2873 WRITE_COEF(0x3c, 0x0014), /* class D test 6 */ 2874 WRITE_COEF(0x3d, 0xc2ba), /* classD OCP */ 2875 UPDATE_COEF(0x42, 0x0f80, 0x0), /* classD pure DC test */ 2876 WRITE_COEF(0x49, 0x0), /* test mode */ 2877 UPDATE_COEF(0x40, 0xf800, 0x9800), /* Class D DC enable */ 2878 UPDATE_COEF(0x42, 0xf000, 0x2000), /* DC offset */ 2879 WRITE_COEF(0x37, 0xfc06), /* Class D amp control */ 2880 UPDATE_COEF(0x1b, 0x8000, 0), /* HP JD control */ 2881 {} 2882}; 2883 2884static void alc283_restore_default_value(struct hda_codec *codec) 2885{ 2886 alc_process_coef_fw(codec, alc283_coefs); 2887} 2888 2889static void alc283_init(struct hda_codec *codec) 2890{ 2891 struct alc_spec *spec = codec->spec; 2892 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; 2893 bool hp_pin_sense; 2894 2895 if (!spec->gen.autocfg.hp_outs) { 2896 if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT) 2897 hp_pin = spec->gen.autocfg.line_out_pins[0]; 2898 } 2899 2900 alc283_restore_default_value(codec); 2901 2902 if (!hp_pin) 2903 return; 2904 2905 msleep(30); 2906 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); 2907 2908 /* Index 0x43 Direct Drive HP AMP LPM Control 1 */ 2909 /* Headphone capless set to high power mode */ 2910 alc_write_coef_idx(codec, 0x43, 0x9004); 2911 2912 snd_hda_codec_write(codec, hp_pin, 0, 2913 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); 2914 2915 if (hp_pin_sense) 2916 msleep(85); 2917 2918 snd_hda_codec_write(codec, hp_pin, 0, 2919 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 2920 2921 if (hp_pin_sense) 2922 msleep(85); 2923 /* Index 0x46 Combo jack auto switch control 2 */ 2924 /* 3k pull low control for Headset jack. */ 2925 alc_update_coef_idx(codec, 0x46, 3 << 12, 0); 2926 /* Headphone capless set to normal mode */ 2927 alc_write_coef_idx(codec, 0x43, 0x9614); 2928} 2929 2930static void alc283_shutup(struct hda_codec *codec) 2931{ 2932 struct alc_spec *spec = codec->spec; 2933 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; 2934 bool hp_pin_sense; 2935 2936 if (!spec->gen.autocfg.hp_outs) { 2937 if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT) 2938 hp_pin = spec->gen.autocfg.line_out_pins[0]; 2939 } 2940 2941 if (!hp_pin) { 2942 alc269_shutup(codec); 2943 return; 2944 } 2945 2946 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); 2947 2948 alc_write_coef_idx(codec, 0x43, 0x9004); 2949 2950 /*depop hp during suspend*/ 2951 alc_write_coef_idx(codec, 0x06, 0x2100); 2952 2953 snd_hda_codec_write(codec, hp_pin, 0, 2954 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); 2955 2956 if (hp_pin_sense) 2957 msleep(100); 2958 2959 snd_hda_codec_write(codec, hp_pin, 0, 2960 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); 2961 2962 alc_update_coef_idx(codec, 0x46, 0, 3 << 12); 2963 2964 if (hp_pin_sense) 2965 msleep(100); 2966 alc_auto_setup_eapd(codec, false); 2967 snd_hda_shutup_pins(codec); 2968 alc_write_coef_idx(codec, 0x43, 0x9614); 2969} 2970 2971static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg, 2972 unsigned int val) 2973{ 2974 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1); 2975 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */ 2976 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */ 2977} 2978 2979static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg) 2980{ 2981 unsigned int val; 2982 2983 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1); 2984 val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0) 2985 & 0xffff; 2986 val |= snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0) 2987 << 16; 2988 return val; 2989} 2990 2991static void alc5505_dsp_halt(struct hda_codec *codec) 2992{ 2993 unsigned int val; 2994 2995 alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */ 2996 alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */ 2997 alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */ 2998 alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */ 2999 alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */ 3000 alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */ 3001 alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */ 3002 val = alc5505_coef_get(codec, 0x6220); 3003 alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */ 3004} 3005 3006static void alc5505_dsp_back_from_halt(struct hda_codec *codec) 3007{ 3008 alc5505_coef_set(codec, 0x61b8, 0x04133302); 3009 alc5505_coef_set(codec, 0x61b0, 0x00005b16); 3010 alc5505_coef_set(codec, 0x61b4, 0x040a2b02); 3011 alc5505_coef_set(codec, 0x6230, 0xf80d4011); 3012 alc5505_coef_set(codec, 0x6220, 0x2002010f); 3013 alc5505_coef_set(codec, 0x880c, 0x00000004); 3014} 3015 3016static void alc5505_dsp_init(struct hda_codec *codec) 3017{ 3018 unsigned int val; 3019 3020 alc5505_dsp_halt(codec); 3021 alc5505_dsp_back_from_halt(codec); 3022 alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */ 3023 alc5505_coef_set(codec, 0x61b0, 0x5b16); 3024 alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */ 3025 alc5505_coef_set(codec, 0x61b4, 0x04132b02); 3026 alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/ 3027 alc5505_coef_set(codec, 0x61b8, 0x041f3302); 3028 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */ 3029 alc5505_coef_set(codec, 0x61b8, 0x041b3302); 3030 alc5505_coef_set(codec, 0x61b8, 0x04173302); 3031 alc5505_coef_set(codec, 0x61b8, 0x04163302); 3032 alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */ 3033 alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */ 3034 alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */ 3035 3036 val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */ 3037 if (val <= 3) 3038 alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */ 3039 else 3040 alc5505_coef_set(codec, 0x6220, 0x6002018f); 3041 3042 alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/ 3043 alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */ 3044 alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */ 3045 alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */ 3046 alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */ 3047 alc5505_coef_set(codec, 0x880c, 0x00000003); 3048 alc5505_coef_set(codec, 0x880c, 0x00000010); 3049 3050#ifdef HALT_REALTEK_ALC5505 3051 alc5505_dsp_halt(codec); 3052#endif 3053} 3054 3055#ifdef HALT_REALTEK_ALC5505 3056#define alc5505_dsp_suspend(codec) /* NOP */ 3057#define alc5505_dsp_resume(codec) /* NOP */ 3058#else 3059#define alc5505_dsp_suspend(codec) alc5505_dsp_halt(codec) 3060#define alc5505_dsp_resume(codec) alc5505_dsp_back_from_halt(codec) 3061#endif 3062 3063#ifdef CONFIG_PM 3064static int alc269_suspend(struct hda_codec *codec) 3065{ 3066 struct alc_spec *spec = codec->spec; 3067 3068 if (spec->has_alc5505_dsp) 3069 alc5505_dsp_suspend(codec); 3070 return alc_suspend(codec); 3071} 3072 3073static int alc269_resume(struct hda_codec *codec) 3074{ 3075 struct alc_spec *spec = codec->spec; 3076 3077 if (spec->codec_variant == ALC269_TYPE_ALC269VB) 3078 alc269vb_toggle_power_output(codec, 0); 3079 if (spec->codec_variant == ALC269_TYPE_ALC269VB && 3080 (alc_get_coef0(codec) & 0x00ff) == 0x018) { 3081 msleep(150); 3082 } 3083 3084 codec->patch_ops.init(codec); 3085 3086 if (spec->codec_variant == ALC269_TYPE_ALC269VB) 3087 alc269vb_toggle_power_output(codec, 1); 3088 if (spec->codec_variant == ALC269_TYPE_ALC269VB && 3089 (alc_get_coef0(codec) & 0x00ff) == 0x017) { 3090 msleep(200); 3091 } 3092 3093 regcache_sync(codec->core.regmap); 3094 hda_call_check_power_status(codec, 0x01); 3095 3096 /* on some machine, the BIOS will clear the codec gpio data when enter 3097 * suspend, and won't restore the data after resume, so we restore it 3098 * in the driver. 3099 */ 3100 if (spec->gpio_led) 3101 snd_hda_codec_write(codec, codec->core.afg, 0, AC_VERB_SET_GPIO_DATA, 3102 spec->gpio_led); 3103 3104 if (spec->has_alc5505_dsp) 3105 alc5505_dsp_resume(codec); 3106 3107 return 0; 3108} 3109#endif /* CONFIG_PM */ 3110 3111static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec, 3112 const struct hda_fixup *fix, int action) 3113{ 3114 struct alc_spec *spec = codec->spec; 3115 3116 if (action == HDA_FIXUP_ACT_PRE_PROBE) 3117 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; 3118} 3119 3120static void alc269_fixup_hweq(struct hda_codec *codec, 3121 const struct hda_fixup *fix, int action) 3122{ 3123 if (action == HDA_FIXUP_ACT_INIT) 3124 alc_update_coef_idx(codec, 0x1e, 0, 0x80); 3125} 3126 3127static void alc269_fixup_headset_mic(struct hda_codec *codec, 3128 const struct hda_fixup *fix, int action) 3129{ 3130 struct alc_spec *spec = codec->spec; 3131 3132 if (action == HDA_FIXUP_ACT_PRE_PROBE) 3133 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; 3134} 3135 3136static void alc271_fixup_dmic(struct hda_codec *codec, 3137 const struct hda_fixup *fix, int action) 3138{ 3139 static const struct hda_verb verbs[] = { 3140 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d}, 3141 {0x20, AC_VERB_SET_PROC_COEF, 0x4000}, 3142 {} 3143 }; 3144 unsigned int cfg; 3145 3146 if (strcmp(codec->core.chip_name, "ALC271X") && 3147 strcmp(codec->core.chip_name, "ALC269VB")) 3148 return; 3149 cfg = snd_hda_codec_get_pincfg(codec, 0x12); 3150 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED) 3151 snd_hda_sequence_write(codec, verbs); 3152} 3153 3154static void alc269_fixup_pcm_44k(struct hda_codec *codec, 3155 const struct hda_fixup *fix, int action) 3156{ 3157 struct alc_spec *spec = codec->spec; 3158 3159 if (action != HDA_FIXUP_ACT_PROBE) 3160 return; 3161 3162 /* Due to a hardware problem on Lenovo Ideadpad, we need to 3163 * fix the sample rate of analog I/O to 44.1kHz 3164 */ 3165 spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback; 3166 spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture; 3167} 3168 3169static void alc269_fixup_stereo_dmic(struct hda_codec *codec, 3170 const struct hda_fixup *fix, int action) 3171{ 3172 /* The digital-mic unit sends PDM (differential signal) instead of 3173 * the standard PCM, thus you can't record a valid mono stream as is. 3174 * Below is a workaround specific to ALC269 to control the dmic 3175 * signal source as mono. 3176 */ 3177 if (action == HDA_FIXUP_ACT_INIT) 3178 alc_update_coef_idx(codec, 0x07, 0, 0x80); 3179} 3180 3181static void alc269_quanta_automute(struct hda_codec *codec) 3182{ 3183 snd_hda_gen_update_outputs(codec); 3184 3185 alc_write_coef_idx(codec, 0x0c, 0x680); 3186 alc_write_coef_idx(codec, 0x0c, 0x480); 3187} 3188 3189static void alc269_fixup_quanta_mute(struct hda_codec *codec, 3190 const struct hda_fixup *fix, int action) 3191{ 3192 struct alc_spec *spec = codec->spec; 3193 if (action != HDA_FIXUP_ACT_PROBE) 3194 return; 3195 spec->gen.automute_hook = alc269_quanta_automute; 3196} 3197 3198static void alc269_x101_hp_automute_hook(struct hda_codec *codec, 3199 struct hda_jack_callback *jack) 3200{ 3201 struct alc_spec *spec = codec->spec; 3202 int vref; 3203 msleep(200); 3204 snd_hda_gen_hp_automute(codec, jack); 3205 3206 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0; 3207 msleep(100); 3208 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 3209 vref); 3210 msleep(500); 3211 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 3212 vref); 3213} 3214 3215static void alc269_fixup_x101_headset_mic(struct hda_codec *codec, 3216 const struct hda_fixup *fix, int action) 3217{ 3218 struct alc_spec *spec = codec->spec; 3219 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 3220 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; 3221 spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook; 3222 } 3223} 3224 3225 3226/* update mute-LED according to the speaker mute state via mic VREF pin */ 3227static void alc269_fixup_mic_mute_hook(void *private_data, int enabled) 3228{ 3229 struct hda_codec *codec = private_data; 3230 struct alc_spec *spec = codec->spec; 3231 unsigned int pinval; 3232 3233 if (spec->mute_led_polarity) 3234 enabled = !enabled; 3235 pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid); 3236 pinval &= ~AC_PINCTL_VREFEN; 3237 pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80; 3238 if (spec->mute_led_nid) 3239 snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval); 3240} 3241 3242/* Make sure the led works even in runtime suspend */ 3243static unsigned int led_power_filter(struct hda_codec *codec, 3244 hda_nid_t nid, 3245 unsigned int power_state) 3246{ 3247 struct alc_spec *spec = codec->spec; 3248 3249 if (power_state != AC_PWRST_D3 || nid == 0 || 3250 (nid != spec->mute_led_nid && nid != spec->cap_mute_led_nid)) 3251 return power_state; 3252 3253 /* Set pin ctl again, it might have just been set to 0 */ 3254 snd_hda_set_pin_ctl(codec, nid, 3255 snd_hda_codec_get_pin_target(codec, nid)); 3256 3257 return snd_hda_gen_path_power_filter(codec, nid, power_state); 3258} 3259 3260static void alc269_fixup_hp_mute_led(struct hda_codec *codec, 3261 const struct hda_fixup *fix, int action) 3262{ 3263 struct alc_spec *spec = codec->spec; 3264 const struct dmi_device *dev = NULL; 3265 3266 if (action != HDA_FIXUP_ACT_PRE_PROBE) 3267 return; 3268 3269 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) { 3270 int pol, pin; 3271 if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2) 3272 continue; 3273 if (pin < 0x0a || pin >= 0x10) 3274 break; 3275 spec->mute_led_polarity = pol; 3276 spec->mute_led_nid = pin - 0x0a + 0x18; 3277 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; 3278 spec->gen.vmaster_mute_enum = 1; 3279 codec->power_filter = led_power_filter; 3280 codec_dbg(codec, 3281 "Detected mute LED for %x:%d\n", spec->mute_led_nid, 3282 spec->mute_led_polarity); 3283 break; 3284 } 3285} 3286 3287static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec, 3288 const struct hda_fixup *fix, int action) 3289{ 3290 struct alc_spec *spec = codec->spec; 3291 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 3292 spec->mute_led_polarity = 0; 3293 spec->mute_led_nid = 0x18; 3294 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; 3295 spec->gen.vmaster_mute_enum = 1; 3296 codec->power_filter = led_power_filter; 3297 } 3298} 3299 3300static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec, 3301 const struct hda_fixup *fix, int action) 3302{ 3303 struct alc_spec *spec = codec->spec; 3304 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 3305 spec->mute_led_polarity = 0; 3306 spec->mute_led_nid = 0x19; 3307 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; 3308 spec->gen.vmaster_mute_enum = 1; 3309 codec->power_filter = led_power_filter; 3310 } 3311} 3312 3313/* update LED status via GPIO */ 3314static void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask, 3315 bool enabled) 3316{ 3317 struct alc_spec *spec = codec->spec; 3318 unsigned int oldval = spec->gpio_led; 3319 3320 if (spec->mute_led_polarity) 3321 enabled = !enabled; 3322 3323 if (enabled) 3324 spec->gpio_led &= ~mask; 3325 else 3326 spec->gpio_led |= mask; 3327 if (spec->gpio_led != oldval) 3328 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 3329 spec->gpio_led); 3330} 3331 3332/* turn on/off mute LED via GPIO per vmaster hook */ 3333static void alc_fixup_gpio_mute_hook(void *private_data, int enabled) 3334{ 3335 struct hda_codec *codec = private_data; 3336 struct alc_spec *spec = codec->spec; 3337 3338 alc_update_gpio_led(codec, spec->gpio_mute_led_mask, enabled); 3339} 3340 3341/* turn on/off mic-mute LED via GPIO per capture hook */ 3342static void alc_fixup_gpio_mic_mute_hook(struct hda_codec *codec, 3343 struct snd_kcontrol *kcontrol, 3344 struct snd_ctl_elem_value *ucontrol) 3345{ 3346 struct alc_spec *spec = codec->spec; 3347 3348 if (ucontrol) 3349 alc_update_gpio_led(codec, spec->gpio_mic_led_mask, 3350 ucontrol->value.integer.value[0] || 3351 ucontrol->value.integer.value[1]); 3352} 3353 3354static void alc269_fixup_hp_gpio_led(struct hda_codec *codec, 3355 const struct hda_fixup *fix, int action) 3356{ 3357 struct alc_spec *spec = codec->spec; 3358 static const struct hda_verb gpio_init[] = { 3359 { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 }, 3360 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 }, 3361 {} 3362 }; 3363 3364 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 3365 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; 3366 spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook; 3367 spec->gpio_led = 0; 3368 spec->mute_led_polarity = 0; 3369 spec->gpio_mute_led_mask = 0x08; 3370 spec->gpio_mic_led_mask = 0x10; 3371 snd_hda_add_verbs(codec, gpio_init); 3372 } 3373} 3374 3375static void alc286_fixup_hp_gpio_led(struct hda_codec *codec, 3376 const struct hda_fixup *fix, int action) 3377{ 3378 struct alc_spec *spec = codec->spec; 3379 static const struct hda_verb gpio_init[] = { 3380 { 0x01, AC_VERB_SET_GPIO_MASK, 0x22 }, 3381 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x22 }, 3382 {} 3383 }; 3384 3385 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 3386 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; 3387 spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook; 3388 spec->gpio_led = 0; 3389 spec->mute_led_polarity = 0; 3390 spec->gpio_mute_led_mask = 0x02; 3391 spec->gpio_mic_led_mask = 0x20; 3392 snd_hda_add_verbs(codec, gpio_init); 3393 } 3394} 3395 3396/* turn on/off mic-mute LED per capture hook */ 3397static void alc269_fixup_hp_cap_mic_mute_hook(struct hda_codec *codec, 3398 struct snd_kcontrol *kcontrol, 3399 struct snd_ctl_elem_value *ucontrol) 3400{ 3401 struct alc_spec *spec = codec->spec; 3402 unsigned int pinval, enable, disable; 3403 3404 pinval = snd_hda_codec_get_pin_target(codec, spec->cap_mute_led_nid); 3405 pinval &= ~AC_PINCTL_VREFEN; 3406 enable = pinval | AC_PINCTL_VREF_80; 3407 disable = pinval | AC_PINCTL_VREF_HIZ; 3408 3409 if (!ucontrol) 3410 return; 3411 3412 if (ucontrol->value.integer.value[0] || 3413 ucontrol->value.integer.value[1]) 3414 pinval = disable; 3415 else 3416 pinval = enable; 3417 3418 if (spec->cap_mute_led_nid) 3419 snd_hda_set_pin_ctl_cache(codec, spec->cap_mute_led_nid, pinval); 3420} 3421 3422static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec, 3423 const struct hda_fixup *fix, int action) 3424{ 3425 struct alc_spec *spec = codec->spec; 3426 static const struct hda_verb gpio_init[] = { 3427 { 0x01, AC_VERB_SET_GPIO_MASK, 0x08 }, 3428 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x08 }, 3429 {} 3430 }; 3431 3432 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 3433 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; 3434 spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook; 3435 spec->gpio_led = 0; 3436 spec->mute_led_polarity = 0; 3437 spec->gpio_mute_led_mask = 0x08; 3438 spec->cap_mute_led_nid = 0x18; 3439 snd_hda_add_verbs(codec, gpio_init); 3440 codec->power_filter = led_power_filter; 3441 } 3442} 3443 3444static void alc280_fixup_hp_gpio4(struct hda_codec *codec, 3445 const struct hda_fixup *fix, int action) 3446{ 3447 /* Like hp_gpio_mic1_led, but also needs GPIO4 low to enable headphone amp */ 3448 struct alc_spec *spec = codec->spec; 3449 static const struct hda_verb gpio_init[] = { 3450 { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 }, 3451 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 }, 3452 {} 3453 }; 3454 3455 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 3456 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; 3457 spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook; 3458 spec->gpio_led = 0; 3459 spec->mute_led_polarity = 0; 3460 spec->gpio_mute_led_mask = 0x08; 3461 spec->cap_mute_led_nid = 0x18; 3462 snd_hda_add_verbs(codec, gpio_init); 3463 codec->power_filter = led_power_filter; 3464 } 3465} 3466 3467static void gpio2_mic_hotkey_event(struct hda_codec *codec, 3468 struct hda_jack_callback *event) 3469{ 3470 struct alc_spec *spec = codec->spec; 3471 3472 /* GPIO2 just toggles on a keypress/keyrelease cycle. Therefore 3473 send both key on and key off event for every interrupt. */ 3474 input_report_key(spec->kb_dev, KEY_MICMUTE, 1); 3475 input_sync(spec->kb_dev); 3476 input_report_key(spec->kb_dev, KEY_MICMUTE, 0); 3477 input_sync(spec->kb_dev); 3478} 3479 3480static int alc_register_micmute_input_device(struct hda_codec *codec) 3481{ 3482 struct alc_spec *spec = codec->spec; 3483 3484 spec->kb_dev = input_allocate_device(); 3485 if (!spec->kb_dev) { 3486 codec_err(codec, "Out of memory (input_allocate_device)\n"); 3487 return -ENOMEM; 3488 } 3489 spec->kb_dev->name = "Microphone Mute Button"; 3490 spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY); 3491 spec->kb_dev->keybit[BIT_WORD(KEY_MICMUTE)] = BIT_MASK(KEY_MICMUTE); 3492 3493 if (input_register_device(spec->kb_dev)) { 3494 codec_err(codec, "input_register_device failed\n"); 3495 input_free_device(spec->kb_dev); 3496 spec->kb_dev = NULL; 3497 return -ENOMEM; 3498 } 3499 3500 return 0; 3501} 3502 3503static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec, 3504 const struct hda_fixup *fix, int action) 3505{ 3506 /* GPIO1 = set according to SKU external amp 3507 GPIO2 = mic mute hotkey 3508 GPIO3 = mute LED 3509 GPIO4 = mic mute LED */ 3510 static const struct hda_verb gpio_init[] = { 3511 { 0x01, AC_VERB_SET_GPIO_MASK, 0x1e }, 3512 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x1a }, 3513 { 0x01, AC_VERB_SET_GPIO_DATA, 0x02 }, 3514 {} 3515 }; 3516 3517 struct alc_spec *spec = codec->spec; 3518 3519 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 3520 if (alc_register_micmute_input_device(codec) != 0) 3521 return; 3522 3523 snd_hda_add_verbs(codec, gpio_init); 3524 snd_hda_codec_write_cache(codec, codec->core.afg, 0, 3525 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x04); 3526 snd_hda_jack_detect_enable_callback(codec, codec->core.afg, 3527 gpio2_mic_hotkey_event); 3528 3529 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; 3530 spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook; 3531 spec->gpio_led = 0; 3532 spec->mute_led_polarity = 0; 3533 spec->gpio_mute_led_mask = 0x08; 3534 spec->gpio_mic_led_mask = 0x10; 3535 return; 3536 } 3537 3538 if (!spec->kb_dev) 3539 return; 3540 3541 switch (action) { 3542 case HDA_FIXUP_ACT_PROBE: 3543 spec->init_amp = ALC_INIT_DEFAULT; 3544 break; 3545 case HDA_FIXUP_ACT_FREE: 3546 input_unregister_device(spec->kb_dev); 3547 spec->kb_dev = NULL; 3548 } 3549} 3550 3551static void alc233_fixup_lenovo_line2_mic_hotkey(struct hda_codec *codec, 3552 const struct hda_fixup *fix, int action) 3553{ 3554 /* Line2 = mic mute hotkey 3555 GPIO2 = mic mute LED */ 3556 static const struct hda_verb gpio_init[] = { 3557 { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 }, 3558 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 }, 3559 {} 3560 }; 3561 3562 struct alc_spec *spec = codec->spec; 3563 3564 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 3565 if (alc_register_micmute_input_device(codec) != 0) 3566 return; 3567 3568 snd_hda_add_verbs(codec, gpio_init); 3569 snd_hda_jack_detect_enable_callback(codec, 0x1b, 3570 gpio2_mic_hotkey_event); 3571 3572 spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook; 3573 spec->gpio_led = 0; 3574 spec->mute_led_polarity = 0; 3575 spec->gpio_mic_led_mask = 0x04; 3576 return; 3577 } 3578 3579 if (!spec->kb_dev) 3580 return; 3581 3582 switch (action) { 3583 case HDA_FIXUP_ACT_PROBE: 3584 spec->init_amp = ALC_INIT_DEFAULT; 3585 break; 3586 case HDA_FIXUP_ACT_FREE: 3587 input_unregister_device(spec->kb_dev); 3588 spec->kb_dev = NULL; 3589 } 3590} 3591 3592static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec, 3593 const struct hda_fixup *fix, int action) 3594{ 3595 struct alc_spec *spec = codec->spec; 3596 3597 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 3598 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; 3599 spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook; 3600 spec->mute_led_polarity = 0; 3601 spec->mute_led_nid = 0x1a; 3602 spec->cap_mute_led_nid = 0x18; 3603 spec->gen.vmaster_mute_enum = 1; 3604 codec->power_filter = led_power_filter; 3605 } 3606} 3607 3608static void alc_headset_mode_unplugged(struct hda_codec *codec) 3609{ 3610 static struct coef_fw coef0255[] = { 3611 WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */ 3612 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/ 3613 WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */ 3614 WRITE_COEFEX(0x57, 0x03, 0x8aa6), /* Direct Drive HP Amp control */ 3615 {} 3616 }; 3617 static struct coef_fw coef0255_1[] = { 3618 WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */ 3619 {} 3620 }; 3621 static struct coef_fw coef0256[] = { 3622 WRITE_COEF(0x1b, 0x0c4b), /* LDO and MISC control */ 3623 {} 3624 }; 3625 static struct coef_fw coef0233[] = { 3626 WRITE_COEF(0x1b, 0x0c0b), 3627 WRITE_COEF(0x45, 0xc429), 3628 UPDATE_COEF(0x35, 0x4000, 0), 3629 WRITE_COEF(0x06, 0x2104), 3630 WRITE_COEF(0x1a, 0x0001), 3631 WRITE_COEF(0x26, 0x0004), 3632 WRITE_COEF(0x32, 0x42a3), 3633 {} 3634 }; 3635 static struct coef_fw coef0288[] = { 3636 UPDATE_COEF(0x4f, 0xfcc0, 0xc400), 3637 UPDATE_COEF(0x50, 0x2000, 0x2000), 3638 UPDATE_COEF(0x56, 0x0006, 0x0006), 3639 UPDATE_COEF(0x66, 0x0008, 0), 3640 UPDATE_COEF(0x67, 0x2000, 0), 3641 {} 3642 }; 3643 static struct coef_fw coef0292[] = { 3644 WRITE_COEF(0x76, 0x000e), 3645 WRITE_COEF(0x6c, 0x2400), 3646 WRITE_COEF(0x18, 0x7308), 3647 WRITE_COEF(0x6b, 0xc429), 3648 {} 3649 }; 3650 static struct coef_fw coef0293[] = { 3651 UPDATE_COEF(0x10, 7<<8, 6<<8), /* SET Line1 JD to 0 */ 3652 UPDATE_COEFEX(0x57, 0x05, 1<<15|1<<13, 0x0), /* SET charge pump by verb */ 3653 UPDATE_COEFEX(0x57, 0x03, 1<<10, 1<<10), /* SET EN_OSW to 1 */ 3654 UPDATE_COEF(0x1a, 1<<3, 1<<3), /* Combo JD gating with LINE1-VREFO */ 3655 WRITE_COEF(0x45, 0xc429), /* Set to TRS type */ 3656 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */ 3657 {} 3658 }; 3659 static struct coef_fw coef0668[] = { 3660 WRITE_COEF(0x15, 0x0d40), 3661 WRITE_COEF(0xb7, 0x802b), 3662 {} 3663 }; 3664 3665 switch (codec->core.vendor_id) { 3666 case 0x10ec0255: 3667 alc_process_coef_fw(codec, coef0255_1); 3668 alc_process_coef_fw(codec, coef0255); 3669 break; 3670 case 0x10ec0256: 3671 alc_process_coef_fw(codec, coef0256); 3672 alc_process_coef_fw(codec, coef0255); 3673 break; 3674 case 0x10ec0233: 3675 case 0x10ec0283: 3676 alc_process_coef_fw(codec, coef0233); 3677 break; 3678 case 0x10ec0286: 3679 case 0x10ec0288: 3680 alc_process_coef_fw(codec, coef0288); 3681 break; 3682 case 0x10ec0292: 3683 alc_process_coef_fw(codec, coef0292); 3684 break; 3685 case 0x10ec0293: 3686 alc_process_coef_fw(codec, coef0293); 3687 break; 3688 case 0x10ec0668: 3689 alc_process_coef_fw(codec, coef0668); 3690 break; 3691 } 3692 codec_dbg(codec, "Headset jack set to unplugged mode.\n"); 3693} 3694 3695 3696static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, 3697 hda_nid_t mic_pin) 3698{ 3699 static struct coef_fw coef0255[] = { 3700 WRITE_COEFEX(0x57, 0x03, 0x8aa6), 3701 WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */ 3702 {} 3703 }; 3704 static struct coef_fw coef0233[] = { 3705 UPDATE_COEF(0x35, 0, 1<<14), 3706 WRITE_COEF(0x06, 0x2100), 3707 WRITE_COEF(0x1a, 0x0021), 3708 WRITE_COEF(0x26, 0x008c), 3709 {} 3710 }; 3711 static struct coef_fw coef0288[] = { 3712 UPDATE_COEF(0x50, 0x2000, 0), 3713 UPDATE_COEF(0x56, 0x0006, 0), 3714 UPDATE_COEF(0x4f, 0xfcc0, 0xc400), 3715 UPDATE_COEF(0x66, 0x0008, 0x0008), 3716 UPDATE_COEF(0x67, 0x2000, 0x2000), 3717 {} 3718 }; 3719 static struct coef_fw coef0292[] = { 3720 WRITE_COEF(0x19, 0xa208), 3721 WRITE_COEF(0x2e, 0xacf0), 3722 {} 3723 }; 3724 static struct coef_fw coef0293[] = { 3725 UPDATE_COEFEX(0x57, 0x05, 0, 1<<15|1<<13), /* SET charge pump by verb */ 3726 UPDATE_COEFEX(0x57, 0x03, 1<<10, 0), /* SET EN_OSW to 0 */ 3727 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */ 3728 {} 3729 }; 3730 static struct coef_fw coef0688[] = { 3731 WRITE_COEF(0xb7, 0x802b), 3732 WRITE_COEF(0xb5, 0x1040), 3733 UPDATE_COEF(0xc3, 0, 1<<12), 3734 {} 3735 }; 3736 3737 switch (codec->core.vendor_id) { 3738 case 0x10ec0255: 3739 case 0x10ec0256: 3740 alc_write_coef_idx(codec, 0x45, 0xc489); 3741 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); 3742 alc_process_coef_fw(codec, coef0255); 3743 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); 3744 break; 3745 case 0x10ec0233: 3746 case 0x10ec0283: 3747 alc_write_coef_idx(codec, 0x45, 0xc429); 3748 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); 3749 alc_process_coef_fw(codec, coef0233); 3750 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); 3751 break; 3752 case 0x10ec0286: 3753 case 0x10ec0288: 3754 alc_update_coef_idx(codec, 0x4f, 0x000c, 0); 3755 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); 3756 alc_process_coef_fw(codec, coef0288); 3757 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); 3758 break; 3759 case 0x10ec0292: 3760 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); 3761 alc_process_coef_fw(codec, coef0292); 3762 break; 3763 case 0x10ec0293: 3764 /* Set to TRS mode */ 3765 alc_write_coef_idx(codec, 0x45, 0xc429); 3766 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); 3767 alc_process_coef_fw(codec, coef0293); 3768 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); 3769 break; 3770 case 0x10ec0662: 3771 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); 3772 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); 3773 break; 3774 case 0x10ec0668: 3775 alc_write_coef_idx(codec, 0x11, 0x0001); 3776 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); 3777 alc_process_coef_fw(codec, coef0688); 3778 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); 3779 break; 3780 } 3781 codec_dbg(codec, "Headset jack set to mic-in mode.\n"); 3782} 3783 3784static void alc_headset_mode_default(struct hda_codec *codec) 3785{ 3786 static struct coef_fw coef0225[] = { 3787 UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10), 3788 {} 3789 }; 3790 static struct coef_fw coef0255[] = { 3791 WRITE_COEF(0x45, 0xc089), 3792 WRITE_COEF(0x45, 0xc489), 3793 WRITE_COEFEX(0x57, 0x03, 0x8ea6), 3794 WRITE_COEF(0x49, 0x0049), 3795 {} 3796 }; 3797 static struct coef_fw coef0233[] = { 3798 WRITE_COEF(0x06, 0x2100), 3799 WRITE_COEF(0x32, 0x4ea3), 3800 {} 3801 }; 3802 static struct coef_fw coef0288[] = { 3803 UPDATE_COEF(0x4f, 0xfcc0, 0xc400), /* Set to TRS type */ 3804 UPDATE_COEF(0x50, 0x2000, 0x2000), 3805 UPDATE_COEF(0x56, 0x0006, 0x0006), 3806 UPDATE_COEF(0x66, 0x0008, 0), 3807 UPDATE_COEF(0x67, 0x2000, 0), 3808 {} 3809 }; 3810 static struct coef_fw coef0292[] = { 3811 WRITE_COEF(0x76, 0x000e), 3812 WRITE_COEF(0x6c, 0x2400), 3813 WRITE_COEF(0x6b, 0xc429), 3814 WRITE_COEF(0x18, 0x7308), 3815 {} 3816 }; 3817 static struct coef_fw coef0293[] = { 3818 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */ 3819 WRITE_COEF(0x45, 0xC429), /* Set to TRS type */ 3820 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */ 3821 {} 3822 }; 3823 static struct coef_fw coef0688[] = { 3824 WRITE_COEF(0x11, 0x0041), 3825 WRITE_COEF(0x15, 0x0d40), 3826 WRITE_COEF(0xb7, 0x802b), 3827 {} 3828 }; 3829 3830 switch (codec->core.vendor_id) { 3831 case 0x10ec0225: 3832 alc_process_coef_fw(codec, coef0225); 3833 break; 3834 case 0x10ec0255: 3835 case 0x10ec0256: 3836 alc_process_coef_fw(codec, coef0255); 3837 break; 3838 case 0x10ec0233: 3839 case 0x10ec0283: 3840 alc_process_coef_fw(codec, coef0233); 3841 break; 3842 case 0x10ec0286: 3843 case 0x10ec0288: 3844 alc_process_coef_fw(codec, coef0288); 3845 break; 3846 case 0x10ec0292: 3847 alc_process_coef_fw(codec, coef0292); 3848 break; 3849 case 0x10ec0293: 3850 alc_process_coef_fw(codec, coef0293); 3851 break; 3852 case 0x10ec0668: 3853 alc_process_coef_fw(codec, coef0688); 3854 break; 3855 } 3856 codec_dbg(codec, "Headset jack set to headphone (default) mode.\n"); 3857} 3858 3859/* Iphone type */ 3860static void alc_headset_mode_ctia(struct hda_codec *codec) 3861{ 3862 static struct coef_fw coef0255[] = { 3863 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */ 3864 WRITE_COEF(0x1b, 0x0c2b), 3865 WRITE_COEFEX(0x57, 0x03, 0x8ea6), 3866 {} 3867 }; 3868 static struct coef_fw coef0256[] = { 3869 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */ 3870 WRITE_COEF(0x1b, 0x0c6b), 3871 WRITE_COEFEX(0x57, 0x03, 0x8ea6), 3872 {} 3873 }; 3874 static struct coef_fw coef0233[] = { 3875 WRITE_COEF(0x45, 0xd429), 3876 WRITE_COEF(0x1b, 0x0c2b), 3877 WRITE_COEF(0x32, 0x4ea3), 3878 {} 3879 }; 3880 static struct coef_fw coef0288[] = { 3881 UPDATE_COEF(0x50, 0x2000, 0x2000), 3882 UPDATE_COEF(0x56, 0x0006, 0x0006), 3883 UPDATE_COEF(0x66, 0x0008, 0), 3884 UPDATE_COEF(0x67, 0x2000, 0), 3885 {} 3886 }; 3887 static struct coef_fw coef0292[] = { 3888 WRITE_COEF(0x6b, 0xd429), 3889 WRITE_COEF(0x76, 0x0008), 3890 WRITE_COEF(0x18, 0x7388), 3891 {} 3892 }; 3893 static struct coef_fw coef0293[] = { 3894 WRITE_COEF(0x45, 0xd429), /* Set to ctia type */ 3895 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */ 3896 {} 3897 }; 3898 static struct coef_fw coef0688[] = { 3899 WRITE_COEF(0x11, 0x0001), 3900 WRITE_COEF(0x15, 0x0d60), 3901 WRITE_COEF(0xc3, 0x0000), 3902 {} 3903 }; 3904 3905 switch (codec->core.vendor_id) { 3906 case 0x10ec0255: 3907 alc_process_coef_fw(codec, coef0255); 3908 break; 3909 case 0x10ec0256: 3910 alc_process_coef_fw(codec, coef0256); 3911 break; 3912 case 0x10ec0233: 3913 case 0x10ec0283: 3914 alc_process_coef_fw(codec, coef0233); 3915 break; 3916 case 0x10ec0286: 3917 case 0x10ec0288: 3918 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400); 3919 msleep(300); 3920 alc_process_coef_fw(codec, coef0288); 3921 break; 3922 case 0x10ec0292: 3923 alc_process_coef_fw(codec, coef0292); 3924 break; 3925 case 0x10ec0293: 3926 alc_process_coef_fw(codec, coef0293); 3927 break; 3928 case 0x10ec0668: 3929 alc_process_coef_fw(codec, coef0688); 3930 break; 3931 } 3932 codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n"); 3933} 3934 3935/* Nokia type */ 3936static void alc_headset_mode_omtp(struct hda_codec *codec) 3937{ 3938 static struct coef_fw coef0255[] = { 3939 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */ 3940 WRITE_COEF(0x1b, 0x0c2b), 3941 WRITE_COEFEX(0x57, 0x03, 0x8ea6), 3942 {} 3943 }; 3944 static struct coef_fw coef0256[] = { 3945 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */ 3946 WRITE_COEF(0x1b, 0x0c6b), 3947 WRITE_COEFEX(0x57, 0x03, 0x8ea6), 3948 {} 3949 }; 3950 static struct coef_fw coef0233[] = { 3951 WRITE_COEF(0x45, 0xe429), 3952 WRITE_COEF(0x1b, 0x0c2b), 3953 WRITE_COEF(0x32, 0x4ea3), 3954 {} 3955 }; 3956 static struct coef_fw coef0288[] = { 3957 UPDATE_COEF(0x50, 0x2000, 0x2000), 3958 UPDATE_COEF(0x56, 0x0006, 0x0006), 3959 UPDATE_COEF(0x66, 0x0008, 0), 3960 UPDATE_COEF(0x67, 0x2000, 0), 3961 {} 3962 }; 3963 static struct coef_fw coef0292[] = { 3964 WRITE_COEF(0x6b, 0xe429), 3965 WRITE_COEF(0x76, 0x0008), 3966 WRITE_COEF(0x18, 0x7388), 3967 {} 3968 }; 3969 static struct coef_fw coef0293[] = { 3970 WRITE_COEF(0x45, 0xe429), /* Set to omtp type */ 3971 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */ 3972 {} 3973 }; 3974 static struct coef_fw coef0688[] = { 3975 WRITE_COEF(0x11, 0x0001), 3976 WRITE_COEF(0x15, 0x0d50), 3977 WRITE_COEF(0xc3, 0x0000), 3978 {} 3979 }; 3980 3981 switch (codec->core.vendor_id) { 3982 case 0x10ec0255: 3983 alc_process_coef_fw(codec, coef0255); 3984 break; 3985 case 0x10ec0256: 3986 alc_process_coef_fw(codec, coef0256); 3987 break; 3988 case 0x10ec0233: 3989 case 0x10ec0283: 3990 alc_process_coef_fw(codec, coef0233); 3991 break; 3992 case 0x10ec0286: 3993 case 0x10ec0288: 3994 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400); 3995 msleep(300); 3996 alc_process_coef_fw(codec, coef0288); 3997 break; 3998 case 0x10ec0292: 3999 alc_process_coef_fw(codec, coef0292); 4000 break; 4001 case 0x10ec0293: 4002 alc_process_coef_fw(codec, coef0293); 4003 break; 4004 case 0x10ec0668: 4005 alc_process_coef_fw(codec, coef0688); 4006 break; 4007 } 4008 codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n"); 4009} 4010 4011static void alc_determine_headset_type(struct hda_codec *codec) 4012{ 4013 int val; 4014 bool is_ctia = false; 4015 struct alc_spec *spec = codec->spec; 4016 static struct coef_fw coef0255[] = { 4017 WRITE_COEF(0x45, 0xd089), /* combo jack auto switch control(Check type)*/ 4018 WRITE_COEF(0x49, 0x0149), /* combo jack auto switch control(Vref 4019 conteol) */ 4020 {} 4021 }; 4022 static struct coef_fw coef0288[] = { 4023 UPDATE_COEF(0x4f, 0xfcc0, 0xd400), /* Check Type */ 4024 {} 4025 }; 4026 static struct coef_fw coef0293[] = { 4027 UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */ 4028 WRITE_COEF(0x45, 0xD429), /* Set to ctia type */ 4029 {} 4030 }; 4031 static struct coef_fw coef0688[] = { 4032 WRITE_COEF(0x11, 0x0001), 4033 WRITE_COEF(0xb7, 0x802b), 4034 WRITE_COEF(0x15, 0x0d60), 4035 WRITE_COEF(0xc3, 0x0c00), 4036 {} 4037 }; 4038 4039 switch (codec->core.vendor_id) { 4040 case 0x10ec0255: 4041 case 0x10ec0256: 4042 alc_process_coef_fw(codec, coef0255); 4043 msleep(300); 4044 val = alc_read_coef_idx(codec, 0x46); 4045 is_ctia = (val & 0x0070) == 0x0070; 4046 break; 4047 case 0x10ec0233: 4048 case 0x10ec0283: 4049 alc_write_coef_idx(codec, 0x45, 0xd029); 4050 msleep(300); 4051 val = alc_read_coef_idx(codec, 0x46); 4052 is_ctia = (val & 0x0070) == 0x0070; 4053 break; 4054 case 0x10ec0286: 4055 case 0x10ec0288: 4056 alc_process_coef_fw(codec, coef0288); 4057 msleep(350); 4058 val = alc_read_coef_idx(codec, 0x50); 4059 is_ctia = (val & 0x0070) == 0x0070; 4060 break; 4061 case 0x10ec0292: 4062 alc_write_coef_idx(codec, 0x6b, 0xd429); 4063 msleep(300); 4064 val = alc_read_coef_idx(codec, 0x6c); 4065 is_ctia = (val & 0x001c) == 0x001c; 4066 break; 4067 case 0x10ec0293: 4068 alc_process_coef_fw(codec, coef0293); 4069 msleep(300); 4070 val = alc_read_coef_idx(codec, 0x46); 4071 is_ctia = (val & 0x0070) == 0x0070; 4072 break; 4073 case 0x10ec0668: 4074 alc_process_coef_fw(codec, coef0688); 4075 msleep(300); 4076 val = alc_read_coef_idx(codec, 0xbe); 4077 is_ctia = (val & 0x1c02) == 0x1c02; 4078 break; 4079 } 4080 4081 codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n", 4082 is_ctia ? "yes" : "no"); 4083 spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP; 4084} 4085 4086static void alc_update_headset_mode(struct hda_codec *codec) 4087{ 4088 struct alc_spec *spec = codec->spec; 4089 4090 hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]]; 4091 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; 4092 4093 int new_headset_mode; 4094 4095 if (!snd_hda_jack_detect(codec, hp_pin)) 4096 new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED; 4097 else if (mux_pin == spec->headset_mic_pin) 4098 new_headset_mode = ALC_HEADSET_MODE_HEADSET; 4099 else if (mux_pin == spec->headphone_mic_pin) 4100 new_headset_mode = ALC_HEADSET_MODE_MIC; 4101 else 4102 new_headset_mode = ALC_HEADSET_MODE_HEADPHONE; 4103 4104 if (new_headset_mode == spec->current_headset_mode) { 4105 snd_hda_gen_update_outputs(codec); 4106 return; 4107 } 4108 4109 switch (new_headset_mode) { 4110 case ALC_HEADSET_MODE_UNPLUGGED: 4111 alc_headset_mode_unplugged(codec); 4112 spec->gen.hp_jack_present = false; 4113 break; 4114 case ALC_HEADSET_MODE_HEADSET: 4115 if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN) 4116 alc_determine_headset_type(codec); 4117 if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA) 4118 alc_headset_mode_ctia(codec); 4119 else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP) 4120 alc_headset_mode_omtp(codec); 4121 spec->gen.hp_jack_present = true; 4122 break; 4123 case ALC_HEADSET_MODE_MIC: 4124 alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin); 4125 spec->gen.hp_jack_present = false; 4126 break; 4127 case ALC_HEADSET_MODE_HEADPHONE: 4128 alc_headset_mode_default(codec); 4129 spec->gen.hp_jack_present = true; 4130 break; 4131 } 4132 if (new_headset_mode != ALC_HEADSET_MODE_MIC) { 4133 snd_hda_set_pin_ctl_cache(codec, hp_pin, 4134 AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN); 4135 if (spec->headphone_mic_pin && spec->headphone_mic_pin != hp_pin) 4136 snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin, 4137 PIN_VREFHIZ); 4138 } 4139 spec->current_headset_mode = new_headset_mode; 4140 4141 snd_hda_gen_update_outputs(codec); 4142} 4143 4144static void alc_update_headset_mode_hook(struct hda_codec *codec, 4145 struct snd_kcontrol *kcontrol, 4146 struct snd_ctl_elem_value *ucontrol) 4147{ 4148 alc_update_headset_mode(codec); 4149} 4150 4151static void alc_update_headset_jack_cb(struct hda_codec *codec, 4152 struct hda_jack_callback *jack) 4153{ 4154 struct alc_spec *spec = codec->spec; 4155 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN; 4156 snd_hda_gen_hp_automute(codec, jack); 4157} 4158 4159static void alc_probe_headset_mode(struct hda_codec *codec) 4160{ 4161 int i; 4162 struct alc_spec *spec = codec->spec; 4163 struct auto_pin_cfg *cfg = &spec->gen.autocfg; 4164 4165 /* Find mic pins */ 4166 for (i = 0; i < cfg->num_inputs; i++) { 4167 if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin) 4168 spec->headset_mic_pin = cfg->inputs[i].pin; 4169 if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin) 4170 spec->headphone_mic_pin = cfg->inputs[i].pin; 4171 } 4172 4173 spec->gen.cap_sync_hook = alc_update_headset_mode_hook; 4174 spec->gen.automute_hook = alc_update_headset_mode; 4175 spec->gen.hp_automute_hook = alc_update_headset_jack_cb; 4176} 4177 4178static void alc_fixup_headset_mode(struct hda_codec *codec, 4179 const struct hda_fixup *fix, int action) 4180{ 4181 struct alc_spec *spec = codec->spec; 4182 4183 switch (action) { 4184 case HDA_FIXUP_ACT_PRE_PROBE: 4185 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC; 4186 break; 4187 case HDA_FIXUP_ACT_PROBE: 4188 alc_probe_headset_mode(codec); 4189 break; 4190 case HDA_FIXUP_ACT_INIT: 4191 spec->current_headset_mode = 0; 4192 alc_update_headset_mode(codec); 4193 break; 4194 } 4195} 4196 4197static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec, 4198 const struct hda_fixup *fix, int action) 4199{ 4200 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 4201 struct alc_spec *spec = codec->spec; 4202 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; 4203 } 4204 else 4205 alc_fixup_headset_mode(codec, fix, action); 4206} 4207 4208static void alc255_set_default_jack_type(struct hda_codec *codec) 4209{ 4210 /* Set to iphone type */ 4211 static struct coef_fw alc255fw[] = { 4212 WRITE_COEF(0x1b, 0x880b), 4213 WRITE_COEF(0x45, 0xd089), 4214 WRITE_COEF(0x1b, 0x080b), 4215 WRITE_COEF(0x46, 0x0004), 4216 WRITE_COEF(0x1b, 0x0c0b), 4217 {} 4218 }; 4219 static struct coef_fw alc256fw[] = { 4220 WRITE_COEF(0x1b, 0x884b), 4221 WRITE_COEF(0x45, 0xd089), 4222 WRITE_COEF(0x1b, 0x084b), 4223 WRITE_COEF(0x46, 0x0004), 4224 WRITE_COEF(0x1b, 0x0c4b), 4225 {} 4226 }; 4227 switch (codec->core.vendor_id) { 4228 case 0x10ec0255: 4229 alc_process_coef_fw(codec, alc255fw); 4230 break; 4231 case 0x10ec0256: 4232 alc_process_coef_fw(codec, alc256fw); 4233 break; 4234 } 4235 msleep(30); 4236} 4237 4238static void alc_fixup_headset_mode_alc255(struct hda_codec *codec, 4239 const struct hda_fixup *fix, int action) 4240{ 4241 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 4242 alc255_set_default_jack_type(codec); 4243 } 4244 alc_fixup_headset_mode(codec, fix, action); 4245} 4246 4247static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec, 4248 const struct hda_fixup *fix, int action) 4249{ 4250 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 4251 struct alc_spec *spec = codec->spec; 4252 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; 4253 alc255_set_default_jack_type(codec); 4254 } 4255 else 4256 alc_fixup_headset_mode(codec, fix, action); 4257} 4258 4259static void alc288_update_headset_jack_cb(struct hda_codec *codec, 4260 struct hda_jack_callback *jack) 4261{ 4262 struct alc_spec *spec = codec->spec; 4263 int present; 4264 4265 alc_update_headset_jack_cb(codec, jack); 4266 /* Headset Mic enable or disable, only for Dell Dino */ 4267 present = spec->gen.hp_jack_present ? 0x40 : 0; 4268 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 4269 present); 4270} 4271 4272static void alc_fixup_headset_mode_dell_alc288(struct hda_codec *codec, 4273 const struct hda_fixup *fix, int action) 4274{ 4275 alc_fixup_headset_mode(codec, fix, action); 4276 if (action == HDA_FIXUP_ACT_PROBE) { 4277 struct alc_spec *spec = codec->spec; 4278 spec->gen.hp_automute_hook = alc288_update_headset_jack_cb; 4279 } 4280} 4281 4282static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec, 4283 const struct hda_fixup *fix, int action) 4284{ 4285 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 4286 struct alc_spec *spec = codec->spec; 4287 spec->gen.auto_mute_via_amp = 1; 4288 } 4289} 4290 4291static void alc_no_shutup(struct hda_codec *codec) 4292{ 4293} 4294 4295static void alc_fixup_no_shutup(struct hda_codec *codec, 4296 const struct hda_fixup *fix, int action) 4297{ 4298 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 4299 struct alc_spec *spec = codec->spec; 4300 spec->shutup = alc_no_shutup; 4301 } 4302} 4303 4304static void alc_fixup_disable_aamix(struct hda_codec *codec, 4305 const struct hda_fixup *fix, int action) 4306{ 4307 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 4308 struct alc_spec *spec = codec->spec; 4309 /* Disable AA-loopback as it causes white noise */ 4310 spec->gen.mixer_nid = 0; 4311 } 4312} 4313 4314/* fixup for Thinkpad docks: add dock pins, avoid HP parser fixup */ 4315static void alc_fixup_tpt440_dock(struct hda_codec *codec, 4316 const struct hda_fixup *fix, int action) 4317{ 4318 static const struct hda_pintbl pincfgs[] = { 4319 { 0x16, 0x21211010 }, /* dock headphone */ 4320 { 0x19, 0x21a11010 }, /* dock mic */ 4321 { } 4322 }; 4323 struct alc_spec *spec = codec->spec; 4324 4325 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 4326 spec->shutup = alc_no_shutup; /* reduce click noise */ 4327 spec->reboot_notify = alc_d3_at_reboot; /* reduce noise */ 4328 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; 4329 codec->power_save_node = 0; /* avoid click noises */ 4330 snd_hda_apply_pincfgs(codec, pincfgs); 4331 } 4332} 4333 4334static void alc_shutup_dell_xps13(struct hda_codec *codec) 4335{ 4336 struct alc_spec *spec = codec->spec; 4337 int hp_pin = spec->gen.autocfg.hp_pins[0]; 4338 4339 /* Prevent pop noises when headphones are plugged in */ 4340 snd_hda_codec_write(codec, hp_pin, 0, 4341 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); 4342 msleep(20); 4343} 4344 4345static void alc_fixup_dell_xps13(struct hda_codec *codec, 4346 const struct hda_fixup *fix, int action) 4347{ 4348 struct alc_spec *spec = codec->spec; 4349 struct hda_input_mux *imux = &spec->gen.input_mux; 4350 int i; 4351 4352 switch (action) { 4353 case HDA_FIXUP_ACT_PRE_PROBE: 4354 /* mic pin 0x19 must be initialized with Vref Hi-Z, otherwise 4355 * it causes a click noise at start up 4356 */ 4357 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ); 4358 break; 4359 case HDA_FIXUP_ACT_PROBE: 4360 spec->shutup = alc_shutup_dell_xps13; 4361 4362 /* Make the internal mic the default input source. */ 4363 for (i = 0; i < imux->num_items; i++) { 4364 if (spec->gen.imux_pins[i] == 0x12) { 4365 spec->gen.cur_mux[0] = i; 4366 break; 4367 } 4368 } 4369 break; 4370 } 4371} 4372 4373static void alc_fixup_headset_mode_alc662(struct hda_codec *codec, 4374 const struct hda_fixup *fix, int action) 4375{ 4376 struct alc_spec *spec = codec->spec; 4377 4378 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 4379 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; 4380 spec->gen.hp_mic = 1; /* Mic-in is same pin as headphone */ 4381 4382 /* Disable boost for mic-in permanently. (This code is only called 4383 from quirks that guarantee that the headphone is at NID 0x1b.) */ 4384 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000); 4385 snd_hda_override_wcaps(codec, 0x1b, get_wcaps(codec, 0x1b) & ~AC_WCAP_IN_AMP); 4386 } else 4387 alc_fixup_headset_mode(codec, fix, action); 4388} 4389 4390static void alc_fixup_headset_mode_alc668(struct hda_codec *codec, 4391 const struct hda_fixup *fix, int action) 4392{ 4393 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 4394 alc_write_coef_idx(codec, 0xc4, 0x8000); 4395 alc_update_coef_idx(codec, 0xc2, ~0xfe, 0); 4396 snd_hda_set_pin_ctl_cache(codec, 0x18, 0); 4397 } 4398 alc_fixup_headset_mode(codec, fix, action); 4399} 4400 4401/* Returns the nid of the external mic input pin, or 0 if it cannot be found. */ 4402static int find_ext_mic_pin(struct hda_codec *codec) 4403{ 4404 struct alc_spec *spec = codec->spec; 4405 struct auto_pin_cfg *cfg = &spec->gen.autocfg; 4406 hda_nid_t nid; 4407 unsigned int defcfg; 4408 int i; 4409 4410 for (i = 0; i < cfg->num_inputs; i++) { 4411 if (cfg->inputs[i].type != AUTO_PIN_MIC) 4412 continue; 4413 nid = cfg->inputs[i].pin; 4414 defcfg = snd_hda_codec_get_pincfg(codec, nid); 4415 if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT) 4416 continue; 4417 return nid; 4418 } 4419 4420 return 0; 4421} 4422 4423static void alc271_hp_gate_mic_jack(struct hda_codec *codec, 4424 const struct hda_fixup *fix, 4425 int action) 4426{ 4427 struct alc_spec *spec = codec->spec; 4428 4429 if (action == HDA_FIXUP_ACT_PROBE) { 4430 int mic_pin = find_ext_mic_pin(codec); 4431 int hp_pin = spec->gen.autocfg.hp_pins[0]; 4432 4433 if (snd_BUG_ON(!mic_pin || !hp_pin)) 4434 return; 4435 snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin); 4436 } 4437} 4438 4439static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec, 4440 const struct hda_fixup *fix, 4441 int action) 4442{ 4443 struct alc_spec *spec = codec->spec; 4444 struct auto_pin_cfg *cfg = &spec->gen.autocfg; 4445 int i; 4446 4447 /* The mic boosts on level 2 and 3 are too noisy 4448 on the internal mic input. 4449 Therefore limit the boost to 0 or 1. */ 4450 4451 if (action != HDA_FIXUP_ACT_PROBE) 4452 return; 4453 4454 for (i = 0; i < cfg->num_inputs; i++) { 4455 hda_nid_t nid = cfg->inputs[i].pin; 4456 unsigned int defcfg; 4457 if (cfg->inputs[i].type != AUTO_PIN_MIC) 4458 continue; 4459 defcfg = snd_hda_codec_get_pincfg(codec, nid); 4460 if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT) 4461 continue; 4462 4463 snd_hda_override_amp_caps(codec, nid, HDA_INPUT, 4464 (0x00 << AC_AMPCAP_OFFSET_SHIFT) | 4465 (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) | 4466 (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) | 4467 (0 << AC_AMPCAP_MUTE_SHIFT)); 4468 } 4469} 4470 4471static void alc283_hp_automute_hook(struct hda_codec *codec, 4472 struct hda_jack_callback *jack) 4473{ 4474 struct alc_spec *spec = codec->spec; 4475 int vref; 4476 4477 msleep(200); 4478 snd_hda_gen_hp_automute(codec, jack); 4479 4480 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0; 4481 4482 msleep(600); 4483 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 4484 vref); 4485} 4486 4487static void alc283_fixup_chromebook(struct hda_codec *codec, 4488 const struct hda_fixup *fix, int action) 4489{ 4490 struct alc_spec *spec = codec->spec; 4491 4492 switch (action) { 4493 case HDA_FIXUP_ACT_PRE_PROBE: 4494 snd_hda_override_wcaps(codec, 0x03, 0); 4495 /* Disable AA-loopback as it causes white noise */ 4496 spec->gen.mixer_nid = 0; 4497 break; 4498 case HDA_FIXUP_ACT_INIT: 4499 /* MIC2-VREF control */ 4500 /* Set to manual mode */ 4501 alc_update_coef_idx(codec, 0x06, 0x000c, 0); 4502 /* Enable Line1 input control by verb */ 4503 alc_update_coef_idx(codec, 0x1a, 0, 1 << 4); 4504 break; 4505 } 4506} 4507 4508static void alc283_fixup_sense_combo_jack(struct hda_codec *codec, 4509 const struct hda_fixup *fix, int action) 4510{ 4511 struct alc_spec *spec = codec->spec; 4512 4513 switch (action) { 4514 case HDA_FIXUP_ACT_PRE_PROBE: 4515 spec->gen.hp_automute_hook = alc283_hp_automute_hook; 4516 break; 4517 case HDA_FIXUP_ACT_INIT: 4518 /* MIC2-VREF control */ 4519 /* Set to manual mode */ 4520 alc_update_coef_idx(codec, 0x06, 0x000c, 0); 4521 break; 4522 } 4523} 4524 4525/* mute tablet speaker pin (0x14) via dock plugging in addition */ 4526static void asus_tx300_automute(struct hda_codec *codec) 4527{ 4528 struct alc_spec *spec = codec->spec; 4529 snd_hda_gen_update_outputs(codec); 4530 if (snd_hda_jack_detect(codec, 0x1b)) 4531 spec->gen.mute_bits |= (1ULL << 0x14); 4532} 4533 4534static void alc282_fixup_asus_tx300(struct hda_codec *codec, 4535 const struct hda_fixup *fix, int action) 4536{ 4537 struct alc_spec *spec = codec->spec; 4538 /* TX300 needs to set up GPIO2 for the speaker amp */ 4539 static const struct hda_verb gpio2_verbs[] = { 4540 { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 }, 4541 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 }, 4542 { 0x01, AC_VERB_SET_GPIO_DATA, 0x04 }, 4543 {} 4544 }; 4545 static const struct hda_pintbl dock_pins[] = { 4546 { 0x1b, 0x21114000 }, /* dock speaker pin */ 4547 {} 4548 }; 4549 struct snd_kcontrol *kctl; 4550 4551 switch (action) { 4552 case HDA_FIXUP_ACT_PRE_PROBE: 4553 snd_hda_add_verbs(codec, gpio2_verbs); 4554 snd_hda_apply_pincfgs(codec, dock_pins); 4555 spec->gen.auto_mute_via_amp = 1; 4556 spec->gen.automute_hook = asus_tx300_automute; 4557 snd_hda_jack_detect_enable_callback(codec, 0x1b, 4558 snd_hda_gen_hp_automute); 4559 break; 4560 case HDA_FIXUP_ACT_BUILD: 4561 /* this is a bit tricky; give more sane names for the main 4562 * (tablet) speaker and the dock speaker, respectively 4563 */ 4564 kctl = snd_hda_find_mixer_ctl(codec, "Speaker Playback Switch"); 4565 if (kctl) 4566 strcpy(kctl->id.name, "Dock Speaker Playback Switch"); 4567 kctl = snd_hda_find_mixer_ctl(codec, "Bass Speaker Playback Switch"); 4568 if (kctl) 4569 strcpy(kctl->id.name, "Speaker Playback Switch"); 4570 break; 4571 } 4572} 4573 4574static void alc290_fixup_mono_speakers(struct hda_codec *codec, 4575 const struct hda_fixup *fix, int action) 4576{ 4577 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 4578 /* DAC node 0x03 is giving mono output. We therefore want to 4579 make sure 0x14 (front speaker) and 0x15 (headphones) use the 4580 stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */ 4581 hda_nid_t conn1[2] = { 0x0c }; 4582 snd_hda_override_conn_list(codec, 0x14, 1, conn1); 4583 snd_hda_override_conn_list(codec, 0x15, 1, conn1); 4584 } 4585} 4586 4587/* for hda_fixup_thinkpad_acpi() */ 4588#include "thinkpad_helper.c" 4589 4590/* for dell wmi mic mute led */ 4591#include "dell_wmi_helper.c" 4592 4593enum { 4594 ALC269_FIXUP_SONY_VAIO, 4595 ALC275_FIXUP_SONY_VAIO_GPIO2, 4596 ALC269_FIXUP_DELL_M101Z, 4597 ALC269_FIXUP_SKU_IGNORE, 4598 ALC269_FIXUP_ASUS_G73JW, 4599 ALC269_FIXUP_LENOVO_EAPD, 4600 ALC275_FIXUP_SONY_HWEQ, 4601 ALC275_FIXUP_SONY_DISABLE_AAMIX, 4602 ALC271_FIXUP_DMIC, 4603 ALC269_FIXUP_PCM_44K, 4604 ALC269_FIXUP_STEREO_DMIC, 4605 ALC269_FIXUP_HEADSET_MIC, 4606 ALC269_FIXUP_QUANTA_MUTE, 4607 ALC269_FIXUP_LIFEBOOK, 4608 ALC269_FIXUP_LIFEBOOK_EXTMIC, 4609 ALC269_FIXUP_LIFEBOOK_HP_PIN, 4610 ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT, 4611 ALC269_FIXUP_AMIC, 4612 ALC269_FIXUP_DMIC, 4613 ALC269VB_FIXUP_AMIC, 4614 ALC269VB_FIXUP_DMIC, 4615 ALC269_FIXUP_HP_MUTE_LED, 4616 ALC269_FIXUP_HP_MUTE_LED_MIC1, 4617 ALC269_FIXUP_HP_MUTE_LED_MIC2, 4618 ALC269_FIXUP_HP_GPIO_LED, 4619 ALC269_FIXUP_HP_GPIO_MIC1_LED, 4620 ALC269_FIXUP_HP_LINE1_MIC1_LED, 4621 ALC269_FIXUP_INV_DMIC, 4622 ALC269_FIXUP_LENOVO_DOCK, 4623 ALC269_FIXUP_NO_SHUTUP, 4624 ALC286_FIXUP_SONY_MIC_NO_PRESENCE, 4625 ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT, 4626 ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, 4627 ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, 4628 ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, 4629 ALC269_FIXUP_HEADSET_MODE, 4630 ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, 4631 ALC269_FIXUP_ASPIRE_HEADSET_MIC, 4632 ALC269_FIXUP_ASUS_X101_FUNC, 4633 ALC269_FIXUP_ASUS_X101_VERB, 4634 ALC269_FIXUP_ASUS_X101, 4635 ALC271_FIXUP_AMIC_MIC2, 4636 ALC271_FIXUP_HP_GATE_MIC_JACK, 4637 ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572, 4638 ALC269_FIXUP_ACER_AC700, 4639 ALC269_FIXUP_LIMIT_INT_MIC_BOOST, 4640 ALC269VB_FIXUP_ASUS_ZENBOOK, 4641 ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A, 4642 ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED, 4643 ALC269VB_FIXUP_ORDISSIMO_EVE2, 4644 ALC283_FIXUP_CHROME_BOOK, 4645 ALC283_FIXUP_SENSE_COMBO_JACK, 4646 ALC282_FIXUP_ASUS_TX300, 4647 ALC283_FIXUP_INT_MIC, 4648 ALC290_FIXUP_MONO_SPEAKERS, 4649 ALC290_FIXUP_MONO_SPEAKERS_HSJACK, 4650 ALC290_FIXUP_SUBWOOFER, 4651 ALC290_FIXUP_SUBWOOFER_HSJACK, 4652 ALC269_FIXUP_THINKPAD_ACPI, 4653 ALC269_FIXUP_DMIC_THINKPAD_ACPI, 4654 ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 4655 ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, 4656 ALC255_FIXUP_HEADSET_MODE, 4657 ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC, 4658 ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, 4659 ALC292_FIXUP_TPT440_DOCK, 4660 ALC292_FIXUP_TPT440, 4661 ALC283_FIXUP_BXBT2807_MIC, 4662 ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED, 4663 ALC282_FIXUP_ASPIRE_V5_PINS, 4664 ALC280_FIXUP_HP_GPIO4, 4665 ALC286_FIXUP_HP_GPIO_LED, 4666 ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY, 4667 ALC280_FIXUP_HP_DOCK_PINS, 4668 ALC288_FIXUP_DELL_HEADSET_MODE, 4669 ALC288_FIXUP_DELL1_MIC_NO_PRESENCE, 4670 ALC288_FIXUP_DELL_XPS_13_GPIO6, 4671 ALC288_FIXUP_DELL_XPS_13, 4672 ALC288_FIXUP_DISABLE_AAMIX, 4673 ALC292_FIXUP_DELL_E7X, 4674 ALC292_FIXUP_DISABLE_AAMIX, 4675 ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK, 4676 ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, 4677 ALC275_FIXUP_DELL_XPS, 4678 ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE, 4679 ALC293_FIXUP_LENOVO_SPK_NOISE, 4680 ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY, 4681 ALC255_FIXUP_DELL_SPK_NOISE, 4682 ALC225_FIXUP_DELL1_MIC_NO_PRESENCE, 4683 ALC280_FIXUP_HP_HEADSET_MIC, 4684 ALC221_FIXUP_HP_FRONT_MIC, 4685 ALC292_FIXUP_TPT460, 4686}; 4687 4688static const struct hda_fixup alc269_fixups[] = { 4689 [ALC269_FIXUP_SONY_VAIO] = { 4690 .type = HDA_FIXUP_PINCTLS, 4691 .v.pins = (const struct hda_pintbl[]) { 4692 {0x19, PIN_VREFGRD}, 4693 {} 4694 } 4695 }, 4696 [ALC275_FIXUP_SONY_VAIO_GPIO2] = { 4697 .type = HDA_FIXUP_VERBS, 4698 .v.verbs = (const struct hda_verb[]) { 4699 {0x01, AC_VERB_SET_GPIO_MASK, 0x04}, 4700 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04}, 4701 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 4702 { } 4703 }, 4704 .chained = true, 4705 .chain_id = ALC269_FIXUP_SONY_VAIO 4706 }, 4707 [ALC269_FIXUP_DELL_M101Z] = { 4708 .type = HDA_FIXUP_VERBS, 4709 .v.verbs = (const struct hda_verb[]) { 4710 /* Enables internal speaker */ 4711 {0x20, AC_VERB_SET_COEF_INDEX, 13}, 4712 {0x20, AC_VERB_SET_PROC_COEF, 0x4040}, 4713 {} 4714 } 4715 }, 4716 [ALC269_FIXUP_SKU_IGNORE] = { 4717 .type = HDA_FIXUP_FUNC, 4718 .v.func = alc_fixup_sku_ignore, 4719 }, 4720 [ALC269_FIXUP_ASUS_G73JW] = { 4721 .type = HDA_FIXUP_PINS, 4722 .v.pins = (const struct hda_pintbl[]) { 4723 { 0x17, 0x99130111 }, /* subwoofer */ 4724 { } 4725 } 4726 }, 4727 [ALC269_FIXUP_LENOVO_EAPD] = { 4728 .type = HDA_FIXUP_VERBS, 4729 .v.verbs = (const struct hda_verb[]) { 4730 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, 4731 {} 4732 } 4733 }, 4734 [ALC275_FIXUP_SONY_HWEQ] = { 4735 .type = HDA_FIXUP_FUNC, 4736 .v.func = alc269_fixup_hweq, 4737 .chained = true, 4738 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2 4739 }, 4740 [ALC275_FIXUP_SONY_DISABLE_AAMIX] = { 4741 .type = HDA_FIXUP_FUNC, 4742 .v.func = alc_fixup_disable_aamix, 4743 .chained = true, 4744 .chain_id = ALC269_FIXUP_SONY_VAIO 4745 }, 4746 [ALC271_FIXUP_DMIC] = { 4747 .type = HDA_FIXUP_FUNC, 4748 .v.func = alc271_fixup_dmic, 4749 }, 4750 [ALC269_FIXUP_PCM_44K] = { 4751 .type = HDA_FIXUP_FUNC, 4752 .v.func = alc269_fixup_pcm_44k, 4753 .chained = true, 4754 .chain_id = ALC269_FIXUP_QUANTA_MUTE 4755 }, 4756 [ALC269_FIXUP_STEREO_DMIC] = { 4757 .type = HDA_FIXUP_FUNC, 4758 .v.func = alc269_fixup_stereo_dmic, 4759 }, 4760 [ALC269_FIXUP_HEADSET_MIC] = { 4761 .type = HDA_FIXUP_FUNC, 4762 .v.func = alc269_fixup_headset_mic, 4763 }, 4764 [ALC269_FIXUP_QUANTA_MUTE] = { 4765 .type = HDA_FIXUP_FUNC, 4766 .v.func = alc269_fixup_quanta_mute, 4767 }, 4768 [ALC269_FIXUP_LIFEBOOK] = { 4769 .type = HDA_FIXUP_PINS, 4770 .v.pins = (const struct hda_pintbl[]) { 4771 { 0x1a, 0x2101103f }, /* dock line-out */ 4772 { 0x1b, 0x23a11040 }, /* dock mic-in */ 4773 { } 4774 }, 4775 .chained = true, 4776 .chain_id = ALC269_FIXUP_QUANTA_MUTE 4777 }, 4778 [ALC269_FIXUP_LIFEBOOK_EXTMIC] = { 4779 .type = HDA_FIXUP_PINS, 4780 .v.pins = (const struct hda_pintbl[]) { 4781 { 0x19, 0x01a1903c }, /* headset mic, with jack detect */ 4782 { } 4783 }, 4784 }, 4785 [ALC269_FIXUP_LIFEBOOK_HP_PIN] = { 4786 .type = HDA_FIXUP_PINS, 4787 .v.pins = (const struct hda_pintbl[]) { 4788 { 0x21, 0x0221102f }, /* HP out */ 4789 { } 4790 }, 4791 }, 4792 [ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT] = { 4793 .type = HDA_FIXUP_FUNC, 4794 .v.func = alc269_fixup_pincfg_no_hp_to_lineout, 4795 }, 4796 [ALC269_FIXUP_AMIC] = { 4797 .type = HDA_FIXUP_PINS, 4798 .v.pins = (const struct hda_pintbl[]) { 4799 { 0x14, 0x99130110 }, /* speaker */ 4800 { 0x15, 0x0121401f }, /* HP out */ 4801 { 0x18, 0x01a19c20 }, /* mic */ 4802 { 0x19, 0x99a3092f }, /* int-mic */ 4803 { } 4804 }, 4805 }, 4806 [ALC269_FIXUP_DMIC] = { 4807 .type = HDA_FIXUP_PINS, 4808 .v.pins = (const struct hda_pintbl[]) { 4809 { 0x12, 0x99a3092f }, /* int-mic */ 4810 { 0x14, 0x99130110 }, /* speaker */ 4811 { 0x15, 0x0121401f }, /* HP out */ 4812 { 0x18, 0x01a19c20 }, /* mic */ 4813 { } 4814 }, 4815 }, 4816 [ALC269VB_FIXUP_AMIC] = { 4817 .type = HDA_FIXUP_PINS, 4818 .v.pins = (const struct hda_pintbl[]) { 4819 { 0x14, 0x99130110 }, /* speaker */ 4820 { 0x18, 0x01a19c20 }, /* mic */ 4821 { 0x19, 0x99a3092f }, /* int-mic */ 4822 { 0x21, 0x0121401f }, /* HP out */ 4823 { } 4824 }, 4825 }, 4826 [ALC269VB_FIXUP_DMIC] = { 4827 .type = HDA_FIXUP_PINS, 4828 .v.pins = (const struct hda_pintbl[]) { 4829 { 0x12, 0x99a3092f }, /* int-mic */ 4830 { 0x14, 0x99130110 }, /* speaker */ 4831 { 0x18, 0x01a19c20 }, /* mic */ 4832 { 0x21, 0x0121401f }, /* HP out */ 4833 { } 4834 }, 4835 }, 4836 [ALC269_FIXUP_HP_MUTE_LED] = { 4837 .type = HDA_FIXUP_FUNC, 4838 .v.func = alc269_fixup_hp_mute_led, 4839 }, 4840 [ALC269_FIXUP_HP_MUTE_LED_MIC1] = { 4841 .type = HDA_FIXUP_FUNC, 4842 .v.func = alc269_fixup_hp_mute_led_mic1, 4843 }, 4844 [ALC269_FIXUP_HP_MUTE_LED_MIC2] = { 4845 .type = HDA_FIXUP_FUNC, 4846 .v.func = alc269_fixup_hp_mute_led_mic2, 4847 }, 4848 [ALC269_FIXUP_HP_GPIO_LED] = { 4849 .type = HDA_FIXUP_FUNC, 4850 .v.func = alc269_fixup_hp_gpio_led, 4851 }, 4852 [ALC269_FIXUP_HP_GPIO_MIC1_LED] = { 4853 .type = HDA_FIXUP_FUNC, 4854 .v.func = alc269_fixup_hp_gpio_mic1_led, 4855 }, 4856 [ALC269_FIXUP_HP_LINE1_MIC1_LED] = { 4857 .type = HDA_FIXUP_FUNC, 4858 .v.func = alc269_fixup_hp_line1_mic1_led, 4859 }, 4860 [ALC269_FIXUP_INV_DMIC] = { 4861 .type = HDA_FIXUP_FUNC, 4862 .v.func = alc_fixup_inv_dmic, 4863 }, 4864 [ALC269_FIXUP_NO_SHUTUP] = { 4865 .type = HDA_FIXUP_FUNC, 4866 .v.func = alc_fixup_no_shutup, 4867 }, 4868 [ALC269_FIXUP_LENOVO_DOCK] = { 4869 .type = HDA_FIXUP_PINS, 4870 .v.pins = (const struct hda_pintbl[]) { 4871 { 0x19, 0x23a11040 }, /* dock mic */ 4872 { 0x1b, 0x2121103f }, /* dock headphone */ 4873 { } 4874 }, 4875 .chained = true, 4876 .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT 4877 }, 4878 [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = { 4879 .type = HDA_FIXUP_FUNC, 4880 .v.func = alc269_fixup_pincfg_no_hp_to_lineout, 4881 .chained = true, 4882 .chain_id = ALC269_FIXUP_THINKPAD_ACPI, 4883 }, 4884 [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = { 4885 .type = HDA_FIXUP_PINS, 4886 .v.pins = (const struct hda_pintbl[]) { 4887 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ 4888 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */ 4889 { } 4890 }, 4891 .chained = true, 4892 .chain_id = ALC269_FIXUP_HEADSET_MODE 4893 }, 4894 [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = { 4895 .type = HDA_FIXUP_PINS, 4896 .v.pins = (const struct hda_pintbl[]) { 4897 { 0x16, 0x21014020 }, /* dock line out */ 4898 { 0x19, 0x21a19030 }, /* dock mic */ 4899 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */ 4900 { } 4901 }, 4902 .chained = true, 4903 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC 4904 }, 4905 [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = { 4906 .type = HDA_FIXUP_PINS, 4907 .v.pins = (const struct hda_pintbl[]) { 4908 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */ 4909 { } 4910 }, 4911 .chained = true, 4912 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC 4913 }, 4914 [ALC269_FIXUP_HEADSET_MODE] = { 4915 .type = HDA_FIXUP_FUNC, 4916 .v.func = alc_fixup_headset_mode, 4917 .chained = true, 4918 .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED 4919 }, 4920 [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = { 4921 .type = HDA_FIXUP_FUNC, 4922 .v.func = alc_fixup_headset_mode_no_hp_mic, 4923 }, 4924 [ALC269_FIXUP_ASPIRE_HEADSET_MIC] = { 4925 .type = HDA_FIXUP_PINS, 4926 .v.pins = (const struct hda_pintbl[]) { 4927 { 0x19, 0x01a1913c }, /* headset mic w/o jack detect */ 4928 { } 4929 }, 4930 .chained = true, 4931 .chain_id = ALC269_FIXUP_HEADSET_MODE, 4932 }, 4933 [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = { 4934 .type = HDA_FIXUP_PINS, 4935 .v.pins = (const struct hda_pintbl[]) { 4936 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */ 4937 { } 4938 }, 4939 .chained = true, 4940 .chain_id = ALC269_FIXUP_HEADSET_MIC 4941 }, 4942 [ALC269_FIXUP_ASUS_X101_FUNC] = { 4943 .type = HDA_FIXUP_FUNC, 4944 .v.func = alc269_fixup_x101_headset_mic, 4945 }, 4946 [ALC269_FIXUP_ASUS_X101_VERB] = { 4947 .type = HDA_FIXUP_VERBS, 4948 .v.verbs = (const struct hda_verb[]) { 4949 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 4950 {0x20, AC_VERB_SET_COEF_INDEX, 0x08}, 4951 {0x20, AC_VERB_SET_PROC_COEF, 0x0310}, 4952 { } 4953 }, 4954 .chained = true, 4955 .chain_id = ALC269_FIXUP_ASUS_X101_FUNC 4956 }, 4957 [ALC269_FIXUP_ASUS_X101] = { 4958 .type = HDA_FIXUP_PINS, 4959 .v.pins = (const struct hda_pintbl[]) { 4960 { 0x18, 0x04a1182c }, /* Headset mic */ 4961 { } 4962 }, 4963 .chained = true, 4964 .chain_id = ALC269_FIXUP_ASUS_X101_VERB 4965 }, 4966 [ALC271_FIXUP_AMIC_MIC2] = { 4967 .type = HDA_FIXUP_PINS, 4968 .v.pins = (const struct hda_pintbl[]) { 4969 { 0x14, 0x99130110 }, /* speaker */ 4970 { 0x19, 0x01a19c20 }, /* mic */ 4971 { 0x1b, 0x99a7012f }, /* int-mic */ 4972 { 0x21, 0x0121401f }, /* HP out */ 4973 { } 4974 }, 4975 }, 4976 [ALC271_FIXUP_HP_GATE_MIC_JACK] = { 4977 .type = HDA_FIXUP_FUNC, 4978 .v.func = alc271_hp_gate_mic_jack, 4979 .chained = true, 4980 .chain_id = ALC271_FIXUP_AMIC_MIC2, 4981 }, 4982 [ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = { 4983 .type = HDA_FIXUP_FUNC, 4984 .v.func = alc269_fixup_limit_int_mic_boost, 4985 .chained = true, 4986 .chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK, 4987 }, 4988 [ALC269_FIXUP_ACER_AC700] = { 4989 .type = HDA_FIXUP_PINS, 4990 .v.pins = (const struct hda_pintbl[]) { 4991 { 0x12, 0x99a3092f }, /* int-mic */ 4992 { 0x14, 0x99130110 }, /* speaker */ 4993 { 0x18, 0x03a11c20 }, /* mic */ 4994 { 0x1e, 0x0346101e }, /* SPDIF1 */ 4995 { 0x21, 0x0321101f }, /* HP out */ 4996 { } 4997 }, 4998 .chained = true, 4999 .chain_id = ALC271_FIXUP_DMIC, 5000 }, 5001 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = { 5002 .type = HDA_FIXUP_FUNC, 5003 .v.func = alc269_fixup_limit_int_mic_boost, 5004 .chained = true, 5005 .chain_id = ALC269_FIXUP_THINKPAD_ACPI, 5006 }, 5007 [ALC269VB_FIXUP_ASUS_ZENBOOK] = { 5008 .type = HDA_FIXUP_FUNC, 5009 .v.func = alc269_fixup_limit_int_mic_boost, 5010 .chained = true, 5011 .chain_id = ALC269VB_FIXUP_DMIC, 5012 }, 5013 [ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = { 5014 .type = HDA_FIXUP_VERBS, 5015 .v.verbs = (const struct hda_verb[]) { 5016 /* class-D output amp +5dB */ 5017 { 0x20, AC_VERB_SET_COEF_INDEX, 0x12 }, 5018 { 0x20, AC_VERB_SET_PROC_COEF, 0x2800 }, 5019 {} 5020 }, 5021 .chained = true, 5022 .chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK, 5023 }, 5024 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = { 5025 .type = HDA_FIXUP_FUNC, 5026 .v.func = alc269_fixup_limit_int_mic_boost, 5027 .chained = true, 5028 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1, 5029 }, 5030 [ALC269VB_FIXUP_ORDISSIMO_EVE2] = { 5031 .type = HDA_FIXUP_PINS, 5032 .v.pins = (const struct hda_pintbl[]) { 5033 { 0x12, 0x99a3092f }, /* int-mic */ 5034 { 0x18, 0x03a11d20 }, /* mic */ 5035 { 0x19, 0x411111f0 }, /* Unused bogus pin */ 5036 { } 5037 }, 5038 }, 5039 [ALC283_FIXUP_CHROME_BOOK] = { 5040 .type = HDA_FIXUP_FUNC, 5041 .v.func = alc283_fixup_chromebook, 5042 }, 5043 [ALC283_FIXUP_SENSE_COMBO_JACK] = { 5044 .type = HDA_FIXUP_FUNC, 5045 .v.func = alc283_fixup_sense_combo_jack, 5046 .chained = true, 5047 .chain_id = ALC283_FIXUP_CHROME_BOOK, 5048 }, 5049 [ALC282_FIXUP_ASUS_TX300] = { 5050 .type = HDA_FIXUP_FUNC, 5051 .v.func = alc282_fixup_asus_tx300, 5052 }, 5053 [ALC283_FIXUP_INT_MIC] = { 5054 .type = HDA_FIXUP_VERBS, 5055 .v.verbs = (const struct hda_verb[]) { 5056 {0x20, AC_VERB_SET_COEF_INDEX, 0x1a}, 5057 {0x20, AC_VERB_SET_PROC_COEF, 0x0011}, 5058 { } 5059 }, 5060 .chained = true, 5061 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST 5062 }, 5063 [ALC290_FIXUP_SUBWOOFER_HSJACK] = { 5064 .type = HDA_FIXUP_PINS, 5065 .v.pins = (const struct hda_pintbl[]) { 5066 { 0x17, 0x90170112 }, /* subwoofer */ 5067 { } 5068 }, 5069 .chained = true, 5070 .chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK, 5071 }, 5072 [ALC290_FIXUP_SUBWOOFER] = { 5073 .type = HDA_FIXUP_PINS, 5074 .v.pins = (const struct hda_pintbl[]) { 5075 { 0x17, 0x90170112 }, /* subwoofer */ 5076 { } 5077 }, 5078 .chained = true, 5079 .chain_id = ALC290_FIXUP_MONO_SPEAKERS, 5080 }, 5081 [ALC290_FIXUP_MONO_SPEAKERS] = { 5082 .type = HDA_FIXUP_FUNC, 5083 .v.func = alc290_fixup_mono_speakers, 5084 }, 5085 [ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = { 5086 .type = HDA_FIXUP_FUNC, 5087 .v.func = alc290_fixup_mono_speakers, 5088 .chained = true, 5089 .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, 5090 }, 5091 [ALC269_FIXUP_THINKPAD_ACPI] = { 5092 .type = HDA_FIXUP_FUNC, 5093 .v.func = hda_fixup_thinkpad_acpi, 5094 }, 5095 [ALC269_FIXUP_DMIC_THINKPAD_ACPI] = { 5096 .type = HDA_FIXUP_FUNC, 5097 .v.func = alc_fixup_inv_dmic, 5098 .chained = true, 5099 .chain_id = ALC269_FIXUP_THINKPAD_ACPI, 5100 }, 5101 [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = { 5102 .type = HDA_FIXUP_PINS, 5103 .v.pins = (const struct hda_pintbl[]) { 5104 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ 5105 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */ 5106 { } 5107 }, 5108 .chained = true, 5109 .chain_id = ALC255_FIXUP_HEADSET_MODE 5110 }, 5111 [ALC255_FIXUP_DELL2_MIC_NO_PRESENCE] = { 5112 .type = HDA_FIXUP_PINS, 5113 .v.pins = (const struct hda_pintbl[]) { 5114 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ 5115 { } 5116 }, 5117 .chained = true, 5118 .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC 5119 }, 5120 [ALC255_FIXUP_HEADSET_MODE] = { 5121 .type = HDA_FIXUP_FUNC, 5122 .v.func = alc_fixup_headset_mode_alc255, 5123 .chained = true, 5124 .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED 5125 }, 5126 [ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = { 5127 .type = HDA_FIXUP_FUNC, 5128 .v.func = alc_fixup_headset_mode_alc255_no_hp_mic, 5129 }, 5130 [ALC293_FIXUP_DELL1_MIC_NO_PRESENCE] = { 5131 .type = HDA_FIXUP_PINS, 5132 .v.pins = (const struct hda_pintbl[]) { 5133 { 0x18, 0x01a1913d }, /* use as headphone mic, without its own jack detect */ 5134 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */ 5135 { } 5136 }, 5137 .chained = true, 5138 .chain_id = ALC269_FIXUP_HEADSET_MODE 5139 }, 5140 [ALC292_FIXUP_TPT440_DOCK] = { 5141 .type = HDA_FIXUP_FUNC, 5142 .v.func = alc_fixup_tpt440_dock, 5143 .chained = true, 5144 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST 5145 }, 5146 [ALC292_FIXUP_TPT440] = { 5147 .type = HDA_FIXUP_FUNC, 5148 .v.func = alc_fixup_disable_aamix, 5149 .chained = true, 5150 .chain_id = ALC292_FIXUP_TPT440_DOCK, 5151 }, 5152 [ALC283_FIXUP_BXBT2807_MIC] = { 5153 .type = HDA_FIXUP_PINS, 5154 .v.pins = (const struct hda_pintbl[]) { 5155 { 0x19, 0x04a110f0 }, 5156 { }, 5157 }, 5158 }, 5159 [ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED] = { 5160 .type = HDA_FIXUP_FUNC, 5161 .v.func = alc_fixup_dell_wmi, 5162 }, 5163 [ALC282_FIXUP_ASPIRE_V5_PINS] = { 5164 .type = HDA_FIXUP_PINS, 5165 .v.pins = (const struct hda_pintbl[]) { 5166 { 0x12, 0x90a60130 }, 5167 { 0x14, 0x90170110 }, 5168 { 0x17, 0x40000008 }, 5169 { 0x18, 0x411111f0 }, 5170 { 0x19, 0x01a1913c }, 5171 { 0x1a, 0x411111f0 }, 5172 { 0x1b, 0x411111f0 }, 5173 { 0x1d, 0x40f89b2d }, 5174 { 0x1e, 0x411111f0 }, 5175 { 0x21, 0x0321101f }, 5176 { }, 5177 }, 5178 }, 5179 [ALC280_FIXUP_HP_GPIO4] = { 5180 .type = HDA_FIXUP_FUNC, 5181 .v.func = alc280_fixup_hp_gpio4, 5182 }, 5183 [ALC286_FIXUP_HP_GPIO_LED] = { 5184 .type = HDA_FIXUP_FUNC, 5185 .v.func = alc286_fixup_hp_gpio_led, 5186 }, 5187 [ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY] = { 5188 .type = HDA_FIXUP_FUNC, 5189 .v.func = alc280_fixup_hp_gpio2_mic_hotkey, 5190 }, 5191 [ALC280_FIXUP_HP_DOCK_PINS] = { 5192 .type = HDA_FIXUP_PINS, 5193 .v.pins = (const struct hda_pintbl[]) { 5194 { 0x1b, 0x21011020 }, /* line-out */ 5195 { 0x1a, 0x01a1903c }, /* headset mic */ 5196 { 0x18, 0x2181103f }, /* line-in */ 5197 { }, 5198 }, 5199 .chained = true, 5200 .chain_id = ALC280_FIXUP_HP_GPIO4 5201 }, 5202 [ALC288_FIXUP_DELL_HEADSET_MODE] = { 5203 .type = HDA_FIXUP_FUNC, 5204 .v.func = alc_fixup_headset_mode_dell_alc288, 5205 .chained = true, 5206 .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED 5207 }, 5208 [ALC288_FIXUP_DELL1_MIC_NO_PRESENCE] = { 5209 .type = HDA_FIXUP_PINS, 5210 .v.pins = (const struct hda_pintbl[]) { 5211 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */ 5212 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */ 5213 { } 5214 }, 5215 .chained = true, 5216 .chain_id = ALC288_FIXUP_DELL_HEADSET_MODE 5217 }, 5218 [ALC288_FIXUP_DELL_XPS_13_GPIO6] = { 5219 .type = HDA_FIXUP_VERBS, 5220 .v.verbs = (const struct hda_verb[]) { 5221 {0x01, AC_VERB_SET_GPIO_MASK, 0x40}, 5222 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x40}, 5223 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 5224 { } 5225 }, 5226 .chained = true, 5227 .chain_id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE 5228 }, 5229 [ALC288_FIXUP_DISABLE_AAMIX] = { 5230 .type = HDA_FIXUP_FUNC, 5231 .v.func = alc_fixup_disable_aamix, 5232 .chained = true, 5233 .chain_id = ALC288_FIXUP_DELL_XPS_13_GPIO6 5234 }, 5235 [ALC288_FIXUP_DELL_XPS_13] = { 5236 .type = HDA_FIXUP_FUNC, 5237 .v.func = alc_fixup_dell_xps13, 5238 .chained = true, 5239 .chain_id = ALC288_FIXUP_DISABLE_AAMIX 5240 }, 5241 [ALC292_FIXUP_DISABLE_AAMIX] = { 5242 .type = HDA_FIXUP_FUNC, 5243 .v.func = alc_fixup_disable_aamix, 5244 .chained = true, 5245 .chain_id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE 5246 }, 5247 [ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK] = { 5248 .type = HDA_FIXUP_FUNC, 5249 .v.func = alc_fixup_disable_aamix, 5250 .chained = true, 5251 .chain_id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE 5252 }, 5253 [ALC292_FIXUP_DELL_E7X] = { 5254 .type = HDA_FIXUP_FUNC, 5255 .v.func = alc_fixup_dell_xps13, 5256 .chained = true, 5257 .chain_id = ALC292_FIXUP_DISABLE_AAMIX 5258 }, 5259 [ALC298_FIXUP_DELL1_MIC_NO_PRESENCE] = { 5260 .type = HDA_FIXUP_PINS, 5261 .v.pins = (const struct hda_pintbl[]) { 5262 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */ 5263 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */ 5264 { } 5265 }, 5266 .chained = true, 5267 .chain_id = ALC269_FIXUP_HEADSET_MODE 5268 }, 5269 [ALC275_FIXUP_DELL_XPS] = { 5270 .type = HDA_FIXUP_VERBS, 5271 .v.verbs = (const struct hda_verb[]) { 5272 /* Enables internal speaker */ 5273 {0x20, AC_VERB_SET_COEF_INDEX, 0x1f}, 5274 {0x20, AC_VERB_SET_PROC_COEF, 0x00c0}, 5275 {0x20, AC_VERB_SET_COEF_INDEX, 0x30}, 5276 {0x20, AC_VERB_SET_PROC_COEF, 0x00b1}, 5277 {} 5278 } 5279 }, 5280 [ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE] = { 5281 .type = HDA_FIXUP_VERBS, 5282 .v.verbs = (const struct hda_verb[]) { 5283 /* Disable pass-through path for FRONT 14h */ 5284 {0x20, AC_VERB_SET_COEF_INDEX, 0x36}, 5285 {0x20, AC_VERB_SET_PROC_COEF, 0x1737}, 5286 {} 5287 }, 5288 .chained = true, 5289 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE 5290 }, 5291 [ALC293_FIXUP_LENOVO_SPK_NOISE] = { 5292 .type = HDA_FIXUP_FUNC, 5293 .v.func = alc_fixup_disable_aamix, 5294 .chained = true, 5295 .chain_id = ALC269_FIXUP_THINKPAD_ACPI 5296 }, 5297 [ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY] = { 5298 .type = HDA_FIXUP_FUNC, 5299 .v.func = alc233_fixup_lenovo_line2_mic_hotkey, 5300 }, 5301 [ALC255_FIXUP_DELL_SPK_NOISE] = { 5302 .type = HDA_FIXUP_FUNC, 5303 .v.func = alc_fixup_disable_aamix, 5304 .chained = true, 5305 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE 5306 }, 5307 [ALC225_FIXUP_DELL1_MIC_NO_PRESENCE] = { 5308 .type = HDA_FIXUP_VERBS, 5309 .v.verbs = (const struct hda_verb[]) { 5310 /* Disable pass-through path for FRONT 14h */ 5311 { 0x20, AC_VERB_SET_COEF_INDEX, 0x36 }, 5312 { 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 }, 5313 {} 5314 }, 5315 .chained = true, 5316 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE 5317 }, 5318 [ALC280_FIXUP_HP_HEADSET_MIC] = { 5319 .type = HDA_FIXUP_FUNC, 5320 .v.func = alc_fixup_disable_aamix, 5321 .chained = true, 5322 .chain_id = ALC269_FIXUP_HEADSET_MIC, 5323 }, 5324 [ALC221_FIXUP_HP_FRONT_MIC] = { 5325 .type = HDA_FIXUP_PINS, 5326 .v.pins = (const struct hda_pintbl[]) { 5327 { 0x19, 0x02a19020 }, /* Front Mic */ 5328 { } 5329 }, 5330 }, 5331 [ALC292_FIXUP_TPT460] = { 5332 .type = HDA_FIXUP_FUNC, 5333 .v.func = alc_fixup_tpt440_dock, 5334 .chained = true, 5335 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE, 5336 }, 5337}; 5338 5339static const struct snd_pci_quirk alc269_fixup_tbl[] = { 5340 SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC), 5341 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC), 5342 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), 5343 SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700), 5344 SND_PCI_QUIRK(0x1025, 0x072d, "Acer Aspire V5-571G", ALC269_FIXUP_ASPIRE_HEADSET_MIC), 5345 SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC), 5346 SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK), 5347 SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK), 5348 SND_PCI_QUIRK(0x1025, 0x0762, "Acer Aspire E1-472", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572), 5349 SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572), 5350 SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS), 5351 SND_PCI_QUIRK(0x1025, 0x106d, "Acer Cloudbook 14", ALC283_FIXUP_CHROME_BOOK), 5352 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), 5353 SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS), 5354 SND_PCI_QUIRK(0x1028, 0x05bd, "Dell Latitude E6440", ALC292_FIXUP_DELL_E7X), 5355 SND_PCI_QUIRK(0x1028, 0x05be, "Dell Latitude E6540", ALC292_FIXUP_DELL_E7X), 5356 SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X), 5357 SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X), 5358 SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER), 5359 SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 5360 SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 5361 SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 5362 SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK), 5363 SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK), 5364 SND_PCI_QUIRK(0x1028, 0x062c, "Dell Latitude E5550", ALC292_FIXUP_DELL_E7X), 5365 SND_PCI_QUIRK(0x1028, 0x062e, "Dell Latitude E7450", ALC292_FIXUP_DELL_E7X), 5366 SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK), 5367 SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), 5368 SND_PCI_QUIRK(0x1028, 0x064b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), 5369 SND_PCI_QUIRK(0x1028, 0x0665, "Dell XPS 13", ALC288_FIXUP_DELL_XPS_13), 5370 SND_PCI_QUIRK(0x1028, 0x0669, "Dell Optiplex 9020m", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), 5371 SND_PCI_QUIRK(0x1028, 0x069a, "Dell Vostro 5480", ALC290_FIXUP_SUBWOOFER_HSJACK), 5372 SND_PCI_QUIRK(0x1028, 0x06c7, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), 5373 SND_PCI_QUIRK(0x1028, 0x06d9, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), 5374 SND_PCI_QUIRK(0x1028, 0x06da, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), 5375 SND_PCI_QUIRK(0x1028, 0x06db, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK), 5376 SND_PCI_QUIRK(0x1028, 0x06dd, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK), 5377 SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK), 5378 SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK), 5379 SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK), 5380 SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13 9350", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE), 5381 SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE), 5382 SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE), 5383 SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), 5384 SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), 5385 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), 5386 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED), 5387 SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED), 5388 SND_PCI_QUIRK(0x103c, 0x225f, "HP", ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY), 5389 /* ALC282 */ 5390 SND_PCI_QUIRK(0x103c, 0x21f9, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 5391 SND_PCI_QUIRK(0x103c, 0x2210, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 5392 SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 5393 SND_PCI_QUIRK(0x103c, 0x2236, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED), 5394 SND_PCI_QUIRK(0x103c, 0x2237, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED), 5395 SND_PCI_QUIRK(0x103c, 0x2238, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED), 5396 SND_PCI_QUIRK(0x103c, 0x2239, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED), 5397 SND_PCI_QUIRK(0x103c, 0x224b, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED), 5398 SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 5399 SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 5400 SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 5401 SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 5402 SND_PCI_QUIRK(0x103c, 0x2271, "HP", ALC286_FIXUP_HP_GPIO_LED), 5403 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC280_FIXUP_HP_DOCK_PINS), 5404 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC280_FIXUP_HP_DOCK_PINS), 5405 SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 5406 SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 5407 SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 5408 SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 5409 SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 5410 SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 5411 SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 5412 /* ALC290 */ 5413 SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 5414 SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 5415 SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 5416 SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 5417 SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 5418 SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 5419 SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 5420 SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 5421 SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 5422 SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 5423 SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 5424 SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 5425 SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 5426 SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 5427 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 5428 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 5429 SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 5430 SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 5431 SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 5432 SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 5433 SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 5434 SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 5435 SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 5436 SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 5437 SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 5438 SND_PCI_QUIRK(0x103c, 0x2334, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 5439 SND_PCI_QUIRK(0x103c, 0x2335, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 5440 SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 5441 SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 5442 SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC), 5443 SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC), 5444 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), 5445 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 5446 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 5447 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), 5448 SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), 5449 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), 5450 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), 5451 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), 5452 SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 5453 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), 5454 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), 5455 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), 5456 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), 5457 SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101), 5458 SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), 5459 SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), 5460 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), 5461 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), 5462 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), 5463 SND_PCI_QUIRK(0x104d, 0x9099, "Sony VAIO S13", ALC275_FIXUP_SONY_DISABLE_AAMIX), 5464 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK), 5465 SND_PCI_QUIRK(0x10cf, 0x159f, "Lifebook E780", ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT), 5466 SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN), 5467 SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN), 5468 SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC), 5469 SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC), 5470 SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_BXBT2807_MIC), 5471 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), 5472 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), 5473 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), 5474 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), 5475 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), 5476 SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK), 5477 SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK), 5478 SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK), 5479 SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK), 5480 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK), 5481 SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK), 5482 SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad T440s", ALC292_FIXUP_TPT440), 5483 SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK), 5484 SND_PCI_QUIRK(0x17aa, 0x2210, "Thinkpad T540p", ALC292_FIXUP_TPT440_DOCK), 5485 SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK), 5486 SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad X240", ALC292_FIXUP_TPT440_DOCK), 5487 SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 5488 SND_PCI_QUIRK(0x17aa, 0x2218, "Thinkpad X1 Carbon 2nd", ALC292_FIXUP_TPT440_DOCK), 5489 SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK), 5490 SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK), 5491 SND_PCI_QUIRK(0x17aa, 0x2231, "Thinkpad T560", ALC292_FIXUP_TPT460), 5492 SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC292_FIXUP_TPT460), 5493 SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), 5494 SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), 5495 SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI), 5496 SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC), 5497 SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP), 5498 SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 5499 SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC), 5500 SND_PCI_QUIRK(0x17aa, 0x501e, "Thinkpad L440", ALC292_FIXUP_TPT440_DOCK), 5501 SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 5502 SND_PCI_QUIRK(0x17aa, 0x5034, "Thinkpad T450", ALC292_FIXUP_TPT440_DOCK), 5503 SND_PCI_QUIRK(0x17aa, 0x5036, "Thinkpad T450s", ALC292_FIXUP_TPT440_DOCK), 5504 SND_PCI_QUIRK(0x17aa, 0x503c, "Thinkpad L450", ALC292_FIXUP_TPT440_DOCK), 5505 SND_PCI_QUIRK(0x17aa, 0x504a, "ThinkPad X260", ALC292_FIXUP_TPT440_DOCK), 5506 SND_PCI_QUIRK(0x17aa, 0x504b, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE), 5507 SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 5508 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), 5509 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), 5510 SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */ 5511 5512#if 0 5513 /* Below is a quirk table taken from the old code. 5514 * Basically the device should work as is without the fixup table. 5515 * If BIOS doesn't give a proper info, enable the corresponding 5516 * fixup entry. 5517 */ 5518 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", 5519 ALC269_FIXUP_AMIC), 5520 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC), 5521 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC), 5522 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC), 5523 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC), 5524 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC), 5525 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC), 5526 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC), 5527 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC), 5528 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC), 5529 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC), 5530 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC), 5531 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC), 5532 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC), 5533 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC), 5534 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC), 5535 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC), 5536 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC), 5537 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC), 5538 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC), 5539 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC), 5540 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC), 5541 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC), 5542 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC), 5543 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC), 5544 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC), 5545 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC), 5546 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC), 5547 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC), 5548 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC), 5549 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC), 5550 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC), 5551 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC), 5552 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC), 5553 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC), 5554 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC), 5555 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC), 5556 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC), 5557 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC), 5558 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC), 5559#endif 5560 {} 5561}; 5562 5563static const struct snd_pci_quirk alc269_fixup_vendor_tbl[] = { 5564 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC), 5565 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED), 5566 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), 5567 SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI), 5568 {} 5569}; 5570 5571static const struct hda_model_fixup alc269_fixup_models[] = { 5572 {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"}, 5573 {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"}, 5574 {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"}, 5575 {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"}, 5576 {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"}, 5577 {.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"}, 5578 {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"}, 5579 {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"}, 5580 {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, 5581 {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"}, 5582 {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"}, 5583 {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"}, 5584 {.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"}, 5585 {.id = ALC292_FIXUP_TPT440, .name = "tpt440"}, 5586 {.id = ALC292_FIXUP_TPT460, .name = "tpt460"}, 5587 {} 5588}; 5589#define ALC225_STANDARD_PINS \ 5590 {0x12, 0xb7a60130}, \ 5591 {0x21, 0x04211020} 5592 5593#define ALC255_STANDARD_PINS \ 5594 {0x18, 0x411111f0}, \ 5595 {0x19, 0x411111f0}, \ 5596 {0x1a, 0x411111f0}, \ 5597 {0x1b, 0x411111f0}, \ 5598 {0x1e, 0x411111f0} 5599 5600#define ALC256_STANDARD_PINS \ 5601 {0x12, 0x90a60140}, \ 5602 {0x14, 0x90170110}, \ 5603 {0x19, 0x411111f0}, \ 5604 {0x1a, 0x411111f0}, \ 5605 {0x1b, 0x411111f0}, \ 5606 {0x1d, 0x40700001}, \ 5607 {0x1e, 0x411111f0}, \ 5608 {0x21, 0x02211020} 5609 5610#define ALC282_STANDARD_PINS \ 5611 {0x14, 0x90170110}, \ 5612 {0x18, 0x411111f0}, \ 5613 {0x1a, 0x411111f0}, \ 5614 {0x1b, 0x411111f0}, \ 5615 {0x1e, 0x411111f0} 5616 5617#define ALC288_STANDARD_PINS \ 5618 {0x17, 0x411111f0}, \ 5619 {0x18, 0x411111f0}, \ 5620 {0x19, 0x411111f0}, \ 5621 {0x1a, 0x411111f0}, \ 5622 {0x1e, 0x411111f0} 5623 5624#define ALC290_STANDARD_PINS \ 5625 {0x12, 0x99a30130}, \ 5626 {0x13, 0x40000000}, \ 5627 {0x16, 0x411111f0}, \ 5628 {0x17, 0x411111f0}, \ 5629 {0x19, 0x411111f0}, \ 5630 {0x1b, 0x411111f0}, \ 5631 {0x1e, 0x411111f0} 5632 5633#define ALC292_STANDARD_PINS \ 5634 {0x14, 0x90170110}, \ 5635 {0x15, 0x0221401f}, \ 5636 {0x1a, 0x411111f0}, \ 5637 {0x1b, 0x411111f0}, \ 5638 {0x1d, 0x40700001}, \ 5639 {0x1e, 0x411111f0} 5640 5641#define ALC298_STANDARD_PINS \ 5642 {0x18, 0x411111f0}, \ 5643 {0x19, 0x411111f0}, \ 5644 {0x1a, 0x411111f0}, \ 5645 {0x1e, 0x411111f0}, \ 5646 {0x1f, 0x411111f0} 5647 5648static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { 5649 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE, 5650 ALC225_STANDARD_PINS, 5651 {0x14, 0x901701a0}), 5652 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE, 5653 ALC225_STANDARD_PINS, 5654 {0x14, 0x901701b0}), 5655 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, 5656 ALC255_STANDARD_PINS, 5657 {0x12, 0x40300000}, 5658 {0x14, 0x90170110}, 5659 {0x17, 0x411111f0}, 5660 {0x1d, 0x40538029}, 5661 {0x21, 0x02211020}), 5662 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 5663 ALC255_STANDARD_PINS, 5664 {0x12, 0x90a60140}, 5665 {0x14, 0x90170110}, 5666 {0x17, 0x40000000}, 5667 {0x1d, 0x40700001}, 5668 {0x21, 0x02211020}), 5669 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 5670 ALC255_STANDARD_PINS, 5671 {0x12, 0x90a60160}, 5672 {0x14, 0x90170120}, 5673 {0x17, 0x40000000}, 5674 {0x1d, 0x40700001}, 5675 {0x21, 0x02211030}), 5676 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 5677 {0x12, 0x40000000}, 5678 {0x14, 0x90170130}, 5679 {0x17, 0x411111f0}, 5680 {0x18, 0x411111f0}, 5681 {0x19, 0x411111f0}, 5682 {0x1a, 0x411111f0}, 5683 {0x1b, 0x01014020}, 5684 {0x1d, 0x4054c029}, 5685 {0x1e, 0x411111f0}, 5686 {0x21, 0x0221103f}), 5687 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 5688 {0x12, 0x90a60160}, 5689 {0x14, 0x90170120}, 5690 {0x17, 0x90170140}, 5691 {0x18, 0x40000000}, 5692 {0x19, 0x411111f0}, 5693 {0x1a, 0x411111f0}, 5694 {0x1b, 0x411111f0}, 5695 {0x1d, 0x41163b05}, 5696 {0x1e, 0x411111f0}, 5697 {0x21, 0x0321102f}), 5698 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 5699 ALC255_STANDARD_PINS, 5700 {0x12, 0x90a60160}, 5701 {0x14, 0x90170130}, 5702 {0x17, 0x40000000}, 5703 {0x1d, 0x40700001}, 5704 {0x21, 0x02211040}), 5705 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 5706 ALC255_STANDARD_PINS, 5707 {0x12, 0x90a60160}, 5708 {0x14, 0x90170140}, 5709 {0x17, 0x40000000}, 5710 {0x1d, 0x40700001}, 5711 {0x21, 0x02211050}), 5712 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 5713 ALC255_STANDARD_PINS, 5714 {0x12, 0x90a60170}, 5715 {0x14, 0x90170120}, 5716 {0x17, 0x40000000}, 5717 {0x1d, 0x40700001}, 5718 {0x21, 0x02211030}), 5719 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 5720 ALC255_STANDARD_PINS, 5721 {0x12, 0x90a60170}, 5722 {0x14, 0x90170130}, 5723 {0x17, 0x40000000}, 5724 {0x1d, 0x40700001}, 5725 {0x21, 0x02211040}), 5726 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 5727 ALC255_STANDARD_PINS, 5728 {0x12, 0x90a60170}, 5729 {0x14, 0x90171130}, 5730 {0x21, 0x02211040}), 5731 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 5732 {0x12, 0x90a60170}, 5733 {0x14, 0x90170140}, 5734 {0x17, 0x40000000}, 5735 {0x1d, 0x40700001}, 5736 {0x21, 0x02211050}), 5737 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5548", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 5738 ALC255_STANDARD_PINS, 5739 {0x12, 0x90a60180}, 5740 {0x14, 0x90170130}, 5741 {0x17, 0x40000000}, 5742 {0x1d, 0x40700001}, 5743 {0x21, 0x02211040}), 5744 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5565", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 5745 {0x12, 0x90a60180}, 5746 {0x14, 0x90170120}, 5747 {0x21, 0x02211030}), 5748 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 5749 ALC255_STANDARD_PINS, 5750 {0x12, 0x90a60160}, 5751 {0x14, 0x90170120}, 5752 {0x17, 0x40000000}, 5753 {0x1d, 0x40700001}, 5754 {0x21, 0x02211030}), 5755 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 5756 ALC256_STANDARD_PINS, 5757 {0x13, 0x40000000}), 5758 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 5759 ALC256_STANDARD_PINS, 5760 {0x13, 0x411111f0}), 5761 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4, 5762 {0x12, 0x90a60130}, 5763 {0x13, 0x40000000}, 5764 {0x14, 0x90170110}, 5765 {0x15, 0x0421101f}, 5766 {0x16, 0x411111f0}, 5767 {0x17, 0x411111f0}, 5768 {0x18, 0x411111f0}, 5769 {0x19, 0x411111f0}, 5770 {0x1a, 0x04a11020}, 5771 {0x1b, 0x411111f0}, 5772 {0x1d, 0x40748605}, 5773 {0x1e, 0x411111f0}), 5774 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED, 5775 {0x12, 0x90a60140}, 5776 {0x13, 0x40000000}, 5777 {0x14, 0x90170110}, 5778 {0x15, 0x0421101f}, 5779 {0x16, 0x411111f0}, 5780 {0x17, 0x411111f0}, 5781 {0x18, 0x02811030}, 5782 {0x19, 0x411111f0}, 5783 {0x1a, 0x04a1103f}, 5784 {0x1b, 0x02011020}, 5785 {0x1d, 0x40700001}, 5786 {0x1e, 0x411111f0}), 5787 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP 15 Touchsmart", ALC269_FIXUP_HP_MUTE_LED_MIC1, 5788 ALC282_STANDARD_PINS, 5789 {0x12, 0x99a30130}, 5790 {0x17, 0x40000000}, 5791 {0x19, 0x03a11020}, 5792 {0x1d, 0x40f41905}, 5793 {0x21, 0x0321101f}), 5794 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1, 5795 ALC282_STANDARD_PINS, 5796 {0x12, 0x99a30130}, 5797 {0x17, 0x40020008}, 5798 {0x19, 0x03a11020}, 5799 {0x1d, 0x40e00001}, 5800 {0x21, 0x03211040}), 5801 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1, 5802 ALC282_STANDARD_PINS, 5803 {0x12, 0x99a30130}, 5804 {0x17, 0x40000000}, 5805 {0x19, 0x03a11030}, 5806 {0x1d, 0x40e00001}, 5807 {0x21, 0x03211020}), 5808 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1, 5809 ALC282_STANDARD_PINS, 5810 {0x12, 0x99a30130}, 5811 {0x17, 0x40000000}, 5812 {0x19, 0x03a11030}, 5813 {0x1d, 0x40f00001}, 5814 {0x21, 0x03211020}), 5815 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1, 5816 ALC282_STANDARD_PINS, 5817 {0x12, 0x99a30130}, 5818 {0x17, 0x40000000}, 5819 {0x19, 0x04a11020}, 5820 {0x1d, 0x40f00001}, 5821 {0x21, 0x0421101f}), 5822 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1, 5823 ALC282_STANDARD_PINS, 5824 {0x12, 0x99a30130}, 5825 {0x17, 0x40000000}, 5826 {0x19, 0x03a11030}, 5827 {0x1d, 0x40f00001}, 5828 {0x21, 0x04211020}), 5829 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED, 5830 ALC282_STANDARD_PINS, 5831 {0x12, 0x90a60140}, 5832 {0x17, 0x40000000}, 5833 {0x19, 0x04a11030}, 5834 {0x1d, 0x40f00001}, 5835 {0x21, 0x04211020}), 5836 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, 5837 ALC282_STANDARD_PINS, 5838 {0x12, 0x90a60130}, 5839 {0x17, 0x40020008}, 5840 {0x19, 0x411111f0}, 5841 {0x1d, 0x40e00001}, 5842 {0x21, 0x0321101f}), 5843 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, 5844 {0x12, 0x90a60160}, 5845 {0x14, 0x90170120}, 5846 {0x17, 0x40000000}, 5847 {0x18, 0x411111f0}, 5848 {0x19, 0x411111f0}, 5849 {0x1a, 0x411111f0}, 5850 {0x1b, 0x411111f0}, 5851 {0x1d, 0x40700001}, 5852 {0x1e, 0x411111f0}, 5853 {0x21, 0x02211030}), 5854 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, 5855 ALC282_STANDARD_PINS, 5856 {0x12, 0x90a60130}, 5857 {0x17, 0x40020008}, 5858 {0x19, 0x03a11020}, 5859 {0x1d, 0x40e00001}, 5860 {0x21, 0x0321101f}), 5861 SND_HDA_PIN_QUIRK(0x10ec0288, 0x1028, "Dell", ALC288_FIXUP_DELL_XPS_13_GPIO6, 5862 ALC288_STANDARD_PINS, 5863 {0x12, 0x90a60120}, 5864 {0x13, 0x40000000}, 5865 {0x14, 0x90170110}, 5866 {0x1d, 0x4076832d}, 5867 {0x21, 0x0321101f}), 5868 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1, 5869 ALC290_STANDARD_PINS, 5870 {0x14, 0x411111f0}, 5871 {0x15, 0x04211040}, 5872 {0x18, 0x90170112}, 5873 {0x1a, 0x04a11020}, 5874 {0x1d, 0x4075812d}), 5875 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1, 5876 ALC290_STANDARD_PINS, 5877 {0x14, 0x411111f0}, 5878 {0x15, 0x04211040}, 5879 {0x18, 0x90170110}, 5880 {0x1a, 0x04a11020}, 5881 {0x1d, 0x4075812d}), 5882 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1, 5883 ALC290_STANDARD_PINS, 5884 {0x14, 0x411111f0}, 5885 {0x15, 0x0421101f}, 5886 {0x18, 0x411111f0}, 5887 {0x1a, 0x04a11020}, 5888 {0x1d, 0x4075812d}), 5889 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1, 5890 ALC290_STANDARD_PINS, 5891 {0x14, 0x411111f0}, 5892 {0x15, 0x04211020}, 5893 {0x18, 0x411111f0}, 5894 {0x1a, 0x04a11040}, 5895 {0x1d, 0x4076a12d}), 5896 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1, 5897 ALC290_STANDARD_PINS, 5898 {0x14, 0x90170110}, 5899 {0x15, 0x04211020}, 5900 {0x18, 0x411111f0}, 5901 {0x1a, 0x04a11040}, 5902 {0x1d, 0x4076a12d}), 5903 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1, 5904 ALC290_STANDARD_PINS, 5905 {0x14, 0x90170110}, 5906 {0x15, 0x04211020}, 5907 {0x18, 0x411111f0}, 5908 {0x1a, 0x04a11020}, 5909 {0x1d, 0x4076a12d}), 5910 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1, 5911 ALC290_STANDARD_PINS, 5912 {0x14, 0x90170110}, 5913 {0x15, 0x0421101f}, 5914 {0x18, 0x411111f0}, 5915 {0x1a, 0x04a11020}, 5916 {0x1d, 0x4075812d}), 5917 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, 5918 ALC292_STANDARD_PINS, 5919 {0x12, 0x90a60140}, 5920 {0x13, 0x411111f0}, 5921 {0x16, 0x01014020}, 5922 {0x18, 0x411111f0}, 5923 {0x19, 0x01a19030}), 5924 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, 5925 ALC292_STANDARD_PINS, 5926 {0x12, 0x90a60140}, 5927 {0x13, 0x411111f0}, 5928 {0x16, 0x01014020}, 5929 {0x18, 0x02a19031}, 5930 {0x19, 0x01a1903e}), 5931 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, 5932 ALC292_STANDARD_PINS, 5933 {0x12, 0x90a60140}, 5934 {0x13, 0x411111f0}, 5935 {0x16, 0x411111f0}, 5936 {0x18, 0x411111f0}, 5937 {0x19, 0x411111f0}), 5938 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, 5939 ALC292_STANDARD_PINS, 5940 {0x12, 0x40000000}, 5941 {0x13, 0x90a60140}, 5942 {0x16, 0x21014020}, 5943 {0x18, 0x411111f0}, 5944 {0x19, 0x21a19030}), 5945 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, 5946 ALC292_STANDARD_PINS, 5947 {0x12, 0x40000000}, 5948 {0x13, 0x90a60140}, 5949 {0x16, 0x411111f0}, 5950 {0x18, 0x411111f0}, 5951 {0x19, 0x411111f0}), 5952 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, 5953 ALC298_STANDARD_PINS, 5954 {0x12, 0x90a60130}, 5955 {0x13, 0x40000000}, 5956 {0x14, 0x411111f0}, 5957 {0x17, 0x90170140}, 5958 {0x1d, 0x4068a36d}, 5959 {0x21, 0x03211020}), 5960 {} 5961}; 5962 5963static void alc269_fill_coef(struct hda_codec *codec) 5964{ 5965 struct alc_spec *spec = codec->spec; 5966 int val; 5967 5968 if (spec->codec_variant != ALC269_TYPE_ALC269VB) 5969 return; 5970 5971 if ((alc_get_coef0(codec) & 0x00ff) < 0x015) { 5972 alc_write_coef_idx(codec, 0xf, 0x960b); 5973 alc_write_coef_idx(codec, 0xe, 0x8817); 5974 } 5975 5976 if ((alc_get_coef0(codec) & 0x00ff) == 0x016) { 5977 alc_write_coef_idx(codec, 0xf, 0x960b); 5978 alc_write_coef_idx(codec, 0xe, 0x8814); 5979 } 5980 5981 if ((alc_get_coef0(codec) & 0x00ff) == 0x017) { 5982 /* Power up output pin */ 5983 alc_update_coef_idx(codec, 0x04, 0, 1<<11); 5984 } 5985 5986 if ((alc_get_coef0(codec) & 0x00ff) == 0x018) { 5987 val = alc_read_coef_idx(codec, 0xd); 5988 if (val != -1 && (val & 0x0c00) >> 10 != 0x1) { 5989 /* Capless ramp up clock control */ 5990 alc_write_coef_idx(codec, 0xd, val | (1<<10)); 5991 } 5992 val = alc_read_coef_idx(codec, 0x17); 5993 if (val != -1 && (val & 0x01c0) >> 6 != 0x4) { 5994 /* Class D power on reset */ 5995 alc_write_coef_idx(codec, 0x17, val | (1<<7)); 5996 } 5997 } 5998 5999 /* HP */ 6000 alc_update_coef_idx(codec, 0x4, 0, 1<<11); 6001} 6002 6003/* 6004 */ 6005static int patch_alc269(struct hda_codec *codec) 6006{ 6007 struct alc_spec *spec; 6008 int err; 6009 6010 err = alc_alloc_spec(codec, 0x0b); 6011 if (err < 0) 6012 return err; 6013 6014 spec = codec->spec; 6015 spec->gen.shared_mic_vref_pin = 0x18; 6016 codec->power_save_node = 1; 6017 6018 snd_hda_pick_fixup(codec, alc269_fixup_models, 6019 alc269_fixup_tbl, alc269_fixups); 6020 snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups); 6021 snd_hda_pick_fixup(codec, NULL, alc269_fixup_vendor_tbl, 6022 alc269_fixups); 6023 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 6024 6025 alc_auto_parse_customize_define(codec); 6026 6027 if (has_cdefine_beep(codec)) 6028 spec->gen.beep_nid = 0x01; 6029 6030 switch (codec->core.vendor_id) { 6031 case 0x10ec0269: 6032 spec->codec_variant = ALC269_TYPE_ALC269VA; 6033 switch (alc_get_coef0(codec) & 0x00f0) { 6034 case 0x0010: 6035 if (codec->bus->pci && 6036 codec->bus->pci->subsystem_vendor == 0x1025 && 6037 spec->cdefine.platform_type == 1) 6038 err = alc_codec_rename(codec, "ALC271X"); 6039 spec->codec_variant = ALC269_TYPE_ALC269VB; 6040 break; 6041 case 0x0020: 6042 if (codec->bus->pci && 6043 codec->bus->pci->subsystem_vendor == 0x17aa && 6044 codec->bus->pci->subsystem_device == 0x21f3) 6045 err = alc_codec_rename(codec, "ALC3202"); 6046 spec->codec_variant = ALC269_TYPE_ALC269VC; 6047 break; 6048 case 0x0030: 6049 spec->codec_variant = ALC269_TYPE_ALC269VD; 6050 break; 6051 default: 6052 alc_fix_pll_init(codec, 0x20, 0x04, 15); 6053 } 6054 if (err < 0) 6055 goto error; 6056 spec->init_hook = alc269_fill_coef; 6057 alc269_fill_coef(codec); 6058 break; 6059 6060 case 0x10ec0280: 6061 case 0x10ec0290: 6062 spec->codec_variant = ALC269_TYPE_ALC280; 6063 break; 6064 case 0x10ec0282: 6065 spec->codec_variant = ALC269_TYPE_ALC282; 6066 spec->shutup = alc282_shutup; 6067 spec->init_hook = alc282_init; 6068 break; 6069 case 0x10ec0233: 6070 case 0x10ec0283: 6071 spec->codec_variant = ALC269_TYPE_ALC283; 6072 spec->shutup = alc283_shutup; 6073 spec->init_hook = alc283_init; 6074 break; 6075 case 0x10ec0284: 6076 case 0x10ec0292: 6077 spec->codec_variant = ALC269_TYPE_ALC284; 6078 break; 6079 case 0x10ec0285: 6080 case 0x10ec0293: 6081 spec->codec_variant = ALC269_TYPE_ALC285; 6082 break; 6083 case 0x10ec0286: 6084 case 0x10ec0288: 6085 spec->codec_variant = ALC269_TYPE_ALC286; 6086 spec->shutup = alc286_shutup; 6087 break; 6088 case 0x10ec0298: 6089 spec->codec_variant = ALC269_TYPE_ALC298; 6090 break; 6091 case 0x10ec0255: 6092 spec->codec_variant = ALC269_TYPE_ALC255; 6093 break; 6094 case 0x10ec0256: 6095 spec->codec_variant = ALC269_TYPE_ALC256; 6096 spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */ 6097 alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/ 6098 break; 6099 } 6100 6101 if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) { 6102 spec->has_alc5505_dsp = 1; 6103 spec->init_hook = alc5505_dsp_init; 6104 } 6105 6106 /* automatic parse from the BIOS config */ 6107 err = alc269_parse_auto_config(codec); 6108 if (err < 0) 6109 goto error; 6110 6111 if (!spec->gen.no_analog && spec->gen.beep_nid && spec->gen.mixer_nid) 6112 set_beep_amp(spec, spec->gen.mixer_nid, 0x04, HDA_INPUT); 6113 6114 codec->patch_ops = alc_patch_ops; 6115 codec->patch_ops.stream_pm = snd_hda_gen_stream_pm; 6116#ifdef CONFIG_PM 6117 codec->patch_ops.suspend = alc269_suspend; 6118 codec->patch_ops.resume = alc269_resume; 6119#endif 6120 if (!spec->shutup) 6121 spec->shutup = alc269_shutup; 6122 6123 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 6124 6125 return 0; 6126 6127 error: 6128 alc_free(codec); 6129 return err; 6130} 6131 6132/* 6133 * ALC861 6134 */ 6135 6136static int alc861_parse_auto_config(struct hda_codec *codec) 6137{ 6138 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 }; 6139 static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 }; 6140 return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids); 6141} 6142 6143/* Pin config fixes */ 6144enum { 6145 ALC861_FIXUP_FSC_AMILO_PI1505, 6146 ALC861_FIXUP_AMP_VREF_0F, 6147 ALC861_FIXUP_NO_JACK_DETECT, 6148 ALC861_FIXUP_ASUS_A6RP, 6149 ALC660_FIXUP_ASUS_W7J, 6150}; 6151 6152/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */ 6153static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec, 6154 const struct hda_fixup *fix, int action) 6155{ 6156 struct alc_spec *spec = codec->spec; 6157 unsigned int val; 6158 6159 if (action != HDA_FIXUP_ACT_INIT) 6160 return; 6161 val = snd_hda_codec_get_pin_target(codec, 0x0f); 6162 if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))) 6163 val |= AC_PINCTL_IN_EN; 6164 val |= AC_PINCTL_VREF_50; 6165 snd_hda_set_pin_ctl(codec, 0x0f, val); 6166 spec->gen.keep_vref_in_automute = 1; 6167} 6168 6169/* suppress the jack-detection */ 6170static void alc_fixup_no_jack_detect(struct hda_codec *codec, 6171 const struct hda_fixup *fix, int action) 6172{ 6173 if (action == HDA_FIXUP_ACT_PRE_PROBE) 6174 codec->no_jack_detect = 1; 6175} 6176 6177static const struct hda_fixup alc861_fixups[] = { 6178 [ALC861_FIXUP_FSC_AMILO_PI1505] = { 6179 .type = HDA_FIXUP_PINS, 6180 .v.pins = (const struct hda_pintbl[]) { 6181 { 0x0b, 0x0221101f }, /* HP */ 6182 { 0x0f, 0x90170310 }, /* speaker */ 6183 { } 6184 } 6185 }, 6186 [ALC861_FIXUP_AMP_VREF_0F] = { 6187 .type = HDA_FIXUP_FUNC, 6188 .v.func = alc861_fixup_asus_amp_vref_0f, 6189 }, 6190 [ALC861_FIXUP_NO_JACK_DETECT] = { 6191 .type = HDA_FIXUP_FUNC, 6192 .v.func = alc_fixup_no_jack_detect, 6193 }, 6194 [ALC861_FIXUP_ASUS_A6RP] = { 6195 .type = HDA_FIXUP_FUNC, 6196 .v.func = alc861_fixup_asus_amp_vref_0f, 6197 .chained = true, 6198 .chain_id = ALC861_FIXUP_NO_JACK_DETECT, 6199 }, 6200 [ALC660_FIXUP_ASUS_W7J] = { 6201 .type = HDA_FIXUP_VERBS, 6202 .v.verbs = (const struct hda_verb[]) { 6203 /* ASUS W7J needs a magic pin setup on unused NID 0x10 6204 * for enabling outputs 6205 */ 6206 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 6207 { } 6208 }, 6209 } 6210}; 6211 6212static const struct snd_pci_quirk alc861_fixup_tbl[] = { 6213 SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J), 6214 SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J), 6215 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP), 6216 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F), 6217 SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT), 6218 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F), 6219 SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F), 6220 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505), 6221 {} 6222}; 6223 6224/* 6225 */ 6226static int patch_alc861(struct hda_codec *codec) 6227{ 6228 struct alc_spec *spec; 6229 int err; 6230 6231 err = alc_alloc_spec(codec, 0x15); 6232 if (err < 0) 6233 return err; 6234 6235 spec = codec->spec; 6236 spec->gen.beep_nid = 0x23; 6237 6238 snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups); 6239 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 6240 6241 /* automatic parse from the BIOS config */ 6242 err = alc861_parse_auto_config(codec); 6243 if (err < 0) 6244 goto error; 6245 6246 if (!spec->gen.no_analog) 6247 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); 6248 6249 codec->patch_ops = alc_patch_ops; 6250#ifdef CONFIG_PM 6251 spec->power_hook = alc_power_eapd; 6252#endif 6253 6254 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 6255 6256 return 0; 6257 6258 error: 6259 alc_free(codec); 6260 return err; 6261} 6262 6263/* 6264 * ALC861-VD support 6265 * 6266 * Based on ALC882 6267 * 6268 * In addition, an independent DAC 6269 */ 6270static int alc861vd_parse_auto_config(struct hda_codec *codec) 6271{ 6272 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; 6273 static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 }; 6274 return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids); 6275} 6276 6277enum { 6278 ALC660VD_FIX_ASUS_GPIO1, 6279 ALC861VD_FIX_DALLAS, 6280}; 6281 6282/* exclude VREF80 */ 6283static void alc861vd_fixup_dallas(struct hda_codec *codec, 6284 const struct hda_fixup *fix, int action) 6285{ 6286 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 6287 snd_hda_override_pin_caps(codec, 0x18, 0x00000734); 6288 snd_hda_override_pin_caps(codec, 0x19, 0x0000073c); 6289 } 6290} 6291 6292static const struct hda_fixup alc861vd_fixups[] = { 6293 [ALC660VD_FIX_ASUS_GPIO1] = { 6294 .type = HDA_FIXUP_VERBS, 6295 .v.verbs = (const struct hda_verb[]) { 6296 /* reset GPIO1 */ 6297 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 6298 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 6299 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 6300 { } 6301 } 6302 }, 6303 [ALC861VD_FIX_DALLAS] = { 6304 .type = HDA_FIXUP_FUNC, 6305 .v.func = alc861vd_fixup_dallas, 6306 }, 6307}; 6308 6309static const struct snd_pci_quirk alc861vd_fixup_tbl[] = { 6310 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS), 6311 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1), 6312 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS), 6313 {} 6314}; 6315 6316/* 6317 */ 6318static int patch_alc861vd(struct hda_codec *codec) 6319{ 6320 struct alc_spec *spec; 6321 int err; 6322 6323 err = alc_alloc_spec(codec, 0x0b); 6324 if (err < 0) 6325 return err; 6326 6327 spec = codec->spec; 6328 spec->gen.beep_nid = 0x23; 6329 6330 snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups); 6331 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 6332 6333 /* automatic parse from the BIOS config */ 6334 err = alc861vd_parse_auto_config(codec); 6335 if (err < 0) 6336 goto error; 6337 6338 if (!spec->gen.no_analog) 6339 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 6340 6341 codec->patch_ops = alc_patch_ops; 6342 6343 spec->shutup = alc_eapd_shutup; 6344 6345 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 6346 6347 return 0; 6348 6349 error: 6350 alc_free(codec); 6351 return err; 6352} 6353 6354/* 6355 * ALC662 support 6356 * 6357 * ALC662 is almost identical with ALC880 but has cleaner and more flexible 6358 * configuration. Each pin widget can choose any input DACs and a mixer. 6359 * Each ADC is connected from a mixer of all inputs. This makes possible 6360 * 6-channel independent captures. 6361 * 6362 * In addition, an independent DAC for the multi-playback (not used in this 6363 * driver yet). 6364 */ 6365 6366/* 6367 * BIOS auto configuration 6368 */ 6369 6370static int alc662_parse_auto_config(struct hda_codec *codec) 6371{ 6372 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 }; 6373 static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 }; 6374 static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 }; 6375 const hda_nid_t *ssids; 6376 6377 if (codec->core.vendor_id == 0x10ec0272 || codec->core.vendor_id == 0x10ec0663 || 6378 codec->core.vendor_id == 0x10ec0665 || codec->core.vendor_id == 0x10ec0670 || 6379 codec->core.vendor_id == 0x10ec0671) 6380 ssids = alc663_ssids; 6381 else 6382 ssids = alc662_ssids; 6383 return alc_parse_auto_config(codec, alc662_ignore, ssids); 6384} 6385 6386static void alc272_fixup_mario(struct hda_codec *codec, 6387 const struct hda_fixup *fix, int action) 6388{ 6389 if (action != HDA_FIXUP_ACT_PRE_PROBE) 6390 return; 6391 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT, 6392 (0x3b << AC_AMPCAP_OFFSET_SHIFT) | 6393 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) | 6394 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) | 6395 (0 << AC_AMPCAP_MUTE_SHIFT))) 6396 codec_warn(codec, "failed to override amp caps for NID 0x2\n"); 6397} 6398 6399static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = { 6400 { .channels = 2, 6401 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } }, 6402 { .channels = 4, 6403 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, 6404 SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */ 6405 { } 6406}; 6407 6408/* override the 2.1 chmap */ 6409static void alc_fixup_bass_chmap(struct hda_codec *codec, 6410 const struct hda_fixup *fix, int action) 6411{ 6412 if (action == HDA_FIXUP_ACT_BUILD) { 6413 struct alc_spec *spec = codec->spec; 6414 spec->gen.pcm_rec[0]->stream[0].chmap = asus_pcm_2_1_chmaps; 6415 } 6416} 6417 6418/* avoid D3 for keeping GPIO up */ 6419static unsigned int gpio_led_power_filter(struct hda_codec *codec, 6420 hda_nid_t nid, 6421 unsigned int power_state) 6422{ 6423 struct alc_spec *spec = codec->spec; 6424 if (nid == codec->core.afg && power_state == AC_PWRST_D3 && spec->gpio_led) 6425 return AC_PWRST_D0; 6426 return power_state; 6427} 6428 6429static void alc662_fixup_led_gpio1(struct hda_codec *codec, 6430 const struct hda_fixup *fix, int action) 6431{ 6432 struct alc_spec *spec = codec->spec; 6433 static const struct hda_verb gpio_init[] = { 6434 { 0x01, AC_VERB_SET_GPIO_MASK, 0x01 }, 6435 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01 }, 6436 {} 6437 }; 6438 6439 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 6440 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; 6441 spec->gpio_led = 0; 6442 spec->mute_led_polarity = 1; 6443 spec->gpio_mute_led_mask = 0x01; 6444 snd_hda_add_verbs(codec, gpio_init); 6445 codec->power_filter = gpio_led_power_filter; 6446 } 6447} 6448 6449static struct coef_fw alc668_coefs[] = { 6450 WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03, 0x0), 6451 WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06, 0x0), WRITE_COEF(0x07, 0x0f80), 6452 WRITE_COEF(0x08, 0x0031), WRITE_COEF(0x0a, 0x0060), WRITE_COEF(0x0b, 0x0), 6453 WRITE_COEF(0x0c, 0x7cf7), WRITE_COEF(0x0d, 0x1080), WRITE_COEF(0x0e, 0x7f7f), 6454 WRITE_COEF(0x0f, 0xcccc), WRITE_COEF(0x10, 0xddcc), WRITE_COEF(0x11, 0x0001), 6455 WRITE_COEF(0x13, 0x0), WRITE_COEF(0x14, 0x2aa0), WRITE_COEF(0x17, 0xa940), 6456 WRITE_COEF(0x19, 0x0), WRITE_COEF(0x1a, 0x0), WRITE_COEF(0x1b, 0x0), 6457 WRITE_COEF(0x1c, 0x0), WRITE_COEF(0x1d, 0x0), WRITE_COEF(0x1e, 0x7418), 6458 WRITE_COEF(0x1f, 0x0804), WRITE_COEF(0x20, 0x4200), WRITE_COEF(0x21, 0x0468), 6459 WRITE_COEF(0x22, 0x8ccc), WRITE_COEF(0x23, 0x0250), WRITE_COEF(0x24, 0x7418), 6460 WRITE_COEF(0x27, 0x0), WRITE_COEF(0x28, 0x8ccc), WRITE_COEF(0x2a, 0xff00), 6461 WRITE_COEF(0x2b, 0x8000), WRITE_COEF(0xa7, 0xff00), WRITE_COEF(0xa8, 0x8000), 6462 WRITE_COEF(0xaa, 0x2e17), WRITE_COEF(0xab, 0xa0c0), WRITE_COEF(0xac, 0x0), 6463 WRITE_COEF(0xad, 0x0), WRITE_COEF(0xae, 0x2ac6), WRITE_COEF(0xaf, 0xa480), 6464 WRITE_COEF(0xb0, 0x0), WRITE_COEF(0xb1, 0x0), WRITE_COEF(0xb2, 0x0), 6465 WRITE_COEF(0xb3, 0x0), WRITE_COEF(0xb4, 0x0), WRITE_COEF(0xb5, 0x1040), 6466 WRITE_COEF(0xb6, 0xd697), WRITE_COEF(0xb7, 0x902b), WRITE_COEF(0xb8, 0xd697), 6467 WRITE_COEF(0xb9, 0x902b), WRITE_COEF(0xba, 0xb8ba), WRITE_COEF(0xbb, 0xaaab), 6468 WRITE_COEF(0xbc, 0xaaaf), WRITE_COEF(0xbd, 0x6aaa), WRITE_COEF(0xbe, 0x1c02), 6469 WRITE_COEF(0xc0, 0x00ff), WRITE_COEF(0xc1, 0x0fa6), 6470 {} 6471}; 6472 6473static void alc668_restore_default_value(struct hda_codec *codec) 6474{ 6475 alc_process_coef_fw(codec, alc668_coefs); 6476} 6477 6478enum { 6479 ALC662_FIXUP_ASPIRE, 6480 ALC662_FIXUP_LED_GPIO1, 6481 ALC662_FIXUP_IDEAPAD, 6482 ALC272_FIXUP_MARIO, 6483 ALC662_FIXUP_CZC_P10T, 6484 ALC662_FIXUP_SKU_IGNORE, 6485 ALC662_FIXUP_HP_RP5800, 6486 ALC662_FIXUP_ASUS_MODE1, 6487 ALC662_FIXUP_ASUS_MODE2, 6488 ALC662_FIXUP_ASUS_MODE3, 6489 ALC662_FIXUP_ASUS_MODE4, 6490 ALC662_FIXUP_ASUS_MODE5, 6491 ALC662_FIXUP_ASUS_MODE6, 6492 ALC662_FIXUP_ASUS_MODE7, 6493 ALC662_FIXUP_ASUS_MODE8, 6494 ALC662_FIXUP_NO_JACK_DETECT, 6495 ALC662_FIXUP_ZOTAC_Z68, 6496 ALC662_FIXUP_INV_DMIC, 6497 ALC662_FIXUP_DELL_MIC_NO_PRESENCE, 6498 ALC668_FIXUP_DELL_MIC_NO_PRESENCE, 6499 ALC662_FIXUP_HEADSET_MODE, 6500 ALC668_FIXUP_HEADSET_MODE, 6501 ALC662_FIXUP_BASS_MODE4_CHMAP, 6502 ALC662_FIXUP_BASS_16, 6503 ALC662_FIXUP_BASS_1A, 6504 ALC662_FIXUP_BASS_CHMAP, 6505 ALC668_FIXUP_AUTO_MUTE, 6506 ALC668_FIXUP_DELL_DISABLE_AAMIX, 6507 ALC668_FIXUP_DELL_XPS13, 6508 ALC662_FIXUP_ASUS_Nx50, 6509 ALC668_FIXUP_ASUS_Nx51, 6510}; 6511 6512static const struct hda_fixup alc662_fixups[] = { 6513 [ALC662_FIXUP_ASPIRE] = { 6514 .type = HDA_FIXUP_PINS, 6515 .v.pins = (const struct hda_pintbl[]) { 6516 { 0x15, 0x99130112 }, /* subwoofer */ 6517 { } 6518 } 6519 }, 6520 [ALC662_FIXUP_LED_GPIO1] = { 6521 .type = HDA_FIXUP_FUNC, 6522 .v.func = alc662_fixup_led_gpio1, 6523 }, 6524 [ALC662_FIXUP_IDEAPAD] = { 6525 .type = HDA_FIXUP_PINS, 6526 .v.pins = (const struct hda_pintbl[]) { 6527 { 0x17, 0x99130112 }, /* subwoofer */ 6528 { } 6529 }, 6530 .chained = true, 6531 .chain_id = ALC662_FIXUP_LED_GPIO1, 6532 }, 6533 [ALC272_FIXUP_MARIO] = { 6534 .type = HDA_FIXUP_FUNC, 6535 .v.func = alc272_fixup_mario, 6536 }, 6537 [ALC662_FIXUP_CZC_P10T] = { 6538 .type = HDA_FIXUP_VERBS, 6539 .v.verbs = (const struct hda_verb[]) { 6540 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, 6541 {} 6542 } 6543 }, 6544 [ALC662_FIXUP_SKU_IGNORE] = { 6545 .type = HDA_FIXUP_FUNC, 6546 .v.func = alc_fixup_sku_ignore, 6547 }, 6548 [ALC662_FIXUP_HP_RP5800] = { 6549 .type = HDA_FIXUP_PINS, 6550 .v.pins = (const struct hda_pintbl[]) { 6551 { 0x14, 0x0221201f }, /* HP out */ 6552 { } 6553 }, 6554 .chained = true, 6555 .chain_id = ALC662_FIXUP_SKU_IGNORE 6556 }, 6557 [ALC662_FIXUP_ASUS_MODE1] = { 6558 .type = HDA_FIXUP_PINS, 6559 .v.pins = (const struct hda_pintbl[]) { 6560 { 0x14, 0x99130110 }, /* speaker */ 6561 { 0x18, 0x01a19c20 }, /* mic */ 6562 { 0x19, 0x99a3092f }, /* int-mic */ 6563 { 0x21, 0x0121401f }, /* HP out */ 6564 { } 6565 }, 6566 .chained = true, 6567 .chain_id = ALC662_FIXUP_SKU_IGNORE 6568 }, 6569 [ALC662_FIXUP_ASUS_MODE2] = { 6570 .type = HDA_FIXUP_PINS, 6571 .v.pins = (const struct hda_pintbl[]) { 6572 { 0x14, 0x99130110 }, /* speaker */ 6573 { 0x18, 0x01a19820 }, /* mic */ 6574 { 0x19, 0x99a3092f }, /* int-mic */ 6575 { 0x1b, 0x0121401f }, /* HP out */ 6576 { } 6577 }, 6578 .chained = true, 6579 .chain_id = ALC662_FIXUP_SKU_IGNORE 6580 }, 6581 [ALC662_FIXUP_ASUS_MODE3] = { 6582 .type = HDA_FIXUP_PINS, 6583 .v.pins = (const struct hda_pintbl[]) { 6584 { 0x14, 0x99130110 }, /* speaker */ 6585 { 0x15, 0x0121441f }, /* HP */ 6586 { 0x18, 0x01a19840 }, /* mic */ 6587 { 0x19, 0x99a3094f }, /* int-mic */ 6588 { 0x21, 0x01211420 }, /* HP2 */ 6589 { } 6590 }, 6591 .chained = true, 6592 .chain_id = ALC662_FIXUP_SKU_IGNORE 6593 }, 6594 [ALC662_FIXUP_ASUS_MODE4] = { 6595 .type = HDA_FIXUP_PINS, 6596 .v.pins = (const struct hda_pintbl[]) { 6597 { 0x14, 0x99130110 }, /* speaker */ 6598 { 0x16, 0x99130111 }, /* speaker */ 6599 { 0x18, 0x01a19840 }, /* mic */ 6600 { 0x19, 0x99a3094f }, /* int-mic */ 6601 { 0x21, 0x0121441f }, /* HP */ 6602 { } 6603 }, 6604 .chained = true, 6605 .chain_id = ALC662_FIXUP_SKU_IGNORE 6606 }, 6607 [ALC662_FIXUP_ASUS_MODE5] = { 6608 .type = HDA_FIXUP_PINS, 6609 .v.pins = (const struct hda_pintbl[]) { 6610 { 0x14, 0x99130110 }, /* speaker */ 6611 { 0x15, 0x0121441f }, /* HP */ 6612 { 0x16, 0x99130111 }, /* speaker */ 6613 { 0x18, 0x01a19840 }, /* mic */ 6614 { 0x19, 0x99a3094f }, /* int-mic */ 6615 { } 6616 }, 6617 .chained = true, 6618 .chain_id = ALC662_FIXUP_SKU_IGNORE 6619 }, 6620 [ALC662_FIXUP_ASUS_MODE6] = { 6621 .type = HDA_FIXUP_PINS, 6622 .v.pins = (const struct hda_pintbl[]) { 6623 { 0x14, 0x99130110 }, /* speaker */ 6624 { 0x15, 0x01211420 }, /* HP2 */ 6625 { 0x18, 0x01a19840 }, /* mic */ 6626 { 0x19, 0x99a3094f }, /* int-mic */ 6627 { 0x1b, 0x0121441f }, /* HP */ 6628 { } 6629 }, 6630 .chained = true, 6631 .chain_id = ALC662_FIXUP_SKU_IGNORE 6632 }, 6633 [ALC662_FIXUP_ASUS_MODE7] = { 6634 .type = HDA_FIXUP_PINS, 6635 .v.pins = (const struct hda_pintbl[]) { 6636 { 0x14, 0x99130110 }, /* speaker */ 6637 { 0x17, 0x99130111 }, /* speaker */ 6638 { 0x18, 0x01a19840 }, /* mic */ 6639 { 0x19, 0x99a3094f }, /* int-mic */ 6640 { 0x1b, 0x01214020 }, /* HP */ 6641 { 0x21, 0x0121401f }, /* HP */ 6642 { } 6643 }, 6644 .chained = true, 6645 .chain_id = ALC662_FIXUP_SKU_IGNORE 6646 }, 6647 [ALC662_FIXUP_ASUS_MODE8] = { 6648 .type = HDA_FIXUP_PINS, 6649 .v.pins = (const struct hda_pintbl[]) { 6650 { 0x14, 0x99130110 }, /* speaker */ 6651 { 0x12, 0x99a30970 }, /* int-mic */ 6652 { 0x15, 0x01214020 }, /* HP */ 6653 { 0x17, 0x99130111 }, /* speaker */ 6654 { 0x18, 0x01a19840 }, /* mic */ 6655 { 0x21, 0x0121401f }, /* HP */ 6656 { } 6657 }, 6658 .chained = true, 6659 .chain_id = ALC662_FIXUP_SKU_IGNORE 6660 }, 6661 [ALC662_FIXUP_NO_JACK_DETECT] = { 6662 .type = HDA_FIXUP_FUNC, 6663 .v.func = alc_fixup_no_jack_detect, 6664 }, 6665 [ALC662_FIXUP_ZOTAC_Z68] = { 6666 .type = HDA_FIXUP_PINS, 6667 .v.pins = (const struct hda_pintbl[]) { 6668 { 0x1b, 0x02214020 }, /* Front HP */ 6669 { } 6670 } 6671 }, 6672 [ALC662_FIXUP_INV_DMIC] = { 6673 .type = HDA_FIXUP_FUNC, 6674 .v.func = alc_fixup_inv_dmic, 6675 }, 6676 [ALC668_FIXUP_DELL_XPS13] = { 6677 .type = HDA_FIXUP_FUNC, 6678 .v.func = alc_fixup_dell_xps13, 6679 .chained = true, 6680 .chain_id = ALC668_FIXUP_DELL_DISABLE_AAMIX 6681 }, 6682 [ALC668_FIXUP_DELL_DISABLE_AAMIX] = { 6683 .type = HDA_FIXUP_FUNC, 6684 .v.func = alc_fixup_disable_aamix, 6685 .chained = true, 6686 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE 6687 }, 6688 [ALC668_FIXUP_AUTO_MUTE] = { 6689 .type = HDA_FIXUP_FUNC, 6690 .v.func = alc_fixup_auto_mute_via_amp, 6691 .chained = true, 6692 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE 6693 }, 6694 [ALC662_FIXUP_DELL_MIC_NO_PRESENCE] = { 6695 .type = HDA_FIXUP_PINS, 6696 .v.pins = (const struct hda_pintbl[]) { 6697 { 0x19, 0x03a1113c }, /* use as headset mic, without its own jack detect */ 6698 /* headphone mic by setting pin control of 0x1b (headphone out) to in + vref_50 */ 6699 { } 6700 }, 6701 .chained = true, 6702 .chain_id = ALC662_FIXUP_HEADSET_MODE 6703 }, 6704 [ALC662_FIXUP_HEADSET_MODE] = { 6705 .type = HDA_FIXUP_FUNC, 6706 .v.func = alc_fixup_headset_mode_alc662, 6707 }, 6708 [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = { 6709 .type = HDA_FIXUP_PINS, 6710 .v.pins = (const struct hda_pintbl[]) { 6711 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */ 6712 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */ 6713 { } 6714 }, 6715 .chained = true, 6716 .chain_id = ALC668_FIXUP_HEADSET_MODE 6717 }, 6718 [ALC668_FIXUP_HEADSET_MODE] = { 6719 .type = HDA_FIXUP_FUNC, 6720 .v.func = alc_fixup_headset_mode_alc668, 6721 }, 6722 [ALC662_FIXUP_BASS_MODE4_CHMAP] = { 6723 .type = HDA_FIXUP_FUNC, 6724 .v.func = alc_fixup_bass_chmap, 6725 .chained = true, 6726 .chain_id = ALC662_FIXUP_ASUS_MODE4 6727 }, 6728 [ALC662_FIXUP_BASS_16] = { 6729 .type = HDA_FIXUP_PINS, 6730 .v.pins = (const struct hda_pintbl[]) { 6731 {0x16, 0x80106111}, /* bass speaker */ 6732 {} 6733 }, 6734 .chained = true, 6735 .chain_id = ALC662_FIXUP_BASS_CHMAP, 6736 }, 6737 [ALC662_FIXUP_BASS_1A] = { 6738 .type = HDA_FIXUP_PINS, 6739 .v.pins = (const struct hda_pintbl[]) { 6740 {0x1a, 0x80106111}, /* bass speaker */ 6741 {} 6742 }, 6743 .chained = true, 6744 .chain_id = ALC662_FIXUP_BASS_CHMAP, 6745 }, 6746 [ALC662_FIXUP_BASS_CHMAP] = { 6747 .type = HDA_FIXUP_FUNC, 6748 .v.func = alc_fixup_bass_chmap, 6749 }, 6750 [ALC662_FIXUP_ASUS_Nx50] = { 6751 .type = HDA_FIXUP_FUNC, 6752 .v.func = alc_fixup_auto_mute_via_amp, 6753 .chained = true, 6754 .chain_id = ALC662_FIXUP_BASS_1A 6755 }, 6756 [ALC668_FIXUP_ASUS_Nx51] = { 6757 .type = HDA_FIXUP_PINS, 6758 .v.pins = (const struct hda_pintbl[]) { 6759 {0x1a, 0x90170151}, /* bass speaker */ 6760 {} 6761 }, 6762 .chained = true, 6763 .chain_id = ALC662_FIXUP_BASS_CHMAP, 6764 }, 6765}; 6766 6767static const struct snd_pci_quirk alc662_fixup_tbl[] = { 6768 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2), 6769 SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC), 6770 SND_PCI_QUIRK(0x1025, 0x0241, "Packard Bell DOTS", ALC662_FIXUP_INV_DMIC), 6771 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), 6772 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), 6773 SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC), 6774 SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC), 6775 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), 6776 SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), 6777 SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), 6778 SND_PCI_QUIRK(0x1028, 0x05fe, "Dell XPS 15", ALC668_FIXUP_DELL_XPS13), 6779 SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_XPS13), 6780 SND_PCI_QUIRK(0x1028, 0x060d, "Dell M3800", ALC668_FIXUP_DELL_XPS13), 6781 SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), 6782 SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), 6783 SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), 6784 SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), 6785 SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), 6786 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), 6787 SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE), 6788 SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_ASUS_Nx50), 6789 SND_PCI_QUIRK(0x1043, 0x13df, "Asus N550JX", ALC662_FIXUP_BASS_1A), 6790 SND_PCI_QUIRK(0x1043, 0x129d, "Asus N750", ALC662_FIXUP_ASUS_Nx50), 6791 SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP), 6792 SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16), 6793 SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51), 6794 SND_PCI_QUIRK(0x1043, 0x17bd, "ASUS N751", ALC668_FIXUP_ASUS_Nx51), 6795 SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16), 6796 SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP), 6797 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), 6798 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), 6799 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), 6800 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), 6801 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), 6802 SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68), 6803 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T), 6804 6805#if 0 6806 /* Below is a quirk table taken from the old code. 6807 * Basically the device should work as is without the fixup table. 6808 * If BIOS doesn't give a proper info, enable the corresponding 6809 * fixup entry. 6810 */ 6811 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1), 6812 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3), 6813 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1), 6814 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3), 6815 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), 6816 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 6817 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), 6818 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1), 6819 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1), 6820 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 6821 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7), 6822 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7), 6823 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8), 6824 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3), 6825 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1), 6826 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 6827 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2), 6828 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1), 6829 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 6830 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), 6831 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), 6832 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 6833 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1), 6834 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3), 6835 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2), 6836 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 6837 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5), 6838 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), 6839 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 6840 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1), 6841 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 6842 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 6843 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3), 6844 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3), 6845 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1), 6846 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1), 6847 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1), 6848 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1), 6849 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1), 6850 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 6851 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2), 6852 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1), 6853 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), 6854 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3), 6855 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1), 6856 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1), 6857 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1), 6858 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2), 6859 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), 6860 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4), 6861#endif 6862 {} 6863}; 6864 6865static const struct hda_model_fixup alc662_fixup_models[] = { 6866 {.id = ALC272_FIXUP_MARIO, .name = "mario"}, 6867 {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"}, 6868 {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"}, 6869 {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"}, 6870 {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"}, 6871 {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"}, 6872 {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"}, 6873 {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"}, 6874 {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"}, 6875 {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"}, 6876 {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, 6877 {} 6878}; 6879 6880static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = { 6881 SND_HDA_PIN_QUIRK(0x10ec0662, 0x1028, "Dell", ALC662_FIXUP_DELL_MIC_NO_PRESENCE, 6882 {0x12, 0x4004c000}, 6883 {0x14, 0x01014010}, 6884 {0x15, 0x411111f0}, 6885 {0x16, 0x411111f0}, 6886 {0x18, 0x01a19020}, 6887 {0x19, 0x411111f0}, 6888 {0x1a, 0x0181302f}, 6889 {0x1b, 0x0221401f}, 6890 {0x1c, 0x411111f0}, 6891 {0x1d, 0x4054c601}, 6892 {0x1e, 0x411111f0}), 6893 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE, 6894 {0x12, 0x99a30130}, 6895 {0x14, 0x90170110}, 6896 {0x15, 0x0321101f}, 6897 {0x16, 0x03011020}, 6898 {0x18, 0x40000008}, 6899 {0x19, 0x411111f0}, 6900 {0x1a, 0x411111f0}, 6901 {0x1b, 0x411111f0}, 6902 {0x1d, 0x41000001}, 6903 {0x1e, 0x411111f0}, 6904 {0x1f, 0x411111f0}), 6905 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE, 6906 {0x12, 0x99a30140}, 6907 {0x14, 0x90170110}, 6908 {0x15, 0x0321101f}, 6909 {0x16, 0x03011020}, 6910 {0x18, 0x40000008}, 6911 {0x19, 0x411111f0}, 6912 {0x1a, 0x411111f0}, 6913 {0x1b, 0x411111f0}, 6914 {0x1d, 0x41000001}, 6915 {0x1e, 0x411111f0}, 6916 {0x1f, 0x411111f0}), 6917 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE, 6918 {0x12, 0x99a30150}, 6919 {0x14, 0x90170110}, 6920 {0x15, 0x0321101f}, 6921 {0x16, 0x03011020}, 6922 {0x18, 0x40000008}, 6923 {0x19, 0x411111f0}, 6924 {0x1a, 0x411111f0}, 6925 {0x1b, 0x411111f0}, 6926 {0x1d, 0x41000001}, 6927 {0x1e, 0x411111f0}, 6928 {0x1f, 0x411111f0}), 6929 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE, 6930 {0x12, 0x411111f0}, 6931 {0x14, 0x90170110}, 6932 {0x15, 0x0321101f}, 6933 {0x16, 0x03011020}, 6934 {0x18, 0x40000008}, 6935 {0x19, 0x411111f0}, 6936 {0x1a, 0x411111f0}, 6937 {0x1b, 0x411111f0}, 6938 {0x1d, 0x41000001}, 6939 {0x1e, 0x411111f0}, 6940 {0x1f, 0x411111f0}), 6941 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell XPS 15", ALC668_FIXUP_AUTO_MUTE, 6942 {0x12, 0x90a60130}, 6943 {0x14, 0x90170110}, 6944 {0x15, 0x0321101f}, 6945 {0x16, 0x40000000}, 6946 {0x18, 0x411111f0}, 6947 {0x19, 0x411111f0}, 6948 {0x1a, 0x411111f0}, 6949 {0x1b, 0x411111f0}, 6950 {0x1d, 0x40d6832d}, 6951 {0x1e, 0x411111f0}, 6952 {0x1f, 0x411111f0}), 6953 {} 6954}; 6955 6956/* 6957 */ 6958static int patch_alc662(struct hda_codec *codec) 6959{ 6960 struct alc_spec *spec; 6961 int err; 6962 6963 err = alc_alloc_spec(codec, 0x0b); 6964 if (err < 0) 6965 return err; 6966 6967 spec = codec->spec; 6968 6969 /* handle multiple HPs as is */ 6970 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; 6971 6972 alc_fix_pll_init(codec, 0x20, 0x04, 15); 6973 6974 switch (codec->core.vendor_id) { 6975 case 0x10ec0668: 6976 spec->init_hook = alc668_restore_default_value; 6977 break; 6978 } 6979 6980 snd_hda_pick_fixup(codec, alc662_fixup_models, 6981 alc662_fixup_tbl, alc662_fixups); 6982 snd_hda_pick_pin_fixup(codec, alc662_pin_fixup_tbl, alc662_fixups); 6983 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 6984 6985 alc_auto_parse_customize_define(codec); 6986 6987 if (has_cdefine_beep(codec)) 6988 spec->gen.beep_nid = 0x01; 6989 6990 if ((alc_get_coef0(codec) & (1 << 14)) && 6991 codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 && 6992 spec->cdefine.platform_type == 1) { 6993 err = alc_codec_rename(codec, "ALC272X"); 6994 if (err < 0) 6995 goto error; 6996 } 6997 6998 /* automatic parse from the BIOS config */ 6999 err = alc662_parse_auto_config(codec); 7000 if (err < 0) 7001 goto error; 7002 7003 if (!spec->gen.no_analog && spec->gen.beep_nid) { 7004 switch (codec->core.vendor_id) { 7005 case 0x10ec0662: 7006 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 7007 break; 7008 case 0x10ec0272: 7009 case 0x10ec0663: 7010 case 0x10ec0665: 7011 case 0x10ec0668: 7012 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 7013 break; 7014 case 0x10ec0273: 7015 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT); 7016 break; 7017 } 7018 } 7019 7020 codec->patch_ops = alc_patch_ops; 7021 spec->shutup = alc_eapd_shutup; 7022 7023 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 7024 7025 return 0; 7026 7027 error: 7028 alc_free(codec); 7029 return err; 7030} 7031 7032/* 7033 * ALC680 support 7034 */ 7035 7036static int alc680_parse_auto_config(struct hda_codec *codec) 7037{ 7038 return alc_parse_auto_config(codec, NULL, NULL); 7039} 7040 7041/* 7042 */ 7043static int patch_alc680(struct hda_codec *codec) 7044{ 7045 int err; 7046 7047 /* ALC680 has no aa-loopback mixer */ 7048 err = alc_alloc_spec(codec, 0); 7049 if (err < 0) 7050 return err; 7051 7052 /* automatic parse from the BIOS config */ 7053 err = alc680_parse_auto_config(codec); 7054 if (err < 0) { 7055 alc_free(codec); 7056 return err; 7057 } 7058 7059 codec->patch_ops = alc_patch_ops; 7060 7061 return 0; 7062} 7063 7064/* 7065 * patch entries 7066 */ 7067static const struct hda_codec_preset snd_hda_preset_realtek[] = { 7068 { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 }, 7069 { .id = 0x10ec0231, .name = "ALC231", .patch = patch_alc269 }, 7070 { .id = 0x10ec0233, .name = "ALC233", .patch = patch_alc269 }, 7071 { .id = 0x10ec0235, .name = "ALC233", .patch = patch_alc269 }, 7072 { .id = 0x10ec0255, .name = "ALC255", .patch = patch_alc269 }, 7073 { .id = 0x10ec0256, .name = "ALC256", .patch = patch_alc269 }, 7074 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, 7075 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, 7076 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, 7077 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, 7078 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 }, 7079 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 }, 7080 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, 7081 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, 7082 { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 }, 7083 { .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 }, 7084 { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 }, 7085 { .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 }, 7086 { .id = 0x10ec0284, .name = "ALC284", .patch = patch_alc269 }, 7087 { .id = 0x10ec0285, .name = "ALC285", .patch = patch_alc269 }, 7088 { .id = 0x10ec0286, .name = "ALC286", .patch = patch_alc269 }, 7089 { .id = 0x10ec0288, .name = "ALC288", .patch = patch_alc269 }, 7090 { .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 }, 7091 { .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 }, 7092 { .id = 0x10ec0293, .name = "ALC293", .patch = patch_alc269 }, 7093 { .id = 0x10ec0298, .name = "ALC298", .patch = patch_alc269 }, 7094 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", 7095 .patch = patch_alc861 }, 7096 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, 7097 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, 7098 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, 7099 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", 7100 .patch = patch_alc882 }, 7101 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", 7102 .patch = patch_alc662 }, 7103 { .id = 0x10ec0662, .rev = 0x100300, .name = "ALC662 rev3", 7104 .patch = patch_alc662 }, 7105 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, 7106 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, 7107 { .id = 0x10ec0667, .name = "ALC667", .patch = patch_alc662 }, 7108 { .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 }, 7109 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, 7110 { .id = 0x10ec0671, .name = "ALC671", .patch = patch_alc662 }, 7111 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, 7112 { .id = 0x10ec0867, .name = "ALC891", .patch = patch_alc882 }, 7113 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 7114 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 7115 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, 7116 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A", 7117 .patch = patch_alc882 }, 7118 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", 7119 .patch = patch_alc882 }, 7120 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, 7121 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 }, 7122 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", 7123 .patch = patch_alc882 }, 7124 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 }, 7125 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, 7126 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, 7127 { .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 }, 7128 { .id = 0x10ec0900, .name = "ALC1150", .patch = patch_alc882 }, 7129 {} /* terminator */ 7130}; 7131 7132MODULE_ALIAS("snd-hda-codec-id:10ec*"); 7133 7134MODULE_LICENSE("GPL"); 7135MODULE_DESCRIPTION("Realtek HD-audio codec"); 7136 7137static struct hda_codec_driver realtek_driver = { 7138 .preset = snd_hda_preset_realtek, 7139}; 7140 7141module_hda_codec_driver(realtek_driver); 7142