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