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