Revert "ALSA: hda: Flush interrupts on disabling"
[linux/fpc-iii.git] / sound / pci / hda / patch_realtek.c
bloba64612db1f155f1c0787cbb79f42628f06079e38
1 /*
2 * Universal Interface for Intel High Definition Audio Codec
4 * HD audio interface patch for Realtek ALC codecs
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>
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.
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.
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
26 #include <linux/init.h>
27 #include <linux/delay.h>
28 #include <linux/slab.h>
29 #include <linux/pci.h>
30 #include <linux/dmi.h>
31 #include <linux/module.h>
32 #include <linux/input.h>
33 #include <sound/core.h>
34 #include <sound/jack.h>
35 #include "hda_codec.h"
36 #include "hda_local.h"
37 #include "hda_auto_parser.h"
38 #include "hda_jack.h"
39 #include "hda_generic.h"
41 /* keep halting ALC5505 DSP, for power saving */
42 #define HALT_REALTEK_ALC5505
44 /* for GPIO Poll */
45 #define GPIO_MASK 0x03
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,
56 enum {
57 ALC_HEADSET_MODE_UNKNOWN,
58 ALC_HEADSET_MODE_UNPLUGGED,
59 ALC_HEADSET_MODE_HEADSET,
60 ALC_HEADSET_MODE_MIC,
61 ALC_HEADSET_MODE_HEADPHONE,
64 enum {
65 ALC_HEADSET_TYPE_UNKNOWN,
66 ALC_HEADSET_TYPE_CTIA,
67 ALC_HEADSET_TYPE_OMTP,
70 enum {
71 ALC_KEY_MICMUTE_INDEX,
74 struct alc_customize_define {
75 unsigned int sku_cfg;
76 unsigned char port_connectivity;
77 unsigned char check_sum;
78 unsigned char customization;
79 unsigned char external_amp;
80 unsigned int enable_pcbeep:1;
81 unsigned int platform_type:1;
82 unsigned int swap:1;
83 unsigned int override:1;
84 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
87 struct alc_spec {
88 struct hda_gen_spec gen; /* must be at head */
90 /* codec parameterization */
91 const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
92 unsigned int num_mixers;
93 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
95 struct alc_customize_define cdefine;
96 unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */
98 /* mute LED for HP laptops, see alc269_fixup_mic_mute_hook() */
99 int mute_led_polarity;
100 hda_nid_t mute_led_nid;
101 hda_nid_t cap_mute_led_nid;
103 unsigned int gpio_led; /* used for alc269_fixup_hp_gpio_led() */
104 unsigned int gpio_mute_led_mask;
105 unsigned int gpio_mic_led_mask;
107 hda_nid_t headset_mic_pin;
108 hda_nid_t headphone_mic_pin;
109 int current_headset_mode;
110 int current_headset_type;
112 /* hooks */
113 void (*init_hook)(struct hda_codec *codec);
114 #ifdef CONFIG_PM
115 void (*power_hook)(struct hda_codec *codec);
116 #endif
117 void (*shutup)(struct hda_codec *codec);
118 void (*reboot_notify)(struct hda_codec *codec);
120 int init_amp;
121 int codec_variant; /* flag for other variants */
122 unsigned int has_alc5505_dsp:1;
123 unsigned int no_depop_delay:1;
125 /* for PLL fix */
126 hda_nid_t pll_nid;
127 unsigned int pll_coef_idx, pll_coef_bit;
128 unsigned int coef0;
129 struct input_dev *kb_dev;
130 u8 alc_mute_keycode_map[1];
134 * COEF access helper functions
137 static int alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
138 unsigned int coef_idx)
140 unsigned int val;
142 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
143 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
144 return val;
147 #define alc_read_coef_idx(codec, coef_idx) \
148 alc_read_coefex_idx(codec, 0x20, coef_idx)
150 static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
151 unsigned int coef_idx, unsigned int coef_val)
153 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
154 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF, coef_val);
157 #define alc_write_coef_idx(codec, coef_idx, coef_val) \
158 alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val)
160 static void alc_update_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
161 unsigned int coef_idx, unsigned int mask,
162 unsigned int bits_set)
164 unsigned int val = alc_read_coefex_idx(codec, nid, coef_idx);
166 if (val != -1)
167 alc_write_coefex_idx(codec, nid, coef_idx,
168 (val & ~mask) | bits_set);
171 #define alc_update_coef_idx(codec, coef_idx, mask, bits_set) \
172 alc_update_coefex_idx(codec, 0x20, coef_idx, mask, bits_set)
174 /* a special bypass for COEF 0; read the cached value at the second time */
175 static unsigned int alc_get_coef0(struct hda_codec *codec)
177 struct alc_spec *spec = codec->spec;
179 if (!spec->coef0)
180 spec->coef0 = alc_read_coef_idx(codec, 0);
181 return spec->coef0;
184 /* coef writes/updates batch */
185 struct coef_fw {
186 unsigned char nid;
187 unsigned char idx;
188 unsigned short mask;
189 unsigned short val;
192 #define UPDATE_COEFEX(_nid, _idx, _mask, _val) \
193 { .nid = (_nid), .idx = (_idx), .mask = (_mask), .val = (_val) }
194 #define WRITE_COEFEX(_nid, _idx, _val) UPDATE_COEFEX(_nid, _idx, -1, _val)
195 #define WRITE_COEF(_idx, _val) WRITE_COEFEX(0x20, _idx, _val)
196 #define UPDATE_COEF(_idx, _mask, _val) UPDATE_COEFEX(0x20, _idx, _mask, _val)
198 static void alc_process_coef_fw(struct hda_codec *codec,
199 const struct coef_fw *fw)
201 for (; fw->nid; fw++) {
202 if (fw->mask == (unsigned short)-1)
203 alc_write_coefex_idx(codec, fw->nid, fw->idx, fw->val);
204 else
205 alc_update_coefex_idx(codec, fw->nid, fw->idx,
206 fw->mask, fw->val);
211 * Append the given mixer and verb elements for the later use
212 * The mixer array is referred in build_controls(), and init_verbs are
213 * called in init().
215 static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
217 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
218 return;
219 spec->mixers[spec->num_mixers++] = mix;
223 * GPIO setup tables, used in initialization
225 /* Enable GPIO mask and set output */
226 static const struct hda_verb alc_gpio1_init_verbs[] = {
227 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
228 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
229 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
233 static const struct hda_verb alc_gpio2_init_verbs[] = {
234 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
235 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
236 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
240 static const struct hda_verb alc_gpio3_init_verbs[] = {
241 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
242 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
243 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
248 * Fix hardware PLL issue
249 * On some codecs, the analog PLL gating control must be off while
250 * the default value is 1.
252 static void alc_fix_pll(struct hda_codec *codec)
254 struct alc_spec *spec = codec->spec;
256 if (spec->pll_nid)
257 alc_update_coefex_idx(codec, spec->pll_nid, spec->pll_coef_idx,
258 1 << spec->pll_coef_bit, 0);
261 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
262 unsigned int coef_idx, unsigned int coef_bit)
264 struct alc_spec *spec = codec->spec;
265 spec->pll_nid = nid;
266 spec->pll_coef_idx = coef_idx;
267 spec->pll_coef_bit = coef_bit;
268 alc_fix_pll(codec);
271 /* update the master volume per volume-knob's unsol event */
272 static void alc_update_knob_master(struct hda_codec *codec,
273 struct hda_jack_callback *jack)
275 unsigned int val;
276 struct snd_kcontrol *kctl;
277 struct snd_ctl_elem_value *uctl;
279 kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume");
280 if (!kctl)
281 return;
282 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
283 if (!uctl)
284 return;
285 val = snd_hda_codec_read(codec, jack->nid, 0,
286 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
287 val &= HDA_AMP_VOLMASK;
288 uctl->value.integer.value[0] = val;
289 uctl->value.integer.value[1] = val;
290 kctl->put(kctl, uctl);
291 kfree(uctl);
294 static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
296 /* For some reason, the res given from ALC880 is broken.
297 Here we adjust it properly. */
298 snd_hda_jack_unsol_event(codec, res >> 2);
301 /* Change EAPD to verb control */
302 static void alc_fill_eapd_coef(struct hda_codec *codec)
304 int coef;
306 coef = alc_get_coef0(codec);
308 switch (codec->core.vendor_id) {
309 case 0x10ec0262:
310 alc_update_coef_idx(codec, 0x7, 0, 1<<5);
311 break;
312 case 0x10ec0267:
313 case 0x10ec0268:
314 alc_update_coef_idx(codec, 0x7, 0, 1<<13);
315 break;
316 case 0x10ec0269:
317 if ((coef & 0x00f0) == 0x0010)
318 alc_update_coef_idx(codec, 0xd, 0, 1<<14);
319 if ((coef & 0x00f0) == 0x0020)
320 alc_update_coef_idx(codec, 0x4, 1<<15, 0);
321 if ((coef & 0x00f0) == 0x0030)
322 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
323 break;
324 case 0x10ec0280:
325 case 0x10ec0284:
326 case 0x10ec0290:
327 case 0x10ec0292:
328 alc_update_coef_idx(codec, 0x4, 1<<15, 0);
329 break;
330 case 0x10ec0225:
331 case 0x10ec0233:
332 case 0x10ec0235:
333 case 0x10ec0236:
334 case 0x10ec0255:
335 case 0x10ec0256:
336 case 0x10ec0257:
337 case 0x10ec0282:
338 case 0x10ec0283:
339 case 0x10ec0286:
340 case 0x10ec0288:
341 case 0x10ec0295:
342 case 0x10ec0298:
343 case 0x10ec0299:
344 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
345 break;
346 case 0x10ec0285:
347 case 0x10ec0293:
348 alc_update_coef_idx(codec, 0xa, 1<<13, 0);
349 break;
350 case 0x10ec0234:
351 case 0x10ec0274:
352 case 0x10ec0294:
353 case 0x10ec0700:
354 case 0x10ec0701:
355 case 0x10ec0703:
356 case 0x10ec0711:
357 alc_update_coef_idx(codec, 0x10, 1<<15, 0);
358 break;
359 case 0x10ec0662:
360 if ((coef & 0x00f0) == 0x0030)
361 alc_update_coef_idx(codec, 0x4, 1<<10, 0); /* EAPD Ctrl */
362 break;
363 case 0x10ec0272:
364 case 0x10ec0273:
365 case 0x10ec0663:
366 case 0x10ec0665:
367 case 0x10ec0670:
368 case 0x10ec0671:
369 case 0x10ec0672:
370 alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */
371 break;
372 case 0x10ec0668:
373 alc_update_coef_idx(codec, 0x7, 3<<13, 0);
374 break;
375 case 0x10ec0867:
376 alc_update_coef_idx(codec, 0x4, 1<<10, 0);
377 break;
378 case 0x10ec0888:
379 if ((coef & 0x00f0) == 0x0020 || (coef & 0x00f0) == 0x0030)
380 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
381 break;
382 case 0x10ec0892:
383 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
384 break;
385 case 0x10ec0899:
386 case 0x10ec0900:
387 alc_update_coef_idx(codec, 0x7, 1<<1, 0);
388 break;
392 /* additional initialization for ALC888 variants */
393 static void alc888_coef_init(struct hda_codec *codec)
395 switch (alc_get_coef0(codec) & 0x00f0) {
396 /* alc888-VA */
397 case 0x00:
398 /* alc888-VB */
399 case 0x10:
400 alc_update_coef_idx(codec, 7, 0, 0x2030); /* Turn EAPD to High */
401 break;
405 /* turn on/off EAPD control (only if available) */
406 static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
408 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
409 return;
410 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
411 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
412 on ? 2 : 0);
415 /* turn on/off EAPD controls of the codec */
416 static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
418 /* We currently only handle front, HP */
419 static hda_nid_t pins[] = {
420 0x0f, 0x10, 0x14, 0x15, 0x17, 0
422 hda_nid_t *p;
423 for (p = pins; *p; p++)
424 set_eapd(codec, *p, on);
427 /* generic shutup callback;
428 * just turning off EPAD and a little pause for avoiding pop-noise
430 static void alc_eapd_shutup(struct hda_codec *codec)
432 struct alc_spec *spec = codec->spec;
434 alc_auto_setup_eapd(codec, false);
435 if (!spec->no_depop_delay)
436 msleep(200);
437 snd_hda_shutup_pins(codec);
440 /* generic EAPD initialization */
441 static void alc_auto_init_amp(struct hda_codec *codec, int type)
443 alc_fill_eapd_coef(codec);
444 alc_auto_setup_eapd(codec, true);
445 switch (type) {
446 case ALC_INIT_GPIO1:
447 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
448 break;
449 case ALC_INIT_GPIO2:
450 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
451 break;
452 case ALC_INIT_GPIO3:
453 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
454 break;
455 case ALC_INIT_DEFAULT:
456 switch (codec->core.vendor_id) {
457 case 0x10ec0260:
458 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x2010);
459 break;
460 case 0x10ec0880:
461 case 0x10ec0882:
462 case 0x10ec0883:
463 case 0x10ec0885:
464 alc_update_coef_idx(codec, 7, 0, 0x2030);
465 break;
466 case 0x10ec0888:
467 alc888_coef_init(codec);
468 break;
470 break;
476 * Realtek SSID verification
479 /* Could be any non-zero and even value. When used as fixup, tells
480 * the driver to ignore any present sku defines.
482 #define ALC_FIXUP_SKU_IGNORE (2)
484 static void alc_fixup_sku_ignore(struct hda_codec *codec,
485 const struct hda_fixup *fix, int action)
487 struct alc_spec *spec = codec->spec;
488 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
489 spec->cdefine.fixup = 1;
490 spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE;
494 static void alc_fixup_no_depop_delay(struct hda_codec *codec,
495 const struct hda_fixup *fix, int action)
497 struct alc_spec *spec = codec->spec;
499 if (action == HDA_FIXUP_ACT_PROBE) {
500 spec->no_depop_delay = 1;
501 codec->depop_delay = 0;
505 static int alc_auto_parse_customize_define(struct hda_codec *codec)
507 unsigned int ass, tmp, i;
508 unsigned nid = 0;
509 struct alc_spec *spec = codec->spec;
511 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
513 if (spec->cdefine.fixup) {
514 ass = spec->cdefine.sku_cfg;
515 if (ass == ALC_FIXUP_SKU_IGNORE)
516 return -1;
517 goto do_sku;
520 if (!codec->bus->pci)
521 return -1;
522 ass = codec->core.subsystem_id & 0xffff;
523 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
524 goto do_sku;
526 nid = 0x1d;
527 if (codec->core.vendor_id == 0x10ec0260)
528 nid = 0x17;
529 ass = snd_hda_codec_get_pincfg(codec, nid);
531 if (!(ass & 1)) {
532 codec_info(codec, "%s: SKU not ready 0x%08x\n",
533 codec->core.chip_name, ass);
534 return -1;
537 /* check sum */
538 tmp = 0;
539 for (i = 1; i < 16; i++) {
540 if ((ass >> i) & 1)
541 tmp++;
543 if (((ass >> 16) & 0xf) != tmp)
544 return -1;
546 spec->cdefine.port_connectivity = ass >> 30;
547 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
548 spec->cdefine.check_sum = (ass >> 16) & 0xf;
549 spec->cdefine.customization = ass >> 8;
550 do_sku:
551 spec->cdefine.sku_cfg = ass;
552 spec->cdefine.external_amp = (ass & 0x38) >> 3;
553 spec->cdefine.platform_type = (ass & 0x4) >> 2;
554 spec->cdefine.swap = (ass & 0x2) >> 1;
555 spec->cdefine.override = ass & 0x1;
557 codec_dbg(codec, "SKU: Nid=0x%x sku_cfg=0x%08x\n",
558 nid, spec->cdefine.sku_cfg);
559 codec_dbg(codec, "SKU: port_connectivity=0x%x\n",
560 spec->cdefine.port_connectivity);
561 codec_dbg(codec, "SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
562 codec_dbg(codec, "SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
563 codec_dbg(codec, "SKU: customization=0x%08x\n", spec->cdefine.customization);
564 codec_dbg(codec, "SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
565 codec_dbg(codec, "SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
566 codec_dbg(codec, "SKU: swap=0x%x\n", spec->cdefine.swap);
567 codec_dbg(codec, "SKU: override=0x%x\n", spec->cdefine.override);
569 return 0;
572 /* return the position of NID in the list, or -1 if not found */
573 static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
575 int i;
576 for (i = 0; i < nums; i++)
577 if (list[i] == nid)
578 return i;
579 return -1;
581 /* return true if the given NID is found in the list */
582 static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
584 return find_idx_in_nid_list(nid, list, nums) >= 0;
587 /* check subsystem ID and set up device-specific initialization;
588 * return 1 if initialized, 0 if invalid SSID
590 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
591 * 31 ~ 16 : Manufacture ID
592 * 15 ~ 8 : SKU ID
593 * 7 ~ 0 : Assembly ID
594 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
596 static int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports)
598 unsigned int ass, tmp, i;
599 unsigned nid;
600 struct alc_spec *spec = codec->spec;
602 if (spec->cdefine.fixup) {
603 ass = spec->cdefine.sku_cfg;
604 if (ass == ALC_FIXUP_SKU_IGNORE)
605 return 0;
606 goto do_sku;
609 ass = codec->core.subsystem_id & 0xffff;
610 if (codec->bus->pci &&
611 ass != codec->bus->pci->subsystem_device && (ass & 1))
612 goto do_sku;
614 /* invalid SSID, check the special NID pin defcfg instead */
616 * 31~30 : port connectivity
617 * 29~21 : reserve
618 * 20 : PCBEEP input
619 * 19~16 : Check sum (15:1)
620 * 15~1 : Custom
621 * 0 : override
623 nid = 0x1d;
624 if (codec->core.vendor_id == 0x10ec0260)
625 nid = 0x17;
626 ass = snd_hda_codec_get_pincfg(codec, nid);
627 codec_dbg(codec,
628 "realtek: No valid SSID, checking pincfg 0x%08x for NID 0x%x\n",
629 ass, nid);
630 if (!(ass & 1))
631 return 0;
632 if ((ass >> 30) != 1) /* no physical connection */
633 return 0;
635 /* check sum */
636 tmp = 0;
637 for (i = 1; i < 16; i++) {
638 if ((ass >> i) & 1)
639 tmp++;
641 if (((ass >> 16) & 0xf) != tmp)
642 return 0;
643 do_sku:
644 codec_dbg(codec, "realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
645 ass & 0xffff, codec->core.vendor_id);
647 * 0 : override
648 * 1 : Swap Jack
649 * 2 : 0 --> Desktop, 1 --> Laptop
650 * 3~5 : External Amplifier control
651 * 7~6 : Reserved
653 tmp = (ass & 0x38) >> 3; /* external Amp control */
654 switch (tmp) {
655 case 1:
656 spec->init_amp = ALC_INIT_GPIO1;
657 break;
658 case 3:
659 spec->init_amp = ALC_INIT_GPIO2;
660 break;
661 case 7:
662 spec->init_amp = ALC_INIT_GPIO3;
663 break;
664 case 5:
665 default:
666 spec->init_amp = ALC_INIT_DEFAULT;
667 break;
670 /* is laptop or Desktop and enable the function "Mute internal speaker
671 * when the external headphone out jack is plugged"
673 if (!(ass & 0x8000))
674 return 1;
676 * 10~8 : Jack location
677 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
678 * 14~13: Resvered
679 * 15 : 1 --> enable the function "Mute internal speaker
680 * when the external headphone out jack is plugged"
682 if (!spec->gen.autocfg.hp_pins[0] &&
683 !(spec->gen.autocfg.line_out_pins[0] &&
684 spec->gen.autocfg.line_out_type == AUTO_PIN_HP_OUT)) {
685 hda_nid_t nid;
686 tmp = (ass >> 11) & 0x3; /* HP to chassis */
687 nid = ports[tmp];
688 if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins,
689 spec->gen.autocfg.line_outs))
690 return 1;
691 spec->gen.autocfg.hp_pins[0] = nid;
693 return 1;
696 /* Check the validity of ALC subsystem-id
697 * ports contains an array of 4 pin NIDs for port-A, E, D and I */
698 static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
700 if (!alc_subsystem_id(codec, ports)) {
701 struct alc_spec *spec = codec->spec;
702 codec_dbg(codec,
703 "realtek: Enable default setup for auto mode as fallback\n");
704 spec->init_amp = ALC_INIT_DEFAULT;
711 static void alc_fixup_inv_dmic(struct hda_codec *codec,
712 const struct hda_fixup *fix, int action)
714 struct alc_spec *spec = codec->spec;
716 spec->gen.inv_dmic_split = 1;
720 #ifdef CONFIG_SND_HDA_INPUT_BEEP
721 /* additional beep mixers; the actual parameters are overwritten at build */
722 static const struct snd_kcontrol_new alc_beep_mixer[] = {
723 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
724 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
725 { } /* end */
727 #endif
729 static int alc_build_controls(struct hda_codec *codec)
731 struct alc_spec *spec = codec->spec;
732 int i, err;
734 err = snd_hda_gen_build_controls(codec);
735 if (err < 0)
736 return err;
738 for (i = 0; i < spec->num_mixers; i++) {
739 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
740 if (err < 0)
741 return err;
744 #ifdef CONFIG_SND_HDA_INPUT_BEEP
745 /* create beep controls if needed */
746 if (spec->beep_amp) {
747 const struct snd_kcontrol_new *knew;
748 for (knew = alc_beep_mixer; knew->name; knew++) {
749 struct snd_kcontrol *kctl;
750 kctl = snd_ctl_new1(knew, codec);
751 if (!kctl)
752 return -ENOMEM;
753 kctl->private_value = spec->beep_amp;
754 err = snd_hda_ctl_add(codec, 0, kctl);
755 if (err < 0)
756 return err;
759 #endif
761 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD);
762 return 0;
767 * Common callbacks
770 static int alc_init(struct hda_codec *codec)
772 struct alc_spec *spec = codec->spec;
774 if (spec->init_hook)
775 spec->init_hook(codec);
777 spec->gen.skip_verbs = 1; /* applied in below */
778 snd_hda_gen_init(codec);
779 alc_fix_pll(codec);
780 alc_auto_init_amp(codec, spec->init_amp);
781 snd_hda_apply_verbs(codec); /* apply verbs here after own init */
783 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
785 return 0;
788 static inline void alc_shutup(struct hda_codec *codec)
790 struct alc_spec *spec = codec->spec;
792 if (spec && spec->shutup)
793 spec->shutup(codec);
794 else
795 snd_hda_shutup_pins(codec);
798 static void alc_reboot_notify(struct hda_codec *codec)
800 struct alc_spec *spec = codec->spec;
802 if (spec && spec->reboot_notify)
803 spec->reboot_notify(codec);
804 else
805 alc_shutup(codec);
808 #define alc_free snd_hda_gen_free
810 #ifdef CONFIG_PM
811 static void alc_power_eapd(struct hda_codec *codec)
813 alc_auto_setup_eapd(codec, false);
816 static int alc_suspend(struct hda_codec *codec)
818 struct alc_spec *spec = codec->spec;
819 alc_shutup(codec);
820 if (spec && spec->power_hook)
821 spec->power_hook(codec);
822 return 0;
824 #endif
826 #ifdef CONFIG_PM
827 static int alc_resume(struct hda_codec *codec)
829 struct alc_spec *spec = codec->spec;
831 if (!spec->no_depop_delay)
832 msleep(150); /* to avoid pop noise */
833 codec->patch_ops.init(codec);
834 regcache_sync(codec->core.regmap);
835 hda_call_check_power_status(codec, 0x01);
836 return 0;
838 #endif
842 static const struct hda_codec_ops alc_patch_ops = {
843 .build_controls = alc_build_controls,
844 .build_pcms = snd_hda_gen_build_pcms,
845 .init = alc_init,
846 .free = alc_free,
847 .unsol_event = snd_hda_jack_unsol_event,
848 #ifdef CONFIG_PM
849 .resume = alc_resume,
850 .suspend = alc_suspend,
851 .check_power_status = snd_hda_gen_check_power_status,
852 #endif
853 .reboot_notify = alc_reboot_notify,
857 #define alc_codec_rename(codec, name) snd_hda_codec_set_name(codec, name)
860 * Rename codecs appropriately from COEF value or subvendor id
862 struct alc_codec_rename_table {
863 unsigned int vendor_id;
864 unsigned short coef_mask;
865 unsigned short coef_bits;
866 const char *name;
869 struct alc_codec_rename_pci_table {
870 unsigned int codec_vendor_id;
871 unsigned short pci_subvendor;
872 unsigned short pci_subdevice;
873 const char *name;
876 static struct alc_codec_rename_table rename_tbl[] = {
877 { 0x10ec0221, 0xf00f, 0x1003, "ALC231" },
878 { 0x10ec0269, 0xfff0, 0x3010, "ALC277" },
879 { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" },
880 { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" },
881 { 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" },
882 { 0x10ec0269, 0xffff, 0xa023, "ALC259" },
883 { 0x10ec0269, 0xffff, 0x6023, "ALC281X" },
884 { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" },
885 { 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" },
886 { 0x10ec0662, 0xffff, 0x4020, "ALC656" },
887 { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" },
888 { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" },
889 { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" },
890 { 0x10ec0899, 0x2000, 0x2000, "ALC899" },
891 { 0x10ec0892, 0xffff, 0x8020, "ALC661" },
892 { 0x10ec0892, 0xffff, 0x8011, "ALC661" },
893 { 0x10ec0892, 0xffff, 0x4011, "ALC656" },
894 { } /* terminator */
897 static struct alc_codec_rename_pci_table rename_pci_tbl[] = {
898 { 0x10ec0280, 0x1028, 0, "ALC3220" },
899 { 0x10ec0282, 0x1028, 0, "ALC3221" },
900 { 0x10ec0283, 0x1028, 0, "ALC3223" },
901 { 0x10ec0288, 0x1028, 0, "ALC3263" },
902 { 0x10ec0292, 0x1028, 0, "ALC3226" },
903 { 0x10ec0293, 0x1028, 0, "ALC3235" },
904 { 0x10ec0255, 0x1028, 0, "ALC3234" },
905 { 0x10ec0668, 0x1028, 0, "ALC3661" },
906 { 0x10ec0275, 0x1028, 0, "ALC3260" },
907 { 0x10ec0899, 0x1028, 0, "ALC3861" },
908 { 0x10ec0298, 0x1028, 0, "ALC3266" },
909 { 0x10ec0236, 0x1028, 0, "ALC3204" },
910 { 0x10ec0256, 0x1028, 0, "ALC3246" },
911 { 0x10ec0225, 0x1028, 0, "ALC3253" },
912 { 0x10ec0295, 0x1028, 0, "ALC3254" },
913 { 0x10ec0299, 0x1028, 0, "ALC3271" },
914 { 0x10ec0670, 0x1025, 0, "ALC669X" },
915 { 0x10ec0676, 0x1025, 0, "ALC679X" },
916 { 0x10ec0282, 0x1043, 0, "ALC3229" },
917 { 0x10ec0233, 0x1043, 0, "ALC3236" },
918 { 0x10ec0280, 0x103c, 0, "ALC3228" },
919 { 0x10ec0282, 0x103c, 0, "ALC3227" },
920 { 0x10ec0286, 0x103c, 0, "ALC3242" },
921 { 0x10ec0290, 0x103c, 0, "ALC3241" },
922 { 0x10ec0668, 0x103c, 0, "ALC3662" },
923 { 0x10ec0283, 0x17aa, 0, "ALC3239" },
924 { 0x10ec0292, 0x17aa, 0, "ALC3232" },
925 { } /* terminator */
928 static int alc_codec_rename_from_preset(struct hda_codec *codec)
930 const struct alc_codec_rename_table *p;
931 const struct alc_codec_rename_pci_table *q;
933 for (p = rename_tbl; p->vendor_id; p++) {
934 if (p->vendor_id != codec->core.vendor_id)
935 continue;
936 if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits)
937 return alc_codec_rename(codec, p->name);
940 if (!codec->bus->pci)
941 return 0;
942 for (q = rename_pci_tbl; q->codec_vendor_id; q++) {
943 if (q->codec_vendor_id != codec->core.vendor_id)
944 continue;
945 if (q->pci_subvendor != codec->bus->pci->subsystem_vendor)
946 continue;
947 if (!q->pci_subdevice ||
948 q->pci_subdevice == codec->bus->pci->subsystem_device)
949 return alc_codec_rename(codec, q->name);
952 return 0;
957 * Digital-beep handlers
959 #ifdef CONFIG_SND_HDA_INPUT_BEEP
960 #define set_beep_amp(spec, nid, idx, dir) \
961 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
963 static const struct snd_pci_quirk beep_white_list[] = {
964 SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1),
965 SND_PCI_QUIRK(0x1043, 0x115d, "ASUS", 1),
966 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
967 SND_PCI_QUIRK(0x1043, 0x8376, "EeePC", 1),
968 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
969 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
970 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
971 SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1),
972 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
973 /* blacklist -- no beep available */
974 SND_PCI_QUIRK(0x17aa, 0x309e, "Lenovo ThinkCentre M73", 0),
975 SND_PCI_QUIRK(0x17aa, 0x30a3, "Lenovo ThinkCentre M93", 0),
979 static inline int has_cdefine_beep(struct hda_codec *codec)
981 struct alc_spec *spec = codec->spec;
982 const struct snd_pci_quirk *q;
983 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
984 if (q)
985 return q->value;
986 return spec->cdefine.enable_pcbeep;
988 #else
989 #define set_beep_amp(spec, nid, idx, dir) /* NOP */
990 #define has_cdefine_beep(codec) 0
991 #endif
993 /* parse the BIOS configuration and set up the alc_spec */
994 /* return 1 if successful, 0 if the proper config is not found,
995 * or a negative error code
997 static int alc_parse_auto_config(struct hda_codec *codec,
998 const hda_nid_t *ignore_nids,
999 const hda_nid_t *ssid_nids)
1001 struct alc_spec *spec = codec->spec;
1002 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
1003 int err;
1005 err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids,
1006 spec->parse_flags);
1007 if (err < 0)
1008 return err;
1010 if (ssid_nids)
1011 alc_ssid_check(codec, ssid_nids);
1013 err = snd_hda_gen_parse_auto_config(codec, cfg);
1014 if (err < 0)
1015 return err;
1017 return 1;
1020 /* common preparation job for alc_spec */
1021 static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid)
1023 struct alc_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1024 int err;
1026 if (!spec)
1027 return -ENOMEM;
1028 codec->spec = spec;
1029 snd_hda_gen_spec_init(&spec->gen);
1030 spec->gen.mixer_nid = mixer_nid;
1031 spec->gen.own_eapd_ctl = 1;
1032 codec->single_adc_amp = 1;
1033 /* FIXME: do we need this for all Realtek codec models? */
1034 codec->spdif_status_reset = 1;
1035 codec->patch_ops = alc_patch_ops;
1037 err = alc_codec_rename_from_preset(codec);
1038 if (err < 0) {
1039 kfree(spec);
1040 return err;
1042 return 0;
1045 static int alc880_parse_auto_config(struct hda_codec *codec)
1047 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
1048 static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 };
1049 return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
1053 * ALC880 fix-ups
1055 enum {
1056 ALC880_FIXUP_GPIO1,
1057 ALC880_FIXUP_GPIO2,
1058 ALC880_FIXUP_MEDION_RIM,
1059 ALC880_FIXUP_LG,
1060 ALC880_FIXUP_LG_LW25,
1061 ALC880_FIXUP_W810,
1062 ALC880_FIXUP_EAPD_COEF,
1063 ALC880_FIXUP_TCL_S700,
1064 ALC880_FIXUP_VOL_KNOB,
1065 ALC880_FIXUP_FUJITSU,
1066 ALC880_FIXUP_F1734,
1067 ALC880_FIXUP_UNIWILL,
1068 ALC880_FIXUP_UNIWILL_DIG,
1069 ALC880_FIXUP_Z71V,
1070 ALC880_FIXUP_ASUS_W5A,
1071 ALC880_FIXUP_3ST_BASE,
1072 ALC880_FIXUP_3ST,
1073 ALC880_FIXUP_3ST_DIG,
1074 ALC880_FIXUP_5ST_BASE,
1075 ALC880_FIXUP_5ST,
1076 ALC880_FIXUP_5ST_DIG,
1077 ALC880_FIXUP_6ST_BASE,
1078 ALC880_FIXUP_6ST,
1079 ALC880_FIXUP_6ST_DIG,
1080 ALC880_FIXUP_6ST_AUTOMUTE,
1083 /* enable the volume-knob widget support on NID 0x21 */
1084 static void alc880_fixup_vol_knob(struct hda_codec *codec,
1085 const struct hda_fixup *fix, int action)
1087 if (action == HDA_FIXUP_ACT_PROBE)
1088 snd_hda_jack_detect_enable_callback(codec, 0x21,
1089 alc_update_knob_master);
1092 static const struct hda_fixup alc880_fixups[] = {
1093 [ALC880_FIXUP_GPIO1] = {
1094 .type = HDA_FIXUP_VERBS,
1095 .v.verbs = alc_gpio1_init_verbs,
1097 [ALC880_FIXUP_GPIO2] = {
1098 .type = HDA_FIXUP_VERBS,
1099 .v.verbs = alc_gpio2_init_verbs,
1101 [ALC880_FIXUP_MEDION_RIM] = {
1102 .type = HDA_FIXUP_VERBS,
1103 .v.verbs = (const struct hda_verb[]) {
1104 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1105 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1108 .chained = true,
1109 .chain_id = ALC880_FIXUP_GPIO2,
1111 [ALC880_FIXUP_LG] = {
1112 .type = HDA_FIXUP_PINS,
1113 .v.pins = (const struct hda_pintbl[]) {
1114 /* disable bogus unused pins */
1115 { 0x16, 0x411111f0 },
1116 { 0x18, 0x411111f0 },
1117 { 0x1a, 0x411111f0 },
1121 [ALC880_FIXUP_LG_LW25] = {
1122 .type = HDA_FIXUP_PINS,
1123 .v.pins = (const struct hda_pintbl[]) {
1124 { 0x1a, 0x0181344f }, /* line-in */
1125 { 0x1b, 0x0321403f }, /* headphone */
1129 [ALC880_FIXUP_W810] = {
1130 .type = HDA_FIXUP_PINS,
1131 .v.pins = (const struct hda_pintbl[]) {
1132 /* disable bogus unused pins */
1133 { 0x17, 0x411111f0 },
1136 .chained = true,
1137 .chain_id = ALC880_FIXUP_GPIO2,
1139 [ALC880_FIXUP_EAPD_COEF] = {
1140 .type = HDA_FIXUP_VERBS,
1141 .v.verbs = (const struct hda_verb[]) {
1142 /* change to EAPD mode */
1143 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1144 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1148 [ALC880_FIXUP_TCL_S700] = {
1149 .type = HDA_FIXUP_VERBS,
1150 .v.verbs = (const struct hda_verb[]) {
1151 /* change to EAPD mode */
1152 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1153 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
1156 .chained = true,
1157 .chain_id = ALC880_FIXUP_GPIO2,
1159 [ALC880_FIXUP_VOL_KNOB] = {
1160 .type = HDA_FIXUP_FUNC,
1161 .v.func = alc880_fixup_vol_knob,
1163 [ALC880_FIXUP_FUJITSU] = {
1164 /* override all pins as BIOS on old Amilo is broken */
1165 .type = HDA_FIXUP_PINS,
1166 .v.pins = (const struct hda_pintbl[]) {
1167 { 0x14, 0x0121401f }, /* HP */
1168 { 0x15, 0x99030120 }, /* speaker */
1169 { 0x16, 0x99030130 }, /* bass speaker */
1170 { 0x17, 0x411111f0 }, /* N/A */
1171 { 0x18, 0x411111f0 }, /* N/A */
1172 { 0x19, 0x01a19950 }, /* mic-in */
1173 { 0x1a, 0x411111f0 }, /* N/A */
1174 { 0x1b, 0x411111f0 }, /* N/A */
1175 { 0x1c, 0x411111f0 }, /* N/A */
1176 { 0x1d, 0x411111f0 }, /* N/A */
1177 { 0x1e, 0x01454140 }, /* SPDIF out */
1180 .chained = true,
1181 .chain_id = ALC880_FIXUP_VOL_KNOB,
1183 [ALC880_FIXUP_F1734] = {
1184 /* almost compatible with FUJITSU, but no bass and SPDIF */
1185 .type = HDA_FIXUP_PINS,
1186 .v.pins = (const struct hda_pintbl[]) {
1187 { 0x14, 0x0121401f }, /* HP */
1188 { 0x15, 0x99030120 }, /* speaker */
1189 { 0x16, 0x411111f0 }, /* N/A */
1190 { 0x17, 0x411111f0 }, /* N/A */
1191 { 0x18, 0x411111f0 }, /* N/A */
1192 { 0x19, 0x01a19950 }, /* mic-in */
1193 { 0x1a, 0x411111f0 }, /* N/A */
1194 { 0x1b, 0x411111f0 }, /* N/A */
1195 { 0x1c, 0x411111f0 }, /* N/A */
1196 { 0x1d, 0x411111f0 }, /* N/A */
1197 { 0x1e, 0x411111f0 }, /* N/A */
1200 .chained = true,
1201 .chain_id = ALC880_FIXUP_VOL_KNOB,
1203 [ALC880_FIXUP_UNIWILL] = {
1204 /* need to fix HP and speaker pins to be parsed correctly */
1205 .type = HDA_FIXUP_PINS,
1206 .v.pins = (const struct hda_pintbl[]) {
1207 { 0x14, 0x0121411f }, /* HP */
1208 { 0x15, 0x99030120 }, /* speaker */
1209 { 0x16, 0x99030130 }, /* bass speaker */
1213 [ALC880_FIXUP_UNIWILL_DIG] = {
1214 .type = HDA_FIXUP_PINS,
1215 .v.pins = (const struct hda_pintbl[]) {
1216 /* disable bogus unused pins */
1217 { 0x17, 0x411111f0 },
1218 { 0x19, 0x411111f0 },
1219 { 0x1b, 0x411111f0 },
1220 { 0x1f, 0x411111f0 },
1224 [ALC880_FIXUP_Z71V] = {
1225 .type = HDA_FIXUP_PINS,
1226 .v.pins = (const struct hda_pintbl[]) {
1227 /* set up the whole pins as BIOS is utterly broken */
1228 { 0x14, 0x99030120 }, /* speaker */
1229 { 0x15, 0x0121411f }, /* HP */
1230 { 0x16, 0x411111f0 }, /* N/A */
1231 { 0x17, 0x411111f0 }, /* N/A */
1232 { 0x18, 0x01a19950 }, /* mic-in */
1233 { 0x19, 0x411111f0 }, /* N/A */
1234 { 0x1a, 0x01813031 }, /* line-in */
1235 { 0x1b, 0x411111f0 }, /* N/A */
1236 { 0x1c, 0x411111f0 }, /* N/A */
1237 { 0x1d, 0x411111f0 }, /* N/A */
1238 { 0x1e, 0x0144111e }, /* SPDIF */
1242 [ALC880_FIXUP_ASUS_W5A] = {
1243 .type = HDA_FIXUP_PINS,
1244 .v.pins = (const struct hda_pintbl[]) {
1245 /* set up the whole pins as BIOS is utterly broken */
1246 { 0x14, 0x0121411f }, /* HP */
1247 { 0x15, 0x411111f0 }, /* N/A */
1248 { 0x16, 0x411111f0 }, /* N/A */
1249 { 0x17, 0x411111f0 }, /* N/A */
1250 { 0x18, 0x90a60160 }, /* mic */
1251 { 0x19, 0x411111f0 }, /* N/A */
1252 { 0x1a, 0x411111f0 }, /* N/A */
1253 { 0x1b, 0x411111f0 }, /* N/A */
1254 { 0x1c, 0x411111f0 }, /* N/A */
1255 { 0x1d, 0x411111f0 }, /* N/A */
1256 { 0x1e, 0xb743111e }, /* SPDIF out */
1259 .chained = true,
1260 .chain_id = ALC880_FIXUP_GPIO1,
1262 [ALC880_FIXUP_3ST_BASE] = {
1263 .type = HDA_FIXUP_PINS,
1264 .v.pins = (const struct hda_pintbl[]) {
1265 { 0x14, 0x01014010 }, /* line-out */
1266 { 0x15, 0x411111f0 }, /* N/A */
1267 { 0x16, 0x411111f0 }, /* N/A */
1268 { 0x17, 0x411111f0 }, /* N/A */
1269 { 0x18, 0x01a19c30 }, /* mic-in */
1270 { 0x19, 0x0121411f }, /* HP */
1271 { 0x1a, 0x01813031 }, /* line-in */
1272 { 0x1b, 0x02a19c40 }, /* front-mic */
1273 { 0x1c, 0x411111f0 }, /* N/A */
1274 { 0x1d, 0x411111f0 }, /* N/A */
1275 /* 0x1e is filled in below */
1276 { 0x1f, 0x411111f0 }, /* N/A */
1280 [ALC880_FIXUP_3ST] = {
1281 .type = HDA_FIXUP_PINS,
1282 .v.pins = (const struct hda_pintbl[]) {
1283 { 0x1e, 0x411111f0 }, /* N/A */
1286 .chained = true,
1287 .chain_id = ALC880_FIXUP_3ST_BASE,
1289 [ALC880_FIXUP_3ST_DIG] = {
1290 .type = HDA_FIXUP_PINS,
1291 .v.pins = (const struct hda_pintbl[]) {
1292 { 0x1e, 0x0144111e }, /* SPDIF */
1295 .chained = true,
1296 .chain_id = ALC880_FIXUP_3ST_BASE,
1298 [ALC880_FIXUP_5ST_BASE] = {
1299 .type = HDA_FIXUP_PINS,
1300 .v.pins = (const struct hda_pintbl[]) {
1301 { 0x14, 0x01014010 }, /* front */
1302 { 0x15, 0x411111f0 }, /* N/A */
1303 { 0x16, 0x01011411 }, /* CLFE */
1304 { 0x17, 0x01016412 }, /* surr */
1305 { 0x18, 0x01a19c30 }, /* mic-in */
1306 { 0x19, 0x0121411f }, /* HP */
1307 { 0x1a, 0x01813031 }, /* line-in */
1308 { 0x1b, 0x02a19c40 }, /* front-mic */
1309 { 0x1c, 0x411111f0 }, /* N/A */
1310 { 0x1d, 0x411111f0 }, /* N/A */
1311 /* 0x1e is filled in below */
1312 { 0x1f, 0x411111f0 }, /* N/A */
1316 [ALC880_FIXUP_5ST] = {
1317 .type = HDA_FIXUP_PINS,
1318 .v.pins = (const struct hda_pintbl[]) {
1319 { 0x1e, 0x411111f0 }, /* N/A */
1322 .chained = true,
1323 .chain_id = ALC880_FIXUP_5ST_BASE,
1325 [ALC880_FIXUP_5ST_DIG] = {
1326 .type = HDA_FIXUP_PINS,
1327 .v.pins = (const struct hda_pintbl[]) {
1328 { 0x1e, 0x0144111e }, /* SPDIF */
1331 .chained = true,
1332 .chain_id = ALC880_FIXUP_5ST_BASE,
1334 [ALC880_FIXUP_6ST_BASE] = {
1335 .type = HDA_FIXUP_PINS,
1336 .v.pins = (const struct hda_pintbl[]) {
1337 { 0x14, 0x01014010 }, /* front */
1338 { 0x15, 0x01016412 }, /* surr */
1339 { 0x16, 0x01011411 }, /* CLFE */
1340 { 0x17, 0x01012414 }, /* side */
1341 { 0x18, 0x01a19c30 }, /* mic-in */
1342 { 0x19, 0x02a19c40 }, /* front-mic */
1343 { 0x1a, 0x01813031 }, /* line-in */
1344 { 0x1b, 0x0121411f }, /* HP */
1345 { 0x1c, 0x411111f0 }, /* N/A */
1346 { 0x1d, 0x411111f0 }, /* N/A */
1347 /* 0x1e is filled in below */
1348 { 0x1f, 0x411111f0 }, /* N/A */
1352 [ALC880_FIXUP_6ST] = {
1353 .type = HDA_FIXUP_PINS,
1354 .v.pins = (const struct hda_pintbl[]) {
1355 { 0x1e, 0x411111f0 }, /* N/A */
1358 .chained = true,
1359 .chain_id = ALC880_FIXUP_6ST_BASE,
1361 [ALC880_FIXUP_6ST_DIG] = {
1362 .type = HDA_FIXUP_PINS,
1363 .v.pins = (const struct hda_pintbl[]) {
1364 { 0x1e, 0x0144111e }, /* SPDIF */
1367 .chained = true,
1368 .chain_id = ALC880_FIXUP_6ST_BASE,
1370 [ALC880_FIXUP_6ST_AUTOMUTE] = {
1371 .type = HDA_FIXUP_PINS,
1372 .v.pins = (const struct hda_pintbl[]) {
1373 { 0x1b, 0x0121401f }, /* HP with jack detect */
1376 .chained_before = true,
1377 .chain_id = ALC880_FIXUP_6ST_BASE,
1381 static const struct snd_pci_quirk alc880_fixup_tbl[] = {
1382 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810),
1383 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS W5A", ALC880_FIXUP_ASUS_W5A),
1384 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V),
1385 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1),
1386 SND_PCI_QUIRK(0x147b, 0x1045, "ABit AA8XE", ALC880_FIXUP_6ST_AUTOMUTE),
1387 SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2),
1388 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF),
1389 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG),
1390 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734),
1391 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL),
1392 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB),
1393 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810),
1394 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
1395 SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST_AUTOMUTE),
1396 SND_PCI_QUIRK(0x1734, 0x107c, "FSC Amilo M1437", ALC880_FIXUP_FUJITSU),
1397 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU),
1398 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734),
1399 SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU),
1400 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
1401 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
1402 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
1403 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_FIXUP_LG_LW25),
1404 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),
1406 /* Below is the copied entries from alc880_quirks.c.
1407 * It's not quite sure whether BIOS sets the correct pin-config table
1408 * on these machines, thus they are kept to be compatible with
1409 * the old static quirks. Once when it's confirmed to work without
1410 * these overrides, it'd be better to remove.
1412 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG),
1413 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST),
1414 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG),
1415 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG),
1416 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG),
1417 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG),
1418 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG),
1419 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST),
1420 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG),
1421 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST),
1422 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST),
1423 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST),
1424 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST),
1425 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST),
1426 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG),
1427 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG),
1428 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG),
1429 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG),
1430 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG),
1431 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG),
1432 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG),
1433 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */
1434 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG),
1435 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1436 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1437 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1438 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1439 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1440 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1441 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1442 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1443 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1444 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1445 /* default Intel */
1446 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST),
1447 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG),
1448 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG),
1452 static const struct hda_model_fixup alc880_fixup_models[] = {
1453 {.id = ALC880_FIXUP_3ST, .name = "3stack"},
1454 {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"},
1455 {.id = ALC880_FIXUP_5ST, .name = "5stack"},
1456 {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"},
1457 {.id = ALC880_FIXUP_6ST, .name = "6stack"},
1458 {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"},
1459 {.id = ALC880_FIXUP_6ST_AUTOMUTE, .name = "6stack-automute"},
1465 * OK, here we have finally the patch for ALC880
1467 static int patch_alc880(struct hda_codec *codec)
1469 struct alc_spec *spec;
1470 int err;
1472 err = alc_alloc_spec(codec, 0x0b);
1473 if (err < 0)
1474 return err;
1476 spec = codec->spec;
1477 spec->gen.need_dac_fix = 1;
1478 spec->gen.beep_nid = 0x01;
1480 codec->patch_ops.unsol_event = alc880_unsol_event;
1482 snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
1483 alc880_fixups);
1484 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
1486 /* automatic parse from the BIOS config */
1487 err = alc880_parse_auto_config(codec);
1488 if (err < 0)
1489 goto error;
1491 if (!spec->gen.no_analog)
1492 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1494 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
1496 return 0;
1498 error:
1499 alc_free(codec);
1500 return err;
1505 * ALC260 support
1507 static int alc260_parse_auto_config(struct hda_codec *codec)
1509 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
1510 static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 };
1511 return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
1515 * Pin config fixes
1517 enum {
1518 ALC260_FIXUP_HP_DC5750,
1519 ALC260_FIXUP_HP_PIN_0F,
1520 ALC260_FIXUP_COEF,
1521 ALC260_FIXUP_GPIO1,
1522 ALC260_FIXUP_GPIO1_TOGGLE,
1523 ALC260_FIXUP_REPLACER,
1524 ALC260_FIXUP_HP_B1900,
1525 ALC260_FIXUP_KN1,
1526 ALC260_FIXUP_FSC_S7020,
1527 ALC260_FIXUP_FSC_S7020_JWSE,
1528 ALC260_FIXUP_VAIO_PINS,
1531 static void alc260_gpio1_automute(struct hda_codec *codec)
1533 struct alc_spec *spec = codec->spec;
1534 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
1535 spec->gen.hp_jack_present);
1538 static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
1539 const struct hda_fixup *fix, int action)
1541 struct alc_spec *spec = codec->spec;
1542 if (action == HDA_FIXUP_ACT_PROBE) {
1543 /* although the machine has only one output pin, we need to
1544 * toggle GPIO1 according to the jack state
1546 spec->gen.automute_hook = alc260_gpio1_automute;
1547 spec->gen.detect_hp = 1;
1548 spec->gen.automute_speaker = 1;
1549 spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
1550 snd_hda_jack_detect_enable_callback(codec, 0x0f,
1551 snd_hda_gen_hp_automute);
1552 snd_hda_add_verbs(codec, alc_gpio1_init_verbs);
1556 static void alc260_fixup_kn1(struct hda_codec *codec,
1557 const struct hda_fixup *fix, int action)
1559 struct alc_spec *spec = codec->spec;
1560 static const struct hda_pintbl pincfgs[] = {
1561 { 0x0f, 0x02214000 }, /* HP/speaker */
1562 { 0x12, 0x90a60160 }, /* int mic */
1563 { 0x13, 0x02a19000 }, /* ext mic */
1564 { 0x18, 0x01446000 }, /* SPDIF out */
1565 /* disable bogus I/O pins */
1566 { 0x10, 0x411111f0 },
1567 { 0x11, 0x411111f0 },
1568 { 0x14, 0x411111f0 },
1569 { 0x15, 0x411111f0 },
1570 { 0x16, 0x411111f0 },
1571 { 0x17, 0x411111f0 },
1572 { 0x19, 0x411111f0 },
1576 switch (action) {
1577 case HDA_FIXUP_ACT_PRE_PROBE:
1578 snd_hda_apply_pincfgs(codec, pincfgs);
1579 break;
1580 case HDA_FIXUP_ACT_PROBE:
1581 spec->init_amp = ALC_INIT_NONE;
1582 break;
1586 static void alc260_fixup_fsc_s7020(struct hda_codec *codec,
1587 const struct hda_fixup *fix, int action)
1589 struct alc_spec *spec = codec->spec;
1590 if (action == HDA_FIXUP_ACT_PROBE)
1591 spec->init_amp = ALC_INIT_NONE;
1594 static void alc260_fixup_fsc_s7020_jwse(struct hda_codec *codec,
1595 const struct hda_fixup *fix, int action)
1597 struct alc_spec *spec = codec->spec;
1598 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1599 spec->gen.add_jack_modes = 1;
1600 spec->gen.hp_mic = 1;
1604 static const struct hda_fixup alc260_fixups[] = {
1605 [ALC260_FIXUP_HP_DC5750] = {
1606 .type = HDA_FIXUP_PINS,
1607 .v.pins = (const struct hda_pintbl[]) {
1608 { 0x11, 0x90130110 }, /* speaker */
1612 [ALC260_FIXUP_HP_PIN_0F] = {
1613 .type = HDA_FIXUP_PINS,
1614 .v.pins = (const struct hda_pintbl[]) {
1615 { 0x0f, 0x01214000 }, /* HP */
1619 [ALC260_FIXUP_COEF] = {
1620 .type = HDA_FIXUP_VERBS,
1621 .v.verbs = (const struct hda_verb[]) {
1622 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1623 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3040 },
1627 [ALC260_FIXUP_GPIO1] = {
1628 .type = HDA_FIXUP_VERBS,
1629 .v.verbs = alc_gpio1_init_verbs,
1631 [ALC260_FIXUP_GPIO1_TOGGLE] = {
1632 .type = HDA_FIXUP_FUNC,
1633 .v.func = alc260_fixup_gpio1_toggle,
1634 .chained = true,
1635 .chain_id = ALC260_FIXUP_HP_PIN_0F,
1637 [ALC260_FIXUP_REPLACER] = {
1638 .type = HDA_FIXUP_VERBS,
1639 .v.verbs = (const struct hda_verb[]) {
1640 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1641 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3050 },
1644 .chained = true,
1645 .chain_id = ALC260_FIXUP_GPIO1_TOGGLE,
1647 [ALC260_FIXUP_HP_B1900] = {
1648 .type = HDA_FIXUP_FUNC,
1649 .v.func = alc260_fixup_gpio1_toggle,
1650 .chained = true,
1651 .chain_id = ALC260_FIXUP_COEF,
1653 [ALC260_FIXUP_KN1] = {
1654 .type = HDA_FIXUP_FUNC,
1655 .v.func = alc260_fixup_kn1,
1657 [ALC260_FIXUP_FSC_S7020] = {
1658 .type = HDA_FIXUP_FUNC,
1659 .v.func = alc260_fixup_fsc_s7020,
1661 [ALC260_FIXUP_FSC_S7020_JWSE] = {
1662 .type = HDA_FIXUP_FUNC,
1663 .v.func = alc260_fixup_fsc_s7020_jwse,
1664 .chained = true,
1665 .chain_id = ALC260_FIXUP_FSC_S7020,
1667 [ALC260_FIXUP_VAIO_PINS] = {
1668 .type = HDA_FIXUP_PINS,
1669 .v.pins = (const struct hda_pintbl[]) {
1670 /* Pin configs are missing completely on some VAIOs */
1671 { 0x0f, 0x01211020 },
1672 { 0x10, 0x0001003f },
1673 { 0x11, 0x411111f0 },
1674 { 0x12, 0x01a15930 },
1675 { 0x13, 0x411111f0 },
1676 { 0x14, 0x411111f0 },
1677 { 0x15, 0x411111f0 },
1678 { 0x16, 0x411111f0 },
1679 { 0x17, 0x411111f0 },
1680 { 0x18, 0x411111f0 },
1681 { 0x19, 0x411111f0 },
1687 static const struct snd_pci_quirk alc260_fixup_tbl[] = {
1688 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1),
1689 SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
1690 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
1691 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
1692 SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
1693 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_FIXUP_VAIO_PINS),
1694 SND_PCI_QUIRK(0x104d, 0x81e2, "Sony VAIO TX", ALC260_FIXUP_HP_PIN_0F),
1695 SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020),
1696 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
1697 SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1),
1698 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
1699 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
1703 static const struct hda_model_fixup alc260_fixup_models[] = {
1704 {.id = ALC260_FIXUP_GPIO1, .name = "gpio1"},
1705 {.id = ALC260_FIXUP_COEF, .name = "coef"},
1706 {.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"},
1707 {.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"},
1713 static int patch_alc260(struct hda_codec *codec)
1715 struct alc_spec *spec;
1716 int err;
1718 err = alc_alloc_spec(codec, 0x07);
1719 if (err < 0)
1720 return err;
1722 spec = codec->spec;
1723 /* as quite a few machines require HP amp for speaker outputs,
1724 * it's easier to enable it unconditionally; even if it's unneeded,
1725 * it's almost harmless.
1727 spec->gen.prefer_hp_amp = 1;
1728 spec->gen.beep_nid = 0x01;
1730 spec->shutup = alc_eapd_shutup;
1732 snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl,
1733 alc260_fixups);
1734 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
1736 /* automatic parse from the BIOS config */
1737 err = alc260_parse_auto_config(codec);
1738 if (err < 0)
1739 goto error;
1741 if (!spec->gen.no_analog)
1742 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
1744 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
1746 return 0;
1748 error:
1749 alc_free(codec);
1750 return err;
1755 * ALC882/883/885/888/889 support
1757 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
1758 * configuration. Each pin widget can choose any input DACs and a mixer.
1759 * Each ADC is connected from a mixer of all inputs. This makes possible
1760 * 6-channel independent captures.
1762 * In addition, an independent DAC for the multi-playback (not used in this
1763 * driver yet).
1767 * Pin config fixes
1769 enum {
1770 ALC882_FIXUP_ABIT_AW9D_MAX,
1771 ALC882_FIXUP_LENOVO_Y530,
1772 ALC882_FIXUP_PB_M5210,
1773 ALC882_FIXUP_ACER_ASPIRE_7736,
1774 ALC882_FIXUP_ASUS_W90V,
1775 ALC889_FIXUP_CD,
1776 ALC889_FIXUP_FRONT_HP_NO_PRESENCE,
1777 ALC889_FIXUP_VAIO_TT,
1778 ALC888_FIXUP_EEE1601,
1779 ALC882_FIXUP_EAPD,
1780 ALC883_FIXUP_EAPD,
1781 ALC883_FIXUP_ACER_EAPD,
1782 ALC882_FIXUP_GPIO1,
1783 ALC882_FIXUP_GPIO2,
1784 ALC882_FIXUP_GPIO3,
1785 ALC889_FIXUP_COEF,
1786 ALC882_FIXUP_ASUS_W2JC,
1787 ALC882_FIXUP_ACER_ASPIRE_4930G,
1788 ALC882_FIXUP_ACER_ASPIRE_8930G,
1789 ALC882_FIXUP_ASPIRE_8930G_VERBS,
1790 ALC885_FIXUP_MACPRO_GPIO,
1791 ALC889_FIXUP_DAC_ROUTE,
1792 ALC889_FIXUP_MBP_VREF,
1793 ALC889_FIXUP_IMAC91_VREF,
1794 ALC889_FIXUP_MBA11_VREF,
1795 ALC889_FIXUP_MBA21_VREF,
1796 ALC889_FIXUP_MP11_VREF,
1797 ALC889_FIXUP_MP41_VREF,
1798 ALC882_FIXUP_INV_DMIC,
1799 ALC882_FIXUP_NO_PRIMARY_HP,
1800 ALC887_FIXUP_ASUS_BASS,
1801 ALC887_FIXUP_BASS_CHMAP,
1804 static void alc889_fixup_coef(struct hda_codec *codec,
1805 const struct hda_fixup *fix, int action)
1807 if (action != HDA_FIXUP_ACT_INIT)
1808 return;
1809 alc_update_coef_idx(codec, 7, 0, 0x2030);
1812 /* toggle speaker-output according to the hp-jack state */
1813 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
1815 unsigned int gpiostate, gpiomask, gpiodir;
1817 gpiostate = snd_hda_codec_read(codec, codec->core.afg, 0,
1818 AC_VERB_GET_GPIO_DATA, 0);
1820 if (!muted)
1821 gpiostate |= (1 << pin);
1822 else
1823 gpiostate &= ~(1 << pin);
1825 gpiomask = snd_hda_codec_read(codec, codec->core.afg, 0,
1826 AC_VERB_GET_GPIO_MASK, 0);
1827 gpiomask |= (1 << pin);
1829 gpiodir = snd_hda_codec_read(codec, codec->core.afg, 0,
1830 AC_VERB_GET_GPIO_DIRECTION, 0);
1831 gpiodir |= (1 << pin);
1834 snd_hda_codec_write(codec, codec->core.afg, 0,
1835 AC_VERB_SET_GPIO_MASK, gpiomask);
1836 snd_hda_codec_write(codec, codec->core.afg, 0,
1837 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
1839 msleep(1);
1841 snd_hda_codec_write(codec, codec->core.afg, 0,
1842 AC_VERB_SET_GPIO_DATA, gpiostate);
1845 /* set up GPIO at initialization */
1846 static void alc885_fixup_macpro_gpio(struct hda_codec *codec,
1847 const struct hda_fixup *fix, int action)
1849 if (action != HDA_FIXUP_ACT_INIT)
1850 return;
1851 alc882_gpio_mute(codec, 0, 0);
1852 alc882_gpio_mute(codec, 1, 0);
1855 /* Fix the connection of some pins for ALC889:
1856 * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't
1857 * work correctly (bko#42740)
1859 static void alc889_fixup_dac_route(struct hda_codec *codec,
1860 const struct hda_fixup *fix, int action)
1862 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1863 /* fake the connections during parsing the tree */
1864 hda_nid_t conn1[2] = { 0x0c, 0x0d };
1865 hda_nid_t conn2[2] = { 0x0e, 0x0f };
1866 snd_hda_override_conn_list(codec, 0x14, 2, conn1);
1867 snd_hda_override_conn_list(codec, 0x15, 2, conn1);
1868 snd_hda_override_conn_list(codec, 0x18, 2, conn2);
1869 snd_hda_override_conn_list(codec, 0x1a, 2, conn2);
1870 } else if (action == HDA_FIXUP_ACT_PROBE) {
1871 /* restore the connections */
1872 hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 };
1873 snd_hda_override_conn_list(codec, 0x14, 5, conn);
1874 snd_hda_override_conn_list(codec, 0x15, 5, conn);
1875 snd_hda_override_conn_list(codec, 0x18, 5, conn);
1876 snd_hda_override_conn_list(codec, 0x1a, 5, conn);
1880 /* Set VREF on HP pin */
1881 static void alc889_fixup_mbp_vref(struct hda_codec *codec,
1882 const struct hda_fixup *fix, int action)
1884 struct alc_spec *spec = codec->spec;
1885 static hda_nid_t nids[3] = { 0x14, 0x15, 0x19 };
1886 int i;
1888 if (action != HDA_FIXUP_ACT_INIT)
1889 return;
1890 for (i = 0; i < ARRAY_SIZE(nids); i++) {
1891 unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]);
1892 if (get_defcfg_device(val) != AC_JACK_HP_OUT)
1893 continue;
1894 val = snd_hda_codec_get_pin_target(codec, nids[i]);
1895 val |= AC_PINCTL_VREF_80;
1896 snd_hda_set_pin_ctl(codec, nids[i], val);
1897 spec->gen.keep_vref_in_automute = 1;
1898 break;
1902 static void alc889_fixup_mac_pins(struct hda_codec *codec,
1903 const hda_nid_t *nids, int num_nids)
1905 struct alc_spec *spec = codec->spec;
1906 int i;
1908 for (i = 0; i < num_nids; i++) {
1909 unsigned int val;
1910 val = snd_hda_codec_get_pin_target(codec, nids[i]);
1911 val |= AC_PINCTL_VREF_50;
1912 snd_hda_set_pin_ctl(codec, nids[i], val);
1914 spec->gen.keep_vref_in_automute = 1;
1917 /* Set VREF on speaker pins on imac91 */
1918 static void alc889_fixup_imac91_vref(struct hda_codec *codec,
1919 const struct hda_fixup *fix, int action)
1921 static hda_nid_t nids[2] = { 0x18, 0x1a };
1923 if (action == HDA_FIXUP_ACT_INIT)
1924 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1927 /* Set VREF on speaker pins on mba11 */
1928 static void alc889_fixup_mba11_vref(struct hda_codec *codec,
1929 const struct hda_fixup *fix, int action)
1931 static hda_nid_t nids[1] = { 0x18 };
1933 if (action == HDA_FIXUP_ACT_INIT)
1934 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1937 /* Set VREF on speaker pins on mba21 */
1938 static void alc889_fixup_mba21_vref(struct hda_codec *codec,
1939 const struct hda_fixup *fix, int action)
1941 static hda_nid_t nids[2] = { 0x18, 0x19 };
1943 if (action == HDA_FIXUP_ACT_INIT)
1944 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1947 /* Don't take HP output as primary
1948 * Strangely, the speaker output doesn't work on Vaio Z and some Vaio
1949 * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05
1951 static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
1952 const struct hda_fixup *fix, int action)
1954 struct alc_spec *spec = codec->spec;
1955 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1956 spec->gen.no_primary_hp = 1;
1957 spec->gen.no_multi_io = 1;
1961 static void alc_fixup_bass_chmap(struct hda_codec *codec,
1962 const struct hda_fixup *fix, int action);
1964 static const struct hda_fixup alc882_fixups[] = {
1965 [ALC882_FIXUP_ABIT_AW9D_MAX] = {
1966 .type = HDA_FIXUP_PINS,
1967 .v.pins = (const struct hda_pintbl[]) {
1968 { 0x15, 0x01080104 }, /* side */
1969 { 0x16, 0x01011012 }, /* rear */
1970 { 0x17, 0x01016011 }, /* clfe */
1974 [ALC882_FIXUP_LENOVO_Y530] = {
1975 .type = HDA_FIXUP_PINS,
1976 .v.pins = (const struct hda_pintbl[]) {
1977 { 0x15, 0x99130112 }, /* rear int speakers */
1978 { 0x16, 0x99130111 }, /* subwoofer */
1982 [ALC882_FIXUP_PB_M5210] = {
1983 .type = HDA_FIXUP_PINCTLS,
1984 .v.pins = (const struct hda_pintbl[]) {
1985 { 0x19, PIN_VREF50 },
1989 [ALC882_FIXUP_ACER_ASPIRE_7736] = {
1990 .type = HDA_FIXUP_FUNC,
1991 .v.func = alc_fixup_sku_ignore,
1993 [ALC882_FIXUP_ASUS_W90V] = {
1994 .type = HDA_FIXUP_PINS,
1995 .v.pins = (const struct hda_pintbl[]) {
1996 { 0x16, 0x99130110 }, /* fix sequence for CLFE */
2000 [ALC889_FIXUP_CD] = {
2001 .type = HDA_FIXUP_PINS,
2002 .v.pins = (const struct hda_pintbl[]) {
2003 { 0x1c, 0x993301f0 }, /* CD */
2007 [ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = {
2008 .type = HDA_FIXUP_PINS,
2009 .v.pins = (const struct hda_pintbl[]) {
2010 { 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */
2013 .chained = true,
2014 .chain_id = ALC889_FIXUP_CD,
2016 [ALC889_FIXUP_VAIO_TT] = {
2017 .type = HDA_FIXUP_PINS,
2018 .v.pins = (const struct hda_pintbl[]) {
2019 { 0x17, 0x90170111 }, /* hidden surround speaker */
2023 [ALC888_FIXUP_EEE1601] = {
2024 .type = HDA_FIXUP_VERBS,
2025 .v.verbs = (const struct hda_verb[]) {
2026 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2027 { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 },
2031 [ALC882_FIXUP_EAPD] = {
2032 .type = HDA_FIXUP_VERBS,
2033 .v.verbs = (const struct hda_verb[]) {
2034 /* change to EAPD mode */
2035 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2036 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
2040 [ALC883_FIXUP_EAPD] = {
2041 .type = HDA_FIXUP_VERBS,
2042 .v.verbs = (const struct hda_verb[]) {
2043 /* change to EAPD mode */
2044 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2045 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2049 [ALC883_FIXUP_ACER_EAPD] = {
2050 .type = HDA_FIXUP_VERBS,
2051 .v.verbs = (const struct hda_verb[]) {
2052 /* eanable EAPD on Acer laptops */
2053 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2054 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2058 [ALC882_FIXUP_GPIO1] = {
2059 .type = HDA_FIXUP_VERBS,
2060 .v.verbs = alc_gpio1_init_verbs,
2062 [ALC882_FIXUP_GPIO2] = {
2063 .type = HDA_FIXUP_VERBS,
2064 .v.verbs = alc_gpio2_init_verbs,
2066 [ALC882_FIXUP_GPIO3] = {
2067 .type = HDA_FIXUP_VERBS,
2068 .v.verbs = alc_gpio3_init_verbs,
2070 [ALC882_FIXUP_ASUS_W2JC] = {
2071 .type = HDA_FIXUP_VERBS,
2072 .v.verbs = alc_gpio1_init_verbs,
2073 .chained = true,
2074 .chain_id = ALC882_FIXUP_EAPD,
2076 [ALC889_FIXUP_COEF] = {
2077 .type = HDA_FIXUP_FUNC,
2078 .v.func = alc889_fixup_coef,
2080 [ALC882_FIXUP_ACER_ASPIRE_4930G] = {
2081 .type = HDA_FIXUP_PINS,
2082 .v.pins = (const struct hda_pintbl[]) {
2083 { 0x16, 0x99130111 }, /* CLFE speaker */
2084 { 0x17, 0x99130112 }, /* surround speaker */
2087 .chained = true,
2088 .chain_id = ALC882_FIXUP_GPIO1,
2090 [ALC882_FIXUP_ACER_ASPIRE_8930G] = {
2091 .type = HDA_FIXUP_PINS,
2092 .v.pins = (const struct hda_pintbl[]) {
2093 { 0x16, 0x99130111 }, /* CLFE speaker */
2094 { 0x1b, 0x99130112 }, /* surround speaker */
2097 .chained = true,
2098 .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS,
2100 [ALC882_FIXUP_ASPIRE_8930G_VERBS] = {
2101 /* additional init verbs for Acer Aspire 8930G */
2102 .type = HDA_FIXUP_VERBS,
2103 .v.verbs = (const struct hda_verb[]) {
2104 /* Enable all DACs */
2105 /* DAC DISABLE/MUTE 1? */
2106 /* setting bits 1-5 disables DAC nids 0x02-0x06
2107 * apparently. Init=0x38 */
2108 { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 },
2109 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2110 /* DAC DISABLE/MUTE 2? */
2111 /* some bit here disables the other DACs.
2112 * Init=0x4900 */
2113 { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 },
2114 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2115 /* DMIC fix
2116 * This laptop has a stereo digital microphone.
2117 * The mics are only 1cm apart which makes the stereo
2118 * useless. However, either the mic or the ALC889
2119 * makes the signal become a difference/sum signal
2120 * instead of standard stereo, which is annoying.
2121 * So instead we flip this bit which makes the
2122 * codec replicate the sum signal to both channels,
2123 * turning it into a normal mono mic.
2125 /* DMIC_CONTROL? Init value = 0x0001 */
2126 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2127 { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
2128 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2129 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2132 .chained = true,
2133 .chain_id = ALC882_FIXUP_GPIO1,
2135 [ALC885_FIXUP_MACPRO_GPIO] = {
2136 .type = HDA_FIXUP_FUNC,
2137 .v.func = alc885_fixup_macpro_gpio,
2139 [ALC889_FIXUP_DAC_ROUTE] = {
2140 .type = HDA_FIXUP_FUNC,
2141 .v.func = alc889_fixup_dac_route,
2143 [ALC889_FIXUP_MBP_VREF] = {
2144 .type = HDA_FIXUP_FUNC,
2145 .v.func = alc889_fixup_mbp_vref,
2146 .chained = true,
2147 .chain_id = ALC882_FIXUP_GPIO1,
2149 [ALC889_FIXUP_IMAC91_VREF] = {
2150 .type = HDA_FIXUP_FUNC,
2151 .v.func = alc889_fixup_imac91_vref,
2152 .chained = true,
2153 .chain_id = ALC882_FIXUP_GPIO1,
2155 [ALC889_FIXUP_MBA11_VREF] = {
2156 .type = HDA_FIXUP_FUNC,
2157 .v.func = alc889_fixup_mba11_vref,
2158 .chained = true,
2159 .chain_id = ALC889_FIXUP_MBP_VREF,
2161 [ALC889_FIXUP_MBA21_VREF] = {
2162 .type = HDA_FIXUP_FUNC,
2163 .v.func = alc889_fixup_mba21_vref,
2164 .chained = true,
2165 .chain_id = ALC889_FIXUP_MBP_VREF,
2167 [ALC889_FIXUP_MP11_VREF] = {
2168 .type = HDA_FIXUP_FUNC,
2169 .v.func = alc889_fixup_mba11_vref,
2170 .chained = true,
2171 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2173 [ALC889_FIXUP_MP41_VREF] = {
2174 .type = HDA_FIXUP_FUNC,
2175 .v.func = alc889_fixup_mbp_vref,
2176 .chained = true,
2177 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2179 [ALC882_FIXUP_INV_DMIC] = {
2180 .type = HDA_FIXUP_FUNC,
2181 .v.func = alc_fixup_inv_dmic,
2183 [ALC882_FIXUP_NO_PRIMARY_HP] = {
2184 .type = HDA_FIXUP_FUNC,
2185 .v.func = alc882_fixup_no_primary_hp,
2187 [ALC887_FIXUP_ASUS_BASS] = {
2188 .type = HDA_FIXUP_PINS,
2189 .v.pins = (const struct hda_pintbl[]) {
2190 {0x16, 0x99130130}, /* bass speaker */
2193 .chained = true,
2194 .chain_id = ALC887_FIXUP_BASS_CHMAP,
2196 [ALC887_FIXUP_BASS_CHMAP] = {
2197 .type = HDA_FIXUP_FUNC,
2198 .v.func = alc_fixup_bass_chmap,
2202 static const struct snd_pci_quirk alc882_fixup_tbl[] = {
2203 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD),
2204 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2205 SND_PCI_QUIRK(0x1025, 0x0107, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2206 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD),
2207 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2208 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD),
2209 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD),
2210 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
2211 ALC882_FIXUP_ACER_ASPIRE_4930G),
2212 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
2213 ALC882_FIXUP_ACER_ASPIRE_4930G),
2214 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
2215 ALC882_FIXUP_ACER_ASPIRE_8930G),
2216 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
2217 ALC882_FIXUP_ACER_ASPIRE_8930G),
2218 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
2219 ALC882_FIXUP_ACER_ASPIRE_4930G),
2220 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
2221 ALC882_FIXUP_ACER_ASPIRE_4930G),
2222 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
2223 ALC882_FIXUP_ACER_ASPIRE_4930G),
2224 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
2225 SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G",
2226 ALC882_FIXUP_ACER_ASPIRE_4930G),
2227 SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
2228 SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G),
2229 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
2230 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
2231 SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
2232 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC),
2233 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
2234 SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS),
2235 SND_PCI_QUIRK(0x1043, 0x8691, "ASUS ROG Ranger VIII", ALC882_FIXUP_GPIO3),
2236 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
2237 SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
2238 SND_PCI_QUIRK(0x104d, 0x9060, "Sony Vaio VPCL14M1R", ALC882_FIXUP_NO_PRIMARY_HP),
2239 SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
2240 SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP),
2242 /* All Apple entries are in codec SSIDs */
2243 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
2244 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
2245 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
2246 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF),
2247 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
2248 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
2249 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
2250 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
2251 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
2252 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF),
2253 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF),
2254 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
2255 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
2256 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
2257 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
2258 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
2259 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
2260 SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 4,1/5,1", ALC889_FIXUP_MP41_VREF),
2261 SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF),
2262 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
2263 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
2264 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_MBA11_VREF),
2266 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
2267 SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
2268 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
2269 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
2270 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
2271 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
2272 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
2273 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
2274 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF),
2278 static const struct hda_model_fixup alc882_fixup_models[] = {
2279 {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"},
2280 {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
2281 {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
2282 {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"},
2283 {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"},
2288 * BIOS auto configuration
2290 /* almost identical with ALC880 parser... */
2291 static int alc882_parse_auto_config(struct hda_codec *codec)
2293 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
2294 static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2295 return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids);
2300 static int patch_alc882(struct hda_codec *codec)
2302 struct alc_spec *spec;
2303 int err;
2305 err = alc_alloc_spec(codec, 0x0b);
2306 if (err < 0)
2307 return err;
2309 spec = codec->spec;
2311 switch (codec->core.vendor_id) {
2312 case 0x10ec0882:
2313 case 0x10ec0885:
2314 case 0x10ec0900:
2315 break;
2316 default:
2317 /* ALC883 and variants */
2318 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2319 break;
2322 snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl,
2323 alc882_fixups);
2324 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
2326 alc_auto_parse_customize_define(codec);
2328 if (has_cdefine_beep(codec))
2329 spec->gen.beep_nid = 0x01;
2331 /* automatic parse from the BIOS config */
2332 err = alc882_parse_auto_config(codec);
2333 if (err < 0)
2334 goto error;
2336 if (!spec->gen.no_analog && spec->gen.beep_nid)
2337 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2339 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
2341 return 0;
2343 error:
2344 alc_free(codec);
2345 return err;
2350 * ALC262 support
2352 static int alc262_parse_auto_config(struct hda_codec *codec)
2354 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
2355 static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2356 return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids);
2360 * Pin config fixes
2362 enum {
2363 ALC262_FIXUP_FSC_H270,
2364 ALC262_FIXUP_FSC_S7110,
2365 ALC262_FIXUP_HP_Z200,
2366 ALC262_FIXUP_TYAN,
2367 ALC262_FIXUP_LENOVO_3000,
2368 ALC262_FIXUP_BENQ,
2369 ALC262_FIXUP_BENQ_T31,
2370 ALC262_FIXUP_INV_DMIC,
2371 ALC262_FIXUP_INTEL_BAYLEYBAY,
2374 static const struct hda_fixup alc262_fixups[] = {
2375 [ALC262_FIXUP_FSC_H270] = {
2376 .type = HDA_FIXUP_PINS,
2377 .v.pins = (const struct hda_pintbl[]) {
2378 { 0x14, 0x99130110 }, /* speaker */
2379 { 0x15, 0x0221142f }, /* front HP */
2380 { 0x1b, 0x0121141f }, /* rear HP */
2384 [ALC262_FIXUP_FSC_S7110] = {
2385 .type = HDA_FIXUP_PINS,
2386 .v.pins = (const struct hda_pintbl[]) {
2387 { 0x15, 0x90170110 }, /* speaker */
2390 .chained = true,
2391 .chain_id = ALC262_FIXUP_BENQ,
2393 [ALC262_FIXUP_HP_Z200] = {
2394 .type = HDA_FIXUP_PINS,
2395 .v.pins = (const struct hda_pintbl[]) {
2396 { 0x16, 0x99130120 }, /* internal speaker */
2400 [ALC262_FIXUP_TYAN] = {
2401 .type = HDA_FIXUP_PINS,
2402 .v.pins = (const struct hda_pintbl[]) {
2403 { 0x14, 0x1993e1f0 }, /* int AUX */
2407 [ALC262_FIXUP_LENOVO_3000] = {
2408 .type = HDA_FIXUP_PINCTLS,
2409 .v.pins = (const struct hda_pintbl[]) {
2410 { 0x19, PIN_VREF50 },
2413 .chained = true,
2414 .chain_id = ALC262_FIXUP_BENQ,
2416 [ALC262_FIXUP_BENQ] = {
2417 .type = HDA_FIXUP_VERBS,
2418 .v.verbs = (const struct hda_verb[]) {
2419 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2420 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2424 [ALC262_FIXUP_BENQ_T31] = {
2425 .type = HDA_FIXUP_VERBS,
2426 .v.verbs = (const struct hda_verb[]) {
2427 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2428 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2432 [ALC262_FIXUP_INV_DMIC] = {
2433 .type = HDA_FIXUP_FUNC,
2434 .v.func = alc_fixup_inv_dmic,
2436 [ALC262_FIXUP_INTEL_BAYLEYBAY] = {
2437 .type = HDA_FIXUP_FUNC,
2438 .v.func = alc_fixup_no_depop_delay,
2442 static const struct snd_pci_quirk alc262_fixup_tbl[] = {
2443 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200),
2444 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110),
2445 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
2446 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN),
2447 SND_PCI_QUIRK(0x1734, 0x1141, "FSC ESPRIMO U9210", ALC262_FIXUP_FSC_H270),
2448 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
2449 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
2450 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
2451 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31),
2452 SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY),
2456 static const struct hda_model_fixup alc262_fixup_models[] = {
2457 {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"},
2463 static int patch_alc262(struct hda_codec *codec)
2465 struct alc_spec *spec;
2466 int err;
2468 err = alc_alloc_spec(codec, 0x0b);
2469 if (err < 0)
2470 return err;
2472 spec = codec->spec;
2473 spec->gen.shared_mic_vref_pin = 0x18;
2475 spec->shutup = alc_eapd_shutup;
2477 #if 0
2478 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
2479 * under-run
2481 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x80);
2482 #endif
2483 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2485 snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl,
2486 alc262_fixups);
2487 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
2489 alc_auto_parse_customize_define(codec);
2491 if (has_cdefine_beep(codec))
2492 spec->gen.beep_nid = 0x01;
2494 /* automatic parse from the BIOS config */
2495 err = alc262_parse_auto_config(codec);
2496 if (err < 0)
2497 goto error;
2499 if (!spec->gen.no_analog && spec->gen.beep_nid)
2500 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2502 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
2504 return 0;
2506 error:
2507 alc_free(codec);
2508 return err;
2512 * ALC268
2514 /* bind Beep switches of both NID 0x0f and 0x10 */
2515 static const struct hda_bind_ctls alc268_bind_beep_sw = {
2516 .ops = &snd_hda_bind_sw,
2517 .values = {
2518 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
2519 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
2524 static const struct snd_kcontrol_new alc268_beep_mixer[] = {
2525 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
2526 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
2530 /* set PCBEEP vol = 0, mute connections */
2531 static const struct hda_verb alc268_beep_init_verbs[] = {
2532 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2533 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2534 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2538 enum {
2539 ALC268_FIXUP_INV_DMIC,
2540 ALC268_FIXUP_HP_EAPD,
2541 ALC268_FIXUP_SPDIF,
2544 static const struct hda_fixup alc268_fixups[] = {
2545 [ALC268_FIXUP_INV_DMIC] = {
2546 .type = HDA_FIXUP_FUNC,
2547 .v.func = alc_fixup_inv_dmic,
2549 [ALC268_FIXUP_HP_EAPD] = {
2550 .type = HDA_FIXUP_VERBS,
2551 .v.verbs = (const struct hda_verb[]) {
2552 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0},
2556 [ALC268_FIXUP_SPDIF] = {
2557 .type = HDA_FIXUP_PINS,
2558 .v.pins = (const struct hda_pintbl[]) {
2559 { 0x1e, 0x014b1180 }, /* enable SPDIF out */
2565 static const struct hda_model_fixup alc268_fixup_models[] = {
2566 {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"},
2567 {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"},
2571 static const struct snd_pci_quirk alc268_fixup_tbl[] = {
2572 SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF),
2573 SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC),
2574 /* below is codec SSID since multiple Toshiba laptops have the
2575 * same PCI SSID 1179:ff00
2577 SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD),
2582 * BIOS auto configuration
2584 static int alc268_parse_auto_config(struct hda_codec *codec)
2586 static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2587 return alc_parse_auto_config(codec, NULL, alc268_ssids);
2592 static int patch_alc268(struct hda_codec *codec)
2594 struct alc_spec *spec;
2595 int err;
2597 /* ALC268 has no aa-loopback mixer */
2598 err = alc_alloc_spec(codec, 0);
2599 if (err < 0)
2600 return err;
2602 spec = codec->spec;
2603 spec->gen.beep_nid = 0x01;
2605 spec->shutup = alc_eapd_shutup;
2607 snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups);
2608 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
2610 /* automatic parse from the BIOS config */
2611 err = alc268_parse_auto_config(codec);
2612 if (err < 0)
2613 goto error;
2615 if (err > 0 && !spec->gen.no_analog &&
2616 spec->gen.autocfg.speaker_pins[0] != 0x1d) {
2617 add_mixer(spec, alc268_beep_mixer);
2618 snd_hda_add_verbs(codec, alc268_beep_init_verbs);
2619 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
2620 /* override the amp caps for beep generator */
2621 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
2622 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
2623 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
2624 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2625 (0 << AC_AMPCAP_MUTE_SHIFT));
2628 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
2630 return 0;
2632 error:
2633 alc_free(codec);
2634 return err;
2638 * ALC269
2641 static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
2642 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
2645 static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
2646 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
2649 /* different alc269-variants */
2650 enum {
2651 ALC269_TYPE_ALC269VA,
2652 ALC269_TYPE_ALC269VB,
2653 ALC269_TYPE_ALC269VC,
2654 ALC269_TYPE_ALC269VD,
2655 ALC269_TYPE_ALC280,
2656 ALC269_TYPE_ALC282,
2657 ALC269_TYPE_ALC283,
2658 ALC269_TYPE_ALC284,
2659 ALC269_TYPE_ALC285,
2660 ALC269_TYPE_ALC286,
2661 ALC269_TYPE_ALC298,
2662 ALC269_TYPE_ALC255,
2663 ALC269_TYPE_ALC256,
2664 ALC269_TYPE_ALC257,
2665 ALC269_TYPE_ALC225,
2666 ALC269_TYPE_ALC294,
2667 ALC269_TYPE_ALC700,
2671 * BIOS auto configuration
2673 static int alc269_parse_auto_config(struct hda_codec *codec)
2675 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
2676 static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 };
2677 static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2678 struct alc_spec *spec = codec->spec;
2679 const hda_nid_t *ssids;
2681 switch (spec->codec_variant) {
2682 case ALC269_TYPE_ALC269VA:
2683 case ALC269_TYPE_ALC269VC:
2684 case ALC269_TYPE_ALC280:
2685 case ALC269_TYPE_ALC284:
2686 case ALC269_TYPE_ALC285:
2687 ssids = alc269va_ssids;
2688 break;
2689 case ALC269_TYPE_ALC269VB:
2690 case ALC269_TYPE_ALC269VD:
2691 case ALC269_TYPE_ALC282:
2692 case ALC269_TYPE_ALC283:
2693 case ALC269_TYPE_ALC286:
2694 case ALC269_TYPE_ALC298:
2695 case ALC269_TYPE_ALC255:
2696 case ALC269_TYPE_ALC256:
2697 case ALC269_TYPE_ALC257:
2698 case ALC269_TYPE_ALC225:
2699 case ALC269_TYPE_ALC294:
2700 case ALC269_TYPE_ALC700:
2701 ssids = alc269_ssids;
2702 break;
2703 default:
2704 ssids = alc269_ssids;
2705 break;
2708 return alc_parse_auto_config(codec, alc269_ignore, ssids);
2711 static int find_ext_mic_pin(struct hda_codec *codec);
2713 static void alc286_shutup(struct hda_codec *codec)
2715 int i;
2716 int mic_pin = find_ext_mic_pin(codec);
2717 /* don't shut up pins when unloading the driver; otherwise it breaks
2718 * the default pin setup at the next load of the driver
2720 if (codec->bus->shutdown)
2721 return;
2722 for (i = 0; i < codec->init_pins.used; i++) {
2723 struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
2724 /* use read here for syncing after issuing each verb */
2725 if (pin->nid != mic_pin)
2726 snd_hda_codec_read(codec, pin->nid, 0,
2727 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
2729 codec->pins_shutup = 1;
2732 static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
2734 alc_update_coef_idx(codec, 0x04, 1 << 11, power_up ? (1 << 11) : 0);
2737 static void alc269_shutup(struct hda_codec *codec)
2739 struct alc_spec *spec = codec->spec;
2741 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
2742 alc269vb_toggle_power_output(codec, 0);
2743 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
2744 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
2745 msleep(150);
2747 snd_hda_shutup_pins(codec);
2750 static struct coef_fw alc282_coefs[] = {
2751 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
2752 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
2753 WRITE_COEF(0x07, 0x0200), /* DMIC control */
2754 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
2755 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
2756 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
2757 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
2758 WRITE_COEF(0x0e, 0x6e00), /* LDO1/2/3, DAC/ADC */
2759 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
2760 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
2761 WRITE_COEF(0x6f, 0x0), /* Class D test 4 */
2762 UPDATE_COEF(0x0c, 0xfe00, 0), /* IO power down directly */
2763 WRITE_COEF(0x34, 0xa0c0), /* ANC */
2764 UPDATE_COEF(0x16, 0x0008, 0), /* AGC MUX */
2765 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
2766 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
2767 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
2768 WRITE_COEF(0x63, 0x2902), /* PLL */
2769 WRITE_COEF(0x68, 0xa080), /* capless control 2 */
2770 WRITE_COEF(0x69, 0x3400), /* capless control 3 */
2771 WRITE_COEF(0x6a, 0x2f3e), /* capless control 4 */
2772 WRITE_COEF(0x6b, 0x0), /* capless control 5 */
2773 UPDATE_COEF(0x6d, 0x0fff, 0x0900), /* class D test 2 */
2774 WRITE_COEF(0x6e, 0x110a), /* class D test 3 */
2775 UPDATE_COEF(0x70, 0x00f8, 0x00d8), /* class D test 5 */
2776 WRITE_COEF(0x71, 0x0014), /* class D test 6 */
2777 WRITE_COEF(0x72, 0xc2ba), /* classD OCP */
2778 UPDATE_COEF(0x77, 0x0f80, 0), /* classD pure DC test */
2779 WRITE_COEF(0x6c, 0xfc06), /* Class D amp control */
2783 static void alc282_restore_default_value(struct hda_codec *codec)
2785 alc_process_coef_fw(codec, alc282_coefs);
2788 static void alc282_init(struct hda_codec *codec)
2790 struct alc_spec *spec = codec->spec;
2791 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2792 bool hp_pin_sense;
2793 int coef78;
2795 alc282_restore_default_value(codec);
2797 if (!hp_pin)
2798 return;
2799 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2800 coef78 = alc_read_coef_idx(codec, 0x78);
2802 /* Index 0x78 Direct Drive HP AMP LPM Control 1 */
2803 /* Headphone capless set to high power mode */
2804 alc_write_coef_idx(codec, 0x78, 0x9004);
2806 if (hp_pin_sense)
2807 msleep(2);
2809 snd_hda_codec_write(codec, hp_pin, 0,
2810 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2812 if (hp_pin_sense)
2813 msleep(85);
2815 snd_hda_codec_write(codec, hp_pin, 0,
2816 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2818 if (hp_pin_sense)
2819 msleep(100);
2821 /* Headphone capless set to normal mode */
2822 alc_write_coef_idx(codec, 0x78, coef78);
2825 static void alc282_shutup(struct hda_codec *codec)
2827 struct alc_spec *spec = codec->spec;
2828 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2829 bool hp_pin_sense;
2830 int coef78;
2832 if (!hp_pin) {
2833 alc269_shutup(codec);
2834 return;
2837 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2838 coef78 = alc_read_coef_idx(codec, 0x78);
2839 alc_write_coef_idx(codec, 0x78, 0x9004);
2841 if (hp_pin_sense)
2842 msleep(2);
2844 snd_hda_codec_write(codec, hp_pin, 0,
2845 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2847 if (hp_pin_sense)
2848 msleep(85);
2850 snd_hda_codec_write(codec, hp_pin, 0,
2851 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
2853 if (hp_pin_sense)
2854 msleep(100);
2856 alc_auto_setup_eapd(codec, false);
2857 snd_hda_shutup_pins(codec);
2858 alc_write_coef_idx(codec, 0x78, coef78);
2861 static struct coef_fw alc283_coefs[] = {
2862 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
2863 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
2864 WRITE_COEF(0x07, 0x0200), /* DMIC control */
2865 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
2866 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
2867 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
2868 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
2869 WRITE_COEF(0x0e, 0x6fc0), /* LDO1/2/3, DAC/ADC */
2870 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
2871 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
2872 WRITE_COEF(0x3a, 0x0), /* Class D test 4 */
2873 UPDATE_COEF(0x0c, 0xfe00, 0x0), /* IO power down directly */
2874 WRITE_COEF(0x22, 0xa0c0), /* ANC */
2875 UPDATE_COEFEX(0x53, 0x01, 0x000f, 0x0008), /* AGC MUX */
2876 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
2877 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
2878 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
2879 WRITE_COEF(0x2e, 0x2902), /* PLL */
2880 WRITE_COEF(0x33, 0xa080), /* capless control 2 */
2881 WRITE_COEF(0x34, 0x3400), /* capless control 3 */
2882 WRITE_COEF(0x35, 0x2f3e), /* capless control 4 */
2883 WRITE_COEF(0x36, 0x0), /* capless control 5 */
2884 UPDATE_COEF(0x38, 0x0fff, 0x0900), /* class D test 2 */
2885 WRITE_COEF(0x39, 0x110a), /* class D test 3 */
2886 UPDATE_COEF(0x3b, 0x00f8, 0x00d8), /* class D test 5 */
2887 WRITE_COEF(0x3c, 0x0014), /* class D test 6 */
2888 WRITE_COEF(0x3d, 0xc2ba), /* classD OCP */
2889 UPDATE_COEF(0x42, 0x0f80, 0x0), /* classD pure DC test */
2890 WRITE_COEF(0x49, 0x0), /* test mode */
2891 UPDATE_COEF(0x40, 0xf800, 0x9800), /* Class D DC enable */
2892 UPDATE_COEF(0x42, 0xf000, 0x2000), /* DC offset */
2893 WRITE_COEF(0x37, 0xfc06), /* Class D amp control */
2894 UPDATE_COEF(0x1b, 0x8000, 0), /* HP JD control */
2898 static void alc283_restore_default_value(struct hda_codec *codec)
2900 alc_process_coef_fw(codec, alc283_coefs);
2903 static void alc283_init(struct hda_codec *codec)
2905 struct alc_spec *spec = codec->spec;
2906 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2907 bool hp_pin_sense;
2909 if (!spec->gen.autocfg.hp_outs) {
2910 if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
2911 hp_pin = spec->gen.autocfg.line_out_pins[0];
2914 alc283_restore_default_value(codec);
2916 if (!hp_pin)
2917 return;
2919 msleep(30);
2920 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2922 /* Index 0x43 Direct Drive HP AMP LPM Control 1 */
2923 /* Headphone capless set to high power mode */
2924 alc_write_coef_idx(codec, 0x43, 0x9004);
2926 snd_hda_codec_write(codec, hp_pin, 0,
2927 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2929 if (hp_pin_sense)
2930 msleep(85);
2932 snd_hda_codec_write(codec, hp_pin, 0,
2933 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2935 if (hp_pin_sense)
2936 msleep(85);
2937 /* Index 0x46 Combo jack auto switch control 2 */
2938 /* 3k pull low control for Headset jack. */
2939 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
2940 /* Headphone capless set to normal mode */
2941 alc_write_coef_idx(codec, 0x43, 0x9614);
2944 static void alc283_shutup(struct hda_codec *codec)
2946 struct alc_spec *spec = codec->spec;
2947 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2948 bool hp_pin_sense;
2950 if (!spec->gen.autocfg.hp_outs) {
2951 if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
2952 hp_pin = spec->gen.autocfg.line_out_pins[0];
2955 if (!hp_pin) {
2956 alc269_shutup(codec);
2957 return;
2960 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2962 alc_write_coef_idx(codec, 0x43, 0x9004);
2964 /*depop hp during suspend*/
2965 alc_write_coef_idx(codec, 0x06, 0x2100);
2967 snd_hda_codec_write(codec, hp_pin, 0,
2968 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2970 if (hp_pin_sense)
2971 msleep(100);
2973 snd_hda_codec_write(codec, hp_pin, 0,
2974 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
2976 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
2978 if (hp_pin_sense)
2979 msleep(100);
2980 alc_auto_setup_eapd(codec, false);
2981 snd_hda_shutup_pins(codec);
2982 alc_write_coef_idx(codec, 0x43, 0x9614);
2985 static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg,
2986 unsigned int val)
2988 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
2989 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */
2990 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */
2993 static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg)
2995 unsigned int val;
2997 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
2998 val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
2999 & 0xffff;
3000 val |= snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3001 << 16;
3002 return val;
3005 static void alc5505_dsp_halt(struct hda_codec *codec)
3007 unsigned int val;
3009 alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */
3010 alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */
3011 alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */
3012 alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */
3013 alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */
3014 alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */
3015 alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */
3016 val = alc5505_coef_get(codec, 0x6220);
3017 alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */
3020 static void alc5505_dsp_back_from_halt(struct hda_codec *codec)
3022 alc5505_coef_set(codec, 0x61b8, 0x04133302);
3023 alc5505_coef_set(codec, 0x61b0, 0x00005b16);
3024 alc5505_coef_set(codec, 0x61b4, 0x040a2b02);
3025 alc5505_coef_set(codec, 0x6230, 0xf80d4011);
3026 alc5505_coef_set(codec, 0x6220, 0x2002010f);
3027 alc5505_coef_set(codec, 0x880c, 0x00000004);
3030 static void alc5505_dsp_init(struct hda_codec *codec)
3032 unsigned int val;
3034 alc5505_dsp_halt(codec);
3035 alc5505_dsp_back_from_halt(codec);
3036 alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */
3037 alc5505_coef_set(codec, 0x61b0, 0x5b16);
3038 alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */
3039 alc5505_coef_set(codec, 0x61b4, 0x04132b02);
3040 alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/
3041 alc5505_coef_set(codec, 0x61b8, 0x041f3302);
3042 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */
3043 alc5505_coef_set(codec, 0x61b8, 0x041b3302);
3044 alc5505_coef_set(codec, 0x61b8, 0x04173302);
3045 alc5505_coef_set(codec, 0x61b8, 0x04163302);
3046 alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */
3047 alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */
3048 alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */
3050 val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */
3051 if (val <= 3)
3052 alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */
3053 else
3054 alc5505_coef_set(codec, 0x6220, 0x6002018f);
3056 alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/
3057 alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */
3058 alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */
3059 alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */
3060 alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */
3061 alc5505_coef_set(codec, 0x880c, 0x00000003);
3062 alc5505_coef_set(codec, 0x880c, 0x00000010);
3064 #ifdef HALT_REALTEK_ALC5505
3065 alc5505_dsp_halt(codec);
3066 #endif
3069 #ifdef HALT_REALTEK_ALC5505
3070 #define alc5505_dsp_suspend(codec) /* NOP */
3071 #define alc5505_dsp_resume(codec) /* NOP */
3072 #else
3073 #define alc5505_dsp_suspend(codec) alc5505_dsp_halt(codec)
3074 #define alc5505_dsp_resume(codec) alc5505_dsp_back_from_halt(codec)
3075 #endif
3077 #ifdef CONFIG_PM
3078 static int alc269_suspend(struct hda_codec *codec)
3080 struct alc_spec *spec = codec->spec;
3082 if (spec->has_alc5505_dsp)
3083 alc5505_dsp_suspend(codec);
3084 return alc_suspend(codec);
3087 static int alc269_resume(struct hda_codec *codec)
3089 struct alc_spec *spec = codec->spec;
3091 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3092 alc269vb_toggle_power_output(codec, 0);
3093 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
3094 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
3095 msleep(150);
3098 codec->patch_ops.init(codec);
3100 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3101 alc269vb_toggle_power_output(codec, 1);
3102 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
3103 (alc_get_coef0(codec) & 0x00ff) == 0x017) {
3104 msleep(200);
3107 regcache_sync(codec->core.regmap);
3108 hda_call_check_power_status(codec, 0x01);
3110 /* on some machine, the BIOS will clear the codec gpio data when enter
3111 * suspend, and won't restore the data after resume, so we restore it
3112 * in the driver.
3114 if (spec->gpio_led)
3115 snd_hda_codec_write(codec, codec->core.afg, 0, AC_VERB_SET_GPIO_DATA,
3116 spec->gpio_led);
3118 if (spec->has_alc5505_dsp)
3119 alc5505_dsp_resume(codec);
3121 return 0;
3123 #endif /* CONFIG_PM */
3125 static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec,
3126 const struct hda_fixup *fix, int action)
3128 struct alc_spec *spec = codec->spec;
3130 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3131 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
3134 static void alc269_fixup_pincfg_U7x7_headset_mic(struct hda_codec *codec,
3135 const struct hda_fixup *fix,
3136 int action)
3138 unsigned int cfg_headphone = snd_hda_codec_get_pincfg(codec, 0x21);
3139 unsigned int cfg_headset_mic = snd_hda_codec_get_pincfg(codec, 0x19);
3141 if (cfg_headphone && cfg_headset_mic == 0x411111f0)
3142 snd_hda_codec_set_pincfg(codec, 0x19,
3143 (cfg_headphone & ~AC_DEFCFG_DEVICE) |
3144 (AC_JACK_MIC_IN << AC_DEFCFG_DEVICE_SHIFT));
3147 static void alc269_fixup_hweq(struct hda_codec *codec,
3148 const struct hda_fixup *fix, int action)
3150 if (action == HDA_FIXUP_ACT_INIT)
3151 alc_update_coef_idx(codec, 0x1e, 0, 0x80);
3154 static void alc269_fixup_headset_mic(struct hda_codec *codec,
3155 const struct hda_fixup *fix, int action)
3157 struct alc_spec *spec = codec->spec;
3159 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3160 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3163 static void alc271_fixup_dmic(struct hda_codec *codec,
3164 const struct hda_fixup *fix, int action)
3166 static const struct hda_verb verbs[] = {
3167 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
3168 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
3171 unsigned int cfg;
3173 if (strcmp(codec->core.chip_name, "ALC271X") &&
3174 strcmp(codec->core.chip_name, "ALC269VB"))
3175 return;
3176 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
3177 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
3178 snd_hda_sequence_write(codec, verbs);
3181 static void alc269_fixup_pcm_44k(struct hda_codec *codec,
3182 const struct hda_fixup *fix, int action)
3184 struct alc_spec *spec = codec->spec;
3186 if (action != HDA_FIXUP_ACT_PROBE)
3187 return;
3189 /* Due to a hardware problem on Lenovo Ideadpad, we need to
3190 * fix the sample rate of analog I/O to 44.1kHz
3192 spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback;
3193 spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture;
3196 static void alc269_fixup_stereo_dmic(struct hda_codec *codec,
3197 const struct hda_fixup *fix, int action)
3199 /* The digital-mic unit sends PDM (differential signal) instead of
3200 * the standard PCM, thus you can't record a valid mono stream as is.
3201 * Below is a workaround specific to ALC269 to control the dmic
3202 * signal source as mono.
3204 if (action == HDA_FIXUP_ACT_INIT)
3205 alc_update_coef_idx(codec, 0x07, 0, 0x80);
3208 static void alc269_quanta_automute(struct hda_codec *codec)
3210 snd_hda_gen_update_outputs(codec);
3212 alc_write_coef_idx(codec, 0x0c, 0x680);
3213 alc_write_coef_idx(codec, 0x0c, 0x480);
3216 static void alc269_fixup_quanta_mute(struct hda_codec *codec,
3217 const struct hda_fixup *fix, int action)
3219 struct alc_spec *spec = codec->spec;
3220 if (action != HDA_FIXUP_ACT_PROBE)
3221 return;
3222 spec->gen.automute_hook = alc269_quanta_automute;
3225 static void alc269_x101_hp_automute_hook(struct hda_codec *codec,
3226 struct hda_jack_callback *jack)
3228 struct alc_spec *spec = codec->spec;
3229 int vref;
3230 msleep(200);
3231 snd_hda_gen_hp_automute(codec, jack);
3233 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
3234 msleep(100);
3235 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3236 vref);
3237 msleep(500);
3238 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3239 vref);
3242 static void alc269_fixup_x101_headset_mic(struct hda_codec *codec,
3243 const struct hda_fixup *fix, int action)
3245 struct alc_spec *spec = codec->spec;
3246 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3247 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3248 spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook;
3253 /* update mute-LED according to the speaker mute state via mic VREF pin */
3254 static void alc269_fixup_mic_mute_hook(void *private_data, int enabled)
3256 struct hda_codec *codec = private_data;
3257 struct alc_spec *spec = codec->spec;
3258 unsigned int pinval;
3260 if (spec->mute_led_polarity)
3261 enabled = !enabled;
3262 pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid);
3263 pinval &= ~AC_PINCTL_VREFEN;
3264 pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80;
3265 if (spec->mute_led_nid) {
3266 /* temporarily power up/down for setting VREF */
3267 snd_hda_power_up_pm(codec);
3268 snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval);
3269 snd_hda_power_down_pm(codec);
3273 /* Make sure the led works even in runtime suspend */
3274 static unsigned int led_power_filter(struct hda_codec *codec,
3275 hda_nid_t nid,
3276 unsigned int power_state)
3278 struct alc_spec *spec = codec->spec;
3280 if (power_state != AC_PWRST_D3 || nid == 0 ||
3281 (nid != spec->mute_led_nid && nid != spec->cap_mute_led_nid))
3282 return power_state;
3284 /* Set pin ctl again, it might have just been set to 0 */
3285 snd_hda_set_pin_ctl(codec, nid,
3286 snd_hda_codec_get_pin_target(codec, nid));
3288 return snd_hda_gen_path_power_filter(codec, nid, power_state);
3291 static void alc269_fixup_hp_mute_led(struct hda_codec *codec,
3292 const struct hda_fixup *fix, int action)
3294 struct alc_spec *spec = codec->spec;
3295 const struct dmi_device *dev = NULL;
3297 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3298 return;
3300 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
3301 int pol, pin;
3302 if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2)
3303 continue;
3304 if (pin < 0x0a || pin >= 0x10)
3305 break;
3306 spec->mute_led_polarity = pol;
3307 spec->mute_led_nid = pin - 0x0a + 0x18;
3308 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3309 spec->gen.vmaster_mute_enum = 1;
3310 codec->power_filter = led_power_filter;
3311 codec_dbg(codec,
3312 "Detected mute LED for %x:%d\n", spec->mute_led_nid,
3313 spec->mute_led_polarity);
3314 break;
3318 static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec,
3319 const struct hda_fixup *fix, int action)
3321 struct alc_spec *spec = codec->spec;
3322 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3323 spec->mute_led_polarity = 0;
3324 spec->mute_led_nid = 0x18;
3325 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3326 spec->gen.vmaster_mute_enum = 1;
3327 codec->power_filter = led_power_filter;
3331 static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec,
3332 const struct hda_fixup *fix, int action)
3334 struct alc_spec *spec = codec->spec;
3335 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3336 spec->mute_led_polarity = 0;
3337 spec->mute_led_nid = 0x19;
3338 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3339 spec->gen.vmaster_mute_enum = 1;
3340 codec->power_filter = led_power_filter;
3344 /* update LED status via GPIO */
3345 static void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask,
3346 bool enabled)
3348 struct alc_spec *spec = codec->spec;
3349 unsigned int oldval = spec->gpio_led;
3351 if (spec->mute_led_polarity)
3352 enabled = !enabled;
3354 if (enabled)
3355 spec->gpio_led &= ~mask;
3356 else
3357 spec->gpio_led |= mask;
3358 if (spec->gpio_led != oldval)
3359 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
3360 spec->gpio_led);
3363 /* turn on/off mute LED via GPIO per vmaster hook */
3364 static void alc_fixup_gpio_mute_hook(void *private_data, int enabled)
3366 struct hda_codec *codec = private_data;
3367 struct alc_spec *spec = codec->spec;
3369 alc_update_gpio_led(codec, spec->gpio_mute_led_mask, enabled);
3372 /* turn on/off mic-mute LED via GPIO per capture hook */
3373 static void alc_fixup_gpio_mic_mute_hook(struct hda_codec *codec,
3374 struct snd_kcontrol *kcontrol,
3375 struct snd_ctl_elem_value *ucontrol)
3377 struct alc_spec *spec = codec->spec;
3379 if (ucontrol)
3380 alc_update_gpio_led(codec, spec->gpio_mic_led_mask,
3381 ucontrol->value.integer.value[0] ||
3382 ucontrol->value.integer.value[1]);
3385 static void alc269_fixup_hp_gpio_led(struct hda_codec *codec,
3386 const struct hda_fixup *fix, int action)
3388 struct alc_spec *spec = codec->spec;
3389 static const struct hda_verb gpio_init[] = {
3390 { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 },
3391 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 },
3395 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3396 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3397 spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook;
3398 spec->gpio_led = 0;
3399 spec->mute_led_polarity = 0;
3400 spec->gpio_mute_led_mask = 0x08;
3401 spec->gpio_mic_led_mask = 0x10;
3402 snd_hda_add_verbs(codec, gpio_init);
3406 static void alc286_fixup_hp_gpio_led(struct hda_codec *codec,
3407 const struct hda_fixup *fix, int action)
3409 struct alc_spec *spec = codec->spec;
3410 static const struct hda_verb gpio_init[] = {
3411 { 0x01, AC_VERB_SET_GPIO_MASK, 0x22 },
3412 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x22 },
3416 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3417 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3418 spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook;
3419 spec->gpio_led = 0;
3420 spec->mute_led_polarity = 0;
3421 spec->gpio_mute_led_mask = 0x02;
3422 spec->gpio_mic_led_mask = 0x20;
3423 snd_hda_add_verbs(codec, gpio_init);
3427 /* turn on/off mic-mute LED per capture hook */
3428 static void alc269_fixup_hp_cap_mic_mute_hook(struct hda_codec *codec,
3429 struct snd_kcontrol *kcontrol,
3430 struct snd_ctl_elem_value *ucontrol)
3432 struct alc_spec *spec = codec->spec;
3433 unsigned int pinval, enable, disable;
3435 pinval = snd_hda_codec_get_pin_target(codec, spec->cap_mute_led_nid);
3436 pinval &= ~AC_PINCTL_VREFEN;
3437 enable = pinval | AC_PINCTL_VREF_80;
3438 disable = pinval | AC_PINCTL_VREF_HIZ;
3440 if (!ucontrol)
3441 return;
3443 if (ucontrol->value.integer.value[0] ||
3444 ucontrol->value.integer.value[1])
3445 pinval = disable;
3446 else
3447 pinval = enable;
3449 if (spec->cap_mute_led_nid)
3450 snd_hda_set_pin_ctl_cache(codec, spec->cap_mute_led_nid, pinval);
3453 static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec,
3454 const struct hda_fixup *fix, int action)
3456 struct alc_spec *spec = codec->spec;
3457 static const struct hda_verb gpio_init[] = {
3458 { 0x01, AC_VERB_SET_GPIO_MASK, 0x08 },
3459 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x08 },
3463 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3464 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3465 spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook;
3466 spec->gpio_led = 0;
3467 spec->mute_led_polarity = 0;
3468 spec->gpio_mute_led_mask = 0x08;
3469 spec->cap_mute_led_nid = 0x18;
3470 snd_hda_add_verbs(codec, gpio_init);
3471 codec->power_filter = led_power_filter;
3475 static void alc280_fixup_hp_gpio4(struct hda_codec *codec,
3476 const struct hda_fixup *fix, int action)
3478 /* Like hp_gpio_mic1_led, but also needs GPIO4 low to enable headphone amp */
3479 struct alc_spec *spec = codec->spec;
3480 static const struct hda_verb gpio_init[] = {
3481 { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 },
3482 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 },
3486 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3487 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3488 spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook;
3489 spec->gpio_led = 0;
3490 spec->mute_led_polarity = 0;
3491 spec->gpio_mute_led_mask = 0x08;
3492 spec->cap_mute_led_nid = 0x18;
3493 snd_hda_add_verbs(codec, gpio_init);
3494 codec->power_filter = led_power_filter;
3498 #if IS_REACHABLE(CONFIG_INPUT)
3499 static void gpio2_mic_hotkey_event(struct hda_codec *codec,
3500 struct hda_jack_callback *event)
3502 struct alc_spec *spec = codec->spec;
3504 /* GPIO2 just toggles on a keypress/keyrelease cycle. Therefore
3505 send both key on and key off event for every interrupt. */
3506 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 1);
3507 input_sync(spec->kb_dev);
3508 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 0);
3509 input_sync(spec->kb_dev);
3512 static int alc_register_micmute_input_device(struct hda_codec *codec)
3514 struct alc_spec *spec = codec->spec;
3515 int i;
3517 spec->kb_dev = input_allocate_device();
3518 if (!spec->kb_dev) {
3519 codec_err(codec, "Out of memory (input_allocate_device)\n");
3520 return -ENOMEM;
3523 spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX] = KEY_MICMUTE;
3525 spec->kb_dev->name = "Microphone Mute Button";
3526 spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY);
3527 spec->kb_dev->keycodesize = sizeof(spec->alc_mute_keycode_map[0]);
3528 spec->kb_dev->keycodemax = ARRAY_SIZE(spec->alc_mute_keycode_map);
3529 spec->kb_dev->keycode = spec->alc_mute_keycode_map;
3530 for (i = 0; i < ARRAY_SIZE(spec->alc_mute_keycode_map); i++)
3531 set_bit(spec->alc_mute_keycode_map[i], spec->kb_dev->keybit);
3533 if (input_register_device(spec->kb_dev)) {
3534 codec_err(codec, "input_register_device failed\n");
3535 input_free_device(spec->kb_dev);
3536 spec->kb_dev = NULL;
3537 return -ENOMEM;
3540 return 0;
3543 static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
3544 const struct hda_fixup *fix, int action)
3546 /* GPIO1 = set according to SKU external amp
3547 GPIO2 = mic mute hotkey
3548 GPIO3 = mute LED
3549 GPIO4 = mic mute LED */
3550 static const struct hda_verb gpio_init[] = {
3551 { 0x01, AC_VERB_SET_GPIO_MASK, 0x1e },
3552 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x1a },
3553 { 0x01, AC_VERB_SET_GPIO_DATA, 0x02 },
3557 struct alc_spec *spec = codec->spec;
3559 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3560 if (alc_register_micmute_input_device(codec) != 0)
3561 return;
3563 snd_hda_add_verbs(codec, gpio_init);
3564 snd_hda_codec_write_cache(codec, codec->core.afg, 0,
3565 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x04);
3566 snd_hda_jack_detect_enable_callback(codec, codec->core.afg,
3567 gpio2_mic_hotkey_event);
3569 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3570 spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook;
3571 spec->gpio_led = 0;
3572 spec->mute_led_polarity = 0;
3573 spec->gpio_mute_led_mask = 0x08;
3574 spec->gpio_mic_led_mask = 0x10;
3575 return;
3578 if (!spec->kb_dev)
3579 return;
3581 switch (action) {
3582 case HDA_FIXUP_ACT_PROBE:
3583 spec->init_amp = ALC_INIT_DEFAULT;
3584 break;
3585 case HDA_FIXUP_ACT_FREE:
3586 input_unregister_device(spec->kb_dev);
3587 spec->kb_dev = NULL;
3591 static void alc233_fixup_lenovo_line2_mic_hotkey(struct hda_codec *codec,
3592 const struct hda_fixup *fix, int action)
3594 /* Line2 = mic mute hotkey
3595 GPIO2 = mic mute LED */
3596 static const struct hda_verb gpio_init[] = {
3597 { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 },
3598 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 },
3602 struct alc_spec *spec = codec->spec;
3604 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3605 if (alc_register_micmute_input_device(codec) != 0)
3606 return;
3608 snd_hda_add_verbs(codec, gpio_init);
3609 snd_hda_jack_detect_enable_callback(codec, 0x1b,
3610 gpio2_mic_hotkey_event);
3612 spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook;
3613 spec->gpio_led = 0;
3614 spec->mute_led_polarity = 0;
3615 spec->gpio_mic_led_mask = 0x04;
3616 return;
3619 if (!spec->kb_dev)
3620 return;
3622 switch (action) {
3623 case HDA_FIXUP_ACT_PROBE:
3624 spec->init_amp = ALC_INIT_DEFAULT;
3625 break;
3626 case HDA_FIXUP_ACT_FREE:
3627 input_unregister_device(spec->kb_dev);
3628 spec->kb_dev = NULL;
3631 #else /* INPUT */
3632 #define alc280_fixup_hp_gpio2_mic_hotkey NULL
3633 #define alc233_fixup_lenovo_line2_mic_hotkey NULL
3634 #endif /* INPUT */
3636 static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
3637 const struct hda_fixup *fix, int action)
3639 struct alc_spec *spec = codec->spec;
3641 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3642 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3643 spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook;
3644 spec->mute_led_polarity = 0;
3645 spec->mute_led_nid = 0x1a;
3646 spec->cap_mute_led_nid = 0x18;
3647 spec->gen.vmaster_mute_enum = 1;
3648 codec->power_filter = led_power_filter;
3652 static void alc_headset_mode_unplugged(struct hda_codec *codec)
3654 static struct coef_fw coef0255[] = {
3655 WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
3656 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
3657 WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
3658 WRITE_COEFEX(0x57, 0x03, 0x8aa6), /* Direct Drive HP Amp control */
3661 static struct coef_fw coef0255_1[] = {
3662 WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
3665 static struct coef_fw coef0256[] = {
3666 WRITE_COEF(0x1b, 0x0c4b), /* LDO and MISC control */
3669 static struct coef_fw coef0233[] = {
3670 WRITE_COEF(0x1b, 0x0c0b),
3671 WRITE_COEF(0x45, 0xc429),
3672 UPDATE_COEF(0x35, 0x4000, 0),
3673 WRITE_COEF(0x06, 0x2104),
3674 WRITE_COEF(0x1a, 0x0001),
3675 WRITE_COEF(0x26, 0x0004),
3676 WRITE_COEF(0x32, 0x42a3),
3679 static struct coef_fw coef0288[] = {
3680 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
3681 UPDATE_COEF(0x50, 0x2000, 0x2000),
3682 UPDATE_COEF(0x56, 0x0006, 0x0006),
3683 UPDATE_COEF(0x66, 0x0008, 0),
3684 UPDATE_COEF(0x67, 0x2000, 0),
3687 static struct coef_fw coef0292[] = {
3688 WRITE_COEF(0x76, 0x000e),
3689 WRITE_COEF(0x6c, 0x2400),
3690 WRITE_COEF(0x18, 0x7308),
3691 WRITE_COEF(0x6b, 0xc429),
3694 static struct coef_fw coef0293[] = {
3695 UPDATE_COEF(0x10, 7<<8, 6<<8), /* SET Line1 JD to 0 */
3696 UPDATE_COEFEX(0x57, 0x05, 1<<15|1<<13, 0x0), /* SET charge pump by verb */
3697 UPDATE_COEFEX(0x57, 0x03, 1<<10, 1<<10), /* SET EN_OSW to 1 */
3698 UPDATE_COEF(0x1a, 1<<3, 1<<3), /* Combo JD gating with LINE1-VREFO */
3699 WRITE_COEF(0x45, 0xc429), /* Set to TRS type */
3700 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
3703 static struct coef_fw coef0668[] = {
3704 WRITE_COEF(0x15, 0x0d40),
3705 WRITE_COEF(0xb7, 0x802b),
3708 static struct coef_fw coef0225[] = {
3709 UPDATE_COEF(0x4a, 1<<8, 0),
3710 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0),
3711 UPDATE_COEF(0x63, 3<<14, 3<<14),
3712 UPDATE_COEF(0x4a, 3<<4, 2<<4),
3713 UPDATE_COEF(0x4a, 3<<10, 3<<10),
3714 UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
3715 UPDATE_COEF(0x4a, 3<<10, 0),
3719 switch (codec->core.vendor_id) {
3720 case 0x10ec0255:
3721 alc_process_coef_fw(codec, coef0255_1);
3722 alc_process_coef_fw(codec, coef0255);
3723 break;
3724 case 0x10ec0236:
3725 case 0x10ec0256:
3726 alc_process_coef_fw(codec, coef0256);
3727 alc_process_coef_fw(codec, coef0255);
3728 break;
3729 case 0x10ec0233:
3730 case 0x10ec0283:
3731 alc_process_coef_fw(codec, coef0233);
3732 break;
3733 case 0x10ec0286:
3734 case 0x10ec0288:
3735 case 0x10ec0298:
3736 alc_process_coef_fw(codec, coef0288);
3737 break;
3738 case 0x10ec0292:
3739 alc_process_coef_fw(codec, coef0292);
3740 break;
3741 case 0x10ec0293:
3742 alc_process_coef_fw(codec, coef0293);
3743 break;
3744 case 0x10ec0668:
3745 alc_process_coef_fw(codec, coef0668);
3746 break;
3747 case 0x10ec0225:
3748 case 0x10ec0295:
3749 case 0x10ec0299:
3750 alc_process_coef_fw(codec, coef0225);
3751 break;
3752 case 0x10ec0867:
3753 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
3754 break;
3756 codec_dbg(codec, "Headset jack set to unplugged mode.\n");
3760 static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
3761 hda_nid_t mic_pin)
3763 static struct coef_fw coef0255[] = {
3764 WRITE_COEFEX(0x57, 0x03, 0x8aa6),
3765 WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
3768 static struct coef_fw coef0233[] = {
3769 UPDATE_COEF(0x35, 0, 1<<14),
3770 WRITE_COEF(0x06, 0x2100),
3771 WRITE_COEF(0x1a, 0x0021),
3772 WRITE_COEF(0x26, 0x008c),
3775 static struct coef_fw coef0288[] = {
3776 UPDATE_COEF(0x50, 0x2000, 0),
3777 UPDATE_COEF(0x56, 0x0006, 0),
3778 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
3779 UPDATE_COEF(0x66, 0x0008, 0x0008),
3780 UPDATE_COEF(0x67, 0x2000, 0x2000),
3783 static struct coef_fw coef0292[] = {
3784 WRITE_COEF(0x19, 0xa208),
3785 WRITE_COEF(0x2e, 0xacf0),
3788 static struct coef_fw coef0293[] = {
3789 UPDATE_COEFEX(0x57, 0x05, 0, 1<<15|1<<13), /* SET charge pump by verb */
3790 UPDATE_COEFEX(0x57, 0x03, 1<<10, 0), /* SET EN_OSW to 0 */
3791 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
3794 static struct coef_fw coef0688[] = {
3795 WRITE_COEF(0xb7, 0x802b),
3796 WRITE_COEF(0xb5, 0x1040),
3797 UPDATE_COEF(0xc3, 0, 1<<12),
3800 static struct coef_fw coef0225[] = {
3801 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14),
3802 UPDATE_COEF(0x4a, 3<<4, 2<<4),
3803 UPDATE_COEF(0x63, 3<<14, 0),
3808 switch (codec->core.vendor_id) {
3809 case 0x10ec0236:
3810 case 0x10ec0255:
3811 case 0x10ec0256:
3812 alc_write_coef_idx(codec, 0x45, 0xc489);
3813 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3814 alc_process_coef_fw(codec, coef0255);
3815 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3816 break;
3817 case 0x10ec0233:
3818 case 0x10ec0283:
3819 alc_write_coef_idx(codec, 0x45, 0xc429);
3820 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3821 alc_process_coef_fw(codec, coef0233);
3822 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3823 break;
3824 case 0x10ec0286:
3825 case 0x10ec0288:
3826 case 0x10ec0298:
3827 alc_update_coef_idx(codec, 0x4f, 0x000c, 0);
3828 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3829 alc_process_coef_fw(codec, coef0288);
3830 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3831 break;
3832 case 0x10ec0292:
3833 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3834 alc_process_coef_fw(codec, coef0292);
3835 break;
3836 case 0x10ec0293:
3837 /* Set to TRS mode */
3838 alc_write_coef_idx(codec, 0x45, 0xc429);
3839 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3840 alc_process_coef_fw(codec, coef0293);
3841 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3842 break;
3843 case 0x10ec0867:
3844 alc_update_coefex_idx(codec, 0x57, 0x5, 0, 1<<14);
3845 /* fallthru */
3846 case 0x10ec0662:
3847 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3848 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3849 break;
3850 case 0x10ec0668:
3851 alc_write_coef_idx(codec, 0x11, 0x0001);
3852 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3853 alc_process_coef_fw(codec, coef0688);
3854 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3855 break;
3856 case 0x10ec0225:
3857 case 0x10ec0295:
3858 case 0x10ec0299:
3859 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10);
3860 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3861 alc_process_coef_fw(codec, coef0225);
3862 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3863 break;
3865 codec_dbg(codec, "Headset jack set to mic-in mode.\n");
3868 static void alc_headset_mode_default(struct hda_codec *codec)
3870 static struct coef_fw coef0225[] = {
3871 UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
3874 static struct coef_fw coef0255[] = {
3875 WRITE_COEF(0x45, 0xc089),
3876 WRITE_COEF(0x45, 0xc489),
3877 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
3878 WRITE_COEF(0x49, 0x0049),
3881 static struct coef_fw coef0233[] = {
3882 WRITE_COEF(0x06, 0x2100),
3883 WRITE_COEF(0x32, 0x4ea3),
3886 static struct coef_fw coef0288[] = {
3887 UPDATE_COEF(0x4f, 0xfcc0, 0xc400), /* Set to TRS type */
3888 UPDATE_COEF(0x50, 0x2000, 0x2000),
3889 UPDATE_COEF(0x56, 0x0006, 0x0006),
3890 UPDATE_COEF(0x66, 0x0008, 0),
3891 UPDATE_COEF(0x67, 0x2000, 0),
3894 static struct coef_fw coef0292[] = {
3895 WRITE_COEF(0x76, 0x000e),
3896 WRITE_COEF(0x6c, 0x2400),
3897 WRITE_COEF(0x6b, 0xc429),
3898 WRITE_COEF(0x18, 0x7308),
3901 static struct coef_fw coef0293[] = {
3902 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
3903 WRITE_COEF(0x45, 0xC429), /* Set to TRS type */
3904 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
3907 static struct coef_fw coef0688[] = {
3908 WRITE_COEF(0x11, 0x0041),
3909 WRITE_COEF(0x15, 0x0d40),
3910 WRITE_COEF(0xb7, 0x802b),
3914 switch (codec->core.vendor_id) {
3915 case 0x10ec0225:
3916 case 0x10ec0295:
3917 case 0x10ec0299:
3918 alc_process_coef_fw(codec, coef0225);
3919 break;
3920 case 0x10ec0236:
3921 case 0x10ec0255:
3922 case 0x10ec0256:
3923 alc_process_coef_fw(codec, coef0255);
3924 break;
3925 case 0x10ec0233:
3926 case 0x10ec0283:
3927 alc_process_coef_fw(codec, coef0233);
3928 break;
3929 case 0x10ec0286:
3930 case 0x10ec0288:
3931 case 0x10ec0298:
3932 alc_process_coef_fw(codec, coef0288);
3933 break;
3934 case 0x10ec0292:
3935 alc_process_coef_fw(codec, coef0292);
3936 break;
3937 case 0x10ec0293:
3938 alc_process_coef_fw(codec, coef0293);
3939 break;
3940 case 0x10ec0668:
3941 alc_process_coef_fw(codec, coef0688);
3942 break;
3943 case 0x10ec0867:
3944 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
3945 break;
3947 codec_dbg(codec, "Headset jack set to headphone (default) mode.\n");
3950 /* Iphone type */
3951 static void alc_headset_mode_ctia(struct hda_codec *codec)
3953 static struct coef_fw coef0255[] = {
3954 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
3955 WRITE_COEF(0x1b, 0x0c2b),
3956 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
3959 static struct coef_fw coef0256[] = {
3960 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
3961 WRITE_COEF(0x1b, 0x0c6b),
3962 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
3965 static struct coef_fw coef0233[] = {
3966 WRITE_COEF(0x45, 0xd429),
3967 WRITE_COEF(0x1b, 0x0c2b),
3968 WRITE_COEF(0x32, 0x4ea3),
3971 static struct coef_fw coef0288[] = {
3972 UPDATE_COEF(0x50, 0x2000, 0x2000),
3973 UPDATE_COEF(0x56, 0x0006, 0x0006),
3974 UPDATE_COEF(0x66, 0x0008, 0),
3975 UPDATE_COEF(0x67, 0x2000, 0),
3978 static struct coef_fw coef0292[] = {
3979 WRITE_COEF(0x6b, 0xd429),
3980 WRITE_COEF(0x76, 0x0008),
3981 WRITE_COEF(0x18, 0x7388),
3984 static struct coef_fw coef0293[] = {
3985 WRITE_COEF(0x45, 0xd429), /* Set to ctia type */
3986 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
3989 static struct coef_fw coef0688[] = {
3990 WRITE_COEF(0x11, 0x0001),
3991 WRITE_COEF(0x15, 0x0d60),
3992 WRITE_COEF(0xc3, 0x0000),
3995 static struct coef_fw coef0225[] = {
3996 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
3997 UPDATE_COEF(0x49, 1<<8, 1<<8),
3998 UPDATE_COEF(0x4a, 7<<6, 7<<6),
3999 UPDATE_COEF(0x4a, 3<<4, 3<<4),
4003 switch (codec->core.vendor_id) {
4004 case 0x10ec0255:
4005 alc_process_coef_fw(codec, coef0255);
4006 break;
4007 case 0x10ec0236:
4008 case 0x10ec0256:
4009 alc_process_coef_fw(codec, coef0256);
4010 break;
4011 case 0x10ec0233:
4012 case 0x10ec0283:
4013 alc_process_coef_fw(codec, coef0233);
4014 break;
4015 case 0x10ec0298:
4016 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);/* Headset output enable */
4017 /* ALC298 jack type setting is the same with ALC286/ALC288 */
4018 case 0x10ec0286:
4019 case 0x10ec0288:
4020 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4021 msleep(300);
4022 alc_process_coef_fw(codec, coef0288);
4023 break;
4024 case 0x10ec0292:
4025 alc_process_coef_fw(codec, coef0292);
4026 break;
4027 case 0x10ec0293:
4028 alc_process_coef_fw(codec, coef0293);
4029 break;
4030 case 0x10ec0668:
4031 alc_process_coef_fw(codec, coef0688);
4032 break;
4033 case 0x10ec0225:
4034 case 0x10ec0295:
4035 case 0x10ec0299:
4036 alc_process_coef_fw(codec, coef0225);
4037 break;
4038 case 0x10ec0867:
4039 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4040 break;
4042 codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n");
4045 /* Nokia type */
4046 static void alc_headset_mode_omtp(struct hda_codec *codec)
4048 static struct coef_fw coef0255[] = {
4049 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
4050 WRITE_COEF(0x1b, 0x0c2b),
4051 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4054 static struct coef_fw coef0256[] = {
4055 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
4056 WRITE_COEF(0x1b, 0x0c6b),
4057 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4060 static struct coef_fw coef0233[] = {
4061 WRITE_COEF(0x45, 0xe429),
4062 WRITE_COEF(0x1b, 0x0c2b),
4063 WRITE_COEF(0x32, 0x4ea3),
4066 static struct coef_fw coef0288[] = {
4067 UPDATE_COEF(0x50, 0x2000, 0x2000),
4068 UPDATE_COEF(0x56, 0x0006, 0x0006),
4069 UPDATE_COEF(0x66, 0x0008, 0),
4070 UPDATE_COEF(0x67, 0x2000, 0),
4073 static struct coef_fw coef0292[] = {
4074 WRITE_COEF(0x6b, 0xe429),
4075 WRITE_COEF(0x76, 0x0008),
4076 WRITE_COEF(0x18, 0x7388),
4079 static struct coef_fw coef0293[] = {
4080 WRITE_COEF(0x45, 0xe429), /* Set to omtp type */
4081 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
4084 static struct coef_fw coef0688[] = {
4085 WRITE_COEF(0x11, 0x0001),
4086 WRITE_COEF(0x15, 0x0d50),
4087 WRITE_COEF(0xc3, 0x0000),
4090 static struct coef_fw coef0225[] = {
4091 UPDATE_COEF(0x45, 0x3f<<10, 0x39<<10),
4092 UPDATE_COEF(0x49, 1<<8, 1<<8),
4093 UPDATE_COEF(0x4a, 7<<6, 7<<6),
4094 UPDATE_COEF(0x4a, 3<<4, 3<<4),
4098 switch (codec->core.vendor_id) {
4099 case 0x10ec0255:
4100 alc_process_coef_fw(codec, coef0255);
4101 break;
4102 case 0x10ec0236:
4103 case 0x10ec0256:
4104 alc_process_coef_fw(codec, coef0256);
4105 break;
4106 case 0x10ec0233:
4107 case 0x10ec0283:
4108 alc_process_coef_fw(codec, coef0233);
4109 break;
4110 case 0x10ec0298:
4111 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);/* Headset output enable */
4112 /* ALC298 jack type setting is the same with ALC286/ALC288 */
4113 case 0x10ec0286:
4114 case 0x10ec0288:
4115 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
4116 msleep(300);
4117 alc_process_coef_fw(codec, coef0288);
4118 break;
4119 case 0x10ec0292:
4120 alc_process_coef_fw(codec, coef0292);
4121 break;
4122 case 0x10ec0293:
4123 alc_process_coef_fw(codec, coef0293);
4124 break;
4125 case 0x10ec0668:
4126 alc_process_coef_fw(codec, coef0688);
4127 break;
4128 case 0x10ec0225:
4129 case 0x10ec0295:
4130 case 0x10ec0299:
4131 alc_process_coef_fw(codec, coef0225);
4132 break;
4134 codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n");
4137 static void alc_determine_headset_type(struct hda_codec *codec)
4139 int val;
4140 bool is_ctia = false;
4141 struct alc_spec *spec = codec->spec;
4142 static struct coef_fw coef0255[] = {
4143 WRITE_COEF(0x45, 0xd089), /* combo jack auto switch control(Check type)*/
4144 WRITE_COEF(0x49, 0x0149), /* combo jack auto switch control(Vref
4145 conteol) */
4148 static struct coef_fw coef0288[] = {
4149 UPDATE_COEF(0x4f, 0xfcc0, 0xd400), /* Check Type */
4152 static struct coef_fw coef0293[] = {
4153 UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */
4154 WRITE_COEF(0x45, 0xD429), /* Set to ctia type */
4157 static struct coef_fw coef0688[] = {
4158 WRITE_COEF(0x11, 0x0001),
4159 WRITE_COEF(0xb7, 0x802b),
4160 WRITE_COEF(0x15, 0x0d60),
4161 WRITE_COEF(0xc3, 0x0c00),
4164 static struct coef_fw coef0225[] = {
4165 UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
4166 UPDATE_COEF(0x49, 1<<8, 1<<8),
4170 switch (codec->core.vendor_id) {
4171 case 0x10ec0236:
4172 case 0x10ec0255:
4173 case 0x10ec0256:
4174 alc_process_coef_fw(codec, coef0255);
4175 msleep(300);
4176 val = alc_read_coef_idx(codec, 0x46);
4177 is_ctia = (val & 0x0070) == 0x0070;
4178 break;
4179 case 0x10ec0233:
4180 case 0x10ec0283:
4181 alc_write_coef_idx(codec, 0x45, 0xd029);
4182 msleep(300);
4183 val = alc_read_coef_idx(codec, 0x46);
4184 is_ctia = (val & 0x0070) == 0x0070;
4185 break;
4186 case 0x10ec0298:
4187 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020); /* Headset output enable */
4188 /* ALC298 check jack type is the same with ALC286/ALC288 */
4189 case 0x10ec0286:
4190 case 0x10ec0288:
4191 alc_process_coef_fw(codec, coef0288);
4192 msleep(350);
4193 val = alc_read_coef_idx(codec, 0x50);
4194 is_ctia = (val & 0x0070) == 0x0070;
4195 break;
4196 case 0x10ec0292:
4197 alc_write_coef_idx(codec, 0x6b, 0xd429);
4198 msleep(300);
4199 val = alc_read_coef_idx(codec, 0x6c);
4200 is_ctia = (val & 0x001c) == 0x001c;
4201 break;
4202 case 0x10ec0293:
4203 alc_process_coef_fw(codec, coef0293);
4204 msleep(300);
4205 val = alc_read_coef_idx(codec, 0x46);
4206 is_ctia = (val & 0x0070) == 0x0070;
4207 break;
4208 case 0x10ec0668:
4209 alc_process_coef_fw(codec, coef0688);
4210 msleep(300);
4211 val = alc_read_coef_idx(codec, 0xbe);
4212 is_ctia = (val & 0x1c02) == 0x1c02;
4213 break;
4214 case 0x10ec0225:
4215 case 0x10ec0295:
4216 case 0x10ec0299:
4217 alc_process_coef_fw(codec, coef0225);
4218 msleep(800);
4219 val = alc_read_coef_idx(codec, 0x46);
4220 is_ctia = (val & 0x00f0) == 0x00f0;
4221 break;
4222 case 0x10ec0867:
4223 is_ctia = true;
4224 break;
4227 codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n",
4228 is_ctia ? "yes" : "no");
4229 spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP;
4232 static void alc_update_headset_mode(struct hda_codec *codec)
4234 struct alc_spec *spec = codec->spec;
4236 hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]];
4237 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
4239 int new_headset_mode;
4241 if (!snd_hda_jack_detect(codec, hp_pin))
4242 new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED;
4243 else if (mux_pin == spec->headset_mic_pin)
4244 new_headset_mode = ALC_HEADSET_MODE_HEADSET;
4245 else if (mux_pin == spec->headphone_mic_pin)
4246 new_headset_mode = ALC_HEADSET_MODE_MIC;
4247 else
4248 new_headset_mode = ALC_HEADSET_MODE_HEADPHONE;
4250 if (new_headset_mode == spec->current_headset_mode) {
4251 snd_hda_gen_update_outputs(codec);
4252 return;
4255 switch (new_headset_mode) {
4256 case ALC_HEADSET_MODE_UNPLUGGED:
4257 alc_headset_mode_unplugged(codec);
4258 spec->gen.hp_jack_present = false;
4259 break;
4260 case ALC_HEADSET_MODE_HEADSET:
4261 if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN)
4262 alc_determine_headset_type(codec);
4263 if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA)
4264 alc_headset_mode_ctia(codec);
4265 else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP)
4266 alc_headset_mode_omtp(codec);
4267 spec->gen.hp_jack_present = true;
4268 break;
4269 case ALC_HEADSET_MODE_MIC:
4270 alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin);
4271 spec->gen.hp_jack_present = false;
4272 break;
4273 case ALC_HEADSET_MODE_HEADPHONE:
4274 alc_headset_mode_default(codec);
4275 spec->gen.hp_jack_present = true;
4276 break;
4278 if (new_headset_mode != ALC_HEADSET_MODE_MIC) {
4279 snd_hda_set_pin_ctl_cache(codec, hp_pin,
4280 AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
4281 if (spec->headphone_mic_pin && spec->headphone_mic_pin != hp_pin)
4282 snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin,
4283 PIN_VREFHIZ);
4285 spec->current_headset_mode = new_headset_mode;
4287 snd_hda_gen_update_outputs(codec);
4290 static void alc_update_headset_mode_hook(struct hda_codec *codec,
4291 struct snd_kcontrol *kcontrol,
4292 struct snd_ctl_elem_value *ucontrol)
4294 alc_update_headset_mode(codec);
4297 static void alc_update_headset_jack_cb(struct hda_codec *codec,
4298 struct hda_jack_callback *jack)
4300 struct alc_spec *spec = codec->spec;
4301 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
4302 snd_hda_gen_hp_automute(codec, jack);
4305 static void alc_probe_headset_mode(struct hda_codec *codec)
4307 int i;
4308 struct alc_spec *spec = codec->spec;
4309 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
4311 /* Find mic pins */
4312 for (i = 0; i < cfg->num_inputs; i++) {
4313 if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin)
4314 spec->headset_mic_pin = cfg->inputs[i].pin;
4315 if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin)
4316 spec->headphone_mic_pin = cfg->inputs[i].pin;
4319 spec->gen.cap_sync_hook = alc_update_headset_mode_hook;
4320 spec->gen.automute_hook = alc_update_headset_mode;
4321 spec->gen.hp_automute_hook = alc_update_headset_jack_cb;
4324 static void alc_fixup_headset_mode(struct hda_codec *codec,
4325 const struct hda_fixup *fix, int action)
4327 struct alc_spec *spec = codec->spec;
4329 switch (action) {
4330 case HDA_FIXUP_ACT_PRE_PROBE:
4331 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC;
4332 break;
4333 case HDA_FIXUP_ACT_PROBE:
4334 alc_probe_headset_mode(codec);
4335 break;
4336 case HDA_FIXUP_ACT_INIT:
4337 spec->current_headset_mode = 0;
4338 alc_update_headset_mode(codec);
4339 break;
4343 static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
4344 const struct hda_fixup *fix, int action)
4346 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4347 struct alc_spec *spec = codec->spec;
4348 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
4350 else
4351 alc_fixup_headset_mode(codec, fix, action);
4354 static void alc255_set_default_jack_type(struct hda_codec *codec)
4356 /* Set to iphone type */
4357 static struct coef_fw alc255fw[] = {
4358 WRITE_COEF(0x1b, 0x880b),
4359 WRITE_COEF(0x45, 0xd089),
4360 WRITE_COEF(0x1b, 0x080b),
4361 WRITE_COEF(0x46, 0x0004),
4362 WRITE_COEF(0x1b, 0x0c0b),
4365 static struct coef_fw alc256fw[] = {
4366 WRITE_COEF(0x1b, 0x884b),
4367 WRITE_COEF(0x45, 0xd089),
4368 WRITE_COEF(0x1b, 0x084b),
4369 WRITE_COEF(0x46, 0x0004),
4370 WRITE_COEF(0x1b, 0x0c4b),
4373 switch (codec->core.vendor_id) {
4374 case 0x10ec0255:
4375 alc_process_coef_fw(codec, alc255fw);
4376 break;
4377 case 0x10ec0236:
4378 case 0x10ec0256:
4379 alc_process_coef_fw(codec, alc256fw);
4380 break;
4382 msleep(30);
4385 static void alc_fixup_headset_mode_alc255(struct hda_codec *codec,
4386 const struct hda_fixup *fix, int action)
4388 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4389 alc255_set_default_jack_type(codec);
4391 alc_fixup_headset_mode(codec, fix, action);
4394 static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec,
4395 const struct hda_fixup *fix, int action)
4397 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4398 struct alc_spec *spec = codec->spec;
4399 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
4400 alc255_set_default_jack_type(codec);
4402 else
4403 alc_fixup_headset_mode(codec, fix, action);
4406 static void alc288_update_headset_jack_cb(struct hda_codec *codec,
4407 struct hda_jack_callback *jack)
4409 struct alc_spec *spec = codec->spec;
4410 int present;
4412 alc_update_headset_jack_cb(codec, jack);
4413 /* Headset Mic enable or disable, only for Dell Dino */
4414 present = spec->gen.hp_jack_present ? 0x40 : 0;
4415 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
4416 present);
4419 static void alc_fixup_headset_mode_dell_alc288(struct hda_codec *codec,
4420 const struct hda_fixup *fix, int action)
4422 alc_fixup_headset_mode(codec, fix, action);
4423 if (action == HDA_FIXUP_ACT_PROBE) {
4424 struct alc_spec *spec = codec->spec;
4425 spec->gen.hp_automute_hook = alc288_update_headset_jack_cb;
4429 static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec,
4430 const struct hda_fixup *fix, int action)
4432 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4433 struct alc_spec *spec = codec->spec;
4434 spec->gen.auto_mute_via_amp = 1;
4438 static void alc_no_shutup(struct hda_codec *codec)
4442 static void alc_fixup_no_shutup(struct hda_codec *codec,
4443 const struct hda_fixup *fix, int action)
4445 if (action == HDA_FIXUP_ACT_PROBE) {
4446 struct alc_spec *spec = codec->spec;
4447 spec->shutup = alc_no_shutup;
4451 static void alc_fixup_disable_aamix(struct hda_codec *codec,
4452 const struct hda_fixup *fix, int action)
4454 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4455 struct alc_spec *spec = codec->spec;
4456 /* Disable AA-loopback as it causes white noise */
4457 spec->gen.mixer_nid = 0;
4461 /* fixup for Thinkpad docks: add dock pins, avoid HP parser fixup */
4462 static void alc_fixup_tpt440_dock(struct hda_codec *codec,
4463 const struct hda_fixup *fix, int action)
4465 static const struct hda_pintbl pincfgs[] = {
4466 { 0x16, 0x21211010 }, /* dock headphone */
4467 { 0x19, 0x21a11010 }, /* dock mic */
4470 struct alc_spec *spec = codec->spec;
4472 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4473 spec->reboot_notify = snd_hda_gen_reboot_notify; /* reduce noise */
4474 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
4475 codec->power_save_node = 0; /* avoid click noises */
4476 snd_hda_apply_pincfgs(codec, pincfgs);
4480 static void alc_fixup_tpt470_dock(struct hda_codec *codec,
4481 const struct hda_fixup *fix, int action)
4483 static const struct hda_pintbl pincfgs[] = {
4484 { 0x17, 0x21211010 }, /* dock headphone */
4485 { 0x19, 0x21a11010 }, /* dock mic */
4488 /* Assure the speaker pin to be coupled with DAC NID 0x03; otherwise
4489 * the speaker output becomes too low by some reason on Thinkpads with
4490 * ALC298 codec
4492 static hda_nid_t preferred_pairs[] = {
4493 0x14, 0x03, 0x17, 0x02, 0x21, 0x02,
4496 struct alc_spec *spec = codec->spec;
4498 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4499 spec->gen.preferred_dacs = preferred_pairs;
4500 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
4501 snd_hda_apply_pincfgs(codec, pincfgs);
4502 } else if (action == HDA_FIXUP_ACT_INIT) {
4503 /* Enable DOCK device */
4504 snd_hda_codec_write(codec, 0x17, 0,
4505 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
4506 /* Enable DOCK device */
4507 snd_hda_codec_write(codec, 0x19, 0,
4508 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
4512 static void alc_shutup_dell_xps13(struct hda_codec *codec)
4514 struct alc_spec *spec = codec->spec;
4515 int hp_pin = spec->gen.autocfg.hp_pins[0];
4517 /* Prevent pop noises when headphones are plugged in */
4518 snd_hda_codec_write(codec, hp_pin, 0,
4519 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
4520 msleep(20);
4523 static void alc_fixup_dell_xps13(struct hda_codec *codec,
4524 const struct hda_fixup *fix, int action)
4526 struct alc_spec *spec = codec->spec;
4527 struct hda_input_mux *imux = &spec->gen.input_mux;
4528 int i;
4530 switch (action) {
4531 case HDA_FIXUP_ACT_PRE_PROBE:
4532 /* mic pin 0x19 must be initialized with Vref Hi-Z, otherwise
4533 * it causes a click noise at start up
4535 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
4536 break;
4537 case HDA_FIXUP_ACT_PROBE:
4538 spec->shutup = alc_shutup_dell_xps13;
4540 /* Make the internal mic the default input source. */
4541 for (i = 0; i < imux->num_items; i++) {
4542 if (spec->gen.imux_pins[i] == 0x12) {
4543 spec->gen.cur_mux[0] = i;
4544 break;
4547 break;
4551 static void alc_fixup_headset_mode_alc662(struct hda_codec *codec,
4552 const struct hda_fixup *fix, int action)
4554 struct alc_spec *spec = codec->spec;
4556 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4557 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
4558 spec->gen.hp_mic = 1; /* Mic-in is same pin as headphone */
4560 /* Disable boost for mic-in permanently. (This code is only called
4561 from quirks that guarantee that the headphone is at NID 0x1b.) */
4562 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000);
4563 snd_hda_override_wcaps(codec, 0x1b, get_wcaps(codec, 0x1b) & ~AC_WCAP_IN_AMP);
4564 } else
4565 alc_fixup_headset_mode(codec, fix, action);
4568 static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
4569 const struct hda_fixup *fix, int action)
4571 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4572 alc_write_coef_idx(codec, 0xc4, 0x8000);
4573 alc_update_coef_idx(codec, 0xc2, ~0xfe, 0);
4574 snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
4576 alc_fixup_headset_mode(codec, fix, action);
4579 /* Returns the nid of the external mic input pin, or 0 if it cannot be found. */
4580 static int find_ext_mic_pin(struct hda_codec *codec)
4582 struct alc_spec *spec = codec->spec;
4583 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
4584 hda_nid_t nid;
4585 unsigned int defcfg;
4586 int i;
4588 for (i = 0; i < cfg->num_inputs; i++) {
4589 if (cfg->inputs[i].type != AUTO_PIN_MIC)
4590 continue;
4591 nid = cfg->inputs[i].pin;
4592 defcfg = snd_hda_codec_get_pincfg(codec, nid);
4593 if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT)
4594 continue;
4595 return nid;
4598 return 0;
4601 static void alc271_hp_gate_mic_jack(struct hda_codec *codec,
4602 const struct hda_fixup *fix,
4603 int action)
4605 struct alc_spec *spec = codec->spec;
4607 if (action == HDA_FIXUP_ACT_PROBE) {
4608 int mic_pin = find_ext_mic_pin(codec);
4609 int hp_pin = spec->gen.autocfg.hp_pins[0];
4611 if (snd_BUG_ON(!mic_pin || !hp_pin))
4612 return;
4613 snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin);
4617 static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec,
4618 const struct hda_fixup *fix,
4619 int action)
4621 struct alc_spec *spec = codec->spec;
4622 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
4623 int i;
4625 /* The mic boosts on level 2 and 3 are too noisy
4626 on the internal mic input.
4627 Therefore limit the boost to 0 or 1. */
4629 if (action != HDA_FIXUP_ACT_PROBE)
4630 return;
4632 for (i = 0; i < cfg->num_inputs; i++) {
4633 hda_nid_t nid = cfg->inputs[i].pin;
4634 unsigned int defcfg;
4635 if (cfg->inputs[i].type != AUTO_PIN_MIC)
4636 continue;
4637 defcfg = snd_hda_codec_get_pincfg(codec, nid);
4638 if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT)
4639 continue;
4641 snd_hda_override_amp_caps(codec, nid, HDA_INPUT,
4642 (0x00 << AC_AMPCAP_OFFSET_SHIFT) |
4643 (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4644 (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) |
4645 (0 << AC_AMPCAP_MUTE_SHIFT));
4649 static void alc283_hp_automute_hook(struct hda_codec *codec,
4650 struct hda_jack_callback *jack)
4652 struct alc_spec *spec = codec->spec;
4653 int vref;
4655 msleep(200);
4656 snd_hda_gen_hp_automute(codec, jack);
4658 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
4660 msleep(600);
4661 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4662 vref);
4665 static void alc283_fixup_chromebook(struct hda_codec *codec,
4666 const struct hda_fixup *fix, int action)
4668 struct alc_spec *spec = codec->spec;
4670 switch (action) {
4671 case HDA_FIXUP_ACT_PRE_PROBE:
4672 snd_hda_override_wcaps(codec, 0x03, 0);
4673 /* Disable AA-loopback as it causes white noise */
4674 spec->gen.mixer_nid = 0;
4675 break;
4676 case HDA_FIXUP_ACT_INIT:
4677 /* MIC2-VREF control */
4678 /* Set to manual mode */
4679 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
4680 /* Enable Line1 input control by verb */
4681 alc_update_coef_idx(codec, 0x1a, 0, 1 << 4);
4682 break;
4686 static void alc283_fixup_sense_combo_jack(struct hda_codec *codec,
4687 const struct hda_fixup *fix, int action)
4689 struct alc_spec *spec = codec->spec;
4691 switch (action) {
4692 case HDA_FIXUP_ACT_PRE_PROBE:
4693 spec->gen.hp_automute_hook = alc283_hp_automute_hook;
4694 break;
4695 case HDA_FIXUP_ACT_INIT:
4696 /* MIC2-VREF control */
4697 /* Set to manual mode */
4698 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
4699 break;
4703 /* mute tablet speaker pin (0x14) via dock plugging in addition */
4704 static void asus_tx300_automute(struct hda_codec *codec)
4706 struct alc_spec *spec = codec->spec;
4707 snd_hda_gen_update_outputs(codec);
4708 if (snd_hda_jack_detect(codec, 0x1b))
4709 spec->gen.mute_bits |= (1ULL << 0x14);
4712 static void alc282_fixup_asus_tx300(struct hda_codec *codec,
4713 const struct hda_fixup *fix, int action)
4715 struct alc_spec *spec = codec->spec;
4716 /* TX300 needs to set up GPIO2 for the speaker amp */
4717 static const struct hda_verb gpio2_verbs[] = {
4718 { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 },
4719 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 },
4720 { 0x01, AC_VERB_SET_GPIO_DATA, 0x04 },
4723 static const struct hda_pintbl dock_pins[] = {
4724 { 0x1b, 0x21114000 }, /* dock speaker pin */
4727 struct snd_kcontrol *kctl;
4729 switch (action) {
4730 case HDA_FIXUP_ACT_PRE_PROBE:
4731 snd_hda_add_verbs(codec, gpio2_verbs);
4732 snd_hda_apply_pincfgs(codec, dock_pins);
4733 spec->gen.auto_mute_via_amp = 1;
4734 spec->gen.automute_hook = asus_tx300_automute;
4735 snd_hda_jack_detect_enable_callback(codec, 0x1b,
4736 snd_hda_gen_hp_automute);
4737 break;
4738 case HDA_FIXUP_ACT_BUILD:
4739 /* this is a bit tricky; give more sane names for the main
4740 * (tablet) speaker and the dock speaker, respectively
4742 kctl = snd_hda_find_mixer_ctl(codec, "Speaker Playback Switch");
4743 if (kctl)
4744 strcpy(kctl->id.name, "Dock Speaker Playback Switch");
4745 kctl = snd_hda_find_mixer_ctl(codec, "Bass Speaker Playback Switch");
4746 if (kctl)
4747 strcpy(kctl->id.name, "Speaker Playback Switch");
4748 break;
4752 static void alc290_fixup_mono_speakers(struct hda_codec *codec,
4753 const struct hda_fixup *fix, int action)
4755 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4756 /* DAC node 0x03 is giving mono output. We therefore want to
4757 make sure 0x14 (front speaker) and 0x15 (headphones) use the
4758 stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */
4759 hda_nid_t conn1[2] = { 0x0c };
4760 snd_hda_override_conn_list(codec, 0x14, 1, conn1);
4761 snd_hda_override_conn_list(codec, 0x15, 1, conn1);
4765 static void alc298_fixup_speaker_volume(struct hda_codec *codec,
4766 const struct hda_fixup *fix, int action)
4768 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4769 /* The speaker is routed to the Node 0x06 by a mistake, as a result
4770 we can't adjust the speaker's volume since this node does not has
4771 Amp-out capability. we change the speaker's route to:
4772 Node 0x02 (Audio Output) -> Node 0x0c (Audio Mixer) -> Node 0x17 (
4773 Pin Complex), since Node 0x02 has Amp-out caps, we can adjust
4774 speaker's volume now. */
4776 hda_nid_t conn1[1] = { 0x0c };
4777 snd_hda_override_conn_list(codec, 0x17, 1, conn1);
4781 /* disable DAC3 (0x06) selection on NID 0x17 as it has no volume amp control */
4782 static void alc295_fixup_disable_dac3(struct hda_codec *codec,
4783 const struct hda_fixup *fix, int action)
4785 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4786 hda_nid_t conn[2] = { 0x02, 0x03 };
4787 snd_hda_override_conn_list(codec, 0x17, 2, conn);
4791 /* Hook to update amp GPIO4 for automute */
4792 static void alc280_hp_gpio4_automute_hook(struct hda_codec *codec,
4793 struct hda_jack_callback *jack)
4795 struct alc_spec *spec = codec->spec;
4797 snd_hda_gen_hp_automute(codec, jack);
4798 /* mute_led_polarity is set to 0, so we pass inverted value here */
4799 alc_update_gpio_led(codec, 0x10, !spec->gen.hp_jack_present);
4802 /* Manage GPIOs for HP EliteBook Folio 9480m.
4804 * GPIO4 is the headphone amplifier power control
4805 * GPIO3 is the audio output mute indicator LED
4808 static void alc280_fixup_hp_9480m(struct hda_codec *codec,
4809 const struct hda_fixup *fix,
4810 int action)
4812 struct alc_spec *spec = codec->spec;
4813 static const struct hda_verb gpio_init[] = {
4814 { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 },
4815 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 },
4819 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4820 /* Set the hooks to turn the headphone amp on/off
4821 * as needed
4823 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
4824 spec->gen.hp_automute_hook = alc280_hp_gpio4_automute_hook;
4826 /* The GPIOs are currently off */
4827 spec->gpio_led = 0;
4829 /* GPIO3 is connected to the output mute LED,
4830 * high is on, low is off
4832 spec->mute_led_polarity = 0;
4833 spec->gpio_mute_led_mask = 0x08;
4835 /* Initialize GPIO configuration */
4836 snd_hda_add_verbs(codec, gpio_init);
4840 static void alc_fixup_disable_mic_vref(struct hda_codec *codec,
4841 const struct hda_fixup *fix, int action)
4843 if (action == HDA_FIXUP_ACT_PRE_PROBE)
4844 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
4847 /* for hda_fixup_thinkpad_acpi() */
4848 #include "thinkpad_helper.c"
4850 static void alc_fixup_thinkpad_acpi(struct hda_codec *codec,
4851 const struct hda_fixup *fix, int action)
4853 alc_fixup_no_shutup(codec, fix, action); /* reduce click noise */
4854 hda_fixup_thinkpad_acpi(codec, fix, action);
4857 /* for dell wmi mic mute led */
4858 #include "dell_wmi_helper.c"
4860 enum {
4861 ALC269_FIXUP_SONY_VAIO,
4862 ALC275_FIXUP_SONY_VAIO_GPIO2,
4863 ALC269_FIXUP_DELL_M101Z,
4864 ALC269_FIXUP_SKU_IGNORE,
4865 ALC269_FIXUP_ASUS_G73JW,
4866 ALC269_FIXUP_LENOVO_EAPD,
4867 ALC275_FIXUP_SONY_HWEQ,
4868 ALC275_FIXUP_SONY_DISABLE_AAMIX,
4869 ALC271_FIXUP_DMIC,
4870 ALC269_FIXUP_PCM_44K,
4871 ALC269_FIXUP_STEREO_DMIC,
4872 ALC269_FIXUP_HEADSET_MIC,
4873 ALC269_FIXUP_QUANTA_MUTE,
4874 ALC269_FIXUP_LIFEBOOK,
4875 ALC269_FIXUP_LIFEBOOK_EXTMIC,
4876 ALC269_FIXUP_LIFEBOOK_HP_PIN,
4877 ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT,
4878 ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC,
4879 ALC269_FIXUP_AMIC,
4880 ALC269_FIXUP_DMIC,
4881 ALC269VB_FIXUP_AMIC,
4882 ALC269VB_FIXUP_DMIC,
4883 ALC269_FIXUP_HP_MUTE_LED,
4884 ALC269_FIXUP_HP_MUTE_LED_MIC1,
4885 ALC269_FIXUP_HP_MUTE_LED_MIC2,
4886 ALC269_FIXUP_HP_GPIO_LED,
4887 ALC269_FIXUP_HP_GPIO_MIC1_LED,
4888 ALC269_FIXUP_HP_LINE1_MIC1_LED,
4889 ALC269_FIXUP_INV_DMIC,
4890 ALC269_FIXUP_LENOVO_DOCK,
4891 ALC269_FIXUP_NO_SHUTUP,
4892 ALC286_FIXUP_SONY_MIC_NO_PRESENCE,
4893 ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
4894 ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
4895 ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
4896 ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
4897 ALC269_FIXUP_HEADSET_MODE,
4898 ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC,
4899 ALC269_FIXUP_ASPIRE_HEADSET_MIC,
4900 ALC269_FIXUP_ASUS_X101_FUNC,
4901 ALC269_FIXUP_ASUS_X101_VERB,
4902 ALC269_FIXUP_ASUS_X101,
4903 ALC271_FIXUP_AMIC_MIC2,
4904 ALC271_FIXUP_HP_GATE_MIC_JACK,
4905 ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572,
4906 ALC269_FIXUP_ACER_AC700,
4907 ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
4908 ALC269VB_FIXUP_ASUS_ZENBOOK,
4909 ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A,
4910 ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED,
4911 ALC269VB_FIXUP_ORDISSIMO_EVE2,
4912 ALC283_FIXUP_CHROME_BOOK,
4913 ALC283_FIXUP_SENSE_COMBO_JACK,
4914 ALC282_FIXUP_ASUS_TX300,
4915 ALC283_FIXUP_INT_MIC,
4916 ALC290_FIXUP_MONO_SPEAKERS,
4917 ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
4918 ALC290_FIXUP_SUBWOOFER,
4919 ALC290_FIXUP_SUBWOOFER_HSJACK,
4920 ALC269_FIXUP_THINKPAD_ACPI,
4921 ALC269_FIXUP_DMIC_THINKPAD_ACPI,
4922 ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
4923 ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
4924 ALC255_FIXUP_HEADSET_MODE,
4925 ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC,
4926 ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
4927 ALC292_FIXUP_TPT440_DOCK,
4928 ALC292_FIXUP_TPT440,
4929 ALC283_FIXUP_HEADSET_MIC,
4930 ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED,
4931 ALC282_FIXUP_ASPIRE_V5_PINS,
4932 ALC280_FIXUP_HP_GPIO4,
4933 ALC286_FIXUP_HP_GPIO_LED,
4934 ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY,
4935 ALC280_FIXUP_HP_DOCK_PINS,
4936 ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED,
4937 ALC280_FIXUP_HP_9480M,
4938 ALC288_FIXUP_DELL_HEADSET_MODE,
4939 ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
4940 ALC288_FIXUP_DELL_XPS_13_GPIO6,
4941 ALC288_FIXUP_DELL_XPS_13,
4942 ALC288_FIXUP_DISABLE_AAMIX,
4943 ALC292_FIXUP_DELL_E7X,
4944 ALC292_FIXUP_DISABLE_AAMIX,
4945 ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK,
4946 ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
4947 ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
4948 ALC275_FIXUP_DELL_XPS,
4949 ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE,
4950 ALC293_FIXUP_LENOVO_SPK_NOISE,
4951 ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
4952 ALC255_FIXUP_DELL_SPK_NOISE,
4953 ALC225_FIXUP_DISABLE_MIC_VREF,
4954 ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
4955 ALC295_FIXUP_DISABLE_DAC3,
4956 ALC280_FIXUP_HP_HEADSET_MIC,
4957 ALC221_FIXUP_HP_FRONT_MIC,
4958 ALC292_FIXUP_TPT460,
4959 ALC298_FIXUP_SPK_VOLUME,
4960 ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER,
4961 ALC298_FIXUP_TPT470_DOCK,
4964 static const struct hda_fixup alc269_fixups[] = {
4965 [ALC269_FIXUP_SONY_VAIO] = {
4966 .type = HDA_FIXUP_PINCTLS,
4967 .v.pins = (const struct hda_pintbl[]) {
4968 {0x19, PIN_VREFGRD},
4972 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
4973 .type = HDA_FIXUP_VERBS,
4974 .v.verbs = (const struct hda_verb[]) {
4975 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
4976 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
4977 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4980 .chained = true,
4981 .chain_id = ALC269_FIXUP_SONY_VAIO
4983 [ALC269_FIXUP_DELL_M101Z] = {
4984 .type = HDA_FIXUP_VERBS,
4985 .v.verbs = (const struct hda_verb[]) {
4986 /* Enables internal speaker */
4987 {0x20, AC_VERB_SET_COEF_INDEX, 13},
4988 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
4992 [ALC269_FIXUP_SKU_IGNORE] = {
4993 .type = HDA_FIXUP_FUNC,
4994 .v.func = alc_fixup_sku_ignore,
4996 [ALC269_FIXUP_ASUS_G73JW] = {
4997 .type = HDA_FIXUP_PINS,
4998 .v.pins = (const struct hda_pintbl[]) {
4999 { 0x17, 0x99130111 }, /* subwoofer */
5003 [ALC269_FIXUP_LENOVO_EAPD] = {
5004 .type = HDA_FIXUP_VERBS,
5005 .v.verbs = (const struct hda_verb[]) {
5006 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
5010 [ALC275_FIXUP_SONY_HWEQ] = {
5011 .type = HDA_FIXUP_FUNC,
5012 .v.func = alc269_fixup_hweq,
5013 .chained = true,
5014 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
5016 [ALC275_FIXUP_SONY_DISABLE_AAMIX] = {
5017 .type = HDA_FIXUP_FUNC,
5018 .v.func = alc_fixup_disable_aamix,
5019 .chained = true,
5020 .chain_id = ALC269_FIXUP_SONY_VAIO
5022 [ALC271_FIXUP_DMIC] = {
5023 .type = HDA_FIXUP_FUNC,
5024 .v.func = alc271_fixup_dmic,
5026 [ALC269_FIXUP_PCM_44K] = {
5027 .type = HDA_FIXUP_FUNC,
5028 .v.func = alc269_fixup_pcm_44k,
5029 .chained = true,
5030 .chain_id = ALC269_FIXUP_QUANTA_MUTE
5032 [ALC269_FIXUP_STEREO_DMIC] = {
5033 .type = HDA_FIXUP_FUNC,
5034 .v.func = alc269_fixup_stereo_dmic,
5036 [ALC269_FIXUP_HEADSET_MIC] = {
5037 .type = HDA_FIXUP_FUNC,
5038 .v.func = alc269_fixup_headset_mic,
5040 [ALC269_FIXUP_QUANTA_MUTE] = {
5041 .type = HDA_FIXUP_FUNC,
5042 .v.func = alc269_fixup_quanta_mute,
5044 [ALC269_FIXUP_LIFEBOOK] = {
5045 .type = HDA_FIXUP_PINS,
5046 .v.pins = (const struct hda_pintbl[]) {
5047 { 0x1a, 0x2101103f }, /* dock line-out */
5048 { 0x1b, 0x23a11040 }, /* dock mic-in */
5051 .chained = true,
5052 .chain_id = ALC269_FIXUP_QUANTA_MUTE
5054 [ALC269_FIXUP_LIFEBOOK_EXTMIC] = {
5055 .type = HDA_FIXUP_PINS,
5056 .v.pins = (const struct hda_pintbl[]) {
5057 { 0x19, 0x01a1903c }, /* headset mic, with jack detect */
5061 [ALC269_FIXUP_LIFEBOOK_HP_PIN] = {
5062 .type = HDA_FIXUP_PINS,
5063 .v.pins = (const struct hda_pintbl[]) {
5064 { 0x21, 0x0221102f }, /* HP out */
5068 [ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT] = {
5069 .type = HDA_FIXUP_FUNC,
5070 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
5072 [ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC] = {
5073 .type = HDA_FIXUP_FUNC,
5074 .v.func = alc269_fixup_pincfg_U7x7_headset_mic,
5076 [ALC269_FIXUP_AMIC] = {
5077 .type = HDA_FIXUP_PINS,
5078 .v.pins = (const struct hda_pintbl[]) {
5079 { 0x14, 0x99130110 }, /* speaker */
5080 { 0x15, 0x0121401f }, /* HP out */
5081 { 0x18, 0x01a19c20 }, /* mic */
5082 { 0x19, 0x99a3092f }, /* int-mic */
5086 [ALC269_FIXUP_DMIC] = {
5087 .type = HDA_FIXUP_PINS,
5088 .v.pins = (const struct hda_pintbl[]) {
5089 { 0x12, 0x99a3092f }, /* int-mic */
5090 { 0x14, 0x99130110 }, /* speaker */
5091 { 0x15, 0x0121401f }, /* HP out */
5092 { 0x18, 0x01a19c20 }, /* mic */
5096 [ALC269VB_FIXUP_AMIC] = {
5097 .type = HDA_FIXUP_PINS,
5098 .v.pins = (const struct hda_pintbl[]) {
5099 { 0x14, 0x99130110 }, /* speaker */
5100 { 0x18, 0x01a19c20 }, /* mic */
5101 { 0x19, 0x99a3092f }, /* int-mic */
5102 { 0x21, 0x0121401f }, /* HP out */
5106 [ALC269VB_FIXUP_DMIC] = {
5107 .type = HDA_FIXUP_PINS,
5108 .v.pins = (const struct hda_pintbl[]) {
5109 { 0x12, 0x99a3092f }, /* int-mic */
5110 { 0x14, 0x99130110 }, /* speaker */
5111 { 0x18, 0x01a19c20 }, /* mic */
5112 { 0x21, 0x0121401f }, /* HP out */
5116 [ALC269_FIXUP_HP_MUTE_LED] = {
5117 .type = HDA_FIXUP_FUNC,
5118 .v.func = alc269_fixup_hp_mute_led,
5120 [ALC269_FIXUP_HP_MUTE_LED_MIC1] = {
5121 .type = HDA_FIXUP_FUNC,
5122 .v.func = alc269_fixup_hp_mute_led_mic1,
5124 [ALC269_FIXUP_HP_MUTE_LED_MIC2] = {
5125 .type = HDA_FIXUP_FUNC,
5126 .v.func = alc269_fixup_hp_mute_led_mic2,
5128 [ALC269_FIXUP_HP_GPIO_LED] = {
5129 .type = HDA_FIXUP_FUNC,
5130 .v.func = alc269_fixup_hp_gpio_led,
5132 [ALC269_FIXUP_HP_GPIO_MIC1_LED] = {
5133 .type = HDA_FIXUP_FUNC,
5134 .v.func = alc269_fixup_hp_gpio_mic1_led,
5136 [ALC269_FIXUP_HP_LINE1_MIC1_LED] = {
5137 .type = HDA_FIXUP_FUNC,
5138 .v.func = alc269_fixup_hp_line1_mic1_led,
5140 [ALC269_FIXUP_INV_DMIC] = {
5141 .type = HDA_FIXUP_FUNC,
5142 .v.func = alc_fixup_inv_dmic,
5144 [ALC269_FIXUP_NO_SHUTUP] = {
5145 .type = HDA_FIXUP_FUNC,
5146 .v.func = alc_fixup_no_shutup,
5148 [ALC269_FIXUP_LENOVO_DOCK] = {
5149 .type = HDA_FIXUP_PINS,
5150 .v.pins = (const struct hda_pintbl[]) {
5151 { 0x19, 0x23a11040 }, /* dock mic */
5152 { 0x1b, 0x2121103f }, /* dock headphone */
5155 .chained = true,
5156 .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT
5158 [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = {
5159 .type = HDA_FIXUP_FUNC,
5160 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
5161 .chained = true,
5162 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
5164 [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5165 .type = HDA_FIXUP_PINS,
5166 .v.pins = (const struct hda_pintbl[]) {
5167 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5168 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5171 .chained = true,
5172 .chain_id = ALC269_FIXUP_HEADSET_MODE
5174 [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = {
5175 .type = HDA_FIXUP_PINS,
5176 .v.pins = (const struct hda_pintbl[]) {
5177 { 0x16, 0x21014020 }, /* dock line out */
5178 { 0x19, 0x21a19030 }, /* dock mic */
5179 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5182 .chained = true,
5183 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
5185 [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = {
5186 .type = HDA_FIXUP_PINS,
5187 .v.pins = (const struct hda_pintbl[]) {
5188 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5191 .chained = true,
5192 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
5194 [ALC269_FIXUP_HEADSET_MODE] = {
5195 .type = HDA_FIXUP_FUNC,
5196 .v.func = alc_fixup_headset_mode,
5197 .chained = true,
5198 .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
5200 [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
5201 .type = HDA_FIXUP_FUNC,
5202 .v.func = alc_fixup_headset_mode_no_hp_mic,
5204 [ALC269_FIXUP_ASPIRE_HEADSET_MIC] = {
5205 .type = HDA_FIXUP_PINS,
5206 .v.pins = (const struct hda_pintbl[]) {
5207 { 0x19, 0x01a1913c }, /* headset mic w/o jack detect */
5210 .chained = true,
5211 .chain_id = ALC269_FIXUP_HEADSET_MODE,
5213 [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = {
5214 .type = HDA_FIXUP_PINS,
5215 .v.pins = (const struct hda_pintbl[]) {
5216 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5219 .chained = true,
5220 .chain_id = ALC269_FIXUP_HEADSET_MIC
5222 [ALC269_FIXUP_ASUS_X101_FUNC] = {
5223 .type = HDA_FIXUP_FUNC,
5224 .v.func = alc269_fixup_x101_headset_mic,
5226 [ALC269_FIXUP_ASUS_X101_VERB] = {
5227 .type = HDA_FIXUP_VERBS,
5228 .v.verbs = (const struct hda_verb[]) {
5229 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5230 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
5231 {0x20, AC_VERB_SET_PROC_COEF, 0x0310},
5234 .chained = true,
5235 .chain_id = ALC269_FIXUP_ASUS_X101_FUNC
5237 [ALC269_FIXUP_ASUS_X101] = {
5238 .type = HDA_FIXUP_PINS,
5239 .v.pins = (const struct hda_pintbl[]) {
5240 { 0x18, 0x04a1182c }, /* Headset mic */
5243 .chained = true,
5244 .chain_id = ALC269_FIXUP_ASUS_X101_VERB
5246 [ALC271_FIXUP_AMIC_MIC2] = {
5247 .type = HDA_FIXUP_PINS,
5248 .v.pins = (const struct hda_pintbl[]) {
5249 { 0x14, 0x99130110 }, /* speaker */
5250 { 0x19, 0x01a19c20 }, /* mic */
5251 { 0x1b, 0x99a7012f }, /* int-mic */
5252 { 0x21, 0x0121401f }, /* HP out */
5256 [ALC271_FIXUP_HP_GATE_MIC_JACK] = {
5257 .type = HDA_FIXUP_FUNC,
5258 .v.func = alc271_hp_gate_mic_jack,
5259 .chained = true,
5260 .chain_id = ALC271_FIXUP_AMIC_MIC2,
5262 [ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = {
5263 .type = HDA_FIXUP_FUNC,
5264 .v.func = alc269_fixup_limit_int_mic_boost,
5265 .chained = true,
5266 .chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK,
5268 [ALC269_FIXUP_ACER_AC700] = {
5269 .type = HDA_FIXUP_PINS,
5270 .v.pins = (const struct hda_pintbl[]) {
5271 { 0x12, 0x99a3092f }, /* int-mic */
5272 { 0x14, 0x99130110 }, /* speaker */
5273 { 0x18, 0x03a11c20 }, /* mic */
5274 { 0x1e, 0x0346101e }, /* SPDIF1 */
5275 { 0x21, 0x0321101f }, /* HP out */
5278 .chained = true,
5279 .chain_id = ALC271_FIXUP_DMIC,
5281 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = {
5282 .type = HDA_FIXUP_FUNC,
5283 .v.func = alc269_fixup_limit_int_mic_boost,
5284 .chained = true,
5285 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
5287 [ALC269VB_FIXUP_ASUS_ZENBOOK] = {
5288 .type = HDA_FIXUP_FUNC,
5289 .v.func = alc269_fixup_limit_int_mic_boost,
5290 .chained = true,
5291 .chain_id = ALC269VB_FIXUP_DMIC,
5293 [ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = {
5294 .type = HDA_FIXUP_VERBS,
5295 .v.verbs = (const struct hda_verb[]) {
5296 /* class-D output amp +5dB */
5297 { 0x20, AC_VERB_SET_COEF_INDEX, 0x12 },
5298 { 0x20, AC_VERB_SET_PROC_COEF, 0x2800 },
5301 .chained = true,
5302 .chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK,
5304 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = {
5305 .type = HDA_FIXUP_FUNC,
5306 .v.func = alc269_fixup_limit_int_mic_boost,
5307 .chained = true,
5308 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1,
5310 [ALC269VB_FIXUP_ORDISSIMO_EVE2] = {
5311 .type = HDA_FIXUP_PINS,
5312 .v.pins = (const struct hda_pintbl[]) {
5313 { 0x12, 0x99a3092f }, /* int-mic */
5314 { 0x18, 0x03a11d20 }, /* mic */
5315 { 0x19, 0x411111f0 }, /* Unused bogus pin */
5319 [ALC283_FIXUP_CHROME_BOOK] = {
5320 .type = HDA_FIXUP_FUNC,
5321 .v.func = alc283_fixup_chromebook,
5323 [ALC283_FIXUP_SENSE_COMBO_JACK] = {
5324 .type = HDA_FIXUP_FUNC,
5325 .v.func = alc283_fixup_sense_combo_jack,
5326 .chained = true,
5327 .chain_id = ALC283_FIXUP_CHROME_BOOK,
5329 [ALC282_FIXUP_ASUS_TX300] = {
5330 .type = HDA_FIXUP_FUNC,
5331 .v.func = alc282_fixup_asus_tx300,
5333 [ALC283_FIXUP_INT_MIC] = {
5334 .type = HDA_FIXUP_VERBS,
5335 .v.verbs = (const struct hda_verb[]) {
5336 {0x20, AC_VERB_SET_COEF_INDEX, 0x1a},
5337 {0x20, AC_VERB_SET_PROC_COEF, 0x0011},
5340 .chained = true,
5341 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
5343 [ALC290_FIXUP_SUBWOOFER_HSJACK] = {
5344 .type = HDA_FIXUP_PINS,
5345 .v.pins = (const struct hda_pintbl[]) {
5346 { 0x17, 0x90170112 }, /* subwoofer */
5349 .chained = true,
5350 .chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
5352 [ALC290_FIXUP_SUBWOOFER] = {
5353 .type = HDA_FIXUP_PINS,
5354 .v.pins = (const struct hda_pintbl[]) {
5355 { 0x17, 0x90170112 }, /* subwoofer */
5358 .chained = true,
5359 .chain_id = ALC290_FIXUP_MONO_SPEAKERS,
5361 [ALC290_FIXUP_MONO_SPEAKERS] = {
5362 .type = HDA_FIXUP_FUNC,
5363 .v.func = alc290_fixup_mono_speakers,
5365 [ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = {
5366 .type = HDA_FIXUP_FUNC,
5367 .v.func = alc290_fixup_mono_speakers,
5368 .chained = true,
5369 .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
5371 [ALC269_FIXUP_THINKPAD_ACPI] = {
5372 .type = HDA_FIXUP_FUNC,
5373 .v.func = alc_fixup_thinkpad_acpi,
5374 .chained = true,
5375 .chain_id = ALC269_FIXUP_SKU_IGNORE,
5377 [ALC269_FIXUP_DMIC_THINKPAD_ACPI] = {
5378 .type = HDA_FIXUP_FUNC,
5379 .v.func = alc_fixup_inv_dmic,
5380 .chained = true,
5381 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
5383 [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5384 .type = HDA_FIXUP_PINS,
5385 .v.pins = (const struct hda_pintbl[]) {
5386 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5387 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5390 .chained = true,
5391 .chain_id = ALC255_FIXUP_HEADSET_MODE
5393 [ALC255_FIXUP_DELL2_MIC_NO_PRESENCE] = {
5394 .type = HDA_FIXUP_PINS,
5395 .v.pins = (const struct hda_pintbl[]) {
5396 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5399 .chained = true,
5400 .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
5402 [ALC255_FIXUP_HEADSET_MODE] = {
5403 .type = HDA_FIXUP_FUNC,
5404 .v.func = alc_fixup_headset_mode_alc255,
5405 .chained = true,
5406 .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
5408 [ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
5409 .type = HDA_FIXUP_FUNC,
5410 .v.func = alc_fixup_headset_mode_alc255_no_hp_mic,
5412 [ALC293_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5413 .type = HDA_FIXUP_PINS,
5414 .v.pins = (const struct hda_pintbl[]) {
5415 { 0x18, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5416 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5419 .chained = true,
5420 .chain_id = ALC269_FIXUP_HEADSET_MODE
5422 [ALC292_FIXUP_TPT440_DOCK] = {
5423 .type = HDA_FIXUP_FUNC,
5424 .v.func = alc_fixup_tpt440_dock,
5425 .chained = true,
5426 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
5428 [ALC292_FIXUP_TPT440] = {
5429 .type = HDA_FIXUP_FUNC,
5430 .v.func = alc_fixup_disable_aamix,
5431 .chained = true,
5432 .chain_id = ALC292_FIXUP_TPT440_DOCK,
5434 [ALC283_FIXUP_HEADSET_MIC] = {
5435 .type = HDA_FIXUP_PINS,
5436 .v.pins = (const struct hda_pintbl[]) {
5437 { 0x19, 0x04a110f0 },
5438 { },
5441 [ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED] = {
5442 .type = HDA_FIXUP_FUNC,
5443 .v.func = alc_fixup_dell_wmi,
5445 [ALC282_FIXUP_ASPIRE_V5_PINS] = {
5446 .type = HDA_FIXUP_PINS,
5447 .v.pins = (const struct hda_pintbl[]) {
5448 { 0x12, 0x90a60130 },
5449 { 0x14, 0x90170110 },
5450 { 0x17, 0x40000008 },
5451 { 0x18, 0x411111f0 },
5452 { 0x19, 0x01a1913c },
5453 { 0x1a, 0x411111f0 },
5454 { 0x1b, 0x411111f0 },
5455 { 0x1d, 0x40f89b2d },
5456 { 0x1e, 0x411111f0 },
5457 { 0x21, 0x0321101f },
5458 { },
5461 [ALC280_FIXUP_HP_GPIO4] = {
5462 .type = HDA_FIXUP_FUNC,
5463 .v.func = alc280_fixup_hp_gpio4,
5465 [ALC286_FIXUP_HP_GPIO_LED] = {
5466 .type = HDA_FIXUP_FUNC,
5467 .v.func = alc286_fixup_hp_gpio_led,
5469 [ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY] = {
5470 .type = HDA_FIXUP_FUNC,
5471 .v.func = alc280_fixup_hp_gpio2_mic_hotkey,
5473 [ALC280_FIXUP_HP_DOCK_PINS] = {
5474 .type = HDA_FIXUP_PINS,
5475 .v.pins = (const struct hda_pintbl[]) {
5476 { 0x1b, 0x21011020 }, /* line-out */
5477 { 0x1a, 0x01a1903c }, /* headset mic */
5478 { 0x18, 0x2181103f }, /* line-in */
5479 { },
5481 .chained = true,
5482 .chain_id = ALC280_FIXUP_HP_GPIO4
5484 [ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED] = {
5485 .type = HDA_FIXUP_PINS,
5486 .v.pins = (const struct hda_pintbl[]) {
5487 { 0x1b, 0x21011020 }, /* line-out */
5488 { 0x18, 0x2181103f }, /* line-in */
5489 { },
5491 .chained = true,
5492 .chain_id = ALC269_FIXUP_HP_GPIO_MIC1_LED
5494 [ALC280_FIXUP_HP_9480M] = {
5495 .type = HDA_FIXUP_FUNC,
5496 .v.func = alc280_fixup_hp_9480m,
5498 [ALC288_FIXUP_DELL_HEADSET_MODE] = {
5499 .type = HDA_FIXUP_FUNC,
5500 .v.func = alc_fixup_headset_mode_dell_alc288,
5501 .chained = true,
5502 .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
5504 [ALC288_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5505 .type = HDA_FIXUP_PINS,
5506 .v.pins = (const struct hda_pintbl[]) {
5507 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5508 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5511 .chained = true,
5512 .chain_id = ALC288_FIXUP_DELL_HEADSET_MODE
5514 [ALC288_FIXUP_DELL_XPS_13_GPIO6] = {
5515 .type = HDA_FIXUP_VERBS,
5516 .v.verbs = (const struct hda_verb[]) {
5517 {0x01, AC_VERB_SET_GPIO_MASK, 0x40},
5518 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x40},
5519 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5522 .chained = true,
5523 .chain_id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE
5525 [ALC288_FIXUP_DISABLE_AAMIX] = {
5526 .type = HDA_FIXUP_FUNC,
5527 .v.func = alc_fixup_disable_aamix,
5528 .chained = true,
5529 .chain_id = ALC288_FIXUP_DELL_XPS_13_GPIO6
5531 [ALC288_FIXUP_DELL_XPS_13] = {
5532 .type = HDA_FIXUP_FUNC,
5533 .v.func = alc_fixup_dell_xps13,
5534 .chained = true,
5535 .chain_id = ALC288_FIXUP_DISABLE_AAMIX
5537 [ALC292_FIXUP_DISABLE_AAMIX] = {
5538 .type = HDA_FIXUP_FUNC,
5539 .v.func = alc_fixup_disable_aamix,
5540 .chained = true,
5541 .chain_id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE
5543 [ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK] = {
5544 .type = HDA_FIXUP_FUNC,
5545 .v.func = alc_fixup_disable_aamix,
5546 .chained = true,
5547 .chain_id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE
5549 [ALC292_FIXUP_DELL_E7X] = {
5550 .type = HDA_FIXUP_FUNC,
5551 .v.func = alc_fixup_dell_xps13,
5552 .chained = true,
5553 .chain_id = ALC292_FIXUP_DISABLE_AAMIX
5555 [ALC298_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5556 .type = HDA_FIXUP_PINS,
5557 .v.pins = (const struct hda_pintbl[]) {
5558 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5559 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5562 .chained = true,
5563 .chain_id = ALC269_FIXUP_HEADSET_MODE
5565 [ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE] = {
5566 .type = HDA_FIXUP_PINS,
5567 .v.pins = (const struct hda_pintbl[]) {
5568 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5571 .chained = true,
5572 .chain_id = ALC269_FIXUP_HEADSET_MODE
5574 [ALC275_FIXUP_DELL_XPS] = {
5575 .type = HDA_FIXUP_VERBS,
5576 .v.verbs = (const struct hda_verb[]) {
5577 /* Enables internal speaker */
5578 {0x20, AC_VERB_SET_COEF_INDEX, 0x1f},
5579 {0x20, AC_VERB_SET_PROC_COEF, 0x00c0},
5580 {0x20, AC_VERB_SET_COEF_INDEX, 0x30},
5581 {0x20, AC_VERB_SET_PROC_COEF, 0x00b1},
5585 [ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE] = {
5586 .type = HDA_FIXUP_VERBS,
5587 .v.verbs = (const struct hda_verb[]) {
5588 /* Disable pass-through path for FRONT 14h */
5589 {0x20, AC_VERB_SET_COEF_INDEX, 0x36},
5590 {0x20, AC_VERB_SET_PROC_COEF, 0x1737},
5593 .chained = true,
5594 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
5596 [ALC293_FIXUP_LENOVO_SPK_NOISE] = {
5597 .type = HDA_FIXUP_FUNC,
5598 .v.func = alc_fixup_disable_aamix,
5599 .chained = true,
5600 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
5602 [ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY] = {
5603 .type = HDA_FIXUP_FUNC,
5604 .v.func = alc233_fixup_lenovo_line2_mic_hotkey,
5606 [ALC255_FIXUP_DELL_SPK_NOISE] = {
5607 .type = HDA_FIXUP_FUNC,
5608 .v.func = alc_fixup_disable_aamix,
5609 .chained = true,
5610 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
5612 [ALC225_FIXUP_DISABLE_MIC_VREF] = {
5613 .type = HDA_FIXUP_FUNC,
5614 .v.func = alc_fixup_disable_mic_vref,
5615 .chained = true,
5616 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
5618 [ALC225_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5619 .type = HDA_FIXUP_VERBS,
5620 .v.verbs = (const struct hda_verb[]) {
5621 /* Disable pass-through path for FRONT 14h */
5622 { 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
5623 { 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
5626 .chained = true,
5627 .chain_id = ALC225_FIXUP_DISABLE_MIC_VREF
5629 [ALC280_FIXUP_HP_HEADSET_MIC] = {
5630 .type = HDA_FIXUP_FUNC,
5631 .v.func = alc_fixup_disable_aamix,
5632 .chained = true,
5633 .chain_id = ALC269_FIXUP_HEADSET_MIC,
5635 [ALC221_FIXUP_HP_FRONT_MIC] = {
5636 .type = HDA_FIXUP_PINS,
5637 .v.pins = (const struct hda_pintbl[]) {
5638 { 0x19, 0x02a19020 }, /* Front Mic */
5642 [ALC292_FIXUP_TPT460] = {
5643 .type = HDA_FIXUP_FUNC,
5644 .v.func = alc_fixup_tpt440_dock,
5645 .chained = true,
5646 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE,
5648 [ALC298_FIXUP_SPK_VOLUME] = {
5649 .type = HDA_FIXUP_FUNC,
5650 .v.func = alc298_fixup_speaker_volume,
5651 .chained = true,
5652 .chain_id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
5654 [ALC295_FIXUP_DISABLE_DAC3] = {
5655 .type = HDA_FIXUP_FUNC,
5656 .v.func = alc295_fixup_disable_dac3,
5658 [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = {
5659 .type = HDA_FIXUP_PINS,
5660 .v.pins = (const struct hda_pintbl[]) {
5661 { 0x1b, 0x90170151 },
5664 .chained = true,
5665 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
5667 [ALC298_FIXUP_TPT470_DOCK] = {
5668 .type = HDA_FIXUP_FUNC,
5669 .v.func = alc_fixup_tpt470_dock,
5670 .chained = true,
5671 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE
5675 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
5676 SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC),
5677 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
5678 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
5679 SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
5680 SND_PCI_QUIRK(0x1025, 0x072d, "Acer Aspire V5-571G", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
5681 SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
5682 SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
5683 SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
5684 SND_PCI_QUIRK(0x1025, 0x0762, "Acer Aspire E1-472", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
5685 SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
5686 SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
5687 SND_PCI_QUIRK(0x1025, 0x106d, "Acer Cloudbook 14", ALC283_FIXUP_CHROME_BOOK),
5688 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
5689 SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS),
5690 SND_PCI_QUIRK(0x1028, 0x05bd, "Dell Latitude E6440", ALC292_FIXUP_DELL_E7X),
5691 SND_PCI_QUIRK(0x1028, 0x05be, "Dell Latitude E6540", ALC292_FIXUP_DELL_E7X),
5692 SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X),
5693 SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X),
5694 SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
5695 SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
5696 SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
5697 SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
5698 SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
5699 SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
5700 SND_PCI_QUIRK(0x1028, 0x062c, "Dell Latitude E5550", ALC292_FIXUP_DELL_E7X),
5701 SND_PCI_QUIRK(0x1028, 0x062e, "Dell Latitude E7450", ALC292_FIXUP_DELL_E7X),
5702 SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK),
5703 SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5704 SND_PCI_QUIRK(0x1028, 0x064b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5705 SND_PCI_QUIRK(0x1028, 0x0665, "Dell XPS 13", ALC288_FIXUP_DELL_XPS_13),
5706 SND_PCI_QUIRK(0x1028, 0x0669, "Dell Optiplex 9020m", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
5707 SND_PCI_QUIRK(0x1028, 0x069a, "Dell Vostro 5480", ALC290_FIXUP_SUBWOOFER_HSJACK),
5708 SND_PCI_QUIRK(0x1028, 0x06c7, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
5709 SND_PCI_QUIRK(0x1028, 0x06d9, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5710 SND_PCI_QUIRK(0x1028, 0x06da, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5711 SND_PCI_QUIRK(0x1028, 0x06db, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
5712 SND_PCI_QUIRK(0x1028, 0x06dd, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
5713 SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
5714 SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
5715 SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
5716 SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13 9350", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
5717 SND_PCI_QUIRK(0x1028, 0x0706, "Dell Inspiron 7559", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
5718 SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE),
5719 SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
5720 SND_PCI_QUIRK(0x1028, 0x075c, "Dell XPS 27 7760", ALC298_FIXUP_SPK_VOLUME),
5721 SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME),
5722 SND_PCI_QUIRK(0x1028, 0x07b0, "Dell Precision 7520", ALC295_FIXUP_DISABLE_DAC3),
5723 SND_PCI_QUIRK(0x1028, 0x0798, "Dell Inspiron 17 7000 Gaming", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
5724 SND_PCI_QUIRK(0x1028, 0x082a, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
5725 SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5726 SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5727 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
5728 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
5729 SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
5730 SND_PCI_QUIRK(0x103c, 0x225f, "HP", ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY),
5731 /* ALC282 */
5732 SND_PCI_QUIRK(0x103c, 0x21f9, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5733 SND_PCI_QUIRK(0x103c, 0x2210, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5734 SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5735 SND_PCI_QUIRK(0x103c, 0x2236, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
5736 SND_PCI_QUIRK(0x103c, 0x2237, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
5737 SND_PCI_QUIRK(0x103c, 0x2238, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
5738 SND_PCI_QUIRK(0x103c, 0x2239, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
5739 SND_PCI_QUIRK(0x103c, 0x224b, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
5740 SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5741 SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5742 SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5743 SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5744 SND_PCI_QUIRK(0x103c, 0x2271, "HP", ALC286_FIXUP_HP_GPIO_LED),
5745 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC280_FIXUP_HP_DOCK_PINS),
5746 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC280_FIXUP_HP_DOCK_PINS),
5747 SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5748 SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5749 SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5750 SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5751 SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5752 SND_PCI_QUIRK(0x103c, 0x22db, "HP", ALC280_FIXUP_HP_9480M),
5753 SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5754 SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5755 /* ALC290 */
5756 SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5757 SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5758 SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5759 SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5760 SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5761 SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5762 SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5763 SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5764 SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5765 SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED),
5766 SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5767 SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5768 SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5769 SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5770 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5771 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5772 SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5773 SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5774 SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5775 SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5776 SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5777 SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5778 SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5779 SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5780 SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5781 SND_PCI_QUIRK(0x103c, 0x2334, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5782 SND_PCI_QUIRK(0x103c, 0x2335, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5783 SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5784 SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5785 SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC),
5786 SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC),
5787 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
5788 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5789 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5790 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
5791 SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
5792 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
5793 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
5794 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
5795 SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5796 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
5797 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
5798 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
5799 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
5800 SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101),
5801 SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
5802 SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
5803 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
5804 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
5805 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
5806 SND_PCI_QUIRK(0x104d, 0x9099, "Sony VAIO S13", ALC275_FIXUP_SONY_DISABLE_AAMIX),
5807 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
5808 SND_PCI_QUIRK(0x10cf, 0x159f, "Lifebook E780", ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT),
5809 SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN),
5810 SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN),
5811 SND_PCI_QUIRK(0x10cf, 0x1629, "Lifebook U7x7", ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC),
5812 SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
5813 SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC),
5814 SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
5815 SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
5816 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
5817 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
5818 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
5819 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
5820 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
5821 SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK),
5822 SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
5823 SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
5824 SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
5825 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
5826 SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
5827 SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad T440s", ALC292_FIXUP_TPT440),
5828 SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK),
5829 SND_PCI_QUIRK(0x17aa, 0x2210, "Thinkpad T540p", ALC292_FIXUP_TPT440_DOCK),
5830 SND_PCI_QUIRK(0x17aa, 0x2211, "Thinkpad W541", ALC292_FIXUP_TPT440_DOCK),
5831 SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK),
5832 SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad X240", ALC292_FIXUP_TPT440_DOCK),
5833 SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5834 SND_PCI_QUIRK(0x17aa, 0x2218, "Thinkpad X1 Carbon 2nd", ALC292_FIXUP_TPT440_DOCK),
5835 SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
5836 SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
5837 SND_PCI_QUIRK(0x17aa, 0x222d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
5838 SND_PCI_QUIRK(0x17aa, 0x222e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
5839 SND_PCI_QUIRK(0x17aa, 0x2231, "Thinkpad T560", ALC292_FIXUP_TPT460),
5840 SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC292_FIXUP_TPT460),
5841 SND_PCI_QUIRK(0x17aa, 0x2245, "Thinkpad T470", ALC298_FIXUP_TPT470_DOCK),
5842 SND_PCI_QUIRK(0x17aa, 0x2246, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
5843 SND_PCI_QUIRK(0x17aa, 0x2247, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
5844 SND_PCI_QUIRK(0x17aa, 0x2249, "Thinkpad", ALC292_FIXUP_TPT460),
5845 SND_PCI_QUIRK(0x17aa, 0x224b, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
5846 SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
5847 SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
5848 SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5849 SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
5850 SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
5851 SND_PCI_QUIRK(0x17aa, 0x3112, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
5852 SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
5853 SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
5854 SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
5855 SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5856 SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC),
5857 SND_PCI_QUIRK(0x17aa, 0x501e, "Thinkpad L440", ALC292_FIXUP_TPT440_DOCK),
5858 SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5859 SND_PCI_QUIRK(0x17aa, 0x5034, "Thinkpad T450", ALC292_FIXUP_TPT440_DOCK),
5860 SND_PCI_QUIRK(0x17aa, 0x5036, "Thinkpad T450s", ALC292_FIXUP_TPT440_DOCK),
5861 SND_PCI_QUIRK(0x17aa, 0x503c, "Thinkpad L450", ALC292_FIXUP_TPT440_DOCK),
5862 SND_PCI_QUIRK(0x17aa, 0x504a, "ThinkPad X260", ALC292_FIXUP_TPT440_DOCK),
5863 SND_PCI_QUIRK(0x17aa, 0x504b, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
5864 SND_PCI_QUIRK(0x17aa, 0x5050, "Thinkpad T560p", ALC292_FIXUP_TPT460),
5865 SND_PCI_QUIRK(0x17aa, 0x5051, "Thinkpad L460", ALC292_FIXUP_TPT460),
5866 SND_PCI_QUIRK(0x17aa, 0x5053, "Thinkpad T460", ALC292_FIXUP_TPT460),
5867 SND_PCI_QUIRK(0x17aa, 0x505d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
5868 SND_PCI_QUIRK(0x17aa, 0x505f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
5869 SND_PCI_QUIRK(0x17aa, 0x5062, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
5870 SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5871 SND_PCI_QUIRK(0x17aa, 0x511e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
5872 SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
5873 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
5874 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
5875 SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
5877 #if 0
5878 /* Below is a quirk table taken from the old code.
5879 * Basically the device should work as is without the fixup table.
5880 * If BIOS doesn't give a proper info, enable the corresponding
5881 * fixup entry.
5883 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
5884 ALC269_FIXUP_AMIC),
5885 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
5886 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
5887 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
5888 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
5889 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC),
5890 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC),
5891 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC),
5892 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC),
5893 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC),
5894 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC),
5895 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC),
5896 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC),
5897 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC),
5898 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC),
5899 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC),
5900 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC),
5901 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC),
5902 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC),
5903 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC),
5904 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC),
5905 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC),
5906 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC),
5907 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC),
5908 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC),
5909 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC),
5910 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC),
5911 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC),
5912 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC),
5913 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC),
5914 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC),
5915 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC),
5916 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC),
5917 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC),
5918 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC),
5919 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC),
5920 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC),
5921 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC),
5922 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC),
5923 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC),
5924 #endif
5928 static const struct snd_pci_quirk alc269_fixup_vendor_tbl[] = {
5929 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
5930 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
5931 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
5932 SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI),
5936 static const struct hda_model_fixup alc269_fixup_models[] = {
5937 {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
5938 {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
5939 {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"},
5940 {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"},
5941 {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"},
5942 {.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"},
5943 {.id = ALC269_FIXUP_HEADSET_MODE, .name = "headset-mode"},
5944 {.id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, .name = "headset-mode-no-hp-mic"},
5945 {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
5946 {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
5947 {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic1-led"},
5948 {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
5949 {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"},
5950 {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"},
5951 {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
5952 {.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"},
5953 {.id = ALC292_FIXUP_TPT440, .name = "tpt440"},
5954 {.id = ALC292_FIXUP_TPT460, .name = "tpt460"},
5957 #define ALC225_STANDARD_PINS \
5958 {0x21, 0x04211020}
5960 #define ALC256_STANDARD_PINS \
5961 {0x12, 0x90a60140}, \
5962 {0x14, 0x90170110}, \
5963 {0x21, 0x02211020}
5965 #define ALC282_STANDARD_PINS \
5966 {0x14, 0x90170110}
5968 #define ALC290_STANDARD_PINS \
5969 {0x12, 0x99a30130}
5971 #define ALC292_STANDARD_PINS \
5972 {0x14, 0x90170110}, \
5973 {0x15, 0x0221401f}
5975 #define ALC295_STANDARD_PINS \
5976 {0x12, 0xb7a60130}, \
5977 {0x14, 0x90170110}, \
5978 {0x21, 0x04211020}
5980 #define ALC298_STANDARD_PINS \
5981 {0x12, 0x90a60130}, \
5982 {0x21, 0x03211020}
5984 static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
5985 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
5986 ALC225_STANDARD_PINS,
5987 {0x12, 0xb7a60130},
5988 {0x14, 0x901701a0}),
5989 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
5990 ALC225_STANDARD_PINS,
5991 {0x12, 0xb7a60130},
5992 {0x14, 0x901701b0}),
5993 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
5994 ALC225_STANDARD_PINS,
5995 {0x12, 0xb7a60150},
5996 {0x14, 0x901701a0}),
5997 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
5998 ALC225_STANDARD_PINS,
5999 {0x12, 0xb7a60150},
6000 {0x14, 0x901701b0}),
6001 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
6002 ALC225_STANDARD_PINS,
6003 {0x12, 0xb7a60130},
6004 {0x1b, 0x90170110}),
6005 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6006 {0x12, 0x90a60140},
6007 {0x14, 0x90170110},
6008 {0x21, 0x02211020}),
6009 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6010 {0x12, 0x90a60140},
6011 {0x14, 0x90170150},
6012 {0x21, 0x02211020}),
6013 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
6014 {0x14, 0x90170110},
6015 {0x21, 0x02211020}),
6016 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6017 {0x14, 0x90170130},
6018 {0x21, 0x02211040}),
6019 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6020 {0x12, 0x90a60140},
6021 {0x14, 0x90170110},
6022 {0x21, 0x02211020}),
6023 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6024 {0x12, 0x90a60160},
6025 {0x14, 0x90170120},
6026 {0x21, 0x02211030}),
6027 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6028 {0x14, 0x90170110},
6029 {0x1b, 0x02011020},
6030 {0x21, 0x0221101f}),
6031 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6032 {0x14, 0x90170110},
6033 {0x1b, 0x01011020},
6034 {0x21, 0x0221101f}),
6035 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6036 {0x14, 0x90170130},
6037 {0x1b, 0x01014020},
6038 {0x21, 0x0221103f}),
6039 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6040 {0x14, 0x90170130},
6041 {0x1b, 0x01011020},
6042 {0x21, 0x0221103f}),
6043 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6044 {0x14, 0x90170130},
6045 {0x1b, 0x02011020},
6046 {0x21, 0x0221103f}),
6047 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6048 {0x14, 0x90170150},
6049 {0x1b, 0x02011020},
6050 {0x21, 0x0221105f}),
6051 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6052 {0x14, 0x90170110},
6053 {0x1b, 0x01014020},
6054 {0x21, 0x0221101f}),
6055 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6056 {0x12, 0x90a60160},
6057 {0x14, 0x90170120},
6058 {0x17, 0x90170140},
6059 {0x21, 0x0321102f}),
6060 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6061 {0x12, 0x90a60160},
6062 {0x14, 0x90170130},
6063 {0x21, 0x02211040}),
6064 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6065 {0x12, 0x90a60160},
6066 {0x14, 0x90170140},
6067 {0x21, 0x02211050}),
6068 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6069 {0x12, 0x90a60170},
6070 {0x14, 0x90170120},
6071 {0x21, 0x02211030}),
6072 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6073 {0x12, 0x90a60170},
6074 {0x14, 0x90170130},
6075 {0x21, 0x02211040}),
6076 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6077 {0x12, 0x90a60170},
6078 {0x14, 0x90171130},
6079 {0x21, 0x02211040}),
6080 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6081 {0x12, 0x90a60170},
6082 {0x14, 0x90170140},
6083 {0x21, 0x02211050}),
6084 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5548", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6085 {0x12, 0x90a60180},
6086 {0x14, 0x90170130},
6087 {0x21, 0x02211040}),
6088 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5565", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6089 {0x12, 0x90a60180},
6090 {0x14, 0x90170120},
6091 {0x21, 0x02211030}),
6092 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6093 {0x1b, 0x01011020},
6094 {0x21, 0x02211010}),
6095 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6096 {0x12, 0x90a60130},
6097 {0x14, 0x90170110},
6098 {0x1b, 0x01011020},
6099 {0x21, 0x0221101f}),
6100 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6101 {0x12, 0x90a60160},
6102 {0x14, 0x90170120},
6103 {0x21, 0x02211030}),
6104 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6105 {0x12, 0x90a60170},
6106 {0x14, 0x90170120},
6107 {0x21, 0x02211030}),
6108 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell Inspiron 5468", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6109 {0x12, 0x90a60180},
6110 {0x14, 0x90170120},
6111 {0x21, 0x02211030}),
6112 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6113 {0x12, 0xb7a60130},
6114 {0x14, 0x90170110},
6115 {0x21, 0x02211020}),
6116 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6117 {0x12, 0x90a60130},
6118 {0x14, 0x90170110},
6119 {0x14, 0x01011020},
6120 {0x21, 0x0221101f}),
6121 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6122 ALC256_STANDARD_PINS),
6123 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
6124 {0x12, 0x90a60130},
6125 {0x14, 0x90170110},
6126 {0x15, 0x0421101f},
6127 {0x1a, 0x04a11020}),
6128 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED,
6129 {0x12, 0x90a60140},
6130 {0x14, 0x90170110},
6131 {0x15, 0x0421101f},
6132 {0x18, 0x02811030},
6133 {0x1a, 0x04a1103f},
6134 {0x1b, 0x02011020}),
6135 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP 15 Touchsmart", ALC269_FIXUP_HP_MUTE_LED_MIC1,
6136 ALC282_STANDARD_PINS,
6137 {0x12, 0x99a30130},
6138 {0x19, 0x03a11020},
6139 {0x21, 0x0321101f}),
6140 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
6141 ALC282_STANDARD_PINS,
6142 {0x12, 0x99a30130},
6143 {0x19, 0x03a11020},
6144 {0x21, 0x03211040}),
6145 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
6146 ALC282_STANDARD_PINS,
6147 {0x12, 0x99a30130},
6148 {0x19, 0x03a11030},
6149 {0x21, 0x03211020}),
6150 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
6151 ALC282_STANDARD_PINS,
6152 {0x12, 0x99a30130},
6153 {0x19, 0x04a11020},
6154 {0x21, 0x0421101f}),
6155 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED,
6156 ALC282_STANDARD_PINS,
6157 {0x12, 0x90a60140},
6158 {0x19, 0x04a11030},
6159 {0x21, 0x04211020}),
6160 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
6161 ALC282_STANDARD_PINS,
6162 {0x12, 0x90a60130},
6163 {0x21, 0x0321101f}),
6164 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
6165 {0x12, 0x90a60160},
6166 {0x14, 0x90170120},
6167 {0x21, 0x02211030}),
6168 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
6169 ALC282_STANDARD_PINS,
6170 {0x12, 0x90a60130},
6171 {0x19, 0x03a11020},
6172 {0x21, 0x0321101f}),
6173 SND_HDA_PIN_QUIRK(0x10ec0288, 0x1028, "Dell", ALC288_FIXUP_DELL_XPS_13_GPIO6,
6174 {0x12, 0x90a60120},
6175 {0x14, 0x90170110},
6176 {0x21, 0x0321101f}),
6177 SND_HDA_PIN_QUIRK(0x10ec0289, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
6178 {0x12, 0xb7a60130},
6179 {0x14, 0x90170110},
6180 {0x21, 0x04211020}),
6181 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
6182 ALC290_STANDARD_PINS,
6183 {0x15, 0x04211040},
6184 {0x18, 0x90170112},
6185 {0x1a, 0x04a11020}),
6186 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
6187 ALC290_STANDARD_PINS,
6188 {0x15, 0x04211040},
6189 {0x18, 0x90170110},
6190 {0x1a, 0x04a11020}),
6191 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
6192 ALC290_STANDARD_PINS,
6193 {0x15, 0x0421101f},
6194 {0x1a, 0x04a11020}),
6195 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
6196 ALC290_STANDARD_PINS,
6197 {0x15, 0x04211020},
6198 {0x1a, 0x04a11040}),
6199 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
6200 ALC290_STANDARD_PINS,
6201 {0x14, 0x90170110},
6202 {0x15, 0x04211020},
6203 {0x1a, 0x04a11040}),
6204 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
6205 ALC290_STANDARD_PINS,
6206 {0x14, 0x90170110},
6207 {0x15, 0x04211020},
6208 {0x1a, 0x04a11020}),
6209 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
6210 ALC290_STANDARD_PINS,
6211 {0x14, 0x90170110},
6212 {0x15, 0x0421101f},
6213 {0x1a, 0x04a11020}),
6214 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
6215 ALC292_STANDARD_PINS,
6216 {0x12, 0x90a60140},
6217 {0x16, 0x01014020},
6218 {0x19, 0x01a19030}),
6219 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
6220 ALC292_STANDARD_PINS,
6221 {0x12, 0x90a60140},
6222 {0x16, 0x01014020},
6223 {0x18, 0x02a19031},
6224 {0x19, 0x01a1903e}),
6225 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
6226 ALC292_STANDARD_PINS,
6227 {0x12, 0x90a60140}),
6228 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
6229 ALC292_STANDARD_PINS,
6230 {0x13, 0x90a60140},
6231 {0x16, 0x21014020},
6232 {0x19, 0x21a19030}),
6233 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
6234 ALC292_STANDARD_PINS,
6235 {0x13, 0x90a60140}),
6236 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
6237 ALC295_STANDARD_PINS,
6238 {0x17, 0x21014020},
6239 {0x18, 0x21a19030}),
6240 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
6241 ALC295_STANDARD_PINS,
6242 {0x17, 0x21014040},
6243 {0x18, 0x21a19050}),
6244 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
6245 ALC295_STANDARD_PINS),
6246 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
6247 ALC298_STANDARD_PINS,
6248 {0x17, 0x90170110}),
6249 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
6250 ALC298_STANDARD_PINS,
6251 {0x17, 0x90170140}),
6252 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
6253 ALC298_STANDARD_PINS,
6254 {0x17, 0x90170150}),
6255 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_SPK_VOLUME,
6256 {0x12, 0xb7a60140},
6257 {0x13, 0xb7a60150},
6258 {0x17, 0x90170110},
6259 {0x1a, 0x03011020},
6260 {0x21, 0x03211030}),
6264 static void alc269_fill_coef(struct hda_codec *codec)
6266 struct alc_spec *spec = codec->spec;
6267 int val;
6269 if (spec->codec_variant != ALC269_TYPE_ALC269VB)
6270 return;
6272 if ((alc_get_coef0(codec) & 0x00ff) < 0x015) {
6273 alc_write_coef_idx(codec, 0xf, 0x960b);
6274 alc_write_coef_idx(codec, 0xe, 0x8817);
6277 if ((alc_get_coef0(codec) & 0x00ff) == 0x016) {
6278 alc_write_coef_idx(codec, 0xf, 0x960b);
6279 alc_write_coef_idx(codec, 0xe, 0x8814);
6282 if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
6283 /* Power up output pin */
6284 alc_update_coef_idx(codec, 0x04, 0, 1<<11);
6287 if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
6288 val = alc_read_coef_idx(codec, 0xd);
6289 if (val != -1 && (val & 0x0c00) >> 10 != 0x1) {
6290 /* Capless ramp up clock control */
6291 alc_write_coef_idx(codec, 0xd, val | (1<<10));
6293 val = alc_read_coef_idx(codec, 0x17);
6294 if (val != -1 && (val & 0x01c0) >> 6 != 0x4) {
6295 /* Class D power on reset */
6296 alc_write_coef_idx(codec, 0x17, val | (1<<7));
6300 /* HP */
6301 alc_update_coef_idx(codec, 0x4, 0, 1<<11);
6306 static int patch_alc269(struct hda_codec *codec)
6308 struct alc_spec *spec;
6309 int err;
6311 err = alc_alloc_spec(codec, 0x0b);
6312 if (err < 0)
6313 return err;
6315 spec = codec->spec;
6316 spec->gen.shared_mic_vref_pin = 0x18;
6317 codec->power_save_node = 0;
6319 #ifdef CONFIG_PM
6320 codec->patch_ops.suspend = alc269_suspend;
6321 codec->patch_ops.resume = alc269_resume;
6322 #endif
6323 spec->shutup = alc269_shutup;
6325 snd_hda_pick_fixup(codec, alc269_fixup_models,
6326 alc269_fixup_tbl, alc269_fixups);
6327 snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups);
6328 snd_hda_pick_fixup(codec, NULL, alc269_fixup_vendor_tbl,
6329 alc269_fixups);
6330 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
6332 alc_auto_parse_customize_define(codec);
6334 if (has_cdefine_beep(codec))
6335 spec->gen.beep_nid = 0x01;
6337 switch (codec->core.vendor_id) {
6338 case 0x10ec0269:
6339 spec->codec_variant = ALC269_TYPE_ALC269VA;
6340 switch (alc_get_coef0(codec) & 0x00f0) {
6341 case 0x0010:
6342 if (codec->bus->pci &&
6343 codec->bus->pci->subsystem_vendor == 0x1025 &&
6344 spec->cdefine.platform_type == 1)
6345 err = alc_codec_rename(codec, "ALC271X");
6346 spec->codec_variant = ALC269_TYPE_ALC269VB;
6347 break;
6348 case 0x0020:
6349 if (codec->bus->pci &&
6350 codec->bus->pci->subsystem_vendor == 0x17aa &&
6351 codec->bus->pci->subsystem_device == 0x21f3)
6352 err = alc_codec_rename(codec, "ALC3202");
6353 spec->codec_variant = ALC269_TYPE_ALC269VC;
6354 break;
6355 case 0x0030:
6356 spec->codec_variant = ALC269_TYPE_ALC269VD;
6357 break;
6358 default:
6359 alc_fix_pll_init(codec, 0x20, 0x04, 15);
6361 if (err < 0)
6362 goto error;
6363 spec->init_hook = alc269_fill_coef;
6364 alc269_fill_coef(codec);
6365 break;
6367 case 0x10ec0280:
6368 case 0x10ec0290:
6369 spec->codec_variant = ALC269_TYPE_ALC280;
6370 break;
6371 case 0x10ec0282:
6372 spec->codec_variant = ALC269_TYPE_ALC282;
6373 spec->shutup = alc282_shutup;
6374 spec->init_hook = alc282_init;
6375 break;
6376 case 0x10ec0233:
6377 case 0x10ec0283:
6378 spec->codec_variant = ALC269_TYPE_ALC283;
6379 spec->shutup = alc283_shutup;
6380 spec->init_hook = alc283_init;
6381 break;
6382 case 0x10ec0284:
6383 case 0x10ec0292:
6384 spec->codec_variant = ALC269_TYPE_ALC284;
6385 break;
6386 case 0x10ec0285:
6387 case 0x10ec0293:
6388 spec->codec_variant = ALC269_TYPE_ALC285;
6389 break;
6390 case 0x10ec0286:
6391 case 0x10ec0288:
6392 spec->codec_variant = ALC269_TYPE_ALC286;
6393 spec->shutup = alc286_shutup;
6394 break;
6395 case 0x10ec0298:
6396 spec->codec_variant = ALC269_TYPE_ALC298;
6397 break;
6398 case 0x10ec0235:
6399 case 0x10ec0255:
6400 spec->codec_variant = ALC269_TYPE_ALC255;
6401 break;
6402 case 0x10ec0236:
6403 case 0x10ec0256:
6404 spec->codec_variant = ALC269_TYPE_ALC256;
6405 spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */
6406 alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/
6407 break;
6408 case 0x10ec0257:
6409 spec->codec_variant = ALC269_TYPE_ALC257;
6410 spec->gen.mixer_nid = 0;
6411 break;
6412 case 0x10ec0225:
6413 case 0x10ec0295:
6414 spec->codec_variant = ALC269_TYPE_ALC225;
6415 break;
6416 case 0x10ec0299:
6417 spec->codec_variant = ALC269_TYPE_ALC225;
6418 spec->gen.mixer_nid = 0; /* no loopback on ALC299 */
6419 break;
6420 case 0x10ec0234:
6421 case 0x10ec0274:
6422 case 0x10ec0294:
6423 spec->codec_variant = ALC269_TYPE_ALC294;
6424 break;
6425 case 0x10ec0700:
6426 case 0x10ec0701:
6427 case 0x10ec0703:
6428 case 0x10ec0711:
6429 spec->codec_variant = ALC269_TYPE_ALC700;
6430 spec->gen.mixer_nid = 0; /* ALC700 does not have any loopback mixer path */
6431 alc_update_coef_idx(codec, 0x4a, 1 << 15, 0); /* Combo jack auto trigger control */
6432 break;
6436 if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
6437 spec->has_alc5505_dsp = 1;
6438 spec->init_hook = alc5505_dsp_init;
6441 /* automatic parse from the BIOS config */
6442 err = alc269_parse_auto_config(codec);
6443 if (err < 0)
6444 goto error;
6446 if (!spec->gen.no_analog && spec->gen.beep_nid && spec->gen.mixer_nid)
6447 set_beep_amp(spec, spec->gen.mixer_nid, 0x04, HDA_INPUT);
6449 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
6451 return 0;
6453 error:
6454 alc_free(codec);
6455 return err;
6459 * ALC861
6462 static int alc861_parse_auto_config(struct hda_codec *codec)
6464 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
6465 static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 };
6466 return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
6469 /* Pin config fixes */
6470 enum {
6471 ALC861_FIXUP_FSC_AMILO_PI1505,
6472 ALC861_FIXUP_AMP_VREF_0F,
6473 ALC861_FIXUP_NO_JACK_DETECT,
6474 ALC861_FIXUP_ASUS_A6RP,
6475 ALC660_FIXUP_ASUS_W7J,
6478 /* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
6479 static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
6480 const struct hda_fixup *fix, int action)
6482 struct alc_spec *spec = codec->spec;
6483 unsigned int val;
6485 if (action != HDA_FIXUP_ACT_INIT)
6486 return;
6487 val = snd_hda_codec_get_pin_target(codec, 0x0f);
6488 if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
6489 val |= AC_PINCTL_IN_EN;
6490 val |= AC_PINCTL_VREF_50;
6491 snd_hda_set_pin_ctl(codec, 0x0f, val);
6492 spec->gen.keep_vref_in_automute = 1;
6495 /* suppress the jack-detection */
6496 static void alc_fixup_no_jack_detect(struct hda_codec *codec,
6497 const struct hda_fixup *fix, int action)
6499 if (action == HDA_FIXUP_ACT_PRE_PROBE)
6500 codec->no_jack_detect = 1;
6503 static const struct hda_fixup alc861_fixups[] = {
6504 [ALC861_FIXUP_FSC_AMILO_PI1505] = {
6505 .type = HDA_FIXUP_PINS,
6506 .v.pins = (const struct hda_pintbl[]) {
6507 { 0x0b, 0x0221101f }, /* HP */
6508 { 0x0f, 0x90170310 }, /* speaker */
6512 [ALC861_FIXUP_AMP_VREF_0F] = {
6513 .type = HDA_FIXUP_FUNC,
6514 .v.func = alc861_fixup_asus_amp_vref_0f,
6516 [ALC861_FIXUP_NO_JACK_DETECT] = {
6517 .type = HDA_FIXUP_FUNC,
6518 .v.func = alc_fixup_no_jack_detect,
6520 [ALC861_FIXUP_ASUS_A6RP] = {
6521 .type = HDA_FIXUP_FUNC,
6522 .v.func = alc861_fixup_asus_amp_vref_0f,
6523 .chained = true,
6524 .chain_id = ALC861_FIXUP_NO_JACK_DETECT,
6526 [ALC660_FIXUP_ASUS_W7J] = {
6527 .type = HDA_FIXUP_VERBS,
6528 .v.verbs = (const struct hda_verb[]) {
6529 /* ASUS W7J needs a magic pin setup on unused NID 0x10
6530 * for enabling outputs
6532 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6538 static const struct snd_pci_quirk alc861_fixup_tbl[] = {
6539 SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J),
6540 SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J),
6541 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
6542 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
6543 SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
6544 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F),
6545 SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F),
6546 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
6552 static int patch_alc861(struct hda_codec *codec)
6554 struct alc_spec *spec;
6555 int err;
6557 err = alc_alloc_spec(codec, 0x15);
6558 if (err < 0)
6559 return err;
6561 spec = codec->spec;
6562 spec->gen.beep_nid = 0x23;
6564 #ifdef CONFIG_PM
6565 spec->power_hook = alc_power_eapd;
6566 #endif
6568 snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
6569 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
6571 /* automatic parse from the BIOS config */
6572 err = alc861_parse_auto_config(codec);
6573 if (err < 0)
6574 goto error;
6576 if (!spec->gen.no_analog)
6577 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
6579 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
6581 return 0;
6583 error:
6584 alc_free(codec);
6585 return err;
6589 * ALC861-VD support
6591 * Based on ALC882
6593 * In addition, an independent DAC
6595 static int alc861vd_parse_auto_config(struct hda_codec *codec)
6597 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
6598 static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 };
6599 return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids);
6602 enum {
6603 ALC660VD_FIX_ASUS_GPIO1,
6604 ALC861VD_FIX_DALLAS,
6607 /* exclude VREF80 */
6608 static void alc861vd_fixup_dallas(struct hda_codec *codec,
6609 const struct hda_fixup *fix, int action)
6611 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
6612 snd_hda_override_pin_caps(codec, 0x18, 0x00000734);
6613 snd_hda_override_pin_caps(codec, 0x19, 0x0000073c);
6617 static const struct hda_fixup alc861vd_fixups[] = {
6618 [ALC660VD_FIX_ASUS_GPIO1] = {
6619 .type = HDA_FIXUP_VERBS,
6620 .v.verbs = (const struct hda_verb[]) {
6621 /* reset GPIO1 */
6622 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6623 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6624 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6628 [ALC861VD_FIX_DALLAS] = {
6629 .type = HDA_FIXUP_FUNC,
6630 .v.func = alc861vd_fixup_dallas,
6634 static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
6635 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS),
6636 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
6637 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS),
6643 static int patch_alc861vd(struct hda_codec *codec)
6645 struct alc_spec *spec;
6646 int err;
6648 err = alc_alloc_spec(codec, 0x0b);
6649 if (err < 0)
6650 return err;
6652 spec = codec->spec;
6653 spec->gen.beep_nid = 0x23;
6655 spec->shutup = alc_eapd_shutup;
6657 snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
6658 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
6660 /* automatic parse from the BIOS config */
6661 err = alc861vd_parse_auto_config(codec);
6662 if (err < 0)
6663 goto error;
6665 if (!spec->gen.no_analog)
6666 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
6668 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
6670 return 0;
6672 error:
6673 alc_free(codec);
6674 return err;
6678 * ALC662 support
6680 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
6681 * configuration. Each pin widget can choose any input DACs and a mixer.
6682 * Each ADC is connected from a mixer of all inputs. This makes possible
6683 * 6-channel independent captures.
6685 * In addition, an independent DAC for the multi-playback (not used in this
6686 * driver yet).
6690 * BIOS auto configuration
6693 static int alc662_parse_auto_config(struct hda_codec *codec)
6695 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
6696 static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 };
6697 static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 };
6698 const hda_nid_t *ssids;
6700 if (codec->core.vendor_id == 0x10ec0272 || codec->core.vendor_id == 0x10ec0663 ||
6701 codec->core.vendor_id == 0x10ec0665 || codec->core.vendor_id == 0x10ec0670 ||
6702 codec->core.vendor_id == 0x10ec0671)
6703 ssids = alc663_ssids;
6704 else
6705 ssids = alc662_ssids;
6706 return alc_parse_auto_config(codec, alc662_ignore, ssids);
6709 static void alc272_fixup_mario(struct hda_codec *codec,
6710 const struct hda_fixup *fix, int action)
6712 if (action != HDA_FIXUP_ACT_PRE_PROBE)
6713 return;
6714 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
6715 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
6716 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
6717 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
6718 (0 << AC_AMPCAP_MUTE_SHIFT)))
6719 codec_warn(codec, "failed to override amp caps for NID 0x2\n");
6722 static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = {
6723 { .channels = 2,
6724 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
6725 { .channels = 4,
6726 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
6727 SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */
6731 /* override the 2.1 chmap */
6732 static void alc_fixup_bass_chmap(struct hda_codec *codec,
6733 const struct hda_fixup *fix, int action)
6735 if (action == HDA_FIXUP_ACT_BUILD) {
6736 struct alc_spec *spec = codec->spec;
6737 spec->gen.pcm_rec[0]->stream[0].chmap = asus_pcm_2_1_chmaps;
6741 /* avoid D3 for keeping GPIO up */
6742 static unsigned int gpio_led_power_filter(struct hda_codec *codec,
6743 hda_nid_t nid,
6744 unsigned int power_state)
6746 struct alc_spec *spec = codec->spec;
6747 if (nid == codec->core.afg && power_state == AC_PWRST_D3 && spec->gpio_led)
6748 return AC_PWRST_D0;
6749 return power_state;
6752 static void alc662_fixup_led_gpio1(struct hda_codec *codec,
6753 const struct hda_fixup *fix, int action)
6755 struct alc_spec *spec = codec->spec;
6756 static const struct hda_verb gpio_init[] = {
6757 { 0x01, AC_VERB_SET_GPIO_MASK, 0x01 },
6758 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01 },
6762 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
6763 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
6764 spec->gpio_led = 0;
6765 spec->mute_led_polarity = 1;
6766 spec->gpio_mute_led_mask = 0x01;
6767 snd_hda_add_verbs(codec, gpio_init);
6768 codec->power_filter = gpio_led_power_filter;
6772 static struct coef_fw alc668_coefs[] = {
6773 WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03, 0x0),
6774 WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06, 0x0), WRITE_COEF(0x07, 0x0f80),
6775 WRITE_COEF(0x08, 0x0031), WRITE_COEF(0x0a, 0x0060), WRITE_COEF(0x0b, 0x0),
6776 WRITE_COEF(0x0c, 0x7cf7), WRITE_COEF(0x0d, 0x1080), WRITE_COEF(0x0e, 0x7f7f),
6777 WRITE_COEF(0x0f, 0xcccc), WRITE_COEF(0x10, 0xddcc), WRITE_COEF(0x11, 0x0001),
6778 WRITE_COEF(0x13, 0x0), WRITE_COEF(0x14, 0x2aa0), WRITE_COEF(0x17, 0xa940),
6779 WRITE_COEF(0x19, 0x0), WRITE_COEF(0x1a, 0x0), WRITE_COEF(0x1b, 0x0),
6780 WRITE_COEF(0x1c, 0x0), WRITE_COEF(0x1d, 0x0), WRITE_COEF(0x1e, 0x7418),
6781 WRITE_COEF(0x1f, 0x0804), WRITE_COEF(0x20, 0x4200), WRITE_COEF(0x21, 0x0468),
6782 WRITE_COEF(0x22, 0x8ccc), WRITE_COEF(0x23, 0x0250), WRITE_COEF(0x24, 0x7418),
6783 WRITE_COEF(0x27, 0x0), WRITE_COEF(0x28, 0x8ccc), WRITE_COEF(0x2a, 0xff00),
6784 WRITE_COEF(0x2b, 0x8000), WRITE_COEF(0xa7, 0xff00), WRITE_COEF(0xa8, 0x8000),
6785 WRITE_COEF(0xaa, 0x2e17), WRITE_COEF(0xab, 0xa0c0), WRITE_COEF(0xac, 0x0),
6786 WRITE_COEF(0xad, 0x0), WRITE_COEF(0xae, 0x2ac6), WRITE_COEF(0xaf, 0xa480),
6787 WRITE_COEF(0xb0, 0x0), WRITE_COEF(0xb1, 0x0), WRITE_COEF(0xb2, 0x0),
6788 WRITE_COEF(0xb3, 0x0), WRITE_COEF(0xb4, 0x0), WRITE_COEF(0xb5, 0x1040),
6789 WRITE_COEF(0xb6, 0xd697), WRITE_COEF(0xb7, 0x902b), WRITE_COEF(0xb8, 0xd697),
6790 WRITE_COEF(0xb9, 0x902b), WRITE_COEF(0xba, 0xb8ba), WRITE_COEF(0xbb, 0xaaab),
6791 WRITE_COEF(0xbc, 0xaaaf), WRITE_COEF(0xbd, 0x6aaa), WRITE_COEF(0xbe, 0x1c02),
6792 WRITE_COEF(0xc0, 0x00ff), WRITE_COEF(0xc1, 0x0fa6),
6796 static void alc668_restore_default_value(struct hda_codec *codec)
6798 alc_process_coef_fw(codec, alc668_coefs);
6801 enum {
6802 ALC662_FIXUP_ASPIRE,
6803 ALC662_FIXUP_LED_GPIO1,
6804 ALC662_FIXUP_IDEAPAD,
6805 ALC272_FIXUP_MARIO,
6806 ALC662_FIXUP_CZC_P10T,
6807 ALC662_FIXUP_SKU_IGNORE,
6808 ALC662_FIXUP_HP_RP5800,
6809 ALC662_FIXUP_ASUS_MODE1,
6810 ALC662_FIXUP_ASUS_MODE2,
6811 ALC662_FIXUP_ASUS_MODE3,
6812 ALC662_FIXUP_ASUS_MODE4,
6813 ALC662_FIXUP_ASUS_MODE5,
6814 ALC662_FIXUP_ASUS_MODE6,
6815 ALC662_FIXUP_ASUS_MODE7,
6816 ALC662_FIXUP_ASUS_MODE8,
6817 ALC662_FIXUP_NO_JACK_DETECT,
6818 ALC662_FIXUP_ZOTAC_Z68,
6819 ALC662_FIXUP_INV_DMIC,
6820 ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
6821 ALC668_FIXUP_DELL_MIC_NO_PRESENCE,
6822 ALC662_FIXUP_HEADSET_MODE,
6823 ALC668_FIXUP_HEADSET_MODE,
6824 ALC662_FIXUP_BASS_MODE4_CHMAP,
6825 ALC662_FIXUP_BASS_16,
6826 ALC662_FIXUP_BASS_1A,
6827 ALC662_FIXUP_BASS_CHMAP,
6828 ALC668_FIXUP_AUTO_MUTE,
6829 ALC668_FIXUP_DELL_DISABLE_AAMIX,
6830 ALC668_FIXUP_DELL_XPS13,
6831 ALC662_FIXUP_ASUS_Nx50,
6832 ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
6833 ALC668_FIXUP_ASUS_Nx51,
6834 ALC668_FIXUP_MIC_COEF,
6835 ALC668_FIXUP_ASUS_G751,
6836 ALC891_FIXUP_HEADSET_MODE,
6837 ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
6838 ALC662_FIXUP_ACER_VERITON,
6839 ALC892_FIXUP_ASROCK_MOBO,
6842 static const struct hda_fixup alc662_fixups[] = {
6843 [ALC662_FIXUP_ASPIRE] = {
6844 .type = HDA_FIXUP_PINS,
6845 .v.pins = (const struct hda_pintbl[]) {
6846 { 0x15, 0x99130112 }, /* subwoofer */
6850 [ALC662_FIXUP_LED_GPIO1] = {
6851 .type = HDA_FIXUP_FUNC,
6852 .v.func = alc662_fixup_led_gpio1,
6854 [ALC662_FIXUP_IDEAPAD] = {
6855 .type = HDA_FIXUP_PINS,
6856 .v.pins = (const struct hda_pintbl[]) {
6857 { 0x17, 0x99130112 }, /* subwoofer */
6860 .chained = true,
6861 .chain_id = ALC662_FIXUP_LED_GPIO1,
6863 [ALC272_FIXUP_MARIO] = {
6864 .type = HDA_FIXUP_FUNC,
6865 .v.func = alc272_fixup_mario,
6867 [ALC662_FIXUP_CZC_P10T] = {
6868 .type = HDA_FIXUP_VERBS,
6869 .v.verbs = (const struct hda_verb[]) {
6870 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
6874 [ALC662_FIXUP_SKU_IGNORE] = {
6875 .type = HDA_FIXUP_FUNC,
6876 .v.func = alc_fixup_sku_ignore,
6878 [ALC662_FIXUP_HP_RP5800] = {
6879 .type = HDA_FIXUP_PINS,
6880 .v.pins = (const struct hda_pintbl[]) {
6881 { 0x14, 0x0221201f }, /* HP out */
6884 .chained = true,
6885 .chain_id = ALC662_FIXUP_SKU_IGNORE
6887 [ALC662_FIXUP_ASUS_MODE1] = {
6888 .type = HDA_FIXUP_PINS,
6889 .v.pins = (const struct hda_pintbl[]) {
6890 { 0x14, 0x99130110 }, /* speaker */
6891 { 0x18, 0x01a19c20 }, /* mic */
6892 { 0x19, 0x99a3092f }, /* int-mic */
6893 { 0x21, 0x0121401f }, /* HP out */
6896 .chained = true,
6897 .chain_id = ALC662_FIXUP_SKU_IGNORE
6899 [ALC662_FIXUP_ASUS_MODE2] = {
6900 .type = HDA_FIXUP_PINS,
6901 .v.pins = (const struct hda_pintbl[]) {
6902 { 0x14, 0x99130110 }, /* speaker */
6903 { 0x18, 0x01a19820 }, /* mic */
6904 { 0x19, 0x99a3092f }, /* int-mic */
6905 { 0x1b, 0x0121401f }, /* HP out */
6908 .chained = true,
6909 .chain_id = ALC662_FIXUP_SKU_IGNORE
6911 [ALC662_FIXUP_ASUS_MODE3] = {
6912 .type = HDA_FIXUP_PINS,
6913 .v.pins = (const struct hda_pintbl[]) {
6914 { 0x14, 0x99130110 }, /* speaker */
6915 { 0x15, 0x0121441f }, /* HP */
6916 { 0x18, 0x01a19840 }, /* mic */
6917 { 0x19, 0x99a3094f }, /* int-mic */
6918 { 0x21, 0x01211420 }, /* HP2 */
6921 .chained = true,
6922 .chain_id = ALC662_FIXUP_SKU_IGNORE
6924 [ALC662_FIXUP_ASUS_MODE4] = {
6925 .type = HDA_FIXUP_PINS,
6926 .v.pins = (const struct hda_pintbl[]) {
6927 { 0x14, 0x99130110 }, /* speaker */
6928 { 0x16, 0x99130111 }, /* speaker */
6929 { 0x18, 0x01a19840 }, /* mic */
6930 { 0x19, 0x99a3094f }, /* int-mic */
6931 { 0x21, 0x0121441f }, /* HP */
6934 .chained = true,
6935 .chain_id = ALC662_FIXUP_SKU_IGNORE
6937 [ALC662_FIXUP_ASUS_MODE5] = {
6938 .type = HDA_FIXUP_PINS,
6939 .v.pins = (const struct hda_pintbl[]) {
6940 { 0x14, 0x99130110 }, /* speaker */
6941 { 0x15, 0x0121441f }, /* HP */
6942 { 0x16, 0x99130111 }, /* speaker */
6943 { 0x18, 0x01a19840 }, /* mic */
6944 { 0x19, 0x99a3094f }, /* int-mic */
6947 .chained = true,
6948 .chain_id = ALC662_FIXUP_SKU_IGNORE
6950 [ALC662_FIXUP_ASUS_MODE6] = {
6951 .type = HDA_FIXUP_PINS,
6952 .v.pins = (const struct hda_pintbl[]) {
6953 { 0x14, 0x99130110 }, /* speaker */
6954 { 0x15, 0x01211420 }, /* HP2 */
6955 { 0x18, 0x01a19840 }, /* mic */
6956 { 0x19, 0x99a3094f }, /* int-mic */
6957 { 0x1b, 0x0121441f }, /* HP */
6960 .chained = true,
6961 .chain_id = ALC662_FIXUP_SKU_IGNORE
6963 [ALC662_FIXUP_ASUS_MODE7] = {
6964 .type = HDA_FIXUP_PINS,
6965 .v.pins = (const struct hda_pintbl[]) {
6966 { 0x14, 0x99130110 }, /* speaker */
6967 { 0x17, 0x99130111 }, /* speaker */
6968 { 0x18, 0x01a19840 }, /* mic */
6969 { 0x19, 0x99a3094f }, /* int-mic */
6970 { 0x1b, 0x01214020 }, /* HP */
6971 { 0x21, 0x0121401f }, /* HP */
6974 .chained = true,
6975 .chain_id = ALC662_FIXUP_SKU_IGNORE
6977 [ALC662_FIXUP_ASUS_MODE8] = {
6978 .type = HDA_FIXUP_PINS,
6979 .v.pins = (const struct hda_pintbl[]) {
6980 { 0x14, 0x99130110 }, /* speaker */
6981 { 0x12, 0x99a30970 }, /* int-mic */
6982 { 0x15, 0x01214020 }, /* HP */
6983 { 0x17, 0x99130111 }, /* speaker */
6984 { 0x18, 0x01a19840 }, /* mic */
6985 { 0x21, 0x0121401f }, /* HP */
6988 .chained = true,
6989 .chain_id = ALC662_FIXUP_SKU_IGNORE
6991 [ALC662_FIXUP_NO_JACK_DETECT] = {
6992 .type = HDA_FIXUP_FUNC,
6993 .v.func = alc_fixup_no_jack_detect,
6995 [ALC662_FIXUP_ZOTAC_Z68] = {
6996 .type = HDA_FIXUP_PINS,
6997 .v.pins = (const struct hda_pintbl[]) {
6998 { 0x1b, 0x02214020 }, /* Front HP */
7002 [ALC662_FIXUP_INV_DMIC] = {
7003 .type = HDA_FIXUP_FUNC,
7004 .v.func = alc_fixup_inv_dmic,
7006 [ALC668_FIXUP_DELL_XPS13] = {
7007 .type = HDA_FIXUP_FUNC,
7008 .v.func = alc_fixup_dell_xps13,
7009 .chained = true,
7010 .chain_id = ALC668_FIXUP_DELL_DISABLE_AAMIX
7012 [ALC668_FIXUP_DELL_DISABLE_AAMIX] = {
7013 .type = HDA_FIXUP_FUNC,
7014 .v.func = alc_fixup_disable_aamix,
7015 .chained = true,
7016 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
7018 [ALC668_FIXUP_AUTO_MUTE] = {
7019 .type = HDA_FIXUP_FUNC,
7020 .v.func = alc_fixup_auto_mute_via_amp,
7021 .chained = true,
7022 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
7024 [ALC662_FIXUP_DELL_MIC_NO_PRESENCE] = {
7025 .type = HDA_FIXUP_PINS,
7026 .v.pins = (const struct hda_pintbl[]) {
7027 { 0x19, 0x03a1113c }, /* use as headset mic, without its own jack detect */
7028 /* headphone mic by setting pin control of 0x1b (headphone out) to in + vref_50 */
7031 .chained = true,
7032 .chain_id = ALC662_FIXUP_HEADSET_MODE
7034 [ALC662_FIXUP_HEADSET_MODE] = {
7035 .type = HDA_FIXUP_FUNC,
7036 .v.func = alc_fixup_headset_mode_alc662,
7038 [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = {
7039 .type = HDA_FIXUP_PINS,
7040 .v.pins = (const struct hda_pintbl[]) {
7041 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
7042 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
7045 .chained = true,
7046 .chain_id = ALC668_FIXUP_HEADSET_MODE
7048 [ALC668_FIXUP_HEADSET_MODE] = {
7049 .type = HDA_FIXUP_FUNC,
7050 .v.func = alc_fixup_headset_mode_alc668,
7052 [ALC662_FIXUP_BASS_MODE4_CHMAP] = {
7053 .type = HDA_FIXUP_FUNC,
7054 .v.func = alc_fixup_bass_chmap,
7055 .chained = true,
7056 .chain_id = ALC662_FIXUP_ASUS_MODE4
7058 [ALC662_FIXUP_BASS_16] = {
7059 .type = HDA_FIXUP_PINS,
7060 .v.pins = (const struct hda_pintbl[]) {
7061 {0x16, 0x80106111}, /* bass speaker */
7064 .chained = true,
7065 .chain_id = ALC662_FIXUP_BASS_CHMAP,
7067 [ALC662_FIXUP_BASS_1A] = {
7068 .type = HDA_FIXUP_PINS,
7069 .v.pins = (const struct hda_pintbl[]) {
7070 {0x1a, 0x80106111}, /* bass speaker */
7073 .chained = true,
7074 .chain_id = ALC662_FIXUP_BASS_CHMAP,
7076 [ALC662_FIXUP_BASS_CHMAP] = {
7077 .type = HDA_FIXUP_FUNC,
7078 .v.func = alc_fixup_bass_chmap,
7080 [ALC662_FIXUP_ASUS_Nx50] = {
7081 .type = HDA_FIXUP_FUNC,
7082 .v.func = alc_fixup_auto_mute_via_amp,
7083 .chained = true,
7084 .chain_id = ALC662_FIXUP_BASS_1A
7086 [ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE] = {
7087 .type = HDA_FIXUP_FUNC,
7088 .v.func = alc_fixup_headset_mode_alc668,
7089 .chain_id = ALC662_FIXUP_BASS_CHMAP
7091 [ALC668_FIXUP_ASUS_Nx51] = {
7092 .type = HDA_FIXUP_PINS,
7093 .v.pins = (const struct hda_pintbl[]) {
7094 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
7095 { 0x1a, 0x90170151 }, /* bass speaker */
7096 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
7099 .chained = true,
7100 .chain_id = ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
7102 [ALC668_FIXUP_MIC_COEF] = {
7103 .type = HDA_FIXUP_VERBS,
7104 .v.verbs = (const struct hda_verb[]) {
7105 { 0x20, AC_VERB_SET_COEF_INDEX, 0xc3 },
7106 { 0x20, AC_VERB_SET_PROC_COEF, 0x4000 },
7110 [ALC668_FIXUP_ASUS_G751] = {
7111 .type = HDA_FIXUP_PINS,
7112 .v.pins = (const struct hda_pintbl[]) {
7113 { 0x16, 0x0421101f }, /* HP */
7116 .chained = true,
7117 .chain_id = ALC668_FIXUP_MIC_COEF
7119 [ALC891_FIXUP_HEADSET_MODE] = {
7120 .type = HDA_FIXUP_FUNC,
7121 .v.func = alc_fixup_headset_mode,
7123 [ALC891_FIXUP_DELL_MIC_NO_PRESENCE] = {
7124 .type = HDA_FIXUP_PINS,
7125 .v.pins = (const struct hda_pintbl[]) {
7126 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
7127 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
7130 .chained = true,
7131 .chain_id = ALC891_FIXUP_HEADSET_MODE
7133 [ALC662_FIXUP_ACER_VERITON] = {
7134 .type = HDA_FIXUP_PINS,
7135 .v.pins = (const struct hda_pintbl[]) {
7136 { 0x15, 0x50170120 }, /* no internal speaker */
7140 [ALC892_FIXUP_ASROCK_MOBO] = {
7141 .type = HDA_FIXUP_PINS,
7142 .v.pins = (const struct hda_pintbl[]) {
7143 { 0x15, 0x40f000f0 }, /* disabled */
7144 { 0x16, 0x40f000f0 }, /* disabled */
7150 static const struct snd_pci_quirk alc662_fixup_tbl[] = {
7151 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
7152 SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
7153 SND_PCI_QUIRK(0x1025, 0x0241, "Packard Bell DOTS", ALC662_FIXUP_INV_DMIC),
7154 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
7155 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
7156 SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
7157 SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC),
7158 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
7159 SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
7160 SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
7161 SND_PCI_QUIRK(0x1028, 0x05fe, "Dell XPS 15", ALC668_FIXUP_DELL_XPS13),
7162 SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_XPS13),
7163 SND_PCI_QUIRK(0x1028, 0x060d, "Dell M3800", ALC668_FIXUP_DELL_XPS13),
7164 SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
7165 SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
7166 SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
7167 SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
7168 SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
7169 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
7170 SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE),
7171 SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_ASUS_Nx50),
7172 SND_PCI_QUIRK(0x1043, 0x13df, "Asus N550JX", ALC662_FIXUP_BASS_1A),
7173 SND_PCI_QUIRK(0x1043, 0x129d, "Asus N750", ALC662_FIXUP_ASUS_Nx50),
7174 SND_PCI_QUIRK(0x1043, 0x12ff, "ASUS G751", ALC668_FIXUP_ASUS_G751),
7175 SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
7176 SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
7177 SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51),
7178 SND_PCI_QUIRK(0x1043, 0x17bd, "ASUS N751", ALC668_FIXUP_ASUS_Nx51),
7179 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71SL", ALC662_FIXUP_ASUS_MODE8),
7180 SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
7181 SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
7182 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
7183 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
7184 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
7185 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
7186 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
7187 SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO),
7188 SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
7189 SND_PCI_QUIRK(0x1b0a, 0x01b8, "ACER Veriton", ALC662_FIXUP_ACER_VERITON),
7190 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
7192 #if 0
7193 /* Below is a quirk table taken from the old code.
7194 * Basically the device should work as is without the fixup table.
7195 * If BIOS doesn't give a proper info, enable the corresponding
7196 * fixup entry.
7198 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1),
7199 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3),
7200 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1),
7201 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3),
7202 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
7203 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
7204 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
7205 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1),
7206 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1),
7207 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
7208 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7),
7209 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7),
7210 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8),
7211 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3),
7212 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1),
7213 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
7214 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2),
7215 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1),
7216 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
7217 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
7218 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
7219 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
7220 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1),
7221 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3),
7222 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2),
7223 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
7224 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5),
7225 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
7226 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
7227 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1),
7228 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
7229 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
7230 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3),
7231 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3),
7232 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1),
7233 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1),
7234 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1),
7235 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1),
7236 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1),
7237 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
7238 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2),
7239 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1),
7240 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
7241 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3),
7242 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1),
7243 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1),
7244 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1),
7245 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2),
7246 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
7247 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4),
7248 #endif
7252 static const struct hda_model_fixup alc662_fixup_models[] = {
7253 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
7254 {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"},
7255 {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"},
7256 {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"},
7257 {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"},
7258 {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"},
7259 {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
7260 {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
7261 {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
7262 {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"},
7263 {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
7267 static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
7268 SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
7269 {0x17, 0x02211010},
7270 {0x18, 0x01a19030},
7271 {0x1a, 0x01813040},
7272 {0x21, 0x01014020}),
7273 SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
7274 {0x16, 0x01813030},
7275 {0x17, 0x02211010},
7276 {0x18, 0x01a19040},
7277 {0x21, 0x01014020}),
7278 SND_HDA_PIN_QUIRK(0x10ec0662, 0x1028, "Dell", ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
7279 {0x14, 0x01014010},
7280 {0x18, 0x01a19020},
7281 {0x1a, 0x0181302f},
7282 {0x1b, 0x0221401f}),
7283 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
7284 {0x12, 0x99a30130},
7285 {0x14, 0x90170110},
7286 {0x15, 0x0321101f},
7287 {0x16, 0x03011020}),
7288 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
7289 {0x12, 0x99a30140},
7290 {0x14, 0x90170110},
7291 {0x15, 0x0321101f},
7292 {0x16, 0x03011020}),
7293 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
7294 {0x12, 0x99a30150},
7295 {0x14, 0x90170110},
7296 {0x15, 0x0321101f},
7297 {0x16, 0x03011020}),
7298 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
7299 {0x14, 0x90170110},
7300 {0x15, 0x0321101f},
7301 {0x16, 0x03011020}),
7302 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell XPS 15", ALC668_FIXUP_AUTO_MUTE,
7303 {0x12, 0x90a60130},
7304 {0x14, 0x90170110},
7305 {0x15, 0x0321101f}),
7311 static int patch_alc662(struct hda_codec *codec)
7313 struct alc_spec *spec;
7314 int err;
7316 err = alc_alloc_spec(codec, 0x0b);
7317 if (err < 0)
7318 return err;
7320 spec = codec->spec;
7322 spec->shutup = alc_eapd_shutup;
7324 /* handle multiple HPs as is */
7325 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
7327 alc_fix_pll_init(codec, 0x20, 0x04, 15);
7329 switch (codec->core.vendor_id) {
7330 case 0x10ec0668:
7331 spec->init_hook = alc668_restore_default_value;
7332 break;
7335 snd_hda_pick_fixup(codec, alc662_fixup_models,
7336 alc662_fixup_tbl, alc662_fixups);
7337 snd_hda_pick_pin_fixup(codec, alc662_pin_fixup_tbl, alc662_fixups);
7338 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
7340 alc_auto_parse_customize_define(codec);
7342 if (has_cdefine_beep(codec))
7343 spec->gen.beep_nid = 0x01;
7345 if ((alc_get_coef0(codec) & (1 << 14)) &&
7346 codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 &&
7347 spec->cdefine.platform_type == 1) {
7348 err = alc_codec_rename(codec, "ALC272X");
7349 if (err < 0)
7350 goto error;
7353 /* automatic parse from the BIOS config */
7354 err = alc662_parse_auto_config(codec);
7355 if (err < 0)
7356 goto error;
7358 if (!spec->gen.no_analog && spec->gen.beep_nid) {
7359 switch (codec->core.vendor_id) {
7360 case 0x10ec0662:
7361 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
7362 break;
7363 case 0x10ec0272:
7364 case 0x10ec0663:
7365 case 0x10ec0665:
7366 case 0x10ec0668:
7367 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
7368 break;
7369 case 0x10ec0273:
7370 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
7371 break;
7375 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
7377 return 0;
7379 error:
7380 alc_free(codec);
7381 return err;
7385 * ALC680 support
7388 static int alc680_parse_auto_config(struct hda_codec *codec)
7390 return alc_parse_auto_config(codec, NULL, NULL);
7395 static int patch_alc680(struct hda_codec *codec)
7397 int err;
7399 /* ALC680 has no aa-loopback mixer */
7400 err = alc_alloc_spec(codec, 0);
7401 if (err < 0)
7402 return err;
7404 /* automatic parse from the BIOS config */
7405 err = alc680_parse_auto_config(codec);
7406 if (err < 0) {
7407 alc_free(codec);
7408 return err;
7411 return 0;
7415 * patch entries
7417 static const struct hda_device_id snd_hda_id_realtek[] = {
7418 HDA_CODEC_ENTRY(0x10ec0221, "ALC221", patch_alc269),
7419 HDA_CODEC_ENTRY(0x10ec0225, "ALC225", patch_alc269),
7420 HDA_CODEC_ENTRY(0x10ec0231, "ALC231", patch_alc269),
7421 HDA_CODEC_ENTRY(0x10ec0233, "ALC233", patch_alc269),
7422 HDA_CODEC_ENTRY(0x10ec0234, "ALC234", patch_alc269),
7423 HDA_CODEC_ENTRY(0x10ec0235, "ALC233", patch_alc269),
7424 HDA_CODEC_ENTRY(0x10ec0236, "ALC236", patch_alc269),
7425 HDA_CODEC_ENTRY(0x10ec0255, "ALC255", patch_alc269),
7426 HDA_CODEC_ENTRY(0x10ec0256, "ALC256", patch_alc269),
7427 HDA_CODEC_ENTRY(0x10ec0257, "ALC257", patch_alc269),
7428 HDA_CODEC_ENTRY(0x10ec0260, "ALC260", patch_alc260),
7429 HDA_CODEC_ENTRY(0x10ec0262, "ALC262", patch_alc262),
7430 HDA_CODEC_ENTRY(0x10ec0267, "ALC267", patch_alc268),
7431 HDA_CODEC_ENTRY(0x10ec0268, "ALC268", patch_alc268),
7432 HDA_CODEC_ENTRY(0x10ec0269, "ALC269", patch_alc269),
7433 HDA_CODEC_ENTRY(0x10ec0270, "ALC270", patch_alc269),
7434 HDA_CODEC_ENTRY(0x10ec0272, "ALC272", patch_alc662),
7435 HDA_CODEC_ENTRY(0x10ec0274, "ALC274", patch_alc269),
7436 HDA_CODEC_ENTRY(0x10ec0275, "ALC275", patch_alc269),
7437 HDA_CODEC_ENTRY(0x10ec0276, "ALC276", patch_alc269),
7438 HDA_CODEC_ENTRY(0x10ec0280, "ALC280", patch_alc269),
7439 HDA_CODEC_ENTRY(0x10ec0282, "ALC282", patch_alc269),
7440 HDA_CODEC_ENTRY(0x10ec0283, "ALC283", patch_alc269),
7441 HDA_CODEC_ENTRY(0x10ec0284, "ALC284", patch_alc269),
7442 HDA_CODEC_ENTRY(0x10ec0285, "ALC285", patch_alc269),
7443 HDA_CODEC_ENTRY(0x10ec0286, "ALC286", patch_alc269),
7444 HDA_CODEC_ENTRY(0x10ec0288, "ALC288", patch_alc269),
7445 HDA_CODEC_ENTRY(0x10ec0290, "ALC290", patch_alc269),
7446 HDA_CODEC_ENTRY(0x10ec0292, "ALC292", patch_alc269),
7447 HDA_CODEC_ENTRY(0x10ec0293, "ALC293", patch_alc269),
7448 HDA_CODEC_ENTRY(0x10ec0294, "ALC294", patch_alc269),
7449 HDA_CODEC_ENTRY(0x10ec0295, "ALC295", patch_alc269),
7450 HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269),
7451 HDA_CODEC_ENTRY(0x10ec0299, "ALC299", patch_alc269),
7452 HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861),
7453 HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd),
7454 HDA_CODEC_ENTRY(0x10ec0861, "ALC861", patch_alc861),
7455 HDA_CODEC_ENTRY(0x10ec0862, "ALC861-VD", patch_alc861vd),
7456 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100002, "ALC662 rev2", patch_alc882),
7457 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100101, "ALC662 rev1", patch_alc662),
7458 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100300, "ALC662 rev3", patch_alc662),
7459 HDA_CODEC_ENTRY(0x10ec0663, "ALC663", patch_alc662),
7460 HDA_CODEC_ENTRY(0x10ec0665, "ALC665", patch_alc662),
7461 HDA_CODEC_ENTRY(0x10ec0667, "ALC667", patch_alc662),
7462 HDA_CODEC_ENTRY(0x10ec0668, "ALC668", patch_alc662),
7463 HDA_CODEC_ENTRY(0x10ec0670, "ALC670", patch_alc662),
7464 HDA_CODEC_ENTRY(0x10ec0671, "ALC671", patch_alc662),
7465 HDA_CODEC_ENTRY(0x10ec0680, "ALC680", patch_alc680),
7466 HDA_CODEC_ENTRY(0x10ec0700, "ALC700", patch_alc269),
7467 HDA_CODEC_ENTRY(0x10ec0701, "ALC701", patch_alc269),
7468 HDA_CODEC_ENTRY(0x10ec0703, "ALC703", patch_alc269),
7469 HDA_CODEC_ENTRY(0x10ec0711, "ALC711", patch_alc269),
7470 HDA_CODEC_ENTRY(0x10ec0867, "ALC891", patch_alc662),
7471 HDA_CODEC_ENTRY(0x10ec0880, "ALC880", patch_alc880),
7472 HDA_CODEC_ENTRY(0x10ec0882, "ALC882", patch_alc882),
7473 HDA_CODEC_ENTRY(0x10ec0883, "ALC883", patch_alc882),
7474 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100101, "ALC889A", patch_alc882),
7475 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100103, "ALC889A", patch_alc882),
7476 HDA_CODEC_ENTRY(0x10ec0885, "ALC885", patch_alc882),
7477 HDA_CODEC_ENTRY(0x10ec0887, "ALC887", patch_alc882),
7478 HDA_CODEC_REV_ENTRY(0x10ec0888, 0x100101, "ALC1200", patch_alc882),
7479 HDA_CODEC_ENTRY(0x10ec0888, "ALC888", patch_alc882),
7480 HDA_CODEC_ENTRY(0x10ec0889, "ALC889", patch_alc882),
7481 HDA_CODEC_ENTRY(0x10ec0892, "ALC892", patch_alc662),
7482 HDA_CODEC_ENTRY(0x10ec0899, "ALC898", patch_alc882),
7483 HDA_CODEC_ENTRY(0x10ec0900, "ALC1150", patch_alc882),
7484 {} /* terminator */
7486 MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_realtek);
7488 MODULE_LICENSE("GPL");
7489 MODULE_DESCRIPTION("Realtek HD-audio codec");
7491 static struct hda_codec_driver realtek_driver = {
7492 .id = snd_hda_id_realtek,
7495 module_hda_codec_driver(realtek_driver);