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 <sound/core.h> 33 #include <sound/jack.h> 34 #include "hda_codec.h" 35 #include "hda_local.h" 36 #include "hda_auto_parser.h" 37 #include "hda_jack.h" 38 #include "hda_generic.h" 39 40 /* unsol event tags */ 41 #define ALC_DCVOL_EVENT 0x08 42 43 /* for GPIO Poll */ 44 #define GPIO_MASK 0x03 45 46 /* extra amp-initialization sequence types */ 47 enum { 48 ALC_INIT_NONE, 49 ALC_INIT_DEFAULT, 50 ALC_INIT_GPIO1, 51 ALC_INIT_GPIO2, 52 ALC_INIT_GPIO3, 53 }; 54 55 enum { 56 ALC_HEADSET_MODE_UNKNOWN, 57 ALC_HEADSET_MODE_UNPLUGGED, 58 ALC_HEADSET_MODE_HEADSET, 59 ALC_HEADSET_MODE_MIC, 60 ALC_HEADSET_MODE_HEADPHONE, 61 }; 62 63 enum { 64 ALC_HEADSET_TYPE_UNKNOWN, 65 ALC_HEADSET_TYPE_CTIA, 66 ALC_HEADSET_TYPE_OMTP, 67 }; 68 69 struct alc_customize_define { 70 unsigned int sku_cfg; 71 unsigned char port_connectivity; 72 unsigned char check_sum; 73 unsigned char customization; 74 unsigned char external_amp; 75 unsigned int enable_pcbeep:1; 76 unsigned int platform_type:1; 77 unsigned int swap:1; 78 unsigned int override:1; 79 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */ 80 }; 81 82 struct alc_spec { 83 struct hda_gen_spec gen; /* must be at head */ 84 85 /* codec parameterization */ 86 const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 87 unsigned int num_mixers; 88 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ 89 90 struct alc_customize_define cdefine; 91 unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */ 92 93 /* inverted dmic fix */ 94 unsigned int inv_dmic_fixup:1; /* has inverted digital-mic workaround */ 95 unsigned int inv_dmic_muted:1; /* R-ch of inv d-mic is muted? */ 96 hda_nid_t inv_dmic_pin; 97 98 /* mute LED for HP laptops, see alc269_fixup_mic_mute_hook() */ 99 int mute_led_polarity; 100 hda_nid_t mute_led_nid; 101 102 unsigned int gpio_led; /* used for alc269_fixup_hp_gpio_led() */ 103 104 hda_nid_t headset_mic_pin; 105 hda_nid_t headphone_mic_pin; 106 int current_headset_mode; 107 int current_headset_type; 108 109 /* hooks */ 110 void (*init_hook)(struct hda_codec *codec); 111 #ifdef CONFIG_PM 112 void (*power_hook)(struct hda_codec *codec); 113 #endif 114 void (*shutup)(struct hda_codec *codec); 115 116 int init_amp; 117 int codec_variant; /* flag for other variants */ 118 119 /* for PLL fix */ 120 hda_nid_t pll_nid; 121 unsigned int pll_coef_idx, pll_coef_bit; 122 unsigned int coef0; 123 }; 124 125 /* 126 * Append the given mixer and verb elements for the later use 127 * The mixer array is referred in build_controls(), and init_verbs are 128 * called in init(). 129 */ 130 static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix) 131 { 132 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers))) 133 return; 134 spec->mixers[spec->num_mixers++] = mix; 135 } 136 137 /* 138 * GPIO setup tables, used in initialization 139 */ 140 /* Enable GPIO mask and set output */ 141 static const struct hda_verb alc_gpio1_init_verbs[] = { 142 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 143 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 144 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 145 { } 146 }; 147 148 static const struct hda_verb alc_gpio2_init_verbs[] = { 149 {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, 150 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, 151 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, 152 { } 153 }; 154 155 static const struct hda_verb alc_gpio3_init_verbs[] = { 156 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 157 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 158 {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 159 { } 160 }; 161 162 /* 163 * Fix hardware PLL issue 164 * On some codecs, the analog PLL gating control must be off while 165 * the default value is 1. 166 */ 167 static void alc_fix_pll(struct hda_codec *codec) 168 { 169 struct alc_spec *spec = codec->spec; 170 unsigned int val; 171 172 if (!spec->pll_nid) 173 return; 174 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, 175 spec->pll_coef_idx); 176 val = snd_hda_codec_read(codec, spec->pll_nid, 0, 177 AC_VERB_GET_PROC_COEF, 0); 178 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, 179 spec->pll_coef_idx); 180 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF, 181 val & ~(1 << spec->pll_coef_bit)); 182 } 183 184 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, 185 unsigned int coef_idx, unsigned int coef_bit) 186 { 187 struct alc_spec *spec = codec->spec; 188 spec->pll_nid = nid; 189 spec->pll_coef_idx = coef_idx; 190 spec->pll_coef_bit = coef_bit; 191 alc_fix_pll(codec); 192 } 193 194 /* update the master volume per volume-knob's unsol event */ 195 static void alc_update_knob_master(struct hda_codec *codec, struct hda_jack_tbl *jack) 196 { 197 unsigned int val; 198 struct snd_kcontrol *kctl; 199 struct snd_ctl_elem_value *uctl; 200 201 kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume"); 202 if (!kctl) 203 return; 204 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); 205 if (!uctl) 206 return; 207 val = snd_hda_codec_read(codec, jack->nid, 0, 208 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0); 209 val &= HDA_AMP_VOLMASK; 210 uctl->value.integer.value[0] = val; 211 uctl->value.integer.value[1] = val; 212 kctl->put(kctl, uctl); 213 kfree(uctl); 214 } 215 216 static void alc880_unsol_event(struct hda_codec *codec, unsigned int res) 217 { 218 /* For some reason, the res given from ALC880 is broken. 219 Here we adjust it properly. */ 220 snd_hda_jack_unsol_event(codec, res >> 2); 221 } 222 223 /* additional initialization for ALC888 variants */ 224 static void alc888_coef_init(struct hda_codec *codec) 225 { 226 unsigned int tmp; 227 228 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0); 229 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 230 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); 231 if ((tmp & 0xf0) == 0x20) 232 /* alc888S-VC */ 233 snd_hda_codec_read(codec, 0x20, 0, 234 AC_VERB_SET_PROC_COEF, 0x830); 235 else 236 /* alc888-VB */ 237 snd_hda_codec_read(codec, 0x20, 0, 238 AC_VERB_SET_PROC_COEF, 0x3030); 239 } 240 241 /* additional initialization for ALC889 variants */ 242 static void alc889_coef_init(struct hda_codec *codec) 243 { 244 unsigned int tmp; 245 246 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); 247 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 248 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); 249 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010); 250 } 251 252 /* turn on/off EAPD control (only if available) */ 253 static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on) 254 { 255 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) 256 return; 257 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD) 258 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, 259 on ? 2 : 0); 260 } 261 262 /* turn on/off EAPD controls of the codec */ 263 static void alc_auto_setup_eapd(struct hda_codec *codec, bool on) 264 { 265 /* We currently only handle front, HP */ 266 static hda_nid_t pins[] = { 267 0x0f, 0x10, 0x14, 0x15, 0 268 }; 269 hda_nid_t *p; 270 for (p = pins; *p; p++) 271 set_eapd(codec, *p, on); 272 } 273 274 /* generic shutup callback; 275 * just turning off EPAD and a little pause for avoiding pop-noise 276 */ 277 static void alc_eapd_shutup(struct hda_codec *codec) 278 { 279 alc_auto_setup_eapd(codec, false); 280 msleep(200); 281 } 282 283 /* generic EAPD initialization */ 284 static void alc_auto_init_amp(struct hda_codec *codec, int type) 285 { 286 unsigned int tmp; 287 288 alc_auto_setup_eapd(codec, true); 289 switch (type) { 290 case ALC_INIT_GPIO1: 291 snd_hda_sequence_write(codec, alc_gpio1_init_verbs); 292 break; 293 case ALC_INIT_GPIO2: 294 snd_hda_sequence_write(codec, alc_gpio2_init_verbs); 295 break; 296 case ALC_INIT_GPIO3: 297 snd_hda_sequence_write(codec, alc_gpio3_init_verbs); 298 break; 299 case ALC_INIT_DEFAULT: 300 switch (codec->vendor_id) { 301 case 0x10ec0260: 302 snd_hda_codec_write(codec, 0x1a, 0, 303 AC_VERB_SET_COEF_INDEX, 7); 304 tmp = snd_hda_codec_read(codec, 0x1a, 0, 305 AC_VERB_GET_PROC_COEF, 0); 306 snd_hda_codec_write(codec, 0x1a, 0, 307 AC_VERB_SET_COEF_INDEX, 7); 308 snd_hda_codec_write(codec, 0x1a, 0, 309 AC_VERB_SET_PROC_COEF, 310 tmp | 0x2010); 311 break; 312 case 0x10ec0262: 313 case 0x10ec0880: 314 case 0x10ec0882: 315 case 0x10ec0883: 316 case 0x10ec0885: 317 case 0x10ec0887: 318 /*case 0x10ec0889:*/ /* this causes an SPDIF problem */ 319 alc889_coef_init(codec); 320 break; 321 case 0x10ec0888: 322 alc888_coef_init(codec); 323 break; 324 #if 0 /* XXX: This may cause the silent output on speaker on some machines */ 325 case 0x10ec0267: 326 case 0x10ec0268: 327 snd_hda_codec_write(codec, 0x20, 0, 328 AC_VERB_SET_COEF_INDEX, 7); 329 tmp = snd_hda_codec_read(codec, 0x20, 0, 330 AC_VERB_GET_PROC_COEF, 0); 331 snd_hda_codec_write(codec, 0x20, 0, 332 AC_VERB_SET_COEF_INDEX, 7); 333 snd_hda_codec_write(codec, 0x20, 0, 334 AC_VERB_SET_PROC_COEF, 335 tmp | 0x3000); 336 break; 337 #endif /* XXX */ 338 } 339 break; 340 } 341 } 342 343 344 /* 345 * Realtek SSID verification 346 */ 347 348 /* Could be any non-zero and even value. When used as fixup, tells 349 * the driver to ignore any present sku defines. 350 */ 351 #define ALC_FIXUP_SKU_IGNORE (2) 352 353 static void alc_fixup_sku_ignore(struct hda_codec *codec, 354 const struct hda_fixup *fix, int action) 355 { 356 struct alc_spec *spec = codec->spec; 357 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 358 spec->cdefine.fixup = 1; 359 spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE; 360 } 361 } 362 363 static int alc_auto_parse_customize_define(struct hda_codec *codec) 364 { 365 unsigned int ass, tmp, i; 366 unsigned nid = 0; 367 struct alc_spec *spec = codec->spec; 368 369 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */ 370 371 if (spec->cdefine.fixup) { 372 ass = spec->cdefine.sku_cfg; 373 if (ass == ALC_FIXUP_SKU_IGNORE) 374 return -1; 375 goto do_sku; 376 } 377 378 ass = codec->subsystem_id & 0xffff; 379 if (ass != codec->bus->pci->subsystem_device && (ass & 1)) 380 goto do_sku; 381 382 nid = 0x1d; 383 if (codec->vendor_id == 0x10ec0260) 384 nid = 0x17; 385 ass = snd_hda_codec_get_pincfg(codec, nid); 386 387 if (!(ass & 1)) { 388 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n", 389 codec->chip_name, ass); 390 return -1; 391 } 392 393 /* check sum */ 394 tmp = 0; 395 for (i = 1; i < 16; i++) { 396 if ((ass >> i) & 1) 397 tmp++; 398 } 399 if (((ass >> 16) & 0xf) != tmp) 400 return -1; 401 402 spec->cdefine.port_connectivity = ass >> 30; 403 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20; 404 spec->cdefine.check_sum = (ass >> 16) & 0xf; 405 spec->cdefine.customization = ass >> 8; 406 do_sku: 407 spec->cdefine.sku_cfg = ass; 408 spec->cdefine.external_amp = (ass & 0x38) >> 3; 409 spec->cdefine.platform_type = (ass & 0x4) >> 2; 410 spec->cdefine.swap = (ass & 0x2) >> 1; 411 spec->cdefine.override = ass & 0x1; 412 413 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n", 414 nid, spec->cdefine.sku_cfg); 415 snd_printd("SKU: port_connectivity=0x%x\n", 416 spec->cdefine.port_connectivity); 417 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep); 418 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum); 419 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization); 420 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp); 421 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type); 422 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap); 423 snd_printd("SKU: override=0x%x\n", spec->cdefine.override); 424 425 return 0; 426 } 427 428 /* return the position of NID in the list, or -1 if not found */ 429 static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) 430 { 431 int i; 432 for (i = 0; i < nums; i++) 433 if (list[i] == nid) 434 return i; 435 return -1; 436 } 437 /* return true if the given NID is found in the list */ 438 static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) 439 { 440 return find_idx_in_nid_list(nid, list, nums) >= 0; 441 } 442 443 /* check subsystem ID and set up device-specific initialization; 444 * return 1 if initialized, 0 if invalid SSID 445 */ 446 /* 32-bit subsystem ID for BIOS loading in HD Audio codec. 447 * 31 ~ 16 : Manufacture ID 448 * 15 ~ 8 : SKU ID 449 * 7 ~ 0 : Assembly ID 450 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 451 */ 452 static int alc_subsystem_id(struct hda_codec *codec, 453 hda_nid_t porta, hda_nid_t porte, 454 hda_nid_t portd, hda_nid_t porti) 455 { 456 unsigned int ass, tmp, i; 457 unsigned nid; 458 struct alc_spec *spec = codec->spec; 459 460 if (spec->cdefine.fixup) { 461 ass = spec->cdefine.sku_cfg; 462 if (ass == ALC_FIXUP_SKU_IGNORE) 463 return 0; 464 goto do_sku; 465 } 466 467 ass = codec->subsystem_id & 0xffff; 468 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1)) 469 goto do_sku; 470 471 /* invalid SSID, check the special NID pin defcfg instead */ 472 /* 473 * 31~30 : port connectivity 474 * 29~21 : reserve 475 * 20 : PCBEEP input 476 * 19~16 : Check sum (15:1) 477 * 15~1 : Custom 478 * 0 : override 479 */ 480 nid = 0x1d; 481 if (codec->vendor_id == 0x10ec0260) 482 nid = 0x17; 483 ass = snd_hda_codec_get_pincfg(codec, nid); 484 snd_printd("realtek: No valid SSID, " 485 "checking pincfg 0x%08x for NID 0x%x\n", 486 ass, nid); 487 if (!(ass & 1)) 488 return 0; 489 if ((ass >> 30) != 1) /* no physical connection */ 490 return 0; 491 492 /* check sum */ 493 tmp = 0; 494 for (i = 1; i < 16; i++) { 495 if ((ass >> i) & 1) 496 tmp++; 497 } 498 if (((ass >> 16) & 0xf) != tmp) 499 return 0; 500 do_sku: 501 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n", 502 ass & 0xffff, codec->vendor_id); 503 /* 504 * 0 : override 505 * 1 : Swap Jack 506 * 2 : 0 --> Desktop, 1 --> Laptop 507 * 3~5 : External Amplifier control 508 * 7~6 : Reserved 509 */ 510 tmp = (ass & 0x38) >> 3; /* external Amp control */ 511 switch (tmp) { 512 case 1: 513 spec->init_amp = ALC_INIT_GPIO1; 514 break; 515 case 3: 516 spec->init_amp = ALC_INIT_GPIO2; 517 break; 518 case 7: 519 spec->init_amp = ALC_INIT_GPIO3; 520 break; 521 case 5: 522 default: 523 spec->init_amp = ALC_INIT_DEFAULT; 524 break; 525 } 526 527 /* is laptop or Desktop and enable the function "Mute internal speaker 528 * when the external headphone out jack is plugged" 529 */ 530 if (!(ass & 0x8000)) 531 return 1; 532 /* 533 * 10~8 : Jack location 534 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered 535 * 14~13: Resvered 536 * 15 : 1 --> enable the function "Mute internal speaker 537 * when the external headphone out jack is plugged" 538 */ 539 if (!spec->gen.autocfg.hp_pins[0] && 540 !(spec->gen.autocfg.line_out_pins[0] && 541 spec->gen.autocfg.line_out_type == AUTO_PIN_HP_OUT)) { 542 hda_nid_t nid; 543 tmp = (ass >> 11) & 0x3; /* HP to chassis */ 544 if (tmp == 0) 545 nid = porta; 546 else if (tmp == 1) 547 nid = porte; 548 else if (tmp == 2) 549 nid = portd; 550 else if (tmp == 3) 551 nid = porti; 552 else 553 return 1; 554 if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins, 555 spec->gen.autocfg.line_outs)) 556 return 1; 557 spec->gen.autocfg.hp_pins[0] = nid; 558 } 559 return 1; 560 } 561 562 /* Check the validity of ALC subsystem-id 563 * ports contains an array of 4 pin NIDs for port-A, E, D and I */ 564 static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports) 565 { 566 if (!alc_subsystem_id(codec, ports[0], ports[1], ports[2], ports[3])) { 567 struct alc_spec *spec = codec->spec; 568 snd_printd("realtek: " 569 "Enable default setup for auto mode as fallback\n"); 570 spec->init_amp = ALC_INIT_DEFAULT; 571 } 572 } 573 574 /* 575 * COEF access helper functions 576 */ 577 static int alc_read_coef_idx(struct hda_codec *codec, 578 unsigned int coef_idx) 579 { 580 unsigned int val; 581 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 582 coef_idx); 583 val = snd_hda_codec_read(codec, 0x20, 0, 584 AC_VERB_GET_PROC_COEF, 0); 585 return val; 586 } 587 588 static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx, 589 unsigned int coef_val) 590 { 591 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 592 coef_idx); 593 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 594 coef_val); 595 } 596 597 /* a special bypass for COEF 0; read the cached value at the second time */ 598 static unsigned int alc_get_coef0(struct hda_codec *codec) 599 { 600 struct alc_spec *spec = codec->spec; 601 if (!spec->coef0) 602 spec->coef0 = alc_read_coef_idx(codec, 0); 603 return spec->coef0; 604 } 605 606 /* 607 */ 608 609 static hda_nid_t get_adc_nid(struct hda_codec *codec, int adc_idx, int imux_idx) 610 { 611 struct hda_gen_spec *spec = codec->spec; 612 if (spec->dyn_adc_switch) 613 adc_idx = spec->dyn_adc_idx[imux_idx]; 614 return spec->adc_nids[adc_idx]; 615 } 616 617 static void alc_inv_dmic_sync_adc(struct hda_codec *codec, int adc_idx) 618 { 619 struct alc_spec *spec = codec->spec; 620 struct hda_input_mux *imux = &spec->gen.input_mux; 621 struct nid_path *path; 622 hda_nid_t nid; 623 int i, dir, parm; 624 unsigned int val; 625 626 for (i = 0; i < imux->num_items; i++) { 627 if (spec->gen.imux_pins[i] == spec->inv_dmic_pin) 628 break; 629 } 630 if (i >= imux->num_items) 631 return; 632 633 path = snd_hda_get_nid_path(codec, spec->inv_dmic_pin, 634 get_adc_nid(codec, adc_idx, i)); 635 val = path->ctls[NID_PATH_MUTE_CTL]; 636 if (!val) 637 return; 638 nid = get_amp_nid_(val); 639 dir = get_amp_direction_(val); 640 parm = AC_AMP_SET_RIGHT | 641 (dir == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT); 642 643 /* flush all cached amps at first */ 644 snd_hda_codec_flush_cache(codec); 645 646 /* we care only right channel */ 647 val = snd_hda_codec_amp_read(codec, nid, 1, dir, 0); 648 if (val & 0x80) /* if already muted, we don't need to touch */ 649 return; 650 val |= 0x80; 651 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 652 parm | val); 653 } 654 655 /* 656 * Inverted digital-mic handling 657 * 658 * First off, it's a bit tricky. The "Inverted Internal Mic Capture Switch" 659 * gives the additional mute only to the right channel of the digital mic 660 * capture stream. This is a workaround for avoiding the almost silence 661 * by summing the stereo stream from some (known to be ForteMedia) 662 * digital mic unit. 663 * 664 * The logic is to call alc_inv_dmic_sync() after each action (possibly) 665 * modifying ADC amp. When the mute flag is set, it mutes the R-channel 666 * without caching so that the cache can still keep the original value. 667 * The cached value is then restored when the flag is set off or any other 668 * than d-mic is used as the current input source. 669 */ 670 static void alc_inv_dmic_sync(struct hda_codec *codec, bool force) 671 { 672 struct alc_spec *spec = codec->spec; 673 int src, nums; 674 675 if (!spec->inv_dmic_fixup) 676 return; 677 if (!spec->inv_dmic_muted && !force) 678 return; 679 nums = spec->gen.dyn_adc_switch ? 1 : spec->gen.num_adc_nids; 680 for (src = 0; src < nums; src++) { 681 bool dmic_fixup = false; 682 683 if (spec->inv_dmic_muted && 684 spec->gen.imux_pins[spec->gen.cur_mux[src]] == spec->inv_dmic_pin) 685 dmic_fixup = true; 686 if (!dmic_fixup && !force) 687 continue; 688 alc_inv_dmic_sync_adc(codec, src); 689 } 690 } 691 692 static void alc_inv_dmic_hook(struct hda_codec *codec, 693 struct snd_ctl_elem_value *ucontrol) 694 { 695 alc_inv_dmic_sync(codec, false); 696 } 697 698 static int alc_inv_dmic_sw_get(struct snd_kcontrol *kcontrol, 699 struct snd_ctl_elem_value *ucontrol) 700 { 701 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 702 struct alc_spec *spec = codec->spec; 703 704 ucontrol->value.integer.value[0] = !spec->inv_dmic_muted; 705 return 0; 706 } 707 708 static int alc_inv_dmic_sw_put(struct snd_kcontrol *kcontrol, 709 struct snd_ctl_elem_value *ucontrol) 710 { 711 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 712 struct alc_spec *spec = codec->spec; 713 unsigned int val = !ucontrol->value.integer.value[0]; 714 715 if (val == spec->inv_dmic_muted) 716 return 0; 717 spec->inv_dmic_muted = val; 718 alc_inv_dmic_sync(codec, true); 719 return 0; 720 } 721 722 static const struct snd_kcontrol_new alc_inv_dmic_sw = { 723 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 724 .name = "Inverted Internal Mic Capture Switch", 725 .info = snd_ctl_boolean_mono_info, 726 .get = alc_inv_dmic_sw_get, 727 .put = alc_inv_dmic_sw_put, 728 }; 729 730 static int alc_add_inv_dmic_mixer(struct hda_codec *codec, hda_nid_t nid) 731 { 732 struct alc_spec *spec = codec->spec; 733 734 if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &alc_inv_dmic_sw)) 735 return -ENOMEM; 736 spec->inv_dmic_fixup = 1; 737 spec->inv_dmic_muted = 0; 738 spec->inv_dmic_pin = nid; 739 spec->gen.cap_sync_hook = alc_inv_dmic_hook; 740 return 0; 741 } 742 743 /* typically the digital mic is put at node 0x12 */ 744 static void alc_fixup_inv_dmic_0x12(struct hda_codec *codec, 745 const struct hda_fixup *fix, int action) 746 { 747 if (action == HDA_FIXUP_ACT_PROBE) 748 alc_add_inv_dmic_mixer(codec, 0x12); 749 } 750 751 752 #ifdef CONFIG_SND_HDA_INPUT_BEEP 753 /* additional beep mixers; the actual parameters are overwritten at build */ 754 static const struct snd_kcontrol_new alc_beep_mixer[] = { 755 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT), 756 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT), 757 { } /* end */ 758 }; 759 #endif 760 761 static int alc_build_controls(struct hda_codec *codec) 762 { 763 struct alc_spec *spec = codec->spec; 764 int i, err; 765 766 err = snd_hda_gen_build_controls(codec); 767 if (err < 0) 768 return err; 769 770 for (i = 0; i < spec->num_mixers; i++) { 771 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 772 if (err < 0) 773 return err; 774 } 775 776 #ifdef CONFIG_SND_HDA_INPUT_BEEP 777 /* create beep controls if needed */ 778 if (spec->beep_amp) { 779 const struct snd_kcontrol_new *knew; 780 for (knew = alc_beep_mixer; knew->name; knew++) { 781 struct snd_kcontrol *kctl; 782 kctl = snd_ctl_new1(knew, codec); 783 if (!kctl) 784 return -ENOMEM; 785 kctl->private_value = spec->beep_amp; 786 err = snd_hda_ctl_add(codec, 0, kctl); 787 if (err < 0) 788 return err; 789 } 790 } 791 #endif 792 793 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD); 794 return 0; 795 } 796 797 798 /* 799 * Common callbacks 800 */ 801 802 static int alc_init(struct hda_codec *codec) 803 { 804 struct alc_spec *spec = codec->spec; 805 806 if (spec->init_hook) 807 spec->init_hook(codec); 808 809 alc_fix_pll(codec); 810 alc_auto_init_amp(codec, spec->init_amp); 811 812 snd_hda_gen_init(codec); 813 814 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT); 815 816 return 0; 817 } 818 819 static inline void alc_shutup(struct hda_codec *codec) 820 { 821 struct alc_spec *spec = codec->spec; 822 823 if (spec && spec->shutup) 824 spec->shutup(codec); 825 snd_hda_shutup_pins(codec); 826 } 827 828 #define alc_free snd_hda_gen_free 829 830 #ifdef CONFIG_PM 831 static void alc_power_eapd(struct hda_codec *codec) 832 { 833 alc_auto_setup_eapd(codec, false); 834 } 835 836 static int alc_suspend(struct hda_codec *codec) 837 { 838 struct alc_spec *spec = codec->spec; 839 alc_shutup(codec); 840 if (spec && spec->power_hook) 841 spec->power_hook(codec); 842 return 0; 843 } 844 #endif 845 846 #ifdef CONFIG_PM 847 static int alc_resume(struct hda_codec *codec) 848 { 849 msleep(150); /* to avoid pop noise */ 850 codec->patch_ops.init(codec); 851 snd_hda_codec_resume_amp(codec); 852 snd_hda_codec_resume_cache(codec); 853 alc_inv_dmic_sync(codec, true); 854 hda_call_check_power_status(codec, 0x01); 855 return 0; 856 } 857 #endif 858 859 /* 860 */ 861 static const struct hda_codec_ops alc_patch_ops = { 862 .build_controls = alc_build_controls, 863 .build_pcms = snd_hda_gen_build_pcms, 864 .init = alc_init, 865 .free = alc_free, 866 .unsol_event = snd_hda_jack_unsol_event, 867 #ifdef CONFIG_PM 868 .resume = alc_resume, 869 .suspend = alc_suspend, 870 .check_power_status = snd_hda_gen_check_power_status, 871 #endif 872 .reboot_notify = alc_shutup, 873 }; 874 875 876 /* replace the codec chip_name with the given string */ 877 static int alc_codec_rename(struct hda_codec *codec, const char *name) 878 { 879 kfree(codec->chip_name); 880 codec->chip_name = kstrdup(name, GFP_KERNEL); 881 if (!codec->chip_name) { 882 alc_free(codec); 883 return -ENOMEM; 884 } 885 return 0; 886 } 887 888 /* 889 * Rename codecs appropriately from COEF value 890 */ 891 struct alc_codec_rename_table { 892 unsigned int vendor_id; 893 unsigned short coef_mask; 894 unsigned short coef_bits; 895 const char *name; 896 }; 897 898 static struct alc_codec_rename_table rename_tbl[] = { 899 { 0x10ec0269, 0xfff0, 0x3010, "ALC277" }, 900 { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" }, 901 { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" }, 902 { 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" }, 903 { 0x10ec0269, 0xffff, 0xa023, "ALC259" }, 904 { 0x10ec0269, 0xffff, 0x6023, "ALC281X" }, 905 { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" }, 906 { 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" }, 907 { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" }, 908 { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" }, 909 { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" }, 910 { 0x10ec0899, 0x2000, 0x2000, "ALC899" }, 911 { 0x10ec0892, 0xffff, 0x8020, "ALC661" }, 912 { 0x10ec0892, 0xffff, 0x8011, "ALC661" }, 913 { 0x10ec0892, 0xffff, 0x4011, "ALC656" }, 914 { } /* terminator */ 915 }; 916 917 static int alc_codec_rename_from_preset(struct hda_codec *codec) 918 { 919 const struct alc_codec_rename_table *p; 920 921 for (p = rename_tbl; p->vendor_id; p++) { 922 if (p->vendor_id != codec->vendor_id) 923 continue; 924 if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits) 925 return alc_codec_rename(codec, p->name); 926 } 927 return 0; 928 } 929 930 931 /* 932 * Digital-beep handlers 933 */ 934 #ifdef CONFIG_SND_HDA_INPUT_BEEP 935 #define set_beep_amp(spec, nid, idx, dir) \ 936 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) 937 938 static const struct snd_pci_quirk beep_white_list[] = { 939 SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1), 940 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), 941 SND_PCI_QUIRK(0x1043, 0x8376, "EeePC", 1), 942 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1), 943 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1), 944 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1), 945 SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1), 946 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), 947 {} 948 }; 949 950 static inline int has_cdefine_beep(struct hda_codec *codec) 951 { 952 struct alc_spec *spec = codec->spec; 953 const struct snd_pci_quirk *q; 954 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list); 955 if (q) 956 return q->value; 957 return spec->cdefine.enable_pcbeep; 958 } 959 #else 960 #define set_beep_amp(spec, nid, idx, dir) /* NOP */ 961 #define has_cdefine_beep(codec) 0 962 #endif 963 964 /* parse the BIOS configuration and set up the alc_spec */ 965 /* return 1 if successful, 0 if the proper config is not found, 966 * or a negative error code 967 */ 968 static int alc_parse_auto_config(struct hda_codec *codec, 969 const hda_nid_t *ignore_nids, 970 const hda_nid_t *ssid_nids) 971 { 972 struct alc_spec *spec = codec->spec; 973 struct auto_pin_cfg *cfg = &spec->gen.autocfg; 974 int err; 975 976 err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids, 977 spec->parse_flags); 978 if (err < 0) 979 return err; 980 981 if (ssid_nids) 982 alc_ssid_check(codec, ssid_nids); 983 984 err = snd_hda_gen_parse_auto_config(codec, cfg); 985 if (err < 0) 986 return err; 987 988 return 1; 989 } 990 991 /* common preparation job for alc_spec */ 992 static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid) 993 { 994 struct alc_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL); 995 int err; 996 997 if (!spec) 998 return -ENOMEM; 999 codec->spec = spec; 1000 snd_hda_gen_spec_init(&spec->gen); 1001 spec->gen.mixer_nid = mixer_nid; 1002 spec->gen.own_eapd_ctl = 1; 1003 codec->single_adc_amp = 1; 1004 /* FIXME: do we need this for all Realtek codec models? */ 1005 codec->spdif_status_reset = 1; 1006 1007 err = alc_codec_rename_from_preset(codec); 1008 if (err < 0) { 1009 kfree(spec); 1010 return err; 1011 } 1012 return 0; 1013 } 1014 1015 static int alc880_parse_auto_config(struct hda_codec *codec) 1016 { 1017 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 }; 1018 static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 }; 1019 return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids); 1020 } 1021 1022 /* 1023 * ALC880 fix-ups 1024 */ 1025 enum { 1026 ALC880_FIXUP_GPIO1, 1027 ALC880_FIXUP_GPIO2, 1028 ALC880_FIXUP_MEDION_RIM, 1029 ALC880_FIXUP_LG, 1030 ALC880_FIXUP_W810, 1031 ALC880_FIXUP_EAPD_COEF, 1032 ALC880_FIXUP_TCL_S700, 1033 ALC880_FIXUP_VOL_KNOB, 1034 ALC880_FIXUP_FUJITSU, 1035 ALC880_FIXUP_F1734, 1036 ALC880_FIXUP_UNIWILL, 1037 ALC880_FIXUP_UNIWILL_DIG, 1038 ALC880_FIXUP_Z71V, 1039 ALC880_FIXUP_3ST_BASE, 1040 ALC880_FIXUP_3ST, 1041 ALC880_FIXUP_3ST_DIG, 1042 ALC880_FIXUP_5ST_BASE, 1043 ALC880_FIXUP_5ST, 1044 ALC880_FIXUP_5ST_DIG, 1045 ALC880_FIXUP_6ST_BASE, 1046 ALC880_FIXUP_6ST, 1047 ALC880_FIXUP_6ST_DIG, 1048 ALC880_FIXUP_6ST_AUTOMUTE, 1049 }; 1050 1051 /* enable the volume-knob widget support on NID 0x21 */ 1052 static void alc880_fixup_vol_knob(struct hda_codec *codec, 1053 const struct hda_fixup *fix, int action) 1054 { 1055 if (action == HDA_FIXUP_ACT_PROBE) 1056 snd_hda_jack_detect_enable_callback(codec, 0x21, ALC_DCVOL_EVENT, alc_update_knob_master); 1057 } 1058 1059 static const struct hda_fixup alc880_fixups[] = { 1060 [ALC880_FIXUP_GPIO1] = { 1061 .type = HDA_FIXUP_VERBS, 1062 .v.verbs = alc_gpio1_init_verbs, 1063 }, 1064 [ALC880_FIXUP_GPIO2] = { 1065 .type = HDA_FIXUP_VERBS, 1066 .v.verbs = alc_gpio2_init_verbs, 1067 }, 1068 [ALC880_FIXUP_MEDION_RIM] = { 1069 .type = HDA_FIXUP_VERBS, 1070 .v.verbs = (const struct hda_verb[]) { 1071 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, 1072 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 }, 1073 { } 1074 }, 1075 .chained = true, 1076 .chain_id = ALC880_FIXUP_GPIO2, 1077 }, 1078 [ALC880_FIXUP_LG] = { 1079 .type = HDA_FIXUP_PINS, 1080 .v.pins = (const struct hda_pintbl[]) { 1081 /* disable bogus unused pins */ 1082 { 0x16, 0x411111f0 }, 1083 { 0x18, 0x411111f0 }, 1084 { 0x1a, 0x411111f0 }, 1085 { } 1086 } 1087 }, 1088 [ALC880_FIXUP_W810] = { 1089 .type = HDA_FIXUP_PINS, 1090 .v.pins = (const struct hda_pintbl[]) { 1091 /* disable bogus unused pins */ 1092 { 0x17, 0x411111f0 }, 1093 { } 1094 }, 1095 .chained = true, 1096 .chain_id = ALC880_FIXUP_GPIO2, 1097 }, 1098 [ALC880_FIXUP_EAPD_COEF] = { 1099 .type = HDA_FIXUP_VERBS, 1100 .v.verbs = (const struct hda_verb[]) { 1101 /* change to EAPD mode */ 1102 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, 1103 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 }, 1104 {} 1105 }, 1106 }, 1107 [ALC880_FIXUP_TCL_S700] = { 1108 .type = HDA_FIXUP_VERBS, 1109 .v.verbs = (const struct hda_verb[]) { 1110 /* change to EAPD mode */ 1111 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, 1112 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, 1113 {} 1114 }, 1115 .chained = true, 1116 .chain_id = ALC880_FIXUP_GPIO2, 1117 }, 1118 [ALC880_FIXUP_VOL_KNOB] = { 1119 .type = HDA_FIXUP_FUNC, 1120 .v.func = alc880_fixup_vol_knob, 1121 }, 1122 [ALC880_FIXUP_FUJITSU] = { 1123 /* override all pins as BIOS on old Amilo is broken */ 1124 .type = HDA_FIXUP_PINS, 1125 .v.pins = (const struct hda_pintbl[]) { 1126 { 0x14, 0x0121411f }, /* HP */ 1127 { 0x15, 0x99030120 }, /* speaker */ 1128 { 0x16, 0x99030130 }, /* bass speaker */ 1129 { 0x17, 0x411111f0 }, /* N/A */ 1130 { 0x18, 0x411111f0 }, /* N/A */ 1131 { 0x19, 0x01a19950 }, /* mic-in */ 1132 { 0x1a, 0x411111f0 }, /* N/A */ 1133 { 0x1b, 0x411111f0 }, /* N/A */ 1134 { 0x1c, 0x411111f0 }, /* N/A */ 1135 { 0x1d, 0x411111f0 }, /* N/A */ 1136 { 0x1e, 0x01454140 }, /* SPDIF out */ 1137 { } 1138 }, 1139 .chained = true, 1140 .chain_id = ALC880_FIXUP_VOL_KNOB, 1141 }, 1142 [ALC880_FIXUP_F1734] = { 1143 /* almost compatible with FUJITSU, but no bass and SPDIF */ 1144 .type = HDA_FIXUP_PINS, 1145 .v.pins = (const struct hda_pintbl[]) { 1146 { 0x14, 0x0121411f }, /* HP */ 1147 { 0x15, 0x99030120 }, /* speaker */ 1148 { 0x16, 0x411111f0 }, /* N/A */ 1149 { 0x17, 0x411111f0 }, /* N/A */ 1150 { 0x18, 0x411111f0 }, /* N/A */ 1151 { 0x19, 0x01a19950 }, /* mic-in */ 1152 { 0x1a, 0x411111f0 }, /* N/A */ 1153 { 0x1b, 0x411111f0 }, /* N/A */ 1154 { 0x1c, 0x411111f0 }, /* N/A */ 1155 { 0x1d, 0x411111f0 }, /* N/A */ 1156 { 0x1e, 0x411111f0 }, /* N/A */ 1157 { } 1158 }, 1159 .chained = true, 1160 .chain_id = ALC880_FIXUP_VOL_KNOB, 1161 }, 1162 [ALC880_FIXUP_UNIWILL] = { 1163 /* need to fix HP and speaker pins to be parsed correctly */ 1164 .type = HDA_FIXUP_PINS, 1165 .v.pins = (const struct hda_pintbl[]) { 1166 { 0x14, 0x0121411f }, /* HP */ 1167 { 0x15, 0x99030120 }, /* speaker */ 1168 { 0x16, 0x99030130 }, /* bass speaker */ 1169 { } 1170 }, 1171 }, 1172 [ALC880_FIXUP_UNIWILL_DIG] = { 1173 .type = HDA_FIXUP_PINS, 1174 .v.pins = (const struct hda_pintbl[]) { 1175 /* disable bogus unused pins */ 1176 { 0x17, 0x411111f0 }, 1177 { 0x19, 0x411111f0 }, 1178 { 0x1b, 0x411111f0 }, 1179 { 0x1f, 0x411111f0 }, 1180 { } 1181 } 1182 }, 1183 [ALC880_FIXUP_Z71V] = { 1184 .type = HDA_FIXUP_PINS, 1185 .v.pins = (const struct hda_pintbl[]) { 1186 /* set up the whole pins as BIOS is utterly broken */ 1187 { 0x14, 0x99030120 }, /* speaker */ 1188 { 0x15, 0x0121411f }, /* HP */ 1189 { 0x16, 0x411111f0 }, /* N/A */ 1190 { 0x17, 0x411111f0 }, /* N/A */ 1191 { 0x18, 0x01a19950 }, /* mic-in */ 1192 { 0x19, 0x411111f0 }, /* N/A */ 1193 { 0x1a, 0x01813031 }, /* line-in */ 1194 { 0x1b, 0x411111f0 }, /* N/A */ 1195 { 0x1c, 0x411111f0 }, /* N/A */ 1196 { 0x1d, 0x411111f0 }, /* N/A */ 1197 { 0x1e, 0x0144111e }, /* SPDIF */ 1198 { } 1199 } 1200 }, 1201 [ALC880_FIXUP_3ST_BASE] = { 1202 .type = HDA_FIXUP_PINS, 1203 .v.pins = (const struct hda_pintbl[]) { 1204 { 0x14, 0x01014010 }, /* line-out */ 1205 { 0x15, 0x411111f0 }, /* N/A */ 1206 { 0x16, 0x411111f0 }, /* N/A */ 1207 { 0x17, 0x411111f0 }, /* N/A */ 1208 { 0x18, 0x01a19c30 }, /* mic-in */ 1209 { 0x19, 0x0121411f }, /* HP */ 1210 { 0x1a, 0x01813031 }, /* line-in */ 1211 { 0x1b, 0x02a19c40 }, /* front-mic */ 1212 { 0x1c, 0x411111f0 }, /* N/A */ 1213 { 0x1d, 0x411111f0 }, /* N/A */ 1214 /* 0x1e is filled in below */ 1215 { 0x1f, 0x411111f0 }, /* N/A */ 1216 { } 1217 } 1218 }, 1219 [ALC880_FIXUP_3ST] = { 1220 .type = HDA_FIXUP_PINS, 1221 .v.pins = (const struct hda_pintbl[]) { 1222 { 0x1e, 0x411111f0 }, /* N/A */ 1223 { } 1224 }, 1225 .chained = true, 1226 .chain_id = ALC880_FIXUP_3ST_BASE, 1227 }, 1228 [ALC880_FIXUP_3ST_DIG] = { 1229 .type = HDA_FIXUP_PINS, 1230 .v.pins = (const struct hda_pintbl[]) { 1231 { 0x1e, 0x0144111e }, /* SPDIF */ 1232 { } 1233 }, 1234 .chained = true, 1235 .chain_id = ALC880_FIXUP_3ST_BASE, 1236 }, 1237 [ALC880_FIXUP_5ST_BASE] = { 1238 .type = HDA_FIXUP_PINS, 1239 .v.pins = (const struct hda_pintbl[]) { 1240 { 0x14, 0x01014010 }, /* front */ 1241 { 0x15, 0x411111f0 }, /* N/A */ 1242 { 0x16, 0x01011411 }, /* CLFE */ 1243 { 0x17, 0x01016412 }, /* surr */ 1244 { 0x18, 0x01a19c30 }, /* mic-in */ 1245 { 0x19, 0x0121411f }, /* HP */ 1246 { 0x1a, 0x01813031 }, /* line-in */ 1247 { 0x1b, 0x02a19c40 }, /* front-mic */ 1248 { 0x1c, 0x411111f0 }, /* N/A */ 1249 { 0x1d, 0x411111f0 }, /* N/A */ 1250 /* 0x1e is filled in below */ 1251 { 0x1f, 0x411111f0 }, /* N/A */ 1252 { } 1253 } 1254 }, 1255 [ALC880_FIXUP_5ST] = { 1256 .type = HDA_FIXUP_PINS, 1257 .v.pins = (const struct hda_pintbl[]) { 1258 { 0x1e, 0x411111f0 }, /* N/A */ 1259 { } 1260 }, 1261 .chained = true, 1262 .chain_id = ALC880_FIXUP_5ST_BASE, 1263 }, 1264 [ALC880_FIXUP_5ST_DIG] = { 1265 .type = HDA_FIXUP_PINS, 1266 .v.pins = (const struct hda_pintbl[]) { 1267 { 0x1e, 0x0144111e }, /* SPDIF */ 1268 { } 1269 }, 1270 .chained = true, 1271 .chain_id = ALC880_FIXUP_5ST_BASE, 1272 }, 1273 [ALC880_FIXUP_6ST_BASE] = { 1274 .type = HDA_FIXUP_PINS, 1275 .v.pins = (const struct hda_pintbl[]) { 1276 { 0x14, 0x01014010 }, /* front */ 1277 { 0x15, 0x01016412 }, /* surr */ 1278 { 0x16, 0x01011411 }, /* CLFE */ 1279 { 0x17, 0x01012414 }, /* side */ 1280 { 0x18, 0x01a19c30 }, /* mic-in */ 1281 { 0x19, 0x02a19c40 }, /* front-mic */ 1282 { 0x1a, 0x01813031 }, /* line-in */ 1283 { 0x1b, 0x0121411f }, /* HP */ 1284 { 0x1c, 0x411111f0 }, /* N/A */ 1285 { 0x1d, 0x411111f0 }, /* N/A */ 1286 /* 0x1e is filled in below */ 1287 { 0x1f, 0x411111f0 }, /* N/A */ 1288 { } 1289 } 1290 }, 1291 [ALC880_FIXUP_6ST] = { 1292 .type = HDA_FIXUP_PINS, 1293 .v.pins = (const struct hda_pintbl[]) { 1294 { 0x1e, 0x411111f0 }, /* N/A */ 1295 { } 1296 }, 1297 .chained = true, 1298 .chain_id = ALC880_FIXUP_6ST_BASE, 1299 }, 1300 [ALC880_FIXUP_6ST_DIG] = { 1301 .type = HDA_FIXUP_PINS, 1302 .v.pins = (const struct hda_pintbl[]) { 1303 { 0x1e, 0x0144111e }, /* SPDIF */ 1304 { } 1305 }, 1306 .chained = true, 1307 .chain_id = ALC880_FIXUP_6ST_BASE, 1308 }, 1309 [ALC880_FIXUP_6ST_AUTOMUTE] = { 1310 .type = HDA_FIXUP_PINS, 1311 .v.pins = (const struct hda_pintbl[]) { 1312 { 0x1b, 0x0121401f }, /* HP with jack detect */ 1313 { } 1314 }, 1315 .chained_before = true, 1316 .chain_id = ALC880_FIXUP_6ST_BASE, 1317 }, 1318 }; 1319 1320 static const struct snd_pci_quirk alc880_fixup_tbl[] = { 1321 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810), 1322 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V), 1323 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1), 1324 SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2), 1325 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF), 1326 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG), 1327 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734), 1328 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL), 1329 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB), 1330 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810), 1331 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM), 1332 SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST_AUTOMUTE), 1333 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_FIXUP_F1734), 1334 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU), 1335 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734), 1336 SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU), 1337 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG), 1338 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG), 1339 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG), 1340 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700), 1341 1342 /* Below is the copied entries from alc880_quirks.c. 1343 * It's not quite sure whether BIOS sets the correct pin-config table 1344 * on these machines, thus they are kept to be compatible with 1345 * the old static quirks. Once when it's confirmed to work without 1346 * these overrides, it'd be better to remove. 1347 */ 1348 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG), 1349 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST), 1350 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG), 1351 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG), 1352 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG), 1353 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG), 1354 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG), 1355 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST), 1356 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG), 1357 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST), 1358 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST), 1359 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST), 1360 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST), 1361 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST), 1362 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG), 1363 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG), 1364 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG), 1365 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG), 1366 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG), 1367 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG), 1368 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG), 1369 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */ 1370 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG), 1371 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG), 1372 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG), 1373 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG), 1374 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG), 1375 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG), 1376 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG), 1377 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG), 1378 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG), 1379 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG), 1380 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG), 1381 /* default Intel */ 1382 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST), 1383 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG), 1384 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG), 1385 {} 1386 }; 1387 1388 static const struct hda_model_fixup alc880_fixup_models[] = { 1389 {.id = ALC880_FIXUP_3ST, .name = "3stack"}, 1390 {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"}, 1391 {.id = ALC880_FIXUP_5ST, .name = "5stack"}, 1392 {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"}, 1393 {.id = ALC880_FIXUP_6ST, .name = "6stack"}, 1394 {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"}, 1395 {.id = ALC880_FIXUP_6ST_AUTOMUTE, .name = "6stack-automute"}, 1396 {} 1397 }; 1398 1399 1400 /* 1401 * OK, here we have finally the patch for ALC880 1402 */ 1403 static int patch_alc880(struct hda_codec *codec) 1404 { 1405 struct alc_spec *spec; 1406 int err; 1407 1408 err = alc_alloc_spec(codec, 0x0b); 1409 if (err < 0) 1410 return err; 1411 1412 spec = codec->spec; 1413 spec->gen.need_dac_fix = 1; 1414 spec->gen.beep_nid = 0x01; 1415 1416 snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl, 1417 alc880_fixups); 1418 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 1419 1420 /* automatic parse from the BIOS config */ 1421 err = alc880_parse_auto_config(codec); 1422 if (err < 0) 1423 goto error; 1424 1425 if (!spec->gen.no_analog) 1426 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 1427 1428 codec->patch_ops = alc_patch_ops; 1429 codec->patch_ops.unsol_event = alc880_unsol_event; 1430 1431 1432 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 1433 1434 return 0; 1435 1436 error: 1437 alc_free(codec); 1438 return err; 1439 } 1440 1441 1442 /* 1443 * ALC260 support 1444 */ 1445 static int alc260_parse_auto_config(struct hda_codec *codec) 1446 { 1447 static const hda_nid_t alc260_ignore[] = { 0x17, 0 }; 1448 static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 }; 1449 return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids); 1450 } 1451 1452 /* 1453 * Pin config fixes 1454 */ 1455 enum { 1456 ALC260_FIXUP_HP_DC5750, 1457 ALC260_FIXUP_HP_PIN_0F, 1458 ALC260_FIXUP_COEF, 1459 ALC260_FIXUP_GPIO1, 1460 ALC260_FIXUP_GPIO1_TOGGLE, 1461 ALC260_FIXUP_REPLACER, 1462 ALC260_FIXUP_HP_B1900, 1463 ALC260_FIXUP_KN1, 1464 ALC260_FIXUP_FSC_S7020, 1465 ALC260_FIXUP_FSC_S7020_JWSE, 1466 }; 1467 1468 static void alc260_gpio1_automute(struct hda_codec *codec) 1469 { 1470 struct alc_spec *spec = codec->spec; 1471 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 1472 spec->gen.hp_jack_present); 1473 } 1474 1475 static void alc260_fixup_gpio1_toggle(struct hda_codec *codec, 1476 const struct hda_fixup *fix, int action) 1477 { 1478 struct alc_spec *spec = codec->spec; 1479 if (action == HDA_FIXUP_ACT_PROBE) { 1480 /* although the machine has only one output pin, we need to 1481 * toggle GPIO1 according to the jack state 1482 */ 1483 spec->gen.automute_hook = alc260_gpio1_automute; 1484 spec->gen.detect_hp = 1; 1485 spec->gen.automute_speaker = 1; 1486 spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */ 1487 snd_hda_jack_detect_enable_callback(codec, 0x0f, HDA_GEN_HP_EVENT, 1488 snd_hda_gen_hp_automute); 1489 snd_hda_add_verbs(codec, alc_gpio1_init_verbs); 1490 } 1491 } 1492 1493 static void alc260_fixup_kn1(struct hda_codec *codec, 1494 const struct hda_fixup *fix, int action) 1495 { 1496 struct alc_spec *spec = codec->spec; 1497 static const struct hda_pintbl pincfgs[] = { 1498 { 0x0f, 0x02214000 }, /* HP/speaker */ 1499 { 0x12, 0x90a60160 }, /* int mic */ 1500 { 0x13, 0x02a19000 }, /* ext mic */ 1501 { 0x18, 0x01446000 }, /* SPDIF out */ 1502 /* disable bogus I/O pins */ 1503 { 0x10, 0x411111f0 }, 1504 { 0x11, 0x411111f0 }, 1505 { 0x14, 0x411111f0 }, 1506 { 0x15, 0x411111f0 }, 1507 { 0x16, 0x411111f0 }, 1508 { 0x17, 0x411111f0 }, 1509 { 0x19, 0x411111f0 }, 1510 { } 1511 }; 1512 1513 switch (action) { 1514 case HDA_FIXUP_ACT_PRE_PROBE: 1515 snd_hda_apply_pincfgs(codec, pincfgs); 1516 break; 1517 case HDA_FIXUP_ACT_PROBE: 1518 spec->init_amp = ALC_INIT_NONE; 1519 break; 1520 } 1521 } 1522 1523 static void alc260_fixup_fsc_s7020(struct hda_codec *codec, 1524 const struct hda_fixup *fix, int action) 1525 { 1526 struct alc_spec *spec = codec->spec; 1527 if (action == HDA_FIXUP_ACT_PROBE) 1528 spec->init_amp = ALC_INIT_NONE; 1529 } 1530 1531 static void alc260_fixup_fsc_s7020_jwse(struct hda_codec *codec, 1532 const struct hda_fixup *fix, int action) 1533 { 1534 struct alc_spec *spec = codec->spec; 1535 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 1536 spec->gen.add_jack_modes = 1; 1537 spec->gen.hp_mic = 1; 1538 } 1539 } 1540 1541 static const struct hda_fixup alc260_fixups[] = { 1542 [ALC260_FIXUP_HP_DC5750] = { 1543 .type = HDA_FIXUP_PINS, 1544 .v.pins = (const struct hda_pintbl[]) { 1545 { 0x11, 0x90130110 }, /* speaker */ 1546 { } 1547 } 1548 }, 1549 [ALC260_FIXUP_HP_PIN_0F] = { 1550 .type = HDA_FIXUP_PINS, 1551 .v.pins = (const struct hda_pintbl[]) { 1552 { 0x0f, 0x01214000 }, /* HP */ 1553 { } 1554 } 1555 }, 1556 [ALC260_FIXUP_COEF] = { 1557 .type = HDA_FIXUP_VERBS, 1558 .v.verbs = (const struct hda_verb[]) { 1559 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, 1560 { 0x20, AC_VERB_SET_PROC_COEF, 0x3040 }, 1561 { } 1562 }, 1563 .chained = true, 1564 .chain_id = ALC260_FIXUP_HP_PIN_0F, 1565 }, 1566 [ALC260_FIXUP_GPIO1] = { 1567 .type = HDA_FIXUP_VERBS, 1568 .v.verbs = alc_gpio1_init_verbs, 1569 }, 1570 [ALC260_FIXUP_GPIO1_TOGGLE] = { 1571 .type = HDA_FIXUP_FUNC, 1572 .v.func = alc260_fixup_gpio1_toggle, 1573 .chained = true, 1574 .chain_id = ALC260_FIXUP_HP_PIN_0F, 1575 }, 1576 [ALC260_FIXUP_REPLACER] = { 1577 .type = HDA_FIXUP_VERBS, 1578 .v.verbs = (const struct hda_verb[]) { 1579 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, 1580 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, 1581 { } 1582 }, 1583 .chained = true, 1584 .chain_id = ALC260_FIXUP_GPIO1_TOGGLE, 1585 }, 1586 [ALC260_FIXUP_HP_B1900] = { 1587 .type = HDA_FIXUP_FUNC, 1588 .v.func = alc260_fixup_gpio1_toggle, 1589 .chained = true, 1590 .chain_id = ALC260_FIXUP_COEF, 1591 }, 1592 [ALC260_FIXUP_KN1] = { 1593 .type = HDA_FIXUP_FUNC, 1594 .v.func = alc260_fixup_kn1, 1595 }, 1596 [ALC260_FIXUP_FSC_S7020] = { 1597 .type = HDA_FIXUP_FUNC, 1598 .v.func = alc260_fixup_fsc_s7020, 1599 }, 1600 [ALC260_FIXUP_FSC_S7020_JWSE] = { 1601 .type = HDA_FIXUP_FUNC, 1602 .v.func = alc260_fixup_fsc_s7020_jwse, 1603 .chained = true, 1604 .chain_id = ALC260_FIXUP_FSC_S7020, 1605 }, 1606 }; 1607 1608 static const struct snd_pci_quirk alc260_fixup_tbl[] = { 1609 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1), 1610 SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF), 1611 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1), 1612 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750), 1613 SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900), 1614 SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020), 1615 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1), 1616 SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1), 1617 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER), 1618 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF), 1619 {} 1620 }; 1621 1622 static const struct hda_model_fixup alc260_fixup_models[] = { 1623 {.id = ALC260_FIXUP_GPIO1, .name = "gpio1"}, 1624 {.id = ALC260_FIXUP_COEF, .name = "coef"}, 1625 {.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"}, 1626 {.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"}, 1627 {} 1628 }; 1629 1630 /* 1631 */ 1632 static int patch_alc260(struct hda_codec *codec) 1633 { 1634 struct alc_spec *spec; 1635 int err; 1636 1637 err = alc_alloc_spec(codec, 0x07); 1638 if (err < 0) 1639 return err; 1640 1641 spec = codec->spec; 1642 /* as quite a few machines require HP amp for speaker outputs, 1643 * it's easier to enable it unconditionally; even if it's unneeded, 1644 * it's almost harmless. 1645 */ 1646 spec->gen.prefer_hp_amp = 1; 1647 spec->gen.beep_nid = 0x01; 1648 1649 snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl, 1650 alc260_fixups); 1651 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 1652 1653 /* automatic parse from the BIOS config */ 1654 err = alc260_parse_auto_config(codec); 1655 if (err < 0) 1656 goto error; 1657 1658 if (!spec->gen.no_analog) 1659 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); 1660 1661 codec->patch_ops = alc_patch_ops; 1662 spec->shutup = alc_eapd_shutup; 1663 1664 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 1665 1666 return 0; 1667 1668 error: 1669 alc_free(codec); 1670 return err; 1671 } 1672 1673 1674 /* 1675 * ALC882/883/885/888/889 support 1676 * 1677 * ALC882 is almost identical with ALC880 but has cleaner and more flexible 1678 * configuration. Each pin widget can choose any input DACs and a mixer. 1679 * Each ADC is connected from a mixer of all inputs. This makes possible 1680 * 6-channel independent captures. 1681 * 1682 * In addition, an independent DAC for the multi-playback (not used in this 1683 * driver yet). 1684 */ 1685 1686 /* 1687 * Pin config fixes 1688 */ 1689 enum { 1690 ALC882_FIXUP_ABIT_AW9D_MAX, 1691 ALC882_FIXUP_LENOVO_Y530, 1692 ALC882_FIXUP_PB_M5210, 1693 ALC882_FIXUP_ACER_ASPIRE_7736, 1694 ALC882_FIXUP_ASUS_W90V, 1695 ALC889_FIXUP_CD, 1696 ALC889_FIXUP_VAIO_TT, 1697 ALC888_FIXUP_EEE1601, 1698 ALC882_FIXUP_EAPD, 1699 ALC883_FIXUP_EAPD, 1700 ALC883_FIXUP_ACER_EAPD, 1701 ALC882_FIXUP_GPIO1, 1702 ALC882_FIXUP_GPIO2, 1703 ALC882_FIXUP_GPIO3, 1704 ALC889_FIXUP_COEF, 1705 ALC882_FIXUP_ASUS_W2JC, 1706 ALC882_FIXUP_ACER_ASPIRE_4930G, 1707 ALC882_FIXUP_ACER_ASPIRE_8930G, 1708 ALC882_FIXUP_ASPIRE_8930G_VERBS, 1709 ALC885_FIXUP_MACPRO_GPIO, 1710 ALC889_FIXUP_DAC_ROUTE, 1711 ALC889_FIXUP_MBP_VREF, 1712 ALC889_FIXUP_IMAC91_VREF, 1713 ALC882_FIXUP_INV_DMIC, 1714 ALC882_FIXUP_NO_PRIMARY_HP, 1715 }; 1716 1717 static void alc889_fixup_coef(struct hda_codec *codec, 1718 const struct hda_fixup *fix, int action) 1719 { 1720 if (action != HDA_FIXUP_ACT_INIT) 1721 return; 1722 alc889_coef_init(codec); 1723 } 1724 1725 /* toggle speaker-output according to the hp-jack state */ 1726 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) 1727 { 1728 unsigned int gpiostate, gpiomask, gpiodir; 1729 1730 gpiostate = snd_hda_codec_read(codec, codec->afg, 0, 1731 AC_VERB_GET_GPIO_DATA, 0); 1732 1733 if (!muted) 1734 gpiostate |= (1 << pin); 1735 else 1736 gpiostate &= ~(1 << pin); 1737 1738 gpiomask = snd_hda_codec_read(codec, codec->afg, 0, 1739 AC_VERB_GET_GPIO_MASK, 0); 1740 gpiomask |= (1 << pin); 1741 1742 gpiodir = snd_hda_codec_read(codec, codec->afg, 0, 1743 AC_VERB_GET_GPIO_DIRECTION, 0); 1744 gpiodir |= (1 << pin); 1745 1746 1747 snd_hda_codec_write(codec, codec->afg, 0, 1748 AC_VERB_SET_GPIO_MASK, gpiomask); 1749 snd_hda_codec_write(codec, codec->afg, 0, 1750 AC_VERB_SET_GPIO_DIRECTION, gpiodir); 1751 1752 msleep(1); 1753 1754 snd_hda_codec_write(codec, codec->afg, 0, 1755 AC_VERB_SET_GPIO_DATA, gpiostate); 1756 } 1757 1758 /* set up GPIO at initialization */ 1759 static void alc885_fixup_macpro_gpio(struct hda_codec *codec, 1760 const struct hda_fixup *fix, int action) 1761 { 1762 if (action != HDA_FIXUP_ACT_INIT) 1763 return; 1764 alc882_gpio_mute(codec, 0, 0); 1765 alc882_gpio_mute(codec, 1, 0); 1766 } 1767 1768 /* Fix the connection of some pins for ALC889: 1769 * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't 1770 * work correctly (bko#42740) 1771 */ 1772 static void alc889_fixup_dac_route(struct hda_codec *codec, 1773 const struct hda_fixup *fix, int action) 1774 { 1775 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 1776 /* fake the connections during parsing the tree */ 1777 hda_nid_t conn1[2] = { 0x0c, 0x0d }; 1778 hda_nid_t conn2[2] = { 0x0e, 0x0f }; 1779 snd_hda_override_conn_list(codec, 0x14, 2, conn1); 1780 snd_hda_override_conn_list(codec, 0x15, 2, conn1); 1781 snd_hda_override_conn_list(codec, 0x18, 2, conn2); 1782 snd_hda_override_conn_list(codec, 0x1a, 2, conn2); 1783 } else if (action == HDA_FIXUP_ACT_PROBE) { 1784 /* restore the connections */ 1785 hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 }; 1786 snd_hda_override_conn_list(codec, 0x14, 5, conn); 1787 snd_hda_override_conn_list(codec, 0x15, 5, conn); 1788 snd_hda_override_conn_list(codec, 0x18, 5, conn); 1789 snd_hda_override_conn_list(codec, 0x1a, 5, conn); 1790 } 1791 } 1792 1793 /* Set VREF on HP pin */ 1794 static void alc889_fixup_mbp_vref(struct hda_codec *codec, 1795 const struct hda_fixup *fix, int action) 1796 { 1797 struct alc_spec *spec = codec->spec; 1798 static hda_nid_t nids[2] = { 0x14, 0x15 }; 1799 int i; 1800 1801 if (action != HDA_FIXUP_ACT_INIT) 1802 return; 1803 for (i = 0; i < ARRAY_SIZE(nids); i++) { 1804 unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]); 1805 if (get_defcfg_device(val) != AC_JACK_HP_OUT) 1806 continue; 1807 val = snd_hda_codec_get_pin_target(codec, nids[i]); 1808 val |= AC_PINCTL_VREF_80; 1809 snd_hda_set_pin_ctl(codec, nids[i], val); 1810 spec->gen.keep_vref_in_automute = 1; 1811 break; 1812 } 1813 } 1814 1815 /* Set VREF on speaker pins on imac91 */ 1816 static void alc889_fixup_imac91_vref(struct hda_codec *codec, 1817 const struct hda_fixup *fix, int action) 1818 { 1819 struct alc_spec *spec = codec->spec; 1820 static hda_nid_t nids[2] = { 0x18, 0x1a }; 1821 int i; 1822 1823 if (action != HDA_FIXUP_ACT_INIT) 1824 return; 1825 for (i = 0; i < ARRAY_SIZE(nids); i++) { 1826 unsigned int val; 1827 val = snd_hda_codec_get_pin_target(codec, nids[i]); 1828 val |= AC_PINCTL_VREF_50; 1829 snd_hda_set_pin_ctl(codec, nids[i], val); 1830 } 1831 spec->gen.keep_vref_in_automute = 1; 1832 } 1833 1834 /* Don't take HP output as primary 1835 * Strangely, the speaker output doesn't work on Vaio Z and some Vaio 1836 * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05 1837 */ 1838 static void alc882_fixup_no_primary_hp(struct hda_codec *codec, 1839 const struct hda_fixup *fix, int action) 1840 { 1841 struct alc_spec *spec = codec->spec; 1842 if (action == HDA_FIXUP_ACT_PRE_PROBE) 1843 spec->gen.no_primary_hp = 1; 1844 } 1845 1846 static const struct hda_fixup alc882_fixups[] = { 1847 [ALC882_FIXUP_ABIT_AW9D_MAX] = { 1848 .type = HDA_FIXUP_PINS, 1849 .v.pins = (const struct hda_pintbl[]) { 1850 { 0x15, 0x01080104 }, /* side */ 1851 { 0x16, 0x01011012 }, /* rear */ 1852 { 0x17, 0x01016011 }, /* clfe */ 1853 { } 1854 } 1855 }, 1856 [ALC882_FIXUP_LENOVO_Y530] = { 1857 .type = HDA_FIXUP_PINS, 1858 .v.pins = (const struct hda_pintbl[]) { 1859 { 0x15, 0x99130112 }, /* rear int speakers */ 1860 { 0x16, 0x99130111 }, /* subwoofer */ 1861 { } 1862 } 1863 }, 1864 [ALC882_FIXUP_PB_M5210] = { 1865 .type = HDA_FIXUP_PINCTLS, 1866 .v.pins = (const struct hda_pintbl[]) { 1867 { 0x19, PIN_VREF50 }, 1868 {} 1869 } 1870 }, 1871 [ALC882_FIXUP_ACER_ASPIRE_7736] = { 1872 .type = HDA_FIXUP_FUNC, 1873 .v.func = alc_fixup_sku_ignore, 1874 }, 1875 [ALC882_FIXUP_ASUS_W90V] = { 1876 .type = HDA_FIXUP_PINS, 1877 .v.pins = (const struct hda_pintbl[]) { 1878 { 0x16, 0x99130110 }, /* fix sequence for CLFE */ 1879 { } 1880 } 1881 }, 1882 [ALC889_FIXUP_CD] = { 1883 .type = HDA_FIXUP_PINS, 1884 .v.pins = (const struct hda_pintbl[]) { 1885 { 0x1c, 0x993301f0 }, /* CD */ 1886 { } 1887 } 1888 }, 1889 [ALC889_FIXUP_VAIO_TT] = { 1890 .type = HDA_FIXUP_PINS, 1891 .v.pins = (const struct hda_pintbl[]) { 1892 { 0x17, 0x90170111 }, /* hidden surround speaker */ 1893 { } 1894 } 1895 }, 1896 [ALC888_FIXUP_EEE1601] = { 1897 .type = HDA_FIXUP_VERBS, 1898 .v.verbs = (const struct hda_verb[]) { 1899 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b }, 1900 { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 }, 1901 { } 1902 } 1903 }, 1904 [ALC882_FIXUP_EAPD] = { 1905 .type = HDA_FIXUP_VERBS, 1906 .v.verbs = (const struct hda_verb[]) { 1907 /* change to EAPD mode */ 1908 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, 1909 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 }, 1910 { } 1911 } 1912 }, 1913 [ALC883_FIXUP_EAPD] = { 1914 .type = HDA_FIXUP_VERBS, 1915 .v.verbs = (const struct hda_verb[]) { 1916 /* change to EAPD mode */ 1917 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, 1918 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, 1919 { } 1920 } 1921 }, 1922 [ALC883_FIXUP_ACER_EAPD] = { 1923 .type = HDA_FIXUP_VERBS, 1924 .v.verbs = (const struct hda_verb[]) { 1925 /* eanable EAPD on Acer laptops */ 1926 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, 1927 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, 1928 { } 1929 } 1930 }, 1931 [ALC882_FIXUP_GPIO1] = { 1932 .type = HDA_FIXUP_VERBS, 1933 .v.verbs = alc_gpio1_init_verbs, 1934 }, 1935 [ALC882_FIXUP_GPIO2] = { 1936 .type = HDA_FIXUP_VERBS, 1937 .v.verbs = alc_gpio2_init_verbs, 1938 }, 1939 [ALC882_FIXUP_GPIO3] = { 1940 .type = HDA_FIXUP_VERBS, 1941 .v.verbs = alc_gpio3_init_verbs, 1942 }, 1943 [ALC882_FIXUP_ASUS_W2JC] = { 1944 .type = HDA_FIXUP_VERBS, 1945 .v.verbs = alc_gpio1_init_verbs, 1946 .chained = true, 1947 .chain_id = ALC882_FIXUP_EAPD, 1948 }, 1949 [ALC889_FIXUP_COEF] = { 1950 .type = HDA_FIXUP_FUNC, 1951 .v.func = alc889_fixup_coef, 1952 }, 1953 [ALC882_FIXUP_ACER_ASPIRE_4930G] = { 1954 .type = HDA_FIXUP_PINS, 1955 .v.pins = (const struct hda_pintbl[]) { 1956 { 0x16, 0x99130111 }, /* CLFE speaker */ 1957 { 0x17, 0x99130112 }, /* surround speaker */ 1958 { } 1959 }, 1960 .chained = true, 1961 .chain_id = ALC882_FIXUP_GPIO1, 1962 }, 1963 [ALC882_FIXUP_ACER_ASPIRE_8930G] = { 1964 .type = HDA_FIXUP_PINS, 1965 .v.pins = (const struct hda_pintbl[]) { 1966 { 0x16, 0x99130111 }, /* CLFE speaker */ 1967 { 0x1b, 0x99130112 }, /* surround speaker */ 1968 { } 1969 }, 1970 .chained = true, 1971 .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS, 1972 }, 1973 [ALC882_FIXUP_ASPIRE_8930G_VERBS] = { 1974 /* additional init verbs for Acer Aspire 8930G */ 1975 .type = HDA_FIXUP_VERBS, 1976 .v.verbs = (const struct hda_verb[]) { 1977 /* Enable all DACs */ 1978 /* DAC DISABLE/MUTE 1? */ 1979 /* setting bits 1-5 disables DAC nids 0x02-0x06 1980 * apparently. Init=0x38 */ 1981 { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 }, 1982 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, 1983 /* DAC DISABLE/MUTE 2? */ 1984 /* some bit here disables the other DACs. 1985 * Init=0x4900 */ 1986 { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 }, 1987 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, 1988 /* DMIC fix 1989 * This laptop has a stereo digital microphone. 1990 * The mics are only 1cm apart which makes the stereo 1991 * useless. However, either the mic or the ALC889 1992 * makes the signal become a difference/sum signal 1993 * instead of standard stereo, which is annoying. 1994 * So instead we flip this bit which makes the 1995 * codec replicate the sum signal to both channels, 1996 * turning it into a normal mono mic. 1997 */ 1998 /* DMIC_CONTROL? Init value = 0x0001 */ 1999 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b }, 2000 { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 }, 2001 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, 2002 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, 2003 { } 2004 }, 2005 .chained = true, 2006 .chain_id = ALC882_FIXUP_GPIO1, 2007 }, 2008 [ALC885_FIXUP_MACPRO_GPIO] = { 2009 .type = HDA_FIXUP_FUNC, 2010 .v.func = alc885_fixup_macpro_gpio, 2011 }, 2012 [ALC889_FIXUP_DAC_ROUTE] = { 2013 .type = HDA_FIXUP_FUNC, 2014 .v.func = alc889_fixup_dac_route, 2015 }, 2016 [ALC889_FIXUP_MBP_VREF] = { 2017 .type = HDA_FIXUP_FUNC, 2018 .v.func = alc889_fixup_mbp_vref, 2019 .chained = true, 2020 .chain_id = ALC882_FIXUP_GPIO1, 2021 }, 2022 [ALC889_FIXUP_IMAC91_VREF] = { 2023 .type = HDA_FIXUP_FUNC, 2024 .v.func = alc889_fixup_imac91_vref, 2025 .chained = true, 2026 .chain_id = ALC882_FIXUP_GPIO1, 2027 }, 2028 [ALC882_FIXUP_INV_DMIC] = { 2029 .type = HDA_FIXUP_FUNC, 2030 .v.func = alc_fixup_inv_dmic_0x12, 2031 }, 2032 [ALC882_FIXUP_NO_PRIMARY_HP] = { 2033 .type = HDA_FIXUP_FUNC, 2034 .v.func = alc882_fixup_no_primary_hp, 2035 }, 2036 }; 2037 2038 static const struct snd_pci_quirk alc882_fixup_tbl[] = { 2039 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD), 2040 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD), 2041 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD), 2042 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD), 2043 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD), 2044 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD), 2045 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G", 2046 ALC882_FIXUP_ACER_ASPIRE_4930G), 2047 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G", 2048 ALC882_FIXUP_ACER_ASPIRE_4930G), 2049 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G", 2050 ALC882_FIXUP_ACER_ASPIRE_8930G), 2051 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G", 2052 ALC882_FIXUP_ACER_ASPIRE_8930G), 2053 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", 2054 ALC882_FIXUP_ACER_ASPIRE_4930G), 2055 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", 2056 ALC882_FIXUP_ACER_ASPIRE_4930G), 2057 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", 2058 ALC882_FIXUP_ACER_ASPIRE_4930G), 2059 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210), 2060 SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G", 2061 ALC882_FIXUP_ACER_ASPIRE_4930G), 2062 SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE), 2063 SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G), 2064 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736), 2065 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD), 2066 SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V), 2067 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC), 2068 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601), 2069 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT), 2070 SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP), 2071 SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP), 2072 2073 /* All Apple entries are in codec SSIDs */ 2074 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF), 2075 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF), 2076 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF), 2077 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_FIXUP_MACPRO_GPIO), 2078 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO), 2079 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO), 2080 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF), 2081 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF), 2082 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD), 2083 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBP_VREF), 2084 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBP_VREF), 2085 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF), 2086 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF), 2087 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO), 2088 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF), 2089 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF), 2090 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF), 2091 SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO), 2092 SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF), 2093 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF), 2094 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF), 2095 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF), 2096 2097 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD), 2098 SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD), 2099 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), 2100 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3", ALC889_FIXUP_CD), 2101 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), 2102 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), 2103 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), 2104 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530), 2105 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF), 2106 {} 2107 }; 2108 2109 static const struct hda_model_fixup alc882_fixup_models[] = { 2110 {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"}, 2111 {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"}, 2112 {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"}, 2113 {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"}, 2114 {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"}, 2115 {} 2116 }; 2117 2118 /* 2119 * BIOS auto configuration 2120 */ 2121 /* almost identical with ALC880 parser... */ 2122 static int alc882_parse_auto_config(struct hda_codec *codec) 2123 { 2124 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 }; 2125 static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 }; 2126 return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids); 2127 } 2128 2129 /* 2130 */ 2131 static int patch_alc882(struct hda_codec *codec) 2132 { 2133 struct alc_spec *spec; 2134 int err; 2135 2136 err = alc_alloc_spec(codec, 0x0b); 2137 if (err < 0) 2138 return err; 2139 2140 spec = codec->spec; 2141 2142 switch (codec->vendor_id) { 2143 case 0x10ec0882: 2144 case 0x10ec0885: 2145 break; 2146 default: 2147 /* ALC883 and variants */ 2148 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 2149 break; 2150 } 2151 2152 snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl, 2153 alc882_fixups); 2154 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 2155 2156 alc_auto_parse_customize_define(codec); 2157 2158 if (has_cdefine_beep(codec)) 2159 spec->gen.beep_nid = 0x01; 2160 2161 /* automatic parse from the BIOS config */ 2162 err = alc882_parse_auto_config(codec); 2163 if (err < 0) 2164 goto error; 2165 2166 if (!spec->gen.no_analog && spec->gen.beep_nid) 2167 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 2168 2169 codec->patch_ops = alc_patch_ops; 2170 2171 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 2172 2173 return 0; 2174 2175 error: 2176 alc_free(codec); 2177 return err; 2178 } 2179 2180 2181 /* 2182 * ALC262 support 2183 */ 2184 static int alc262_parse_auto_config(struct hda_codec *codec) 2185 { 2186 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 }; 2187 static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 }; 2188 return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids); 2189 } 2190 2191 /* 2192 * Pin config fixes 2193 */ 2194 enum { 2195 ALC262_FIXUP_FSC_H270, 2196 ALC262_FIXUP_FSC_S7110, 2197 ALC262_FIXUP_HP_Z200, 2198 ALC262_FIXUP_TYAN, 2199 ALC262_FIXUP_LENOVO_3000, 2200 ALC262_FIXUP_BENQ, 2201 ALC262_FIXUP_BENQ_T31, 2202 ALC262_FIXUP_INV_DMIC, 2203 }; 2204 2205 static const struct hda_fixup alc262_fixups[] = { 2206 [ALC262_FIXUP_FSC_H270] = { 2207 .type = HDA_FIXUP_PINS, 2208 .v.pins = (const struct hda_pintbl[]) { 2209 { 0x14, 0x99130110 }, /* speaker */ 2210 { 0x15, 0x0221142f }, /* front HP */ 2211 { 0x1b, 0x0121141f }, /* rear HP */ 2212 { } 2213 } 2214 }, 2215 [ALC262_FIXUP_FSC_S7110] = { 2216 .type = HDA_FIXUP_PINS, 2217 .v.pins = (const struct hda_pintbl[]) { 2218 { 0x15, 0x90170110 }, /* speaker */ 2219 { } 2220 }, 2221 .chained = true, 2222 .chain_id = ALC262_FIXUP_BENQ, 2223 }, 2224 [ALC262_FIXUP_HP_Z200] = { 2225 .type = HDA_FIXUP_PINS, 2226 .v.pins = (const struct hda_pintbl[]) { 2227 { 0x16, 0x99130120 }, /* internal speaker */ 2228 { } 2229 } 2230 }, 2231 [ALC262_FIXUP_TYAN] = { 2232 .type = HDA_FIXUP_PINS, 2233 .v.pins = (const struct hda_pintbl[]) { 2234 { 0x14, 0x1993e1f0 }, /* int AUX */ 2235 { } 2236 } 2237 }, 2238 [ALC262_FIXUP_LENOVO_3000] = { 2239 .type = HDA_FIXUP_PINCTLS, 2240 .v.pins = (const struct hda_pintbl[]) { 2241 { 0x19, PIN_VREF50 }, 2242 {} 2243 }, 2244 .chained = true, 2245 .chain_id = ALC262_FIXUP_BENQ, 2246 }, 2247 [ALC262_FIXUP_BENQ] = { 2248 .type = HDA_FIXUP_VERBS, 2249 .v.verbs = (const struct hda_verb[]) { 2250 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, 2251 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, 2252 {} 2253 } 2254 }, 2255 [ALC262_FIXUP_BENQ_T31] = { 2256 .type = HDA_FIXUP_VERBS, 2257 .v.verbs = (const struct hda_verb[]) { 2258 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, 2259 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, 2260 {} 2261 } 2262 }, 2263 [ALC262_FIXUP_INV_DMIC] = { 2264 .type = HDA_FIXUP_FUNC, 2265 .v.func = alc_fixup_inv_dmic_0x12, 2266 }, 2267 }; 2268 2269 static const struct snd_pci_quirk alc262_fixup_tbl[] = { 2270 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200), 2271 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110), 2272 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ), 2273 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN), 2274 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270), 2275 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000), 2276 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ), 2277 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31), 2278 {} 2279 }; 2280 2281 static const struct hda_model_fixup alc262_fixup_models[] = { 2282 {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"}, 2283 {} 2284 }; 2285 2286 /* 2287 */ 2288 static int patch_alc262(struct hda_codec *codec) 2289 { 2290 struct alc_spec *spec; 2291 int err; 2292 2293 err = alc_alloc_spec(codec, 0x0b); 2294 if (err < 0) 2295 return err; 2296 2297 spec = codec->spec; 2298 spec->gen.shared_mic_vref_pin = 0x18; 2299 2300 #if 0 2301 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is 2302 * under-run 2303 */ 2304 { 2305 int tmp; 2306 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 2307 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 2308 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 2309 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80); 2310 } 2311 #endif 2312 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 2313 2314 snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl, 2315 alc262_fixups); 2316 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 2317 2318 alc_auto_parse_customize_define(codec); 2319 2320 if (has_cdefine_beep(codec)) 2321 spec->gen.beep_nid = 0x01; 2322 2323 /* automatic parse from the BIOS config */ 2324 err = alc262_parse_auto_config(codec); 2325 if (err < 0) 2326 goto error; 2327 2328 if (!spec->gen.no_analog && spec->gen.beep_nid) 2329 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 2330 2331 codec->patch_ops = alc_patch_ops; 2332 spec->shutup = alc_eapd_shutup; 2333 2334 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 2335 2336 return 0; 2337 2338 error: 2339 alc_free(codec); 2340 return err; 2341 } 2342 2343 /* 2344 * ALC268 2345 */ 2346 /* bind Beep switches of both NID 0x0f and 0x10 */ 2347 static const struct hda_bind_ctls alc268_bind_beep_sw = { 2348 .ops = &snd_hda_bind_sw, 2349 .values = { 2350 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT), 2351 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT), 2352 0 2353 }, 2354 }; 2355 2356 static const struct snd_kcontrol_new alc268_beep_mixer[] = { 2357 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT), 2358 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw), 2359 { } 2360 }; 2361 2362 /* set PCBEEP vol = 0, mute connections */ 2363 static const struct hda_verb alc268_beep_init_verbs[] = { 2364 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2365 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2366 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2367 { } 2368 }; 2369 2370 enum { 2371 ALC268_FIXUP_INV_DMIC, 2372 ALC268_FIXUP_HP_EAPD, 2373 }; 2374 2375 static const struct hda_fixup alc268_fixups[] = { 2376 [ALC268_FIXUP_INV_DMIC] = { 2377 .type = HDA_FIXUP_FUNC, 2378 .v.func = alc_fixup_inv_dmic_0x12, 2379 }, 2380 [ALC268_FIXUP_HP_EAPD] = { 2381 .type = HDA_FIXUP_VERBS, 2382 .v.verbs = (const struct hda_verb[]) { 2383 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0}, 2384 {} 2385 } 2386 }, 2387 }; 2388 2389 static const struct hda_model_fixup alc268_fixup_models[] = { 2390 {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"}, 2391 {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"}, 2392 {} 2393 }; 2394 2395 static const struct snd_pci_quirk alc268_fixup_tbl[] = { 2396 SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC), 2397 /* below is codec SSID since multiple Toshiba laptops have the 2398 * same PCI SSID 1179:ff00 2399 */ 2400 SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD), 2401 {} 2402 }; 2403 2404 /* 2405 * BIOS auto configuration 2406 */ 2407 static int alc268_parse_auto_config(struct hda_codec *codec) 2408 { 2409 static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 }; 2410 return alc_parse_auto_config(codec, NULL, alc268_ssids); 2411 } 2412 2413 /* 2414 */ 2415 static int patch_alc268(struct hda_codec *codec) 2416 { 2417 struct alc_spec *spec; 2418 int err; 2419 2420 /* ALC268 has no aa-loopback mixer */ 2421 err = alc_alloc_spec(codec, 0); 2422 if (err < 0) 2423 return err; 2424 2425 spec = codec->spec; 2426 spec->gen.beep_nid = 0x01; 2427 2428 snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups); 2429 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 2430 2431 /* automatic parse from the BIOS config */ 2432 err = alc268_parse_auto_config(codec); 2433 if (err < 0) 2434 goto error; 2435 2436 if (err > 0 && !spec->gen.no_analog && 2437 spec->gen.autocfg.speaker_pins[0] != 0x1d) { 2438 add_mixer(spec, alc268_beep_mixer); 2439 snd_hda_add_verbs(codec, alc268_beep_init_verbs); 2440 if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) 2441 /* override the amp caps for beep generator */ 2442 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT, 2443 (0x0c << AC_AMPCAP_OFFSET_SHIFT) | 2444 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) | 2445 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) | 2446 (0 << AC_AMPCAP_MUTE_SHIFT)); 2447 } 2448 2449 codec->patch_ops = alc_patch_ops; 2450 spec->shutup = alc_eapd_shutup; 2451 2452 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 2453 2454 return 0; 2455 2456 error: 2457 alc_free(codec); 2458 return err; 2459 } 2460 2461 /* 2462 * ALC269 2463 */ 2464 2465 static int playback_pcm_open(struct hda_pcm_stream *hinfo, 2466 struct hda_codec *codec, 2467 struct snd_pcm_substream *substream) 2468 { 2469 struct hda_gen_spec *spec = codec->spec; 2470 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, 2471 hinfo); 2472 } 2473 2474 static int playback_pcm_prepare(struct hda_pcm_stream *hinfo, 2475 struct hda_codec *codec, 2476 unsigned int stream_tag, 2477 unsigned int format, 2478 struct snd_pcm_substream *substream) 2479 { 2480 struct hda_gen_spec *spec = codec->spec; 2481 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, 2482 stream_tag, format, substream); 2483 } 2484 2485 static int playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 2486 struct hda_codec *codec, 2487 struct snd_pcm_substream *substream) 2488 { 2489 struct hda_gen_spec *spec = codec->spec; 2490 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 2491 } 2492 2493 static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = { 2494 .substreams = 1, 2495 .channels_min = 2, 2496 .channels_max = 8, 2497 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ 2498 /* NID is set in alc_build_pcms */ 2499 .ops = { 2500 .open = playback_pcm_open, 2501 .prepare = playback_pcm_prepare, 2502 .cleanup = playback_pcm_cleanup 2503 }, 2504 }; 2505 2506 static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = { 2507 .substreams = 1, 2508 .channels_min = 2, 2509 .channels_max = 2, 2510 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ 2511 /* NID is set in alc_build_pcms */ 2512 }; 2513 2514 /* different alc269-variants */ 2515 enum { 2516 ALC269_TYPE_ALC269VA, 2517 ALC269_TYPE_ALC269VB, 2518 ALC269_TYPE_ALC269VC, 2519 ALC269_TYPE_ALC269VD, 2520 ALC269_TYPE_ALC280, 2521 ALC269_TYPE_ALC282, 2522 ALC269_TYPE_ALC284, 2523 ALC269_TYPE_ALC286, 2524 }; 2525 2526 /* 2527 * BIOS auto configuration 2528 */ 2529 static int alc269_parse_auto_config(struct hda_codec *codec) 2530 { 2531 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 }; 2532 static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 }; 2533 static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 }; 2534 struct alc_spec *spec = codec->spec; 2535 const hda_nid_t *ssids; 2536 2537 switch (spec->codec_variant) { 2538 case ALC269_TYPE_ALC269VA: 2539 case ALC269_TYPE_ALC269VC: 2540 case ALC269_TYPE_ALC280: 2541 case ALC269_TYPE_ALC284: 2542 ssids = alc269va_ssids; 2543 break; 2544 case ALC269_TYPE_ALC269VB: 2545 case ALC269_TYPE_ALC269VD: 2546 case ALC269_TYPE_ALC282: 2547 case ALC269_TYPE_ALC286: 2548 ssids = alc269_ssids; 2549 break; 2550 default: 2551 ssids = alc269_ssids; 2552 break; 2553 } 2554 2555 return alc_parse_auto_config(codec, alc269_ignore, ssids); 2556 } 2557 2558 static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up) 2559 { 2560 int val = alc_read_coef_idx(codec, 0x04); 2561 if (power_up) 2562 val |= 1 << 11; 2563 else 2564 val &= ~(1 << 11); 2565 alc_write_coef_idx(codec, 0x04, val); 2566 } 2567 2568 static void alc269_shutup(struct hda_codec *codec) 2569 { 2570 struct alc_spec *spec = codec->spec; 2571 2572 if (spec->codec_variant != ALC269_TYPE_ALC269VB) 2573 return; 2574 2575 if (spec->codec_variant == ALC269_TYPE_ALC269VB) 2576 alc269vb_toggle_power_output(codec, 0); 2577 if (spec->codec_variant == ALC269_TYPE_ALC269VB && 2578 (alc_get_coef0(codec) & 0x00ff) == 0x018) { 2579 msleep(150); 2580 } 2581 } 2582 2583 #ifdef CONFIG_PM 2584 static int alc269_resume(struct hda_codec *codec) 2585 { 2586 struct alc_spec *spec = codec->spec; 2587 2588 if (spec->codec_variant == ALC269_TYPE_ALC269VB) 2589 alc269vb_toggle_power_output(codec, 0); 2590 if (spec->codec_variant == ALC269_TYPE_ALC269VB && 2591 (alc_get_coef0(codec) & 0x00ff) == 0x018) { 2592 msleep(150); 2593 } 2594 2595 codec->patch_ops.init(codec); 2596 2597 if (spec->codec_variant == ALC269_TYPE_ALC269VB) 2598 alc269vb_toggle_power_output(codec, 1); 2599 if (spec->codec_variant == ALC269_TYPE_ALC269VB && 2600 (alc_get_coef0(codec) & 0x00ff) == 0x017) { 2601 msleep(200); 2602 } 2603 2604 snd_hda_codec_resume_amp(codec); 2605 snd_hda_codec_resume_cache(codec); 2606 hda_call_check_power_status(codec, 0x01); 2607 return 0; 2608 } 2609 #endif /* CONFIG_PM */ 2610 2611 static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec, 2612 const struct hda_fixup *fix, int action) 2613 { 2614 struct alc_spec *spec = codec->spec; 2615 2616 if (action == HDA_FIXUP_ACT_PRE_PROBE) 2617 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; 2618 } 2619 2620 static void alc269_fixup_hweq(struct hda_codec *codec, 2621 const struct hda_fixup *fix, int action) 2622 { 2623 int coef; 2624 2625 if (action != HDA_FIXUP_ACT_INIT) 2626 return; 2627 coef = alc_read_coef_idx(codec, 0x1e); 2628 alc_write_coef_idx(codec, 0x1e, coef | 0x80); 2629 } 2630 2631 static void alc271_fixup_dmic(struct hda_codec *codec, 2632 const struct hda_fixup *fix, int action) 2633 { 2634 static const struct hda_verb verbs[] = { 2635 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d}, 2636 {0x20, AC_VERB_SET_PROC_COEF, 0x4000}, 2637 {} 2638 }; 2639 unsigned int cfg; 2640 2641 if (strcmp(codec->chip_name, "ALC271X") && 2642 strcmp(codec->chip_name, "ALC269VB")) 2643 return; 2644 cfg = snd_hda_codec_get_pincfg(codec, 0x12); 2645 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED) 2646 snd_hda_sequence_write(codec, verbs); 2647 } 2648 2649 static void alc269_fixup_pcm_44k(struct hda_codec *codec, 2650 const struct hda_fixup *fix, int action) 2651 { 2652 struct alc_spec *spec = codec->spec; 2653 2654 if (action != HDA_FIXUP_ACT_PROBE) 2655 return; 2656 2657 /* Due to a hardware problem on Lenovo Ideadpad, we need to 2658 * fix the sample rate of analog I/O to 44.1kHz 2659 */ 2660 spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback; 2661 spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture; 2662 } 2663 2664 static void alc269_fixup_stereo_dmic(struct hda_codec *codec, 2665 const struct hda_fixup *fix, int action) 2666 { 2667 int coef; 2668 2669 if (action != HDA_FIXUP_ACT_INIT) 2670 return; 2671 /* The digital-mic unit sends PDM (differential signal) instead of 2672 * the standard PCM, thus you can't record a valid mono stream as is. 2673 * Below is a workaround specific to ALC269 to control the dmic 2674 * signal source as mono. 2675 */ 2676 coef = alc_read_coef_idx(codec, 0x07); 2677 alc_write_coef_idx(codec, 0x07, coef | 0x80); 2678 } 2679 2680 static void alc269_quanta_automute(struct hda_codec *codec) 2681 { 2682 snd_hda_gen_update_outputs(codec); 2683 2684 snd_hda_codec_write(codec, 0x20, 0, 2685 AC_VERB_SET_COEF_INDEX, 0x0c); 2686 snd_hda_codec_write(codec, 0x20, 0, 2687 AC_VERB_SET_PROC_COEF, 0x680); 2688 2689 snd_hda_codec_write(codec, 0x20, 0, 2690 AC_VERB_SET_COEF_INDEX, 0x0c); 2691 snd_hda_codec_write(codec, 0x20, 0, 2692 AC_VERB_SET_PROC_COEF, 0x480); 2693 } 2694 2695 static void alc269_fixup_quanta_mute(struct hda_codec *codec, 2696 const struct hda_fixup *fix, int action) 2697 { 2698 struct alc_spec *spec = codec->spec; 2699 if (action != HDA_FIXUP_ACT_PROBE) 2700 return; 2701 spec->gen.automute_hook = alc269_quanta_automute; 2702 } 2703 2704 static void alc269_x101_hp_automute_hook(struct hda_codec *codec, 2705 struct hda_jack_tbl *jack) 2706 { 2707 struct alc_spec *spec = codec->spec; 2708 int vref; 2709 msleep(200); 2710 snd_hda_gen_hp_automute(codec, jack); 2711 2712 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0; 2713 msleep(100); 2714 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 2715 vref); 2716 msleep(500); 2717 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 2718 vref); 2719 } 2720 2721 static void alc269_fixup_x101_headset_mic(struct hda_codec *codec, 2722 const struct hda_fixup *fix, int action) 2723 { 2724 struct alc_spec *spec = codec->spec; 2725 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 2726 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; 2727 spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook; 2728 } 2729 } 2730 2731 2732 /* update mute-LED according to the speaker mute state via mic VREF pin */ 2733 static void alc269_fixup_mic_mute_hook(void *private_data, int enabled) 2734 { 2735 struct hda_codec *codec = private_data; 2736 struct alc_spec *spec = codec->spec; 2737 unsigned int pinval; 2738 2739 if (spec->mute_led_polarity) 2740 enabled = !enabled; 2741 pinval = AC_PINCTL_IN_EN | 2742 (enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80); 2743 if (spec->mute_led_nid) 2744 snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval); 2745 } 2746 2747 static void alc269_fixup_hp_mute_led(struct hda_codec *codec, 2748 const struct hda_fixup *fix, int action) 2749 { 2750 struct alc_spec *spec = codec->spec; 2751 const struct dmi_device *dev = NULL; 2752 2753 if (action != HDA_FIXUP_ACT_PRE_PROBE) 2754 return; 2755 2756 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) { 2757 int pol, pin; 2758 if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2) 2759 continue; 2760 if (pin < 0x0a || pin >= 0x10) 2761 break; 2762 spec->mute_led_polarity = pol; 2763 spec->mute_led_nid = pin - 0x0a + 0x18; 2764 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; 2765 spec->gen.vmaster_mute_enum = 1; 2766 snd_printd("Detected mute LED for %x:%d\n", spec->mute_led_nid, 2767 spec->mute_led_polarity); 2768 break; 2769 } 2770 } 2771 2772 static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec, 2773 const struct hda_fixup *fix, int action) 2774 { 2775 struct alc_spec *spec = codec->spec; 2776 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 2777 spec->mute_led_polarity = 0; 2778 spec->mute_led_nid = 0x18; 2779 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; 2780 spec->gen.vmaster_mute_enum = 1; 2781 } 2782 } 2783 2784 static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec, 2785 const struct hda_fixup *fix, int action) 2786 { 2787 struct alc_spec *spec = codec->spec; 2788 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 2789 spec->mute_led_polarity = 0; 2790 spec->mute_led_nid = 0x19; 2791 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; 2792 spec->gen.vmaster_mute_enum = 1; 2793 } 2794 } 2795 2796 /* turn on/off mute LED per vmaster hook */ 2797 static void alc269_fixup_hp_gpio_mute_hook(void *private_data, int enabled) 2798 { 2799 struct hda_codec *codec = private_data; 2800 struct alc_spec *spec = codec->spec; 2801 unsigned int oldval = spec->gpio_led; 2802 2803 if (enabled) 2804 spec->gpio_led &= ~0x08; 2805 else 2806 spec->gpio_led |= 0x08; 2807 if (spec->gpio_led != oldval) 2808 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2809 spec->gpio_led); 2810 } 2811 2812 /* turn on/off mic-mute LED per capture hook */ 2813 static void alc269_fixup_hp_gpio_mic_mute_hook(struct hda_codec *codec, 2814 struct snd_ctl_elem_value *ucontrol) 2815 { 2816 struct alc_spec *spec = codec->spec; 2817 unsigned int oldval = spec->gpio_led; 2818 2819 if (!ucontrol) 2820 return; 2821 2822 if (ucontrol->value.integer.value[0] || 2823 ucontrol->value.integer.value[1]) 2824 spec->gpio_led &= ~0x10; 2825 else 2826 spec->gpio_led |= 0x10; 2827 if (spec->gpio_led != oldval) 2828 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2829 spec->gpio_led); 2830 } 2831 2832 static void alc269_fixup_hp_gpio_led(struct hda_codec *codec, 2833 const struct hda_fixup *fix, int action) 2834 { 2835 struct alc_spec *spec = codec->spec; 2836 static const struct hda_verb gpio_init[] = { 2837 { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 }, 2838 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 }, 2839 {} 2840 }; 2841 2842 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 2843 spec->gen.vmaster_mute.hook = alc269_fixup_hp_gpio_mute_hook; 2844 spec->gen.cap_sync_hook = alc269_fixup_hp_gpio_mic_mute_hook; 2845 spec->gpio_led = 0; 2846 snd_hda_add_verbs(codec, gpio_init); 2847 } 2848 } 2849 2850 static void alc_headset_mode_unplugged(struct hda_codec *codec) 2851 { 2852 int val; 2853 2854 switch (codec->vendor_id) { 2855 case 0x10ec0283: 2856 alc_write_coef_idx(codec, 0x1b, 0x0c0b); 2857 alc_write_coef_idx(codec, 0x45, 0xc429); 2858 val = alc_read_coef_idx(codec, 0x35); 2859 alc_write_coef_idx(codec, 0x35, val & 0xbfff); 2860 alc_write_coef_idx(codec, 0x06, 0x2104); 2861 alc_write_coef_idx(codec, 0x1a, 0x0001); 2862 alc_write_coef_idx(codec, 0x26, 0x0004); 2863 alc_write_coef_idx(codec, 0x32, 0x42a3); 2864 break; 2865 case 0x10ec0292: 2866 alc_write_coef_idx(codec, 0x76, 0x000e); 2867 alc_write_coef_idx(codec, 0x6c, 0x2400); 2868 alc_write_coef_idx(codec, 0x18, 0x7308); 2869 alc_write_coef_idx(codec, 0x6b, 0xc429); 2870 break; 2871 case 0x10ec0668: 2872 alc_write_coef_idx(codec, 0x15, 0x0d40); 2873 alc_write_coef_idx(codec, 0xb7, 0x802b); 2874 break; 2875 } 2876 snd_printdd("Headset jack set to unplugged mode.\n"); 2877 } 2878 2879 2880 static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, 2881 hda_nid_t mic_pin) 2882 { 2883 int val; 2884 2885 switch (codec->vendor_id) { 2886 case 0x10ec0283: 2887 alc_write_coef_idx(codec, 0x45, 0xc429); 2888 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); 2889 val = alc_read_coef_idx(codec, 0x35); 2890 alc_write_coef_idx(codec, 0x35, val | 1<<14); 2891 alc_write_coef_idx(codec, 0x06, 0x2100); 2892 alc_write_coef_idx(codec, 0x1a, 0x0021); 2893 alc_write_coef_idx(codec, 0x26, 0x008c); 2894 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); 2895 break; 2896 case 0x10ec0292: 2897 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); 2898 alc_write_coef_idx(codec, 0x19, 0xa208); 2899 alc_write_coef_idx(codec, 0x2e, 0xacf0); 2900 break; 2901 case 0x10ec0668: 2902 alc_write_coef_idx(codec, 0x11, 0x0001); 2903 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); 2904 alc_write_coef_idx(codec, 0xb7, 0x802b); 2905 alc_write_coef_idx(codec, 0xb5, 0x1040); 2906 val = alc_read_coef_idx(codec, 0xc3); 2907 alc_write_coef_idx(codec, 0xc3, val | 1<<12); 2908 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); 2909 break; 2910 } 2911 snd_printdd("Headset jack set to mic-in mode.\n"); 2912 } 2913 2914 static void alc_headset_mode_default(struct hda_codec *codec) 2915 { 2916 switch (codec->vendor_id) { 2917 case 0x10ec0283: 2918 alc_write_coef_idx(codec, 0x06, 0x2100); 2919 alc_write_coef_idx(codec, 0x32, 0x4ea3); 2920 break; 2921 case 0x10ec0292: 2922 alc_write_coef_idx(codec, 0x76, 0x000e); 2923 alc_write_coef_idx(codec, 0x6c, 0x2400); 2924 alc_write_coef_idx(codec, 0x6b, 0xc429); 2925 alc_write_coef_idx(codec, 0x18, 0x7308); 2926 break; 2927 case 0x10ec0668: 2928 alc_write_coef_idx(codec, 0x11, 0x0041); 2929 alc_write_coef_idx(codec, 0x15, 0x0d40); 2930 alc_write_coef_idx(codec, 0xb7, 0x802b); 2931 break; 2932 } 2933 snd_printdd("Headset jack set to headphone (default) mode.\n"); 2934 } 2935 2936 /* Iphone type */ 2937 static void alc_headset_mode_ctia(struct hda_codec *codec) 2938 { 2939 switch (codec->vendor_id) { 2940 case 0x10ec0283: 2941 alc_write_coef_idx(codec, 0x45, 0xd429); 2942 alc_write_coef_idx(codec, 0x1b, 0x0c2b); 2943 alc_write_coef_idx(codec, 0x32, 0x4ea3); 2944 break; 2945 case 0x10ec0292: 2946 alc_write_coef_idx(codec, 0x6b, 0xd429); 2947 alc_write_coef_idx(codec, 0x76, 0x0008); 2948 alc_write_coef_idx(codec, 0x18, 0x7388); 2949 break; 2950 case 0x10ec0668: 2951 alc_write_coef_idx(codec, 0x15, 0x0d60); 2952 alc_write_coef_idx(codec, 0xc3, 0x0000); 2953 break; 2954 } 2955 snd_printdd("Headset jack set to iPhone-style headset mode.\n"); 2956 } 2957 2958 /* Nokia type */ 2959 static void alc_headset_mode_omtp(struct hda_codec *codec) 2960 { 2961 switch (codec->vendor_id) { 2962 case 0x10ec0283: 2963 alc_write_coef_idx(codec, 0x45, 0xe429); 2964 alc_write_coef_idx(codec, 0x1b, 0x0c2b); 2965 alc_write_coef_idx(codec, 0x32, 0x4ea3); 2966 break; 2967 case 0x10ec0292: 2968 alc_write_coef_idx(codec, 0x6b, 0xe429); 2969 alc_write_coef_idx(codec, 0x76, 0x0008); 2970 alc_write_coef_idx(codec, 0x18, 0x7388); 2971 break; 2972 case 0x10ec0668: 2973 alc_write_coef_idx(codec, 0x15, 0x0d50); 2974 alc_write_coef_idx(codec, 0xc3, 0x0000); 2975 break; 2976 } 2977 snd_printdd("Headset jack set to Nokia-style headset mode.\n"); 2978 } 2979 2980 static void alc_determine_headset_type(struct hda_codec *codec) 2981 { 2982 int val; 2983 bool is_ctia = false; 2984 struct alc_spec *spec = codec->spec; 2985 2986 switch (codec->vendor_id) { 2987 case 0x10ec0283: 2988 alc_write_coef_idx(codec, 0x45, 0xd029); 2989 msleep(300); 2990 val = alc_read_coef_idx(codec, 0x46); 2991 is_ctia = (val & 0x0070) == 0x0070; 2992 break; 2993 case 0x10ec0292: 2994 alc_write_coef_idx(codec, 0x6b, 0xd429); 2995 msleep(300); 2996 val = alc_read_coef_idx(codec, 0x6c); 2997 is_ctia = (val & 0x001c) == 0x001c; 2998 break; 2999 case 0x10ec0668: 3000 alc_write_coef_idx(codec, 0x11, 0x0001); 3001 alc_write_coef_idx(codec, 0xb7, 0x802b); 3002 alc_write_coef_idx(codec, 0x15, 0x0d60); 3003 alc_write_coef_idx(codec, 0xc3, 0x0c00); 3004 msleep(300); 3005 val = alc_read_coef_idx(codec, 0xbe); 3006 is_ctia = (val & 0x1c02) == 0x1c02; 3007 break; 3008 } 3009 3010 snd_printdd("Headset jack detected iPhone-style headset: %s\n", 3011 is_ctia ? "yes" : "no"); 3012 spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP; 3013 } 3014 3015 static void alc_update_headset_mode(struct hda_codec *codec) 3016 { 3017 struct alc_spec *spec = codec->spec; 3018 3019 hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]]; 3020 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; 3021 3022 int new_headset_mode; 3023 3024 if (!snd_hda_jack_detect(codec, hp_pin)) 3025 new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED; 3026 else if (mux_pin == spec->headset_mic_pin) 3027 new_headset_mode = ALC_HEADSET_MODE_HEADSET; 3028 else if (mux_pin == spec->headphone_mic_pin) 3029 new_headset_mode = ALC_HEADSET_MODE_MIC; 3030 else 3031 new_headset_mode = ALC_HEADSET_MODE_HEADPHONE; 3032 3033 if (new_headset_mode == spec->current_headset_mode) 3034 return; 3035 3036 switch (new_headset_mode) { 3037 case ALC_HEADSET_MODE_UNPLUGGED: 3038 alc_headset_mode_unplugged(codec); 3039 spec->gen.hp_jack_present = false; 3040 break; 3041 case ALC_HEADSET_MODE_HEADSET: 3042 if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN) 3043 alc_determine_headset_type(codec); 3044 if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA) 3045 alc_headset_mode_ctia(codec); 3046 else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP) 3047 alc_headset_mode_omtp(codec); 3048 spec->gen.hp_jack_present = true; 3049 break; 3050 case ALC_HEADSET_MODE_MIC: 3051 alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin); 3052 spec->gen.hp_jack_present = false; 3053 break; 3054 case ALC_HEADSET_MODE_HEADPHONE: 3055 alc_headset_mode_default(codec); 3056 spec->gen.hp_jack_present = true; 3057 break; 3058 } 3059 if (new_headset_mode != ALC_HEADSET_MODE_MIC) { 3060 snd_hda_set_pin_ctl_cache(codec, hp_pin, 3061 AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN); 3062 if (spec->headphone_mic_pin) 3063 snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin, 3064 PIN_VREFHIZ); 3065 } 3066 spec->current_headset_mode = new_headset_mode; 3067 3068 snd_hda_gen_update_outputs(codec); 3069 } 3070 3071 static void alc_update_headset_mode_hook(struct hda_codec *codec, 3072 struct snd_ctl_elem_value *ucontrol) 3073 { 3074 alc_update_headset_mode(codec); 3075 } 3076 3077 static void alc_update_headset_jack_cb(struct hda_codec *codec, struct hda_jack_tbl *jack) 3078 { 3079 struct alc_spec *spec = codec->spec; 3080 spec->current_headset_type = ALC_HEADSET_MODE_UNKNOWN; 3081 snd_hda_gen_hp_automute(codec, jack); 3082 } 3083 3084 static void alc_probe_headset_mode(struct hda_codec *codec) 3085 { 3086 int i; 3087 struct alc_spec *spec = codec->spec; 3088 struct auto_pin_cfg *cfg = &spec->gen.autocfg; 3089 3090 /* Find mic pins */ 3091 for (i = 0; i < cfg->num_inputs; i++) { 3092 if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin) 3093 spec->headset_mic_pin = cfg->inputs[i].pin; 3094 if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin) 3095 spec->headphone_mic_pin = cfg->inputs[i].pin; 3096 } 3097 3098 spec->gen.cap_sync_hook = alc_update_headset_mode_hook; 3099 spec->gen.automute_hook = alc_update_headset_mode; 3100 spec->gen.hp_automute_hook = alc_update_headset_jack_cb; 3101 } 3102 3103 static void alc_fixup_headset_mode(struct hda_codec *codec, 3104 const struct hda_fixup *fix, int action) 3105 { 3106 struct alc_spec *spec = codec->spec; 3107 3108 switch (action) { 3109 case HDA_FIXUP_ACT_PRE_PROBE: 3110 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC; 3111 break; 3112 case HDA_FIXUP_ACT_PROBE: 3113 alc_probe_headset_mode(codec); 3114 break; 3115 case HDA_FIXUP_ACT_INIT: 3116 spec->current_headset_mode = 0; 3117 alc_update_headset_mode(codec); 3118 break; 3119 } 3120 } 3121 3122 static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec, 3123 const struct hda_fixup *fix, int action) 3124 { 3125 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 3126 struct alc_spec *spec = codec->spec; 3127 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; 3128 } 3129 else 3130 alc_fixup_headset_mode(codec, fix, action); 3131 } 3132 3133 static void alc_fixup_headset_mode_alc668(struct hda_codec *codec, 3134 const struct hda_fixup *fix, int action) 3135 { 3136 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 3137 int val; 3138 alc_write_coef_idx(codec, 0xc4, 0x8000); 3139 val = alc_read_coef_idx(codec, 0xc2); 3140 alc_write_coef_idx(codec, 0xc2, val & 0xfe); 3141 snd_hda_set_pin_ctl_cache(codec, 0x18, 0); 3142 } 3143 alc_fixup_headset_mode(codec, fix, action); 3144 } 3145 3146 static void alc271_hp_gate_mic_jack(struct hda_codec *codec, 3147 const struct hda_fixup *fix, 3148 int action) 3149 { 3150 struct alc_spec *spec = codec->spec; 3151 3152 if (action == HDA_FIXUP_ACT_PROBE) { 3153 if (snd_BUG_ON(!spec->gen.am_entry[1].pin || 3154 !spec->gen.autocfg.hp_pins[0])) 3155 return; 3156 snd_hda_jack_set_gating_jack(codec, spec->gen.am_entry[1].pin, 3157 spec->gen.autocfg.hp_pins[0]); 3158 } 3159 } 3160 3161 static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec, 3162 const struct hda_fixup *fix, 3163 int action) 3164 { 3165 struct alc_spec *spec = codec->spec; 3166 struct auto_pin_cfg *cfg = &spec->gen.autocfg; 3167 int i; 3168 3169 /* The mic boosts on level 2 and 3 are too noisy 3170 on the internal mic input. 3171 Therefore limit the boost to 0 or 1. */ 3172 3173 if (action != HDA_FIXUP_ACT_PROBE) 3174 return; 3175 3176 for (i = 0; i < cfg->num_inputs; i++) { 3177 hda_nid_t nid = cfg->inputs[i].pin; 3178 unsigned int defcfg; 3179 if (cfg->inputs[i].type != AUTO_PIN_MIC) 3180 continue; 3181 defcfg = snd_hda_codec_get_pincfg(codec, nid); 3182 if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT) 3183 continue; 3184 3185 snd_hda_override_amp_caps(codec, nid, HDA_INPUT, 3186 (0x00 << AC_AMPCAP_OFFSET_SHIFT) | 3187 (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) | 3188 (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) | 3189 (0 << AC_AMPCAP_MUTE_SHIFT)); 3190 } 3191 } 3192 3193 enum { 3194 ALC269_FIXUP_SONY_VAIO, 3195 ALC275_FIXUP_SONY_VAIO_GPIO2, 3196 ALC269_FIXUP_DELL_M101Z, 3197 ALC269_FIXUP_SKU_IGNORE, 3198 ALC269_FIXUP_ASUS_G73JW, 3199 ALC269_FIXUP_LENOVO_EAPD, 3200 ALC275_FIXUP_SONY_HWEQ, 3201 ALC271_FIXUP_DMIC, 3202 ALC269_FIXUP_PCM_44K, 3203 ALC269_FIXUP_STEREO_DMIC, 3204 ALC269_FIXUP_QUANTA_MUTE, 3205 ALC269_FIXUP_LIFEBOOK, 3206 ALC269_FIXUP_AMIC, 3207 ALC269_FIXUP_DMIC, 3208 ALC269VB_FIXUP_AMIC, 3209 ALC269VB_FIXUP_DMIC, 3210 ALC269_FIXUP_HP_MUTE_LED, 3211 ALC269_FIXUP_HP_MUTE_LED_MIC1, 3212 ALC269_FIXUP_HP_MUTE_LED_MIC2, 3213 ALC269_FIXUP_HP_GPIO_LED, 3214 ALC269_FIXUP_INV_DMIC, 3215 ALC269_FIXUP_LENOVO_DOCK, 3216 ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT, 3217 ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, 3218 ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, 3219 ALC269_FIXUP_HEADSET_MODE, 3220 ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, 3221 ALC269_FIXUP_ASUS_X101_FUNC, 3222 ALC269_FIXUP_ASUS_X101_VERB, 3223 ALC269_FIXUP_ASUS_X101, 3224 ALC271_FIXUP_AMIC_MIC2, 3225 ALC271_FIXUP_HP_GATE_MIC_JACK, 3226 ALC269_FIXUP_ACER_AC700, 3227 ALC269_FIXUP_LIMIT_INT_MIC_BOOST, 3228 }; 3229 3230 static const struct hda_fixup alc269_fixups[] = { 3231 [ALC269_FIXUP_SONY_VAIO] = { 3232 .type = HDA_FIXUP_PINCTLS, 3233 .v.pins = (const struct hda_pintbl[]) { 3234 {0x19, PIN_VREFGRD}, 3235 {} 3236 } 3237 }, 3238 [ALC275_FIXUP_SONY_VAIO_GPIO2] = { 3239 .type = HDA_FIXUP_VERBS, 3240 .v.verbs = (const struct hda_verb[]) { 3241 {0x01, AC_VERB_SET_GPIO_MASK, 0x04}, 3242 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04}, 3243 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 3244 { } 3245 }, 3246 .chained = true, 3247 .chain_id = ALC269_FIXUP_SONY_VAIO 3248 }, 3249 [ALC269_FIXUP_DELL_M101Z] = { 3250 .type = HDA_FIXUP_VERBS, 3251 .v.verbs = (const struct hda_verb[]) { 3252 /* Enables internal speaker */ 3253 {0x20, AC_VERB_SET_COEF_INDEX, 13}, 3254 {0x20, AC_VERB_SET_PROC_COEF, 0x4040}, 3255 {} 3256 } 3257 }, 3258 [ALC269_FIXUP_SKU_IGNORE] = { 3259 .type = HDA_FIXUP_FUNC, 3260 .v.func = alc_fixup_sku_ignore, 3261 }, 3262 [ALC269_FIXUP_ASUS_G73JW] = { 3263 .type = HDA_FIXUP_PINS, 3264 .v.pins = (const struct hda_pintbl[]) { 3265 { 0x17, 0x99130111 }, /* subwoofer */ 3266 { } 3267 } 3268 }, 3269 [ALC269_FIXUP_LENOVO_EAPD] = { 3270 .type = HDA_FIXUP_VERBS, 3271 .v.verbs = (const struct hda_verb[]) { 3272 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, 3273 {} 3274 } 3275 }, 3276 [ALC275_FIXUP_SONY_HWEQ] = { 3277 .type = HDA_FIXUP_FUNC, 3278 .v.func = alc269_fixup_hweq, 3279 .chained = true, 3280 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2 3281 }, 3282 [ALC271_FIXUP_DMIC] = { 3283 .type = HDA_FIXUP_FUNC, 3284 .v.func = alc271_fixup_dmic, 3285 }, 3286 [ALC269_FIXUP_PCM_44K] = { 3287 .type = HDA_FIXUP_FUNC, 3288 .v.func = alc269_fixup_pcm_44k, 3289 .chained = true, 3290 .chain_id = ALC269_FIXUP_QUANTA_MUTE 3291 }, 3292 [ALC269_FIXUP_STEREO_DMIC] = { 3293 .type = HDA_FIXUP_FUNC, 3294 .v.func = alc269_fixup_stereo_dmic, 3295 }, 3296 [ALC269_FIXUP_QUANTA_MUTE] = { 3297 .type = HDA_FIXUP_FUNC, 3298 .v.func = alc269_fixup_quanta_mute, 3299 }, 3300 [ALC269_FIXUP_LIFEBOOK] = { 3301 .type = HDA_FIXUP_PINS, 3302 .v.pins = (const struct hda_pintbl[]) { 3303 { 0x1a, 0x2101103f }, /* dock line-out */ 3304 { 0x1b, 0x23a11040 }, /* dock mic-in */ 3305 { } 3306 }, 3307 .chained = true, 3308 .chain_id = ALC269_FIXUP_QUANTA_MUTE 3309 }, 3310 [ALC269_FIXUP_AMIC] = { 3311 .type = HDA_FIXUP_PINS, 3312 .v.pins = (const struct hda_pintbl[]) { 3313 { 0x14, 0x99130110 }, /* speaker */ 3314 { 0x15, 0x0121401f }, /* HP out */ 3315 { 0x18, 0x01a19c20 }, /* mic */ 3316 { 0x19, 0x99a3092f }, /* int-mic */ 3317 { } 3318 }, 3319 }, 3320 [ALC269_FIXUP_DMIC] = { 3321 .type = HDA_FIXUP_PINS, 3322 .v.pins = (const struct hda_pintbl[]) { 3323 { 0x12, 0x99a3092f }, /* int-mic */ 3324 { 0x14, 0x99130110 }, /* speaker */ 3325 { 0x15, 0x0121401f }, /* HP out */ 3326 { 0x18, 0x01a19c20 }, /* mic */ 3327 { } 3328 }, 3329 }, 3330 [ALC269VB_FIXUP_AMIC] = { 3331 .type = HDA_FIXUP_PINS, 3332 .v.pins = (const struct hda_pintbl[]) { 3333 { 0x14, 0x99130110 }, /* speaker */ 3334 { 0x18, 0x01a19c20 }, /* mic */ 3335 { 0x19, 0x99a3092f }, /* int-mic */ 3336 { 0x21, 0x0121401f }, /* HP out */ 3337 { } 3338 }, 3339 }, 3340 [ALC269VB_FIXUP_DMIC] = { 3341 .type = HDA_FIXUP_PINS, 3342 .v.pins = (const struct hda_pintbl[]) { 3343 { 0x12, 0x99a3092f }, /* int-mic */ 3344 { 0x14, 0x99130110 }, /* speaker */ 3345 { 0x18, 0x01a19c20 }, /* mic */ 3346 { 0x21, 0x0121401f }, /* HP out */ 3347 { } 3348 }, 3349 }, 3350 [ALC269_FIXUP_HP_MUTE_LED] = { 3351 .type = HDA_FIXUP_FUNC, 3352 .v.func = alc269_fixup_hp_mute_led, 3353 }, 3354 [ALC269_FIXUP_HP_MUTE_LED_MIC1] = { 3355 .type = HDA_FIXUP_FUNC, 3356 .v.func = alc269_fixup_hp_mute_led_mic1, 3357 }, 3358 [ALC269_FIXUP_HP_MUTE_LED_MIC2] = { 3359 .type = HDA_FIXUP_FUNC, 3360 .v.func = alc269_fixup_hp_mute_led_mic2, 3361 }, 3362 [ALC269_FIXUP_HP_GPIO_LED] = { 3363 .type = HDA_FIXUP_FUNC, 3364 .v.func = alc269_fixup_hp_gpio_led, 3365 }, 3366 [ALC269_FIXUP_INV_DMIC] = { 3367 .type = HDA_FIXUP_FUNC, 3368 .v.func = alc_fixup_inv_dmic_0x12, 3369 }, 3370 [ALC269_FIXUP_LENOVO_DOCK] = { 3371 .type = HDA_FIXUP_PINS, 3372 .v.pins = (const struct hda_pintbl[]) { 3373 { 0x19, 0x23a11040 }, /* dock mic */ 3374 { 0x1b, 0x2121103f }, /* dock headphone */ 3375 { } 3376 }, 3377 .chained = true, 3378 .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT 3379 }, 3380 [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = { 3381 .type = HDA_FIXUP_FUNC, 3382 .v.func = alc269_fixup_pincfg_no_hp_to_lineout, 3383 }, 3384 [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = { 3385 .type = HDA_FIXUP_PINS, 3386 .v.pins = (const struct hda_pintbl[]) { 3387 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ 3388 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */ 3389 { } 3390 }, 3391 .chained = true, 3392 .chain_id = ALC269_FIXUP_HEADSET_MODE 3393 }, 3394 [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = { 3395 .type = HDA_FIXUP_PINS, 3396 .v.pins = (const struct hda_pintbl[]) { 3397 { 0x16, 0x21014020 }, /* dock line out */ 3398 { 0x19, 0x21a19030 }, /* dock mic */ 3399 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */ 3400 { } 3401 }, 3402 .chained = true, 3403 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC 3404 }, 3405 [ALC269_FIXUP_HEADSET_MODE] = { 3406 .type = HDA_FIXUP_FUNC, 3407 .v.func = alc_fixup_headset_mode, 3408 }, 3409 [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = { 3410 .type = HDA_FIXUP_FUNC, 3411 .v.func = alc_fixup_headset_mode_no_hp_mic, 3412 }, 3413 [ALC269_FIXUP_ASUS_X101_FUNC] = { 3414 .type = HDA_FIXUP_FUNC, 3415 .v.func = alc269_fixup_x101_headset_mic, 3416 }, 3417 [ALC269_FIXUP_ASUS_X101_VERB] = { 3418 .type = HDA_FIXUP_VERBS, 3419 .v.verbs = (const struct hda_verb[]) { 3420 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 3421 {0x20, AC_VERB_SET_COEF_INDEX, 0x08}, 3422 {0x20, AC_VERB_SET_PROC_COEF, 0x0310}, 3423 { } 3424 }, 3425 .chained = true, 3426 .chain_id = ALC269_FIXUP_ASUS_X101_FUNC 3427 }, 3428 [ALC269_FIXUP_ASUS_X101] = { 3429 .type = HDA_FIXUP_PINS, 3430 .v.pins = (const struct hda_pintbl[]) { 3431 { 0x18, 0x04a1182c }, /* Headset mic */ 3432 { } 3433 }, 3434 .chained = true, 3435 .chain_id = ALC269_FIXUP_ASUS_X101_VERB 3436 }, 3437 [ALC271_FIXUP_AMIC_MIC2] = { 3438 .type = HDA_FIXUP_PINS, 3439 .v.pins = (const struct hda_pintbl[]) { 3440 { 0x14, 0x99130110 }, /* speaker */ 3441 { 0x19, 0x01a19c20 }, /* mic */ 3442 { 0x1b, 0x99a7012f }, /* int-mic */ 3443 { 0x21, 0x0121401f }, /* HP out */ 3444 { } 3445 }, 3446 }, 3447 [ALC271_FIXUP_HP_GATE_MIC_JACK] = { 3448 .type = HDA_FIXUP_FUNC, 3449 .v.func = alc271_hp_gate_mic_jack, 3450 .chained = true, 3451 .chain_id = ALC271_FIXUP_AMIC_MIC2, 3452 }, 3453 [ALC269_FIXUP_ACER_AC700] = { 3454 .type = HDA_FIXUP_PINS, 3455 .v.pins = (const struct hda_pintbl[]) { 3456 { 0x12, 0x99a3092f }, /* int-mic */ 3457 { 0x14, 0x99130110 }, /* speaker */ 3458 { 0x18, 0x03a11c20 }, /* mic */ 3459 { 0x1e, 0x0346101e }, /* SPDIF1 */ 3460 { 0x21, 0x0321101f }, /* HP out */ 3461 { } 3462 }, 3463 .chained = true, 3464 .chain_id = ALC271_FIXUP_DMIC, 3465 }, 3466 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = { 3467 .type = HDA_FIXUP_FUNC, 3468 .v.func = alc269_fixup_limit_int_mic_boost, 3469 }, 3470 }; 3471 3472 static const struct snd_pci_quirk alc269_fixup_tbl[] = { 3473 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC), 3474 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), 3475 SND_PCI_QUIRK(0x1028, 0x05bd, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), 3476 SND_PCI_QUIRK(0x1028, 0x05be, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), 3477 SND_PCI_QUIRK(0x1028, 0x05c4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3478 SND_PCI_QUIRK(0x1028, 0x05c5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3479 SND_PCI_QUIRK(0x1028, 0x05c6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3480 SND_PCI_QUIRK(0x1028, 0x05c7, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3481 SND_PCI_QUIRK(0x1028, 0x05c8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3482 SND_PCI_QUIRK(0x1028, 0x05c9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3483 SND_PCI_QUIRK(0x1028, 0x05ca, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), 3484 SND_PCI_QUIRK(0x1028, 0x05cb, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), 3485 SND_PCI_QUIRK(0x1028, 0x05de, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), 3486 SND_PCI_QUIRK(0x1028, 0x05e9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3487 SND_PCI_QUIRK(0x1028, 0x05ea, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3488 SND_PCI_QUIRK(0x1028, 0x05eb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3489 SND_PCI_QUIRK(0x1028, 0x05ec, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3490 SND_PCI_QUIRK(0x1028, 0x05ed, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3491 SND_PCI_QUIRK(0x1028, 0x05ee, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3492 SND_PCI_QUIRK(0x1028, 0x05f3, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3493 SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3494 SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3495 SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3496 SND_PCI_QUIRK(0x1028, 0x05f8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3497 SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3498 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), 3499 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED), 3500 SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), 3501 SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), 3502 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED), 3503 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 3504 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 3505 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC), 3506 SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_DMIC), 3507 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), 3508 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), 3509 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), 3510 SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 3511 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), 3512 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), 3513 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), 3514 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), 3515 SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101), 3516 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), 3517 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), 3518 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), 3519 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), 3520 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), 3521 SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700), 3522 SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK), 3523 SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK), 3524 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC), 3525 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK), 3526 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), 3527 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), 3528 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), 3529 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), 3530 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), 3531 SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK), 3532 SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK), 3533 SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK), 3534 SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK), 3535 SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK), 3536 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK), 3537 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), 3538 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), 3539 3540 #if 0 3541 /* Below is a quirk table taken from the old code. 3542 * Basically the device should work as is without the fixup table. 3543 * If BIOS doesn't give a proper info, enable the corresponding 3544 * fixup entry. 3545 */ 3546 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", 3547 ALC269_FIXUP_AMIC), 3548 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC), 3549 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC), 3550 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC), 3551 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC), 3552 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC), 3553 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC), 3554 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC), 3555 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC), 3556 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC), 3557 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC), 3558 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC), 3559 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC), 3560 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC), 3561 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC), 3562 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC), 3563 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC), 3564 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC), 3565 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC), 3566 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC), 3567 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC), 3568 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC), 3569 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC), 3570 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC), 3571 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC), 3572 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC), 3573 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC), 3574 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC), 3575 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC), 3576 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC), 3577 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC), 3578 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC), 3579 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC), 3580 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC), 3581 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC), 3582 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC), 3583 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC), 3584 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC), 3585 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC), 3586 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC), 3587 #endif 3588 {} 3589 }; 3590 3591 static const struct hda_model_fixup alc269_fixup_models[] = { 3592 {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"}, 3593 {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"}, 3594 {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"}, 3595 {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"}, 3596 {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"}, 3597 {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"}, 3598 {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"}, 3599 {} 3600 }; 3601 3602 3603 static void alc269_fill_coef(struct hda_codec *codec) 3604 { 3605 struct alc_spec *spec = codec->spec; 3606 int val; 3607 3608 if (spec->codec_variant != ALC269_TYPE_ALC269VB) 3609 return; 3610 3611 if ((alc_get_coef0(codec) & 0x00ff) < 0x015) { 3612 alc_write_coef_idx(codec, 0xf, 0x960b); 3613 alc_write_coef_idx(codec, 0xe, 0x8817); 3614 } 3615 3616 if ((alc_get_coef0(codec) & 0x00ff) == 0x016) { 3617 alc_write_coef_idx(codec, 0xf, 0x960b); 3618 alc_write_coef_idx(codec, 0xe, 0x8814); 3619 } 3620 3621 if ((alc_get_coef0(codec) & 0x00ff) == 0x017) { 3622 val = alc_read_coef_idx(codec, 0x04); 3623 /* Power up output pin */ 3624 alc_write_coef_idx(codec, 0x04, val | (1<<11)); 3625 } 3626 3627 if ((alc_get_coef0(codec) & 0x00ff) == 0x018) { 3628 val = alc_read_coef_idx(codec, 0xd); 3629 if ((val & 0x0c00) >> 10 != 0x1) { 3630 /* Capless ramp up clock control */ 3631 alc_write_coef_idx(codec, 0xd, val | (1<<10)); 3632 } 3633 val = alc_read_coef_idx(codec, 0x17); 3634 if ((val & 0x01c0) >> 6 != 0x4) { 3635 /* Class D power on reset */ 3636 alc_write_coef_idx(codec, 0x17, val | (1<<7)); 3637 } 3638 } 3639 3640 val = alc_read_coef_idx(codec, 0xd); /* Class D */ 3641 alc_write_coef_idx(codec, 0xd, val | (1<<14)); 3642 3643 val = alc_read_coef_idx(codec, 0x4); /* HP */ 3644 alc_write_coef_idx(codec, 0x4, val | (1<<11)); 3645 } 3646 3647 /* 3648 */ 3649 static int patch_alc269(struct hda_codec *codec) 3650 { 3651 struct alc_spec *spec; 3652 int err; 3653 3654 err = alc_alloc_spec(codec, 0x0b); 3655 if (err < 0) 3656 return err; 3657 3658 spec = codec->spec; 3659 spec->gen.shared_mic_vref_pin = 0x18; 3660 3661 snd_hda_pick_fixup(codec, alc269_fixup_models, 3662 alc269_fixup_tbl, alc269_fixups); 3663 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 3664 3665 alc_auto_parse_customize_define(codec); 3666 3667 if (has_cdefine_beep(codec)) 3668 spec->gen.beep_nid = 0x01; 3669 3670 switch (codec->vendor_id) { 3671 case 0x10ec0269: 3672 spec->codec_variant = ALC269_TYPE_ALC269VA; 3673 switch (alc_get_coef0(codec) & 0x00f0) { 3674 case 0x0010: 3675 if (codec->bus->pci->subsystem_vendor == 0x1025 && 3676 spec->cdefine.platform_type == 1) 3677 err = alc_codec_rename(codec, "ALC271X"); 3678 spec->codec_variant = ALC269_TYPE_ALC269VB; 3679 break; 3680 case 0x0020: 3681 if (codec->bus->pci->subsystem_vendor == 0x17aa && 3682 codec->bus->pci->subsystem_device == 0x21f3) 3683 err = alc_codec_rename(codec, "ALC3202"); 3684 spec->codec_variant = ALC269_TYPE_ALC269VC; 3685 break; 3686 case 0x0030: 3687 spec->codec_variant = ALC269_TYPE_ALC269VD; 3688 break; 3689 default: 3690 alc_fix_pll_init(codec, 0x20, 0x04, 15); 3691 } 3692 if (err < 0) 3693 goto error; 3694 spec->init_hook = alc269_fill_coef; 3695 alc269_fill_coef(codec); 3696 break; 3697 3698 case 0x10ec0280: 3699 case 0x10ec0290: 3700 spec->codec_variant = ALC269_TYPE_ALC280; 3701 break; 3702 case 0x10ec0233: 3703 case 0x10ec0282: 3704 case 0x10ec0283: 3705 spec->codec_variant = ALC269_TYPE_ALC282; 3706 break; 3707 case 0x10ec0284: 3708 case 0x10ec0292: 3709 spec->codec_variant = ALC269_TYPE_ALC284; 3710 break; 3711 case 0x10ec0286: 3712 spec->codec_variant = ALC269_TYPE_ALC286; 3713 break; 3714 } 3715 3716 /* automatic parse from the BIOS config */ 3717 err = alc269_parse_auto_config(codec); 3718 if (err < 0) 3719 goto error; 3720 3721 if (!spec->gen.no_analog && spec->gen.beep_nid) 3722 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 3723 3724 codec->patch_ops = alc_patch_ops; 3725 #ifdef CONFIG_PM 3726 codec->patch_ops.resume = alc269_resume; 3727 #endif 3728 spec->shutup = alc269_shutup; 3729 3730 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 3731 3732 return 0; 3733 3734 error: 3735 alc_free(codec); 3736 return err; 3737 } 3738 3739 /* 3740 * ALC861 3741 */ 3742 3743 static int alc861_parse_auto_config(struct hda_codec *codec) 3744 { 3745 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 }; 3746 static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 }; 3747 return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids); 3748 } 3749 3750 /* Pin config fixes */ 3751 enum { 3752 ALC861_FIXUP_FSC_AMILO_PI1505, 3753 ALC861_FIXUP_AMP_VREF_0F, 3754 ALC861_FIXUP_NO_JACK_DETECT, 3755 ALC861_FIXUP_ASUS_A6RP, 3756 }; 3757 3758 /* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */ 3759 static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec, 3760 const struct hda_fixup *fix, int action) 3761 { 3762 struct alc_spec *spec = codec->spec; 3763 unsigned int val; 3764 3765 if (action != HDA_FIXUP_ACT_INIT) 3766 return; 3767 val = snd_hda_codec_get_pin_target(codec, 0x0f); 3768 if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))) 3769 val |= AC_PINCTL_IN_EN; 3770 val |= AC_PINCTL_VREF_50; 3771 snd_hda_set_pin_ctl(codec, 0x0f, val); 3772 spec->gen.keep_vref_in_automute = 1; 3773 } 3774 3775 /* suppress the jack-detection */ 3776 static void alc_fixup_no_jack_detect(struct hda_codec *codec, 3777 const struct hda_fixup *fix, int action) 3778 { 3779 if (action == HDA_FIXUP_ACT_PRE_PROBE) 3780 codec->no_jack_detect = 1; 3781 } 3782 3783 static const struct hda_fixup alc861_fixups[] = { 3784 [ALC861_FIXUP_FSC_AMILO_PI1505] = { 3785 .type = HDA_FIXUP_PINS, 3786 .v.pins = (const struct hda_pintbl[]) { 3787 { 0x0b, 0x0221101f }, /* HP */ 3788 { 0x0f, 0x90170310 }, /* speaker */ 3789 { } 3790 } 3791 }, 3792 [ALC861_FIXUP_AMP_VREF_0F] = { 3793 .type = HDA_FIXUP_FUNC, 3794 .v.func = alc861_fixup_asus_amp_vref_0f, 3795 }, 3796 [ALC861_FIXUP_NO_JACK_DETECT] = { 3797 .type = HDA_FIXUP_FUNC, 3798 .v.func = alc_fixup_no_jack_detect, 3799 }, 3800 [ALC861_FIXUP_ASUS_A6RP] = { 3801 .type = HDA_FIXUP_FUNC, 3802 .v.func = alc861_fixup_asus_amp_vref_0f, 3803 .chained = true, 3804 .chain_id = ALC861_FIXUP_NO_JACK_DETECT, 3805 } 3806 }; 3807 3808 static const struct snd_pci_quirk alc861_fixup_tbl[] = { 3809 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP), 3810 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F), 3811 SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT), 3812 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F), 3813 SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F), 3814 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505), 3815 {} 3816 }; 3817 3818 /* 3819 */ 3820 static int patch_alc861(struct hda_codec *codec) 3821 { 3822 struct alc_spec *spec; 3823 int err; 3824 3825 err = alc_alloc_spec(codec, 0x15); 3826 if (err < 0) 3827 return err; 3828 3829 spec = codec->spec; 3830 spec->gen.beep_nid = 0x23; 3831 3832 snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups); 3833 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 3834 3835 /* automatic parse from the BIOS config */ 3836 err = alc861_parse_auto_config(codec); 3837 if (err < 0) 3838 goto error; 3839 3840 if (!spec->gen.no_analog) 3841 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); 3842 3843 codec->patch_ops = alc_patch_ops; 3844 #ifdef CONFIG_PM 3845 spec->power_hook = alc_power_eapd; 3846 #endif 3847 3848 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 3849 3850 return 0; 3851 3852 error: 3853 alc_free(codec); 3854 return err; 3855 } 3856 3857 /* 3858 * ALC861-VD support 3859 * 3860 * Based on ALC882 3861 * 3862 * In addition, an independent DAC 3863 */ 3864 static int alc861vd_parse_auto_config(struct hda_codec *codec) 3865 { 3866 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; 3867 static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 }; 3868 return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids); 3869 } 3870 3871 enum { 3872 ALC660VD_FIX_ASUS_GPIO1, 3873 ALC861VD_FIX_DALLAS, 3874 }; 3875 3876 /* exclude VREF80 */ 3877 static void alc861vd_fixup_dallas(struct hda_codec *codec, 3878 const struct hda_fixup *fix, int action) 3879 { 3880 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 3881 snd_hda_override_pin_caps(codec, 0x18, 0x00000734); 3882 snd_hda_override_pin_caps(codec, 0x19, 0x0000073c); 3883 } 3884 } 3885 3886 static const struct hda_fixup alc861vd_fixups[] = { 3887 [ALC660VD_FIX_ASUS_GPIO1] = { 3888 .type = HDA_FIXUP_VERBS, 3889 .v.verbs = (const struct hda_verb[]) { 3890 /* reset GPIO1 */ 3891 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 3892 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 3893 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 3894 { } 3895 } 3896 }, 3897 [ALC861VD_FIX_DALLAS] = { 3898 .type = HDA_FIXUP_FUNC, 3899 .v.func = alc861vd_fixup_dallas, 3900 }, 3901 }; 3902 3903 static const struct snd_pci_quirk alc861vd_fixup_tbl[] = { 3904 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS), 3905 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1), 3906 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS), 3907 {} 3908 }; 3909 3910 /* 3911 */ 3912 static int patch_alc861vd(struct hda_codec *codec) 3913 { 3914 struct alc_spec *spec; 3915 int err; 3916 3917 err = alc_alloc_spec(codec, 0x0b); 3918 if (err < 0) 3919 return err; 3920 3921 spec = codec->spec; 3922 spec->gen.beep_nid = 0x23; 3923 3924 snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups); 3925 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 3926 3927 /* automatic parse from the BIOS config */ 3928 err = alc861vd_parse_auto_config(codec); 3929 if (err < 0) 3930 goto error; 3931 3932 if (!spec->gen.no_analog) 3933 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 3934 3935 codec->patch_ops = alc_patch_ops; 3936 3937 spec->shutup = alc_eapd_shutup; 3938 3939 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 3940 3941 return 0; 3942 3943 error: 3944 alc_free(codec); 3945 return err; 3946 } 3947 3948 /* 3949 * ALC662 support 3950 * 3951 * ALC662 is almost identical with ALC880 but has cleaner and more flexible 3952 * configuration. Each pin widget can choose any input DACs and a mixer. 3953 * Each ADC is connected from a mixer of all inputs. This makes possible 3954 * 6-channel independent captures. 3955 * 3956 * In addition, an independent DAC for the multi-playback (not used in this 3957 * driver yet). 3958 */ 3959 3960 /* 3961 * BIOS auto configuration 3962 */ 3963 3964 static int alc662_parse_auto_config(struct hda_codec *codec) 3965 { 3966 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 }; 3967 static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 }; 3968 static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 }; 3969 const hda_nid_t *ssids; 3970 3971 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || 3972 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670 || 3973 codec->vendor_id == 0x10ec0671) 3974 ssids = alc663_ssids; 3975 else 3976 ssids = alc662_ssids; 3977 return alc_parse_auto_config(codec, alc662_ignore, ssids); 3978 } 3979 3980 static void alc272_fixup_mario(struct hda_codec *codec, 3981 const struct hda_fixup *fix, int action) 3982 { 3983 if (action != HDA_FIXUP_ACT_PRE_PROBE) 3984 return; 3985 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT, 3986 (0x3b << AC_AMPCAP_OFFSET_SHIFT) | 3987 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) | 3988 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) | 3989 (0 << AC_AMPCAP_MUTE_SHIFT))) 3990 printk(KERN_WARNING 3991 "hda_codec: failed to override amp caps for NID 0x2\n"); 3992 } 3993 3994 enum { 3995 ALC662_FIXUP_ASPIRE, 3996 ALC662_FIXUP_IDEAPAD, 3997 ALC272_FIXUP_MARIO, 3998 ALC662_FIXUP_CZC_P10T, 3999 ALC662_FIXUP_SKU_IGNORE, 4000 ALC662_FIXUP_HP_RP5800, 4001 ALC662_FIXUP_ASUS_MODE1, 4002 ALC662_FIXUP_ASUS_MODE2, 4003 ALC662_FIXUP_ASUS_MODE3, 4004 ALC662_FIXUP_ASUS_MODE4, 4005 ALC662_FIXUP_ASUS_MODE5, 4006 ALC662_FIXUP_ASUS_MODE6, 4007 ALC662_FIXUP_ASUS_MODE7, 4008 ALC662_FIXUP_ASUS_MODE8, 4009 ALC662_FIXUP_NO_JACK_DETECT, 4010 ALC662_FIXUP_ZOTAC_Z68, 4011 ALC662_FIXUP_INV_DMIC, 4012 ALC668_FIXUP_DELL_MIC_NO_PRESENCE, 4013 ALC668_FIXUP_HEADSET_MODE, 4014 }; 4015 4016 static const struct hda_fixup alc662_fixups[] = { 4017 [ALC662_FIXUP_ASPIRE] = { 4018 .type = HDA_FIXUP_PINS, 4019 .v.pins = (const struct hda_pintbl[]) { 4020 { 0x15, 0x99130112 }, /* subwoofer */ 4021 { } 4022 } 4023 }, 4024 [ALC662_FIXUP_IDEAPAD] = { 4025 .type = HDA_FIXUP_PINS, 4026 .v.pins = (const struct hda_pintbl[]) { 4027 { 0x17, 0x99130112 }, /* subwoofer */ 4028 { } 4029 } 4030 }, 4031 [ALC272_FIXUP_MARIO] = { 4032 .type = HDA_FIXUP_FUNC, 4033 .v.func = alc272_fixup_mario, 4034 }, 4035 [ALC662_FIXUP_CZC_P10T] = { 4036 .type = HDA_FIXUP_VERBS, 4037 .v.verbs = (const struct hda_verb[]) { 4038 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, 4039 {} 4040 } 4041 }, 4042 [ALC662_FIXUP_SKU_IGNORE] = { 4043 .type = HDA_FIXUP_FUNC, 4044 .v.func = alc_fixup_sku_ignore, 4045 }, 4046 [ALC662_FIXUP_HP_RP5800] = { 4047 .type = HDA_FIXUP_PINS, 4048 .v.pins = (const struct hda_pintbl[]) { 4049 { 0x14, 0x0221201f }, /* HP out */ 4050 { } 4051 }, 4052 .chained = true, 4053 .chain_id = ALC662_FIXUP_SKU_IGNORE 4054 }, 4055 [ALC662_FIXUP_ASUS_MODE1] = { 4056 .type = HDA_FIXUP_PINS, 4057 .v.pins = (const struct hda_pintbl[]) { 4058 { 0x14, 0x99130110 }, /* speaker */ 4059 { 0x18, 0x01a19c20 }, /* mic */ 4060 { 0x19, 0x99a3092f }, /* int-mic */ 4061 { 0x21, 0x0121401f }, /* HP out */ 4062 { } 4063 }, 4064 .chained = true, 4065 .chain_id = ALC662_FIXUP_SKU_IGNORE 4066 }, 4067 [ALC662_FIXUP_ASUS_MODE2] = { 4068 .type = HDA_FIXUP_PINS, 4069 .v.pins = (const struct hda_pintbl[]) { 4070 { 0x14, 0x99130110 }, /* speaker */ 4071 { 0x18, 0x01a19820 }, /* mic */ 4072 { 0x19, 0x99a3092f }, /* int-mic */ 4073 { 0x1b, 0x0121401f }, /* HP out */ 4074 { } 4075 }, 4076 .chained = true, 4077 .chain_id = ALC662_FIXUP_SKU_IGNORE 4078 }, 4079 [ALC662_FIXUP_ASUS_MODE3] = { 4080 .type = HDA_FIXUP_PINS, 4081 .v.pins = (const struct hda_pintbl[]) { 4082 { 0x14, 0x99130110 }, /* speaker */ 4083 { 0x15, 0x0121441f }, /* HP */ 4084 { 0x18, 0x01a19840 }, /* mic */ 4085 { 0x19, 0x99a3094f }, /* int-mic */ 4086 { 0x21, 0x01211420 }, /* HP2 */ 4087 { } 4088 }, 4089 .chained = true, 4090 .chain_id = ALC662_FIXUP_SKU_IGNORE 4091 }, 4092 [ALC662_FIXUP_ASUS_MODE4] = { 4093 .type = HDA_FIXUP_PINS, 4094 .v.pins = (const struct hda_pintbl[]) { 4095 { 0x14, 0x99130110 }, /* speaker */ 4096 { 0x16, 0x99130111 }, /* speaker */ 4097 { 0x18, 0x01a19840 }, /* mic */ 4098 { 0x19, 0x99a3094f }, /* int-mic */ 4099 { 0x21, 0x0121441f }, /* HP */ 4100 { } 4101 }, 4102 .chained = true, 4103 .chain_id = ALC662_FIXUP_SKU_IGNORE 4104 }, 4105 [ALC662_FIXUP_ASUS_MODE5] = { 4106 .type = HDA_FIXUP_PINS, 4107 .v.pins = (const struct hda_pintbl[]) { 4108 { 0x14, 0x99130110 }, /* speaker */ 4109 { 0x15, 0x0121441f }, /* HP */ 4110 { 0x16, 0x99130111 }, /* speaker */ 4111 { 0x18, 0x01a19840 }, /* mic */ 4112 { 0x19, 0x99a3094f }, /* int-mic */ 4113 { } 4114 }, 4115 .chained = true, 4116 .chain_id = ALC662_FIXUP_SKU_IGNORE 4117 }, 4118 [ALC662_FIXUP_ASUS_MODE6] = { 4119 .type = HDA_FIXUP_PINS, 4120 .v.pins = (const struct hda_pintbl[]) { 4121 { 0x14, 0x99130110 }, /* speaker */ 4122 { 0x15, 0x01211420 }, /* HP2 */ 4123 { 0x18, 0x01a19840 }, /* mic */ 4124 { 0x19, 0x99a3094f }, /* int-mic */ 4125 { 0x1b, 0x0121441f }, /* HP */ 4126 { } 4127 }, 4128 .chained = true, 4129 .chain_id = ALC662_FIXUP_SKU_IGNORE 4130 }, 4131 [ALC662_FIXUP_ASUS_MODE7] = { 4132 .type = HDA_FIXUP_PINS, 4133 .v.pins = (const struct hda_pintbl[]) { 4134 { 0x14, 0x99130110 }, /* speaker */ 4135 { 0x17, 0x99130111 }, /* speaker */ 4136 { 0x18, 0x01a19840 }, /* mic */ 4137 { 0x19, 0x99a3094f }, /* int-mic */ 4138 { 0x1b, 0x01214020 }, /* HP */ 4139 { 0x21, 0x0121401f }, /* HP */ 4140 { } 4141 }, 4142 .chained = true, 4143 .chain_id = ALC662_FIXUP_SKU_IGNORE 4144 }, 4145 [ALC662_FIXUP_ASUS_MODE8] = { 4146 .type = HDA_FIXUP_PINS, 4147 .v.pins = (const struct hda_pintbl[]) { 4148 { 0x14, 0x99130110 }, /* speaker */ 4149 { 0x12, 0x99a30970 }, /* int-mic */ 4150 { 0x15, 0x01214020 }, /* HP */ 4151 { 0x17, 0x99130111 }, /* speaker */ 4152 { 0x18, 0x01a19840 }, /* mic */ 4153 { 0x21, 0x0121401f }, /* HP */ 4154 { } 4155 }, 4156 .chained = true, 4157 .chain_id = ALC662_FIXUP_SKU_IGNORE 4158 }, 4159 [ALC662_FIXUP_NO_JACK_DETECT] = { 4160 .type = HDA_FIXUP_FUNC, 4161 .v.func = alc_fixup_no_jack_detect, 4162 }, 4163 [ALC662_FIXUP_ZOTAC_Z68] = { 4164 .type = HDA_FIXUP_PINS, 4165 .v.pins = (const struct hda_pintbl[]) { 4166 { 0x1b, 0x02214020 }, /* Front HP */ 4167 { } 4168 } 4169 }, 4170 [ALC662_FIXUP_INV_DMIC] = { 4171 .type = HDA_FIXUP_FUNC, 4172 .v.func = alc_fixup_inv_dmic_0x12, 4173 }, 4174 [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = { 4175 .type = HDA_FIXUP_PINS, 4176 .v.pins = (const struct hda_pintbl[]) { 4177 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */ 4178 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */ 4179 { } 4180 }, 4181 .chained = true, 4182 .chain_id = ALC668_FIXUP_HEADSET_MODE 4183 }, 4184 [ALC668_FIXUP_HEADSET_MODE] = { 4185 .type = HDA_FIXUP_FUNC, 4186 .v.func = alc_fixup_headset_mode_alc668, 4187 }, 4188 }; 4189 4190 static const struct snd_pci_quirk alc662_fixup_tbl[] = { 4191 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2), 4192 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), 4193 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), 4194 SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC), 4195 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), 4196 SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), 4197 SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), 4198 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), 4199 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), 4200 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), 4201 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), 4202 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), 4203 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), 4204 SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68), 4205 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T), 4206 4207 #if 0 4208 /* Below is a quirk table taken from the old code. 4209 * Basically the device should work as is without the fixup table. 4210 * If BIOS doesn't give a proper info, enable the corresponding 4211 * fixup entry. 4212 */ 4213 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1), 4214 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3), 4215 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1), 4216 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3), 4217 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), 4218 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 4219 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), 4220 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1), 4221 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1), 4222 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 4223 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7), 4224 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7), 4225 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8), 4226 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3), 4227 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1), 4228 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 4229 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2), 4230 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1), 4231 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 4232 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), 4233 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), 4234 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 4235 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1), 4236 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3), 4237 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2), 4238 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 4239 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5), 4240 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), 4241 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 4242 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1), 4243 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 4244 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 4245 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3), 4246 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3), 4247 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1), 4248 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1), 4249 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1), 4250 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1), 4251 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1), 4252 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), 4253 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2), 4254 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1), 4255 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), 4256 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3), 4257 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1), 4258 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1), 4259 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1), 4260 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2), 4261 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), 4262 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4), 4263 #endif 4264 {} 4265 }; 4266 4267 static const struct hda_model_fixup alc662_fixup_models[] = { 4268 {.id = ALC272_FIXUP_MARIO, .name = "mario"}, 4269 {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"}, 4270 {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"}, 4271 {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"}, 4272 {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"}, 4273 {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"}, 4274 {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"}, 4275 {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"}, 4276 {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"}, 4277 {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"}, 4278 {} 4279 }; 4280 4281 static void alc662_fill_coef(struct hda_codec *codec) 4282 { 4283 int val, coef; 4284 4285 coef = alc_get_coef0(codec); 4286 4287 switch (codec->vendor_id) { 4288 case 0x10ec0662: 4289 if ((coef & 0x00f0) == 0x0030) { 4290 val = alc_read_coef_idx(codec, 0x4); /* EAPD Ctrl */ 4291 alc_write_coef_idx(codec, 0x4, val & ~(1<<10)); 4292 } 4293 break; 4294 case 0x10ec0272: 4295 case 0x10ec0273: 4296 case 0x10ec0663: 4297 case 0x10ec0665: 4298 case 0x10ec0670: 4299 case 0x10ec0671: 4300 case 0x10ec0672: 4301 val = alc_read_coef_idx(codec, 0xd); /* EAPD Ctrl */ 4302 alc_write_coef_idx(codec, 0xd, val | (1<<14)); 4303 break; 4304 } 4305 } 4306 4307 /* 4308 */ 4309 static int patch_alc662(struct hda_codec *codec) 4310 { 4311 struct alc_spec *spec; 4312 int err; 4313 4314 err = alc_alloc_spec(codec, 0x0b); 4315 if (err < 0) 4316 return err; 4317 4318 spec = codec->spec; 4319 4320 /* handle multiple HPs as is */ 4321 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; 4322 4323 alc_fix_pll_init(codec, 0x20, 0x04, 15); 4324 4325 spec->init_hook = alc662_fill_coef; 4326 alc662_fill_coef(codec); 4327 4328 snd_hda_pick_fixup(codec, alc662_fixup_models, 4329 alc662_fixup_tbl, alc662_fixups); 4330 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 4331 4332 alc_auto_parse_customize_define(codec); 4333 4334 if (has_cdefine_beep(codec)) 4335 spec->gen.beep_nid = 0x01; 4336 4337 if ((alc_get_coef0(codec) & (1 << 14)) && 4338 codec->bus->pci->subsystem_vendor == 0x1025 && 4339 spec->cdefine.platform_type == 1) { 4340 err = alc_codec_rename(codec, "ALC272X"); 4341 if (err < 0) 4342 goto error; 4343 } 4344 4345 /* automatic parse from the BIOS config */ 4346 err = alc662_parse_auto_config(codec); 4347 if (err < 0) 4348 goto error; 4349 4350 if (!spec->gen.no_analog && spec->gen.beep_nid) { 4351 switch (codec->vendor_id) { 4352 case 0x10ec0662: 4353 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 4354 break; 4355 case 0x10ec0272: 4356 case 0x10ec0663: 4357 case 0x10ec0665: 4358 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 4359 break; 4360 case 0x10ec0273: 4361 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT); 4362 break; 4363 } 4364 } 4365 4366 codec->patch_ops = alc_patch_ops; 4367 spec->shutup = alc_eapd_shutup; 4368 4369 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 4370 4371 return 0; 4372 4373 error: 4374 alc_free(codec); 4375 return err; 4376 } 4377 4378 /* 4379 * ALC680 support 4380 */ 4381 4382 static int alc680_parse_auto_config(struct hda_codec *codec) 4383 { 4384 return alc_parse_auto_config(codec, NULL, NULL); 4385 } 4386 4387 /* 4388 */ 4389 static int patch_alc680(struct hda_codec *codec) 4390 { 4391 int err; 4392 4393 /* ALC680 has no aa-loopback mixer */ 4394 err = alc_alloc_spec(codec, 0); 4395 if (err < 0) 4396 return err; 4397 4398 /* automatic parse from the BIOS config */ 4399 err = alc680_parse_auto_config(codec); 4400 if (err < 0) { 4401 alc_free(codec); 4402 return err; 4403 } 4404 4405 codec->patch_ops = alc_patch_ops; 4406 4407 return 0; 4408 } 4409 4410 /* 4411 * patch entries 4412 */ 4413 static const struct hda_codec_preset snd_hda_preset_realtek[] = { 4414 { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 }, 4415 { .id = 0x10ec0233, .name = "ALC233", .patch = patch_alc269 }, 4416 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, 4417 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, 4418 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, 4419 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, 4420 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 }, 4421 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 }, 4422 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, 4423 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, 4424 { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 }, 4425 { .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 }, 4426 { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 }, 4427 { .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 }, 4428 { .id = 0x10ec0284, .name = "ALC284", .patch = patch_alc269 }, 4429 { .id = 0x10ec0286, .name = "ALC286", .patch = patch_alc269 }, 4430 { .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 }, 4431 { .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 }, 4432 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", 4433 .patch = patch_alc861 }, 4434 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, 4435 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, 4436 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, 4437 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", 4438 .patch = patch_alc882 }, 4439 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", 4440 .patch = patch_alc662 }, 4441 { .id = 0x10ec0662, .rev = 0x100300, .name = "ALC662 rev3", 4442 .patch = patch_alc662 }, 4443 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, 4444 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, 4445 { .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 }, 4446 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, 4447 { .id = 0x10ec0671, .name = "ALC671", .patch = patch_alc662 }, 4448 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, 4449 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 4450 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 4451 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, 4452 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A", 4453 .patch = patch_alc882 }, 4454 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", 4455 .patch = patch_alc882 }, 4456 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, 4457 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 }, 4458 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", 4459 .patch = patch_alc882 }, 4460 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 }, 4461 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, 4462 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, 4463 { .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 }, 4464 { .id = 0x10ec0900, .name = "ALC1150", .patch = patch_alc882 }, 4465 {} /* terminator */ 4466 }; 4467 4468 MODULE_ALIAS("snd-hda-codec-id:10ec*"); 4469 4470 MODULE_LICENSE("GPL"); 4471 MODULE_DESCRIPTION("Realtek HD-audio codec"); 4472 4473 static struct hda_codec_preset_list realtek_list = { 4474 .preset = snd_hda_preset_realtek, 4475 .owner = THIS_MODULE, 4476 }; 4477 4478 static int __init patch_realtek_init(void) 4479 { 4480 return snd_hda_add_codec_preset(&realtek_list); 4481 } 4482 4483 static void __exit patch_realtek_exit(void) 4484 { 4485 snd_hda_delete_codec_preset(&realtek_list); 4486 } 4487 4488 module_init(patch_realtek_init) 4489 module_exit(patch_realtek_exit) 4490