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