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