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