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 <linux/input.h>
33#include <sound/core.h>
34#include <sound/jack.h>
35#include "hda_codec.h"
36#include "hda_local.h"
37#include "hda_auto_parser.h"
38#include "hda_jack.h"
39#include "hda_generic.h"
40
41/* keep halting ALC5505 DSP, for power saving */
42#define HALT_REALTEK_ALC5505
43
44/* for GPIO Poll */
45#define GPIO_MASK	0x03
46
47/* extra amp-initialization sequence types */
48enum {
49	ALC_INIT_NONE,
50	ALC_INIT_DEFAULT,
51	ALC_INIT_GPIO1,
52	ALC_INIT_GPIO2,
53	ALC_INIT_GPIO3,
54};
55
56enum {
57	ALC_HEADSET_MODE_UNKNOWN,
58	ALC_HEADSET_MODE_UNPLUGGED,
59	ALC_HEADSET_MODE_HEADSET,
60	ALC_HEADSET_MODE_MIC,
61	ALC_HEADSET_MODE_HEADPHONE,
62};
63
64enum {
65	ALC_HEADSET_TYPE_UNKNOWN,
66	ALC_HEADSET_TYPE_CTIA,
67	ALC_HEADSET_TYPE_OMTP,
68};
69
70struct alc_customize_define {
71	unsigned int  sku_cfg;
72	unsigned char port_connectivity;
73	unsigned char check_sum;
74	unsigned char customization;
75	unsigned char external_amp;
76	unsigned int  enable_pcbeep:1;
77	unsigned int  platform_type:1;
78	unsigned int  swap:1;
79	unsigned int  override:1;
80	unsigned int  fixup:1; /* Means that this sku is set by driver, not read from hw */
81};
82
83struct alc_spec {
84	struct hda_gen_spec gen; /* must be at head */
85
86	/* codec parameterization */
87	const struct snd_kcontrol_new *mixers[5];	/* mixer arrays */
88	unsigned int num_mixers;
89	unsigned int beep_amp;	/* beep amp value, set via set_beep_amp() */
90
91	struct alc_customize_define cdefine;
92	unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */
93
94	/* mute LED for HP laptops, see alc269_fixup_mic_mute_hook() */
95	int mute_led_polarity;
96	hda_nid_t mute_led_nid;
97	hda_nid_t cap_mute_led_nid;
98
99	unsigned int gpio_led; /* used for alc269_fixup_hp_gpio_led() */
100	unsigned int gpio_mute_led_mask;
101	unsigned int gpio_mic_led_mask;
102
103	hda_nid_t headset_mic_pin;
104	hda_nid_t headphone_mic_pin;
105	int current_headset_mode;
106	int current_headset_type;
107
108	/* hooks */
109	void (*init_hook)(struct hda_codec *codec);
110#ifdef CONFIG_PM
111	void (*power_hook)(struct hda_codec *codec);
112#endif
113	void (*shutup)(struct hda_codec *codec);
114	void (*reboot_notify)(struct hda_codec *codec);
115
116	int init_amp;
117	int codec_variant;	/* flag for other variants */
118	unsigned int has_alc5505_dsp:1;
119	unsigned int no_depop_delay:1;
120
121	/* for PLL fix */
122	hda_nid_t pll_nid;
123	unsigned int pll_coef_idx, pll_coef_bit;
124	unsigned int coef0;
125	struct input_dev *kb_dev;
126};
127
128/*
129 * COEF access helper functions
130 */
131
132static int alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
133			       unsigned int coef_idx)
134{
135	unsigned int val;
136
137	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
138	val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
139	return val;
140}
141
142#define alc_read_coef_idx(codec, coef_idx) \
143	alc_read_coefex_idx(codec, 0x20, coef_idx)
144
145static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
146				 unsigned int coef_idx, unsigned int coef_val)
147{
148	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
149	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF, coef_val);
150}
151
152#define alc_write_coef_idx(codec, coef_idx, coef_val) \
153	alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val)
154
155static void alc_update_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
156				  unsigned int coef_idx, unsigned int mask,
157				  unsigned int bits_set)
158{
159	unsigned int val = alc_read_coefex_idx(codec, nid, coef_idx);
160
161	if (val != -1)
162		alc_write_coefex_idx(codec, nid, coef_idx,
163				     (val & ~mask) | bits_set);
164}
165
166#define alc_update_coef_idx(codec, coef_idx, mask, bits_set)	\
167	alc_update_coefex_idx(codec, 0x20, coef_idx, mask, bits_set)
168
169/* a special bypass for COEF 0; read the cached value at the second time */
170static unsigned int alc_get_coef0(struct hda_codec *codec)
171{
172	struct alc_spec *spec = codec->spec;
173
174	if (!spec->coef0)
175		spec->coef0 = alc_read_coef_idx(codec, 0);
176	return spec->coef0;
177}
178
179/* coef writes/updates batch */
180struct coef_fw {
181	unsigned char nid;
182	unsigned char idx;
183	unsigned short mask;
184	unsigned short val;
185};
186
187#define UPDATE_COEFEX(_nid, _idx, _mask, _val) \
188	{ .nid = (_nid), .idx = (_idx), .mask = (_mask), .val = (_val) }
189#define WRITE_COEFEX(_nid, _idx, _val) UPDATE_COEFEX(_nid, _idx, -1, _val)
190#define WRITE_COEF(_idx, _val) WRITE_COEFEX(0x20, _idx, _val)
191#define UPDATE_COEF(_idx, _mask, _val) UPDATE_COEFEX(0x20, _idx, _mask, _val)
192
193static void alc_process_coef_fw(struct hda_codec *codec,
194				const struct coef_fw *fw)
195{
196	for (; fw->nid; fw++) {
197		if (fw->mask == (unsigned short)-1)
198			alc_write_coefex_idx(codec, fw->nid, fw->idx, fw->val);
199		else
200			alc_update_coefex_idx(codec, fw->nid, fw->idx,
201					      fw->mask, fw->val);
202	}
203}
204
205/*
206 * Append the given mixer and verb elements for the later use
207 * The mixer array is referred in build_controls(), and init_verbs are
208 * called in init().
209 */
210static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
211{
212	if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
213		return;
214	spec->mixers[spec->num_mixers++] = mix;
215}
216
217/*
218 * GPIO setup tables, used in initialization
219 */
220/* Enable GPIO mask and set output */
221static const struct hda_verb alc_gpio1_init_verbs[] = {
222	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
223	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
224	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
225	{ }
226};
227
228static const struct hda_verb alc_gpio2_init_verbs[] = {
229	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
230	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
231	{0x01, AC_VERB_SET_GPIO_DATA, 0x02},
232	{ }
233};
234
235static const struct hda_verb alc_gpio3_init_verbs[] = {
236	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
237	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
238	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
239	{ }
240};
241
242/*
243 * Fix hardware PLL issue
244 * On some codecs, the analog PLL gating control must be off while
245 * the default value is 1.
246 */
247static void alc_fix_pll(struct hda_codec *codec)
248{
249	struct alc_spec *spec = codec->spec;
250
251	if (spec->pll_nid)
252		alc_update_coefex_idx(codec, spec->pll_nid, spec->pll_coef_idx,
253				      1 << spec->pll_coef_bit, 0);
254}
255
256static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
257			     unsigned int coef_idx, unsigned int coef_bit)
258{
259	struct alc_spec *spec = codec->spec;
260	spec->pll_nid = nid;
261	spec->pll_coef_idx = coef_idx;
262	spec->pll_coef_bit = coef_bit;
263	alc_fix_pll(codec);
264}
265
266/* update the master volume per volume-knob's unsol event */
267static void alc_update_knob_master(struct hda_codec *codec,
268				   struct hda_jack_callback *jack)
269{
270	unsigned int val;
271	struct snd_kcontrol *kctl;
272	struct snd_ctl_elem_value *uctl;
273
274	kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume");
275	if (!kctl)
276		return;
277	uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
278	if (!uctl)
279		return;
280	val = snd_hda_codec_read(codec, jack->nid, 0,
281				 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
282	val &= HDA_AMP_VOLMASK;
283	uctl->value.integer.value[0] = val;
284	uctl->value.integer.value[1] = val;
285	kctl->put(kctl, uctl);
286	kfree(uctl);
287}
288
289static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
290{
291	/* For some reason, the res given from ALC880 is broken.
292	   Here we adjust it properly. */
293	snd_hda_jack_unsol_event(codec, res >> 2);
294}
295
296/* Change EAPD to verb control */
297static void alc_fill_eapd_coef(struct hda_codec *codec)
298{
299	int coef;
300
301	coef = alc_get_coef0(codec);
302
303	switch (codec->core.vendor_id) {
304	case 0x10ec0262:
305		alc_update_coef_idx(codec, 0x7, 0, 1<<5);
306		break;
307	case 0x10ec0267:
308	case 0x10ec0268:
309		alc_update_coef_idx(codec, 0x7, 0, 1<<13);
310		break;
311	case 0x10ec0269:
312		if ((coef & 0x00f0) == 0x0010)
313			alc_update_coef_idx(codec, 0xd, 0, 1<<14);
314		if ((coef & 0x00f0) == 0x0020)
315			alc_update_coef_idx(codec, 0x4, 1<<15, 0);
316		if ((coef & 0x00f0) == 0x0030)
317			alc_update_coef_idx(codec, 0x10, 1<<9, 0);
318		break;
319	case 0x10ec0280:
320	case 0x10ec0284:
321	case 0x10ec0290:
322	case 0x10ec0292:
323		alc_update_coef_idx(codec, 0x4, 1<<15, 0);
324		break;
325	case 0x10ec0233:
326	case 0x10ec0255:
327	case 0x10ec0256:
328	case 0x10ec0282:
329	case 0x10ec0283:
330	case 0x10ec0286:
331	case 0x10ec0288:
332	case 0x10ec0298:
333		alc_update_coef_idx(codec, 0x10, 1<<9, 0);
334		break;
335	case 0x10ec0285:
336	case 0x10ec0293:
337		alc_update_coef_idx(codec, 0xa, 1<<13, 0);
338		break;
339	case 0x10ec0662:
340		if ((coef & 0x00f0) == 0x0030)
341			alc_update_coef_idx(codec, 0x4, 1<<10, 0); /* EAPD Ctrl */
342		break;
343	case 0x10ec0272:
344	case 0x10ec0273:
345	case 0x10ec0663:
346	case 0x10ec0665:
347	case 0x10ec0670:
348	case 0x10ec0671:
349	case 0x10ec0672:
350		alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */
351		break;
352	case 0x10ec0668:
353		alc_update_coef_idx(codec, 0x7, 3<<13, 0);
354		break;
355	case 0x10ec0867:
356		alc_update_coef_idx(codec, 0x4, 1<<10, 0);
357		break;
358	case 0x10ec0888:
359		if ((coef & 0x00f0) == 0x0020 || (coef & 0x00f0) == 0x0030)
360			alc_update_coef_idx(codec, 0x7, 1<<5, 0);
361		break;
362	case 0x10ec0892:
363		alc_update_coef_idx(codec, 0x7, 1<<5, 0);
364		break;
365	case 0x10ec0899:
366	case 0x10ec0900:
367		alc_update_coef_idx(codec, 0x7, 1<<1, 0);
368		break;
369	}
370}
371
372/* additional initialization for ALC888 variants */
373static void alc888_coef_init(struct hda_codec *codec)
374{
375	switch (alc_get_coef0(codec) & 0x00f0) {
376	/* alc888-VA */
377	case 0x00:
378	/* alc888-VB */
379	case 0x10:
380		alc_update_coef_idx(codec, 7, 0, 0x2030); /* Turn EAPD to High */
381		break;
382	}
383}
384
385/* turn on/off EAPD control (only if available) */
386static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
387{
388	if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
389		return;
390	if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
391		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
392				    on ? 2 : 0);
393}
394
395/* turn on/off EAPD controls of the codec */
396static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
397{
398	/* We currently only handle front, HP */
399	static hda_nid_t pins[] = {
400		0x0f, 0x10, 0x14, 0x15, 0x17, 0
401	};
402	hda_nid_t *p;
403	for (p = pins; *p; p++)
404		set_eapd(codec, *p, on);
405}
406
407/* generic shutup callback;
408 * just turning off EPAD and a little pause for avoiding pop-noise
409 */
410static void alc_eapd_shutup(struct hda_codec *codec)
411{
412	struct alc_spec *spec = codec->spec;
413
414	alc_auto_setup_eapd(codec, false);
415	if (!spec->no_depop_delay)
416		msleep(200);
417	snd_hda_shutup_pins(codec);
418}
419
420/* generic EAPD initialization */
421static void alc_auto_init_amp(struct hda_codec *codec, int type)
422{
423	alc_fill_eapd_coef(codec);
424	alc_auto_setup_eapd(codec, true);
425	switch (type) {
426	case ALC_INIT_GPIO1:
427		snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
428		break;
429	case ALC_INIT_GPIO2:
430		snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
431		break;
432	case ALC_INIT_GPIO3:
433		snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
434		break;
435	case ALC_INIT_DEFAULT:
436		switch (codec->core.vendor_id) {
437		case 0x10ec0260:
438			alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x2010);
439			break;
440		case 0x10ec0880:
441		case 0x10ec0882:
442		case 0x10ec0883:
443		case 0x10ec0885:
444			alc_update_coef_idx(codec, 7, 0, 0x2030);
445			break;
446		case 0x10ec0888:
447			alc888_coef_init(codec);
448			break;
449		}
450		break;
451	}
452}
453
454
455/*
456 * Realtek SSID verification
457 */
458
459/* Could be any non-zero and even value. When used as fixup, tells
460 * the driver to ignore any present sku defines.
461 */
462#define ALC_FIXUP_SKU_IGNORE (2)
463
464static void alc_fixup_sku_ignore(struct hda_codec *codec,
465				 const struct hda_fixup *fix, int action)
466{
467	struct alc_spec *spec = codec->spec;
468	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
469		spec->cdefine.fixup = 1;
470		spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE;
471	}
472}
473
474static void alc_fixup_no_depop_delay(struct hda_codec *codec,
475				    const struct hda_fixup *fix, int action)
476{
477	struct alc_spec *spec = codec->spec;
478
479	if (action == HDA_FIXUP_ACT_PROBE) {
480		spec->no_depop_delay = 1;
481		codec->depop_delay = 0;
482	}
483}
484
485static int alc_auto_parse_customize_define(struct hda_codec *codec)
486{
487	unsigned int ass, tmp, i;
488	unsigned nid = 0;
489	struct alc_spec *spec = codec->spec;
490
491	spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
492
493	if (spec->cdefine.fixup) {
494		ass = spec->cdefine.sku_cfg;
495		if (ass == ALC_FIXUP_SKU_IGNORE)
496			return -1;
497		goto do_sku;
498	}
499
500	if (!codec->bus->pci)
501		return -1;
502	ass = codec->core.subsystem_id & 0xffff;
503	if (ass != codec->bus->pci->subsystem_device && (ass & 1))
504		goto do_sku;
505
506	nid = 0x1d;
507	if (codec->core.vendor_id == 0x10ec0260)
508		nid = 0x17;
509	ass = snd_hda_codec_get_pincfg(codec, nid);
510
511	if (!(ass & 1)) {
512		codec_info(codec, "%s: SKU not ready 0x%08x\n",
513			   codec->core.chip_name, ass);
514		return -1;
515	}
516
517	/* check sum */
518	tmp = 0;
519	for (i = 1; i < 16; i++) {
520		if ((ass >> i) & 1)
521			tmp++;
522	}
523	if (((ass >> 16) & 0xf) != tmp)
524		return -1;
525
526	spec->cdefine.port_connectivity = ass >> 30;
527	spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
528	spec->cdefine.check_sum = (ass >> 16) & 0xf;
529	spec->cdefine.customization = ass >> 8;
530do_sku:
531	spec->cdefine.sku_cfg = ass;
532	spec->cdefine.external_amp = (ass & 0x38) >> 3;
533	spec->cdefine.platform_type = (ass & 0x4) >> 2;
534	spec->cdefine.swap = (ass & 0x2) >> 1;
535	spec->cdefine.override = ass & 0x1;
536
537	codec_dbg(codec, "SKU: Nid=0x%x sku_cfg=0x%08x\n",
538		   nid, spec->cdefine.sku_cfg);
539	codec_dbg(codec, "SKU: port_connectivity=0x%x\n",
540		   spec->cdefine.port_connectivity);
541	codec_dbg(codec, "SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
542	codec_dbg(codec, "SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
543	codec_dbg(codec, "SKU: customization=0x%08x\n", spec->cdefine.customization);
544	codec_dbg(codec, "SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
545	codec_dbg(codec, "SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
546	codec_dbg(codec, "SKU: swap=0x%x\n", spec->cdefine.swap);
547	codec_dbg(codec, "SKU: override=0x%x\n", spec->cdefine.override);
548
549	return 0;
550}
551
552/* return the position of NID in the list, or -1 if not found */
553static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
554{
555	int i;
556	for (i = 0; i < nums; i++)
557		if (list[i] == nid)
558			return i;
559	return -1;
560}
561/* return true if the given NID is found in the list */
562static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
563{
564	return find_idx_in_nid_list(nid, list, nums) >= 0;
565}
566
567/* check subsystem ID and set up device-specific initialization;
568 * return 1 if initialized, 0 if invalid SSID
569 */
570/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
571 *	31 ~ 16 :	Manufacture ID
572 *	15 ~ 8	:	SKU ID
573 *	7  ~ 0	:	Assembly ID
574 *	port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
575 */
576static int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports)
577{
578	unsigned int ass, tmp, i;
579	unsigned nid;
580	struct alc_spec *spec = codec->spec;
581
582	if (spec->cdefine.fixup) {
583		ass = spec->cdefine.sku_cfg;
584		if (ass == ALC_FIXUP_SKU_IGNORE)
585			return 0;
586		goto do_sku;
587	}
588
589	ass = codec->core.subsystem_id & 0xffff;
590	if (codec->bus->pci &&
591	    ass != codec->bus->pci->subsystem_device && (ass & 1))
592		goto do_sku;
593
594	/* invalid SSID, check the special NID pin defcfg instead */
595	/*
596	 * 31~30	: port connectivity
597	 * 29~21	: reserve
598	 * 20		: PCBEEP input
599	 * 19~16	: Check sum (15:1)
600	 * 15~1		: Custom
601	 * 0		: override
602	*/
603	nid = 0x1d;
604	if (codec->core.vendor_id == 0x10ec0260)
605		nid = 0x17;
606	ass = snd_hda_codec_get_pincfg(codec, nid);
607	codec_dbg(codec,
608		  "realtek: No valid SSID, checking pincfg 0x%08x for NID 0x%x\n",
609		   ass, nid);
610	if (!(ass & 1))
611		return 0;
612	if ((ass >> 30) != 1)	/* no physical connection */
613		return 0;
614
615	/* check sum */
616	tmp = 0;
617	for (i = 1; i < 16; i++) {
618		if ((ass >> i) & 1)
619			tmp++;
620	}
621	if (((ass >> 16) & 0xf) != tmp)
622		return 0;
623do_sku:
624	codec_dbg(codec, "realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
625		   ass & 0xffff, codec->core.vendor_id);
626	/*
627	 * 0 : override
628	 * 1 :	Swap Jack
629	 * 2 : 0 --> Desktop, 1 --> Laptop
630	 * 3~5 : External Amplifier control
631	 * 7~6 : Reserved
632	*/
633	tmp = (ass & 0x38) >> 3;	/* external Amp control */
634	switch (tmp) {
635	case 1:
636		spec->init_amp = ALC_INIT_GPIO1;
637		break;
638	case 3:
639		spec->init_amp = ALC_INIT_GPIO2;
640		break;
641	case 7:
642		spec->init_amp = ALC_INIT_GPIO3;
643		break;
644	case 5:
645	default:
646		spec->init_amp = ALC_INIT_DEFAULT;
647		break;
648	}
649
650	/* is laptop or Desktop and enable the function "Mute internal speaker
651	 * when the external headphone out jack is plugged"
652	 */
653	if (!(ass & 0x8000))
654		return 1;
655	/*
656	 * 10~8 : Jack location
657	 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
658	 * 14~13: Resvered
659	 * 15   : 1 --> enable the function "Mute internal speaker
660	 *	        when the external headphone out jack is plugged"
661	 */
662	if (!spec->gen.autocfg.hp_pins[0] &&
663	    !(spec->gen.autocfg.line_out_pins[0] &&
664	      spec->gen.autocfg.line_out_type == AUTO_PIN_HP_OUT)) {
665		hda_nid_t nid;
666		tmp = (ass >> 11) & 0x3;	/* HP to chassis */
667		nid = ports[tmp];
668		if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins,
669				      spec->gen.autocfg.line_outs))
670			return 1;
671		spec->gen.autocfg.hp_pins[0] = nid;
672	}
673	return 1;
674}
675
676/* Check the validity of ALC subsystem-id
677 * ports contains an array of 4 pin NIDs for port-A, E, D and I */
678static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
679{
680	if (!alc_subsystem_id(codec, ports)) {
681		struct alc_spec *spec = codec->spec;
682		codec_dbg(codec,
683			  "realtek: Enable default setup for auto mode as fallback\n");
684		spec->init_amp = ALC_INIT_DEFAULT;
685	}
686}
687
688/*
689 */
690
691static void alc_fixup_inv_dmic(struct hda_codec *codec,
692			       const struct hda_fixup *fix, int action)
693{
694	struct alc_spec *spec = codec->spec;
695
696	spec->gen.inv_dmic_split = 1;
697}
698
699
700#ifdef CONFIG_SND_HDA_INPUT_BEEP
701/* additional beep mixers; the actual parameters are overwritten at build */
702static const struct snd_kcontrol_new alc_beep_mixer[] = {
703	HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
704	HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
705	{ } /* end */
706};
707#endif
708
709static int alc_build_controls(struct hda_codec *codec)
710{
711	struct alc_spec *spec = codec->spec;
712	int i, err;
713
714	err = snd_hda_gen_build_controls(codec);
715	if (err < 0)
716		return err;
717
718	for (i = 0; i < spec->num_mixers; i++) {
719		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
720		if (err < 0)
721			return err;
722	}
723
724#ifdef CONFIG_SND_HDA_INPUT_BEEP
725	/* create beep controls if needed */
726	if (spec->beep_amp) {
727		const struct snd_kcontrol_new *knew;
728		for (knew = alc_beep_mixer; knew->name; knew++) {
729			struct snd_kcontrol *kctl;
730			kctl = snd_ctl_new1(knew, codec);
731			if (!kctl)
732				return -ENOMEM;
733			kctl->private_value = spec->beep_amp;
734			err = snd_hda_ctl_add(codec, 0, kctl);
735			if (err < 0)
736				return err;
737		}
738	}
739#endif
740
741	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD);
742	return 0;
743}
744
745
746/*
747 * Common callbacks
748 */
749
750static int alc_init(struct hda_codec *codec)
751{
752	struct alc_spec *spec = codec->spec;
753
754	if (spec->init_hook)
755		spec->init_hook(codec);
756
757	alc_fix_pll(codec);
758	alc_auto_init_amp(codec, spec->init_amp);
759
760	snd_hda_gen_init(codec);
761
762	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
763
764	return 0;
765}
766
767static inline void alc_shutup(struct hda_codec *codec)
768{
769	struct alc_spec *spec = codec->spec;
770
771	if (spec && spec->shutup)
772		spec->shutup(codec);
773	else
774		snd_hda_shutup_pins(codec);
775}
776
777static void alc_reboot_notify(struct hda_codec *codec)
778{
779	struct alc_spec *spec = codec->spec;
780
781	if (spec && spec->reboot_notify)
782		spec->reboot_notify(codec);
783	else
784		alc_shutup(codec);
785}
786
787/* power down codec to D3 at reboot/shutdown; set as reboot_notify ops */
788static void alc_d3_at_reboot(struct hda_codec *codec)
789{
790	snd_hda_codec_set_power_to_all(codec, codec->core.afg, AC_PWRST_D3);
791	snd_hda_codec_write(codec, codec->core.afg, 0,
792			    AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
793	msleep(10);
794}
795
796#define alc_free	snd_hda_gen_free
797
798#ifdef CONFIG_PM
799static void alc_power_eapd(struct hda_codec *codec)
800{
801	alc_auto_setup_eapd(codec, false);
802}
803
804static int alc_suspend(struct hda_codec *codec)
805{
806	struct alc_spec *spec = codec->spec;
807	alc_shutup(codec);
808	if (spec && spec->power_hook)
809		spec->power_hook(codec);
810	return 0;
811}
812#endif
813
814#ifdef CONFIG_PM
815static int alc_resume(struct hda_codec *codec)
816{
817	struct alc_spec *spec = codec->spec;
818
819	if (!spec->no_depop_delay)
820		msleep(150); /* to avoid pop noise */
821	codec->patch_ops.init(codec);
822	regcache_sync(codec->core.regmap);
823	hda_call_check_power_status(codec, 0x01);
824	return 0;
825}
826#endif
827
828/*
829 */
830static const struct hda_codec_ops alc_patch_ops = {
831	.build_controls = alc_build_controls,
832	.build_pcms = snd_hda_gen_build_pcms,
833	.init = alc_init,
834	.free = alc_free,
835	.unsol_event = snd_hda_jack_unsol_event,
836#ifdef CONFIG_PM
837	.resume = alc_resume,
838	.suspend = alc_suspend,
839	.check_power_status = snd_hda_gen_check_power_status,
840#endif
841	.reboot_notify = alc_reboot_notify,
842};
843
844
845/* replace the codec chip_name with the given string */
846static int alc_codec_rename(struct hda_codec *codec, const char *name)
847{
848	kfree(codec->core.chip_name);
849	codec->core.chip_name = kstrdup(name, GFP_KERNEL);
850	if (!codec->core.chip_name) {
851		alc_free(codec);
852		return -ENOMEM;
853	}
854	return 0;
855}
856
857/*
858 * Rename codecs appropriately from COEF value or subvendor id
859 */
860struct alc_codec_rename_table {
861	unsigned int vendor_id;
862	unsigned short coef_mask;
863	unsigned short coef_bits;
864	const char *name;
865};
866
867struct alc_codec_rename_pci_table {
868	unsigned int codec_vendor_id;
869	unsigned short pci_subvendor;
870	unsigned short pci_subdevice;
871	const char *name;
872};
873
874static struct alc_codec_rename_table rename_tbl[] = {
875	{ 0x10ec0221, 0xf00f, 0x1003, "ALC231" },
876	{ 0x10ec0269, 0xfff0, 0x3010, "ALC277" },
877	{ 0x10ec0269, 0xf0f0, 0x2010, "ALC259" },
878	{ 0x10ec0269, 0xf0f0, 0x3010, "ALC258" },
879	{ 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" },
880	{ 0x10ec0269, 0xffff, 0xa023, "ALC259" },
881	{ 0x10ec0269, 0xffff, 0x6023, "ALC281X" },
882	{ 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" },
883	{ 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" },
884	{ 0x10ec0662, 0xffff, 0x4020, "ALC656" },
885	{ 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" },
886	{ 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" },
887	{ 0x10ec0888, 0xf0f0, 0x3020, "ALC886" },
888	{ 0x10ec0899, 0x2000, 0x2000, "ALC899" },
889	{ 0x10ec0892, 0xffff, 0x8020, "ALC661" },
890	{ 0x10ec0892, 0xffff, 0x8011, "ALC661" },
891	{ 0x10ec0892, 0xffff, 0x4011, "ALC656" },
892	{ } /* terminator */
893};
894
895static struct alc_codec_rename_pci_table rename_pci_tbl[] = {
896	{ 0x10ec0280, 0x1028, 0, "ALC3220" },
897	{ 0x10ec0282, 0x1028, 0, "ALC3221" },
898	{ 0x10ec0283, 0x1028, 0, "ALC3223" },
899	{ 0x10ec0288, 0x1028, 0, "ALC3263" },
900	{ 0x10ec0292, 0x1028, 0, "ALC3226" },
901	{ 0x10ec0293, 0x1028, 0, "ALC3235" },
902	{ 0x10ec0255, 0x1028, 0, "ALC3234" },
903	{ 0x10ec0668, 0x1028, 0, "ALC3661" },
904	{ 0x10ec0275, 0x1028, 0, "ALC3260" },
905	{ 0x10ec0899, 0x1028, 0, "ALC3861" },
906	{ 0x10ec0298, 0x1028, 0, "ALC3266" },
907	{ 0x10ec0256, 0x1028, 0, "ALC3246" },
908	{ 0x10ec0670, 0x1025, 0, "ALC669X" },
909	{ 0x10ec0676, 0x1025, 0, "ALC679X" },
910	{ 0x10ec0282, 0x1043, 0, "ALC3229" },
911	{ 0x10ec0233, 0x1043, 0, "ALC3236" },
912	{ 0x10ec0280, 0x103c, 0, "ALC3228" },
913	{ 0x10ec0282, 0x103c, 0, "ALC3227" },
914	{ 0x10ec0286, 0x103c, 0, "ALC3242" },
915	{ 0x10ec0290, 0x103c, 0, "ALC3241" },
916	{ 0x10ec0668, 0x103c, 0, "ALC3662" },
917	{ 0x10ec0283, 0x17aa, 0, "ALC3239" },
918	{ 0x10ec0292, 0x17aa, 0, "ALC3232" },
919	{ } /* terminator */
920};
921
922static int alc_codec_rename_from_preset(struct hda_codec *codec)
923{
924	const struct alc_codec_rename_table *p;
925	const struct alc_codec_rename_pci_table *q;
926
927	for (p = rename_tbl; p->vendor_id; p++) {
928		if (p->vendor_id != codec->core.vendor_id)
929			continue;
930		if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits)
931			return alc_codec_rename(codec, p->name);
932	}
933
934	if (!codec->bus->pci)
935		return 0;
936	for (q = rename_pci_tbl; q->codec_vendor_id; q++) {
937		if (q->codec_vendor_id != codec->core.vendor_id)
938			continue;
939		if (q->pci_subvendor != codec->bus->pci->subsystem_vendor)
940			continue;
941		if (!q->pci_subdevice ||
942		    q->pci_subdevice == codec->bus->pci->subsystem_device)
943			return alc_codec_rename(codec, q->name);
944	}
945
946	return 0;
947}
948
949
950/*
951 * Digital-beep handlers
952 */
953#ifdef CONFIG_SND_HDA_INPUT_BEEP
954#define set_beep_amp(spec, nid, idx, dir) \
955	((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
956
957static const struct snd_pci_quirk beep_white_list[] = {
958	SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1),
959	SND_PCI_QUIRK(0x1043, 0x115d, "ASUS", 1),
960	SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
961	SND_PCI_QUIRK(0x1043, 0x8376, "EeePC", 1),
962	SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
963	SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
964	SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
965	SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1),
966	SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
967	{}
968};
969
970static inline int has_cdefine_beep(struct hda_codec *codec)
971{
972	struct alc_spec *spec = codec->spec;
973	const struct snd_pci_quirk *q;
974	q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
975	if (q)
976		return q->value;
977	return spec->cdefine.enable_pcbeep;
978}
979#else
980#define set_beep_amp(spec, nid, idx, dir) /* NOP */
981#define has_cdefine_beep(codec)		0
982#endif
983
984/* parse the BIOS configuration and set up the alc_spec */
985/* return 1 if successful, 0 if the proper config is not found,
986 * or a negative error code
987 */
988static int alc_parse_auto_config(struct hda_codec *codec,
989				 const hda_nid_t *ignore_nids,
990				 const hda_nid_t *ssid_nids)
991{
992	struct alc_spec *spec = codec->spec;
993	struct auto_pin_cfg *cfg = &spec->gen.autocfg;
994	int err;
995
996	err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids,
997				       spec->parse_flags);
998	if (err < 0)
999		return err;
1000
1001	if (ssid_nids)
1002		alc_ssid_check(codec, ssid_nids);
1003
1004	err = snd_hda_gen_parse_auto_config(codec, cfg);
1005	if (err < 0)
1006		return err;
1007
1008	return 1;
1009}
1010
1011/* common preparation job for alc_spec */
1012static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid)
1013{
1014	struct alc_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1015	int err;
1016
1017	if (!spec)
1018		return -ENOMEM;
1019	codec->spec = spec;
1020	snd_hda_gen_spec_init(&spec->gen);
1021	spec->gen.mixer_nid = mixer_nid;
1022	spec->gen.own_eapd_ctl = 1;
1023	codec->single_adc_amp = 1;
1024	/* FIXME: do we need this for all Realtek codec models? */
1025	codec->spdif_status_reset = 1;
1026
1027	err = alc_codec_rename_from_preset(codec);
1028	if (err < 0) {
1029		kfree(spec);
1030		return err;
1031	}
1032	return 0;
1033}
1034
1035static int alc880_parse_auto_config(struct hda_codec *codec)
1036{
1037	static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
1038	static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 };
1039	return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
1040}
1041
1042/*
1043 * ALC880 fix-ups
1044 */
1045enum {
1046	ALC880_FIXUP_GPIO1,
1047	ALC880_FIXUP_GPIO2,
1048	ALC880_FIXUP_MEDION_RIM,
1049	ALC880_FIXUP_LG,
1050	ALC880_FIXUP_LG_LW25,
1051	ALC880_FIXUP_W810,
1052	ALC880_FIXUP_EAPD_COEF,
1053	ALC880_FIXUP_TCL_S700,
1054	ALC880_FIXUP_VOL_KNOB,
1055	ALC880_FIXUP_FUJITSU,
1056	ALC880_FIXUP_F1734,
1057	ALC880_FIXUP_UNIWILL,
1058	ALC880_FIXUP_UNIWILL_DIG,
1059	ALC880_FIXUP_Z71V,
1060	ALC880_FIXUP_ASUS_W5A,
1061	ALC880_FIXUP_3ST_BASE,
1062	ALC880_FIXUP_3ST,
1063	ALC880_FIXUP_3ST_DIG,
1064	ALC880_FIXUP_5ST_BASE,
1065	ALC880_FIXUP_5ST,
1066	ALC880_FIXUP_5ST_DIG,
1067	ALC880_FIXUP_6ST_BASE,
1068	ALC880_FIXUP_6ST,
1069	ALC880_FIXUP_6ST_DIG,
1070	ALC880_FIXUP_6ST_AUTOMUTE,
1071};
1072
1073/* enable the volume-knob widget support on NID 0x21 */
1074static void alc880_fixup_vol_knob(struct hda_codec *codec,
1075				  const struct hda_fixup *fix, int action)
1076{
1077	if (action == HDA_FIXUP_ACT_PROBE)
1078		snd_hda_jack_detect_enable_callback(codec, 0x21,
1079						    alc_update_knob_master);
1080}
1081
1082static const struct hda_fixup alc880_fixups[] = {
1083	[ALC880_FIXUP_GPIO1] = {
1084		.type = HDA_FIXUP_VERBS,
1085		.v.verbs = alc_gpio1_init_verbs,
1086	},
1087	[ALC880_FIXUP_GPIO2] = {
1088		.type = HDA_FIXUP_VERBS,
1089		.v.verbs = alc_gpio2_init_verbs,
1090	},
1091	[ALC880_FIXUP_MEDION_RIM] = {
1092		.type = HDA_FIXUP_VERBS,
1093		.v.verbs = (const struct hda_verb[]) {
1094			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1095			{ 0x20, AC_VERB_SET_PROC_COEF,  0x3060 },
1096			{ }
1097		},
1098		.chained = true,
1099		.chain_id = ALC880_FIXUP_GPIO2,
1100	},
1101	[ALC880_FIXUP_LG] = {
1102		.type = HDA_FIXUP_PINS,
1103		.v.pins = (const struct hda_pintbl[]) {
1104			/* disable bogus unused pins */
1105			{ 0x16, 0x411111f0 },
1106			{ 0x18, 0x411111f0 },
1107			{ 0x1a, 0x411111f0 },
1108			{ }
1109		}
1110	},
1111	[ALC880_FIXUP_LG_LW25] = {
1112		.type = HDA_FIXUP_PINS,
1113		.v.pins = (const struct hda_pintbl[]) {
1114			{ 0x1a, 0x0181344f }, /* line-in */
1115			{ 0x1b, 0x0321403f }, /* headphone */
1116			{ }
1117		}
1118	},
1119	[ALC880_FIXUP_W810] = {
1120		.type = HDA_FIXUP_PINS,
1121		.v.pins = (const struct hda_pintbl[]) {
1122			/* disable bogus unused pins */
1123			{ 0x17, 0x411111f0 },
1124			{ }
1125		},
1126		.chained = true,
1127		.chain_id = ALC880_FIXUP_GPIO2,
1128	},
1129	[ALC880_FIXUP_EAPD_COEF] = {
1130		.type = HDA_FIXUP_VERBS,
1131		.v.verbs = (const struct hda_verb[]) {
1132			/* change to EAPD mode */
1133			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1134			{ 0x20, AC_VERB_SET_PROC_COEF,  0x3060 },
1135			{}
1136		},
1137	},
1138	[ALC880_FIXUP_TCL_S700] = {
1139		.type = HDA_FIXUP_VERBS,
1140		.v.verbs = (const struct hda_verb[]) {
1141			/* change to EAPD mode */
1142			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1143			{ 0x20, AC_VERB_SET_PROC_COEF,  0x3070 },
1144			{}
1145		},
1146		.chained = true,
1147		.chain_id = ALC880_FIXUP_GPIO2,
1148	},
1149	[ALC880_FIXUP_VOL_KNOB] = {
1150		.type = HDA_FIXUP_FUNC,
1151		.v.func = alc880_fixup_vol_knob,
1152	},
1153	[ALC880_FIXUP_FUJITSU] = {
1154		/* override all pins as BIOS on old Amilo is broken */
1155		.type = HDA_FIXUP_PINS,
1156		.v.pins = (const struct hda_pintbl[]) {
1157			{ 0x14, 0x0121401f }, /* HP */
1158			{ 0x15, 0x99030120 }, /* speaker */
1159			{ 0x16, 0x99030130 }, /* bass speaker */
1160			{ 0x17, 0x411111f0 }, /* N/A */
1161			{ 0x18, 0x411111f0 }, /* N/A */
1162			{ 0x19, 0x01a19950 }, /* mic-in */
1163			{ 0x1a, 0x411111f0 }, /* N/A */
1164			{ 0x1b, 0x411111f0 }, /* N/A */
1165			{ 0x1c, 0x411111f0 }, /* N/A */
1166			{ 0x1d, 0x411111f0 }, /* N/A */
1167			{ 0x1e, 0x01454140 }, /* SPDIF out */
1168			{ }
1169		},
1170		.chained = true,
1171		.chain_id = ALC880_FIXUP_VOL_KNOB,
1172	},
1173	[ALC880_FIXUP_F1734] = {
1174		/* almost compatible with FUJITSU, but no bass and SPDIF */
1175		.type = HDA_FIXUP_PINS,
1176		.v.pins = (const struct hda_pintbl[]) {
1177			{ 0x14, 0x0121401f }, /* HP */
1178			{ 0x15, 0x99030120 }, /* speaker */
1179			{ 0x16, 0x411111f0 }, /* N/A */
1180			{ 0x17, 0x411111f0 }, /* N/A */
1181			{ 0x18, 0x411111f0 }, /* N/A */
1182			{ 0x19, 0x01a19950 }, /* mic-in */
1183			{ 0x1a, 0x411111f0 }, /* N/A */
1184			{ 0x1b, 0x411111f0 }, /* N/A */
1185			{ 0x1c, 0x411111f0 }, /* N/A */
1186			{ 0x1d, 0x411111f0 }, /* N/A */
1187			{ 0x1e, 0x411111f0 }, /* N/A */
1188			{ }
1189		},
1190		.chained = true,
1191		.chain_id = ALC880_FIXUP_VOL_KNOB,
1192	},
1193	[ALC880_FIXUP_UNIWILL] = {
1194		/* need to fix HP and speaker pins to be parsed correctly */
1195		.type = HDA_FIXUP_PINS,
1196		.v.pins = (const struct hda_pintbl[]) {
1197			{ 0x14, 0x0121411f }, /* HP */
1198			{ 0x15, 0x99030120 }, /* speaker */
1199			{ 0x16, 0x99030130 }, /* bass speaker */
1200			{ }
1201		},
1202	},
1203	[ALC880_FIXUP_UNIWILL_DIG] = {
1204		.type = HDA_FIXUP_PINS,
1205		.v.pins = (const struct hda_pintbl[]) {
1206			/* disable bogus unused pins */
1207			{ 0x17, 0x411111f0 },
1208			{ 0x19, 0x411111f0 },
1209			{ 0x1b, 0x411111f0 },
1210			{ 0x1f, 0x411111f0 },
1211			{ }
1212		}
1213	},
1214	[ALC880_FIXUP_Z71V] = {
1215		.type = HDA_FIXUP_PINS,
1216		.v.pins = (const struct hda_pintbl[]) {
1217			/* set up the whole pins as BIOS is utterly broken */
1218			{ 0x14, 0x99030120 }, /* speaker */
1219			{ 0x15, 0x0121411f }, /* HP */
1220			{ 0x16, 0x411111f0 }, /* N/A */
1221			{ 0x17, 0x411111f0 }, /* N/A */
1222			{ 0x18, 0x01a19950 }, /* mic-in */
1223			{ 0x19, 0x411111f0 }, /* N/A */
1224			{ 0x1a, 0x01813031 }, /* line-in */
1225			{ 0x1b, 0x411111f0 }, /* N/A */
1226			{ 0x1c, 0x411111f0 }, /* N/A */
1227			{ 0x1d, 0x411111f0 }, /* N/A */
1228			{ 0x1e, 0x0144111e }, /* SPDIF */
1229			{ }
1230		}
1231	},
1232	[ALC880_FIXUP_ASUS_W5A] = {
1233		.type = HDA_FIXUP_PINS,
1234		.v.pins = (const struct hda_pintbl[]) {
1235			/* set up the whole pins as BIOS is utterly broken */
1236			{ 0x14, 0x0121411f }, /* HP */
1237			{ 0x15, 0x411111f0 }, /* N/A */
1238			{ 0x16, 0x411111f0 }, /* N/A */
1239			{ 0x17, 0x411111f0 }, /* N/A */
1240			{ 0x18, 0x90a60160 }, /* mic */
1241			{ 0x19, 0x411111f0 }, /* N/A */
1242			{ 0x1a, 0x411111f0 }, /* N/A */
1243			{ 0x1b, 0x411111f0 }, /* N/A */
1244			{ 0x1c, 0x411111f0 }, /* N/A */
1245			{ 0x1d, 0x411111f0 }, /* N/A */
1246			{ 0x1e, 0xb743111e }, /* SPDIF out */
1247			{ }
1248		},
1249		.chained = true,
1250		.chain_id = ALC880_FIXUP_GPIO1,
1251	},
1252	[ALC880_FIXUP_3ST_BASE] = {
1253		.type = HDA_FIXUP_PINS,
1254		.v.pins = (const struct hda_pintbl[]) {
1255			{ 0x14, 0x01014010 }, /* line-out */
1256			{ 0x15, 0x411111f0 }, /* N/A */
1257			{ 0x16, 0x411111f0 }, /* N/A */
1258			{ 0x17, 0x411111f0 }, /* N/A */
1259			{ 0x18, 0x01a19c30 }, /* mic-in */
1260			{ 0x19, 0x0121411f }, /* HP */
1261			{ 0x1a, 0x01813031 }, /* line-in */
1262			{ 0x1b, 0x02a19c40 }, /* front-mic */
1263			{ 0x1c, 0x411111f0 }, /* N/A */
1264			{ 0x1d, 0x411111f0 }, /* N/A */
1265			/* 0x1e is filled in below */
1266			{ 0x1f, 0x411111f0 }, /* N/A */
1267			{ }
1268		}
1269	},
1270	[ALC880_FIXUP_3ST] = {
1271		.type = HDA_FIXUP_PINS,
1272		.v.pins = (const struct hda_pintbl[]) {
1273			{ 0x1e, 0x411111f0 }, /* N/A */
1274			{ }
1275		},
1276		.chained = true,
1277		.chain_id = ALC880_FIXUP_3ST_BASE,
1278	},
1279	[ALC880_FIXUP_3ST_DIG] = {
1280		.type = HDA_FIXUP_PINS,
1281		.v.pins = (const struct hda_pintbl[]) {
1282			{ 0x1e, 0x0144111e }, /* SPDIF */
1283			{ }
1284		},
1285		.chained = true,
1286		.chain_id = ALC880_FIXUP_3ST_BASE,
1287	},
1288	[ALC880_FIXUP_5ST_BASE] = {
1289		.type = HDA_FIXUP_PINS,
1290		.v.pins = (const struct hda_pintbl[]) {
1291			{ 0x14, 0x01014010 }, /* front */
1292			{ 0x15, 0x411111f0 }, /* N/A */
1293			{ 0x16, 0x01011411 }, /* CLFE */
1294			{ 0x17, 0x01016412 }, /* surr */
1295			{ 0x18, 0x01a19c30 }, /* mic-in */
1296			{ 0x19, 0x0121411f }, /* HP */
1297			{ 0x1a, 0x01813031 }, /* line-in */
1298			{ 0x1b, 0x02a19c40 }, /* front-mic */
1299			{ 0x1c, 0x411111f0 }, /* N/A */
1300			{ 0x1d, 0x411111f0 }, /* N/A */
1301			/* 0x1e is filled in below */
1302			{ 0x1f, 0x411111f0 }, /* N/A */
1303			{ }
1304		}
1305	},
1306	[ALC880_FIXUP_5ST] = {
1307		.type = HDA_FIXUP_PINS,
1308		.v.pins = (const struct hda_pintbl[]) {
1309			{ 0x1e, 0x411111f0 }, /* N/A */
1310			{ }
1311		},
1312		.chained = true,
1313		.chain_id = ALC880_FIXUP_5ST_BASE,
1314	},
1315	[ALC880_FIXUP_5ST_DIG] = {
1316		.type = HDA_FIXUP_PINS,
1317		.v.pins = (const struct hda_pintbl[]) {
1318			{ 0x1e, 0x0144111e }, /* SPDIF */
1319			{ }
1320		},
1321		.chained = true,
1322		.chain_id = ALC880_FIXUP_5ST_BASE,
1323	},
1324	[ALC880_FIXUP_6ST_BASE] = {
1325		.type = HDA_FIXUP_PINS,
1326		.v.pins = (const struct hda_pintbl[]) {
1327			{ 0x14, 0x01014010 }, /* front */
1328			{ 0x15, 0x01016412 }, /* surr */
1329			{ 0x16, 0x01011411 }, /* CLFE */
1330			{ 0x17, 0x01012414 }, /* side */
1331			{ 0x18, 0x01a19c30 }, /* mic-in */
1332			{ 0x19, 0x02a19c40 }, /* front-mic */
1333			{ 0x1a, 0x01813031 }, /* line-in */
1334			{ 0x1b, 0x0121411f }, /* HP */
1335			{ 0x1c, 0x411111f0 }, /* N/A */
1336			{ 0x1d, 0x411111f0 }, /* N/A */
1337			/* 0x1e is filled in below */
1338			{ 0x1f, 0x411111f0 }, /* N/A */
1339			{ }
1340		}
1341	},
1342	[ALC880_FIXUP_6ST] = {
1343		.type = HDA_FIXUP_PINS,
1344		.v.pins = (const struct hda_pintbl[]) {
1345			{ 0x1e, 0x411111f0 }, /* N/A */
1346			{ }
1347		},
1348		.chained = true,
1349		.chain_id = ALC880_FIXUP_6ST_BASE,
1350	},
1351	[ALC880_FIXUP_6ST_DIG] = {
1352		.type = HDA_FIXUP_PINS,
1353		.v.pins = (const struct hda_pintbl[]) {
1354			{ 0x1e, 0x0144111e }, /* SPDIF */
1355			{ }
1356		},
1357		.chained = true,
1358		.chain_id = ALC880_FIXUP_6ST_BASE,
1359	},
1360	[ALC880_FIXUP_6ST_AUTOMUTE] = {
1361		.type = HDA_FIXUP_PINS,
1362		.v.pins = (const struct hda_pintbl[]) {
1363			{ 0x1b, 0x0121401f }, /* HP with jack detect */
1364			{ }
1365		},
1366		.chained_before = true,
1367		.chain_id = ALC880_FIXUP_6ST_BASE,
1368	},
1369};
1370
1371static const struct snd_pci_quirk alc880_fixup_tbl[] = {
1372	SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810),
1373	SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS W5A", ALC880_FIXUP_ASUS_W5A),
1374	SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V),
1375	SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1),
1376	SND_PCI_QUIRK(0x147b, 0x1045, "ABit AA8XE", ALC880_FIXUP_6ST_AUTOMUTE),
1377	SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2),
1378	SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF),
1379	SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG),
1380	SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734),
1381	SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL),
1382	SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB),
1383	SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810),
1384	SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
1385	SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST_AUTOMUTE),
1386	SND_PCI_QUIRK(0x1734, 0x107c, "FSC Amilo M1437", ALC880_FIXUP_FUJITSU),
1387	SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU),
1388	SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734),
1389	SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU),
1390	SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
1391	SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
1392	SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
1393	SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_FIXUP_LG_LW25),
1394	SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),
1395
1396	/* Below is the copied entries from alc880_quirks.c.
1397	 * It's not quite sure whether BIOS sets the correct pin-config table
1398	 * on these machines, thus they are kept to be compatible with
1399	 * the old static quirks.  Once when it's confirmed to work without
1400	 * these overrides, it'd be better to remove.
1401	 */
1402	SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG),
1403	SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST),
1404	SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG),
1405	SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG),
1406	SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG),
1407	SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG),
1408	SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG),
1409	SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST),
1410	SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG),
1411	SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST),
1412	SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST),
1413	SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST),
1414	SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST),
1415	SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST),
1416	SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG),
1417	SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG),
1418	SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG),
1419	SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG),
1420	SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG),
1421	SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG),
1422	SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG),
1423	SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */
1424	SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG),
1425	SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1426	SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1427	SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1428	SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1429	SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1430	SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1431	SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1432	SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1433	SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1434	SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1435	/* default Intel */
1436	SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST),
1437	SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG),
1438	SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG),
1439	{}
1440};
1441
1442static const struct hda_model_fixup alc880_fixup_models[] = {
1443	{.id = ALC880_FIXUP_3ST, .name = "3stack"},
1444	{.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"},
1445	{.id = ALC880_FIXUP_5ST, .name = "5stack"},
1446	{.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"},
1447	{.id = ALC880_FIXUP_6ST, .name = "6stack"},
1448	{.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"},
1449	{.id = ALC880_FIXUP_6ST_AUTOMUTE, .name = "6stack-automute"},
1450	{}
1451};
1452
1453
1454/*
1455 * OK, here we have finally the patch for ALC880
1456 */
1457static int patch_alc880(struct hda_codec *codec)
1458{
1459	struct alc_spec *spec;
1460	int err;
1461
1462	err = alc_alloc_spec(codec, 0x0b);
1463	if (err < 0)
1464		return err;
1465
1466	spec = codec->spec;
1467	spec->gen.need_dac_fix = 1;
1468	spec->gen.beep_nid = 0x01;
1469
1470	snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
1471		       alc880_fixups);
1472	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
1473
1474	/* automatic parse from the BIOS config */
1475	err = alc880_parse_auto_config(codec);
1476	if (err < 0)
1477		goto error;
1478
1479	if (!spec->gen.no_analog)
1480		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1481
1482	codec->patch_ops = alc_patch_ops;
1483	codec->patch_ops.unsol_event = alc880_unsol_event;
1484
1485
1486	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
1487
1488	return 0;
1489
1490 error:
1491	alc_free(codec);
1492	return err;
1493}
1494
1495
1496/*
1497 * ALC260 support
1498 */
1499static int alc260_parse_auto_config(struct hda_codec *codec)
1500{
1501	static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
1502	static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 };
1503	return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
1504}
1505
1506/*
1507 * Pin config fixes
1508 */
1509enum {
1510	ALC260_FIXUP_HP_DC5750,
1511	ALC260_FIXUP_HP_PIN_0F,
1512	ALC260_FIXUP_COEF,
1513	ALC260_FIXUP_GPIO1,
1514	ALC260_FIXUP_GPIO1_TOGGLE,
1515	ALC260_FIXUP_REPLACER,
1516	ALC260_FIXUP_HP_B1900,
1517	ALC260_FIXUP_KN1,
1518	ALC260_FIXUP_FSC_S7020,
1519	ALC260_FIXUP_FSC_S7020_JWSE,
1520	ALC260_FIXUP_VAIO_PINS,
1521};
1522
1523static void alc260_gpio1_automute(struct hda_codec *codec)
1524{
1525	struct alc_spec *spec = codec->spec;
1526	snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
1527			    spec->gen.hp_jack_present);
1528}
1529
1530static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
1531				      const struct hda_fixup *fix, int action)
1532{
1533	struct alc_spec *spec = codec->spec;
1534	if (action == HDA_FIXUP_ACT_PROBE) {
1535		/* although the machine has only one output pin, we need to
1536		 * toggle GPIO1 according to the jack state
1537		 */
1538		spec->gen.automute_hook = alc260_gpio1_automute;
1539		spec->gen.detect_hp = 1;
1540		spec->gen.automute_speaker = 1;
1541		spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
1542		snd_hda_jack_detect_enable_callback(codec, 0x0f,
1543						    snd_hda_gen_hp_automute);
1544		snd_hda_add_verbs(codec, alc_gpio1_init_verbs);
1545	}
1546}
1547
1548static void alc260_fixup_kn1(struct hda_codec *codec,
1549			     const struct hda_fixup *fix, int action)
1550{
1551	struct alc_spec *spec = codec->spec;
1552	static const struct hda_pintbl pincfgs[] = {
1553		{ 0x0f, 0x02214000 }, /* HP/speaker */
1554		{ 0x12, 0x90a60160 }, /* int mic */
1555		{ 0x13, 0x02a19000 }, /* ext mic */
1556		{ 0x18, 0x01446000 }, /* SPDIF out */
1557		/* disable bogus I/O pins */
1558		{ 0x10, 0x411111f0 },
1559		{ 0x11, 0x411111f0 },
1560		{ 0x14, 0x411111f0 },
1561		{ 0x15, 0x411111f0 },
1562		{ 0x16, 0x411111f0 },
1563		{ 0x17, 0x411111f0 },
1564		{ 0x19, 0x411111f0 },
1565		{ }
1566	};
1567
1568	switch (action) {
1569	case HDA_FIXUP_ACT_PRE_PROBE:
1570		snd_hda_apply_pincfgs(codec, pincfgs);
1571		break;
1572	case HDA_FIXUP_ACT_PROBE:
1573		spec->init_amp = ALC_INIT_NONE;
1574		break;
1575	}
1576}
1577
1578static void alc260_fixup_fsc_s7020(struct hda_codec *codec,
1579				   const struct hda_fixup *fix, int action)
1580{
1581	struct alc_spec *spec = codec->spec;
1582	if (action == HDA_FIXUP_ACT_PROBE)
1583		spec->init_amp = ALC_INIT_NONE;
1584}
1585
1586static void alc260_fixup_fsc_s7020_jwse(struct hda_codec *codec,
1587				   const struct hda_fixup *fix, int action)
1588{
1589	struct alc_spec *spec = codec->spec;
1590	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1591		spec->gen.add_jack_modes = 1;
1592		spec->gen.hp_mic = 1;
1593	}
1594}
1595
1596static const struct hda_fixup alc260_fixups[] = {
1597	[ALC260_FIXUP_HP_DC5750] = {
1598		.type = HDA_FIXUP_PINS,
1599		.v.pins = (const struct hda_pintbl[]) {
1600			{ 0x11, 0x90130110 }, /* speaker */
1601			{ }
1602		}
1603	},
1604	[ALC260_FIXUP_HP_PIN_0F] = {
1605		.type = HDA_FIXUP_PINS,
1606		.v.pins = (const struct hda_pintbl[]) {
1607			{ 0x0f, 0x01214000 }, /* HP */
1608			{ }
1609		}
1610	},
1611	[ALC260_FIXUP_COEF] = {
1612		.type = HDA_FIXUP_VERBS,
1613		.v.verbs = (const struct hda_verb[]) {
1614			{ 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1615			{ 0x1a, AC_VERB_SET_PROC_COEF,  0x3040 },
1616			{ }
1617		},
1618	},
1619	[ALC260_FIXUP_GPIO1] = {
1620		.type = HDA_FIXUP_VERBS,
1621		.v.verbs = alc_gpio1_init_verbs,
1622	},
1623	[ALC260_FIXUP_GPIO1_TOGGLE] = {
1624		.type = HDA_FIXUP_FUNC,
1625		.v.func = alc260_fixup_gpio1_toggle,
1626		.chained = true,
1627		.chain_id = ALC260_FIXUP_HP_PIN_0F,
1628	},
1629	[ALC260_FIXUP_REPLACER] = {
1630		.type = HDA_FIXUP_VERBS,
1631		.v.verbs = (const struct hda_verb[]) {
1632			{ 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1633			{ 0x1a, AC_VERB_SET_PROC_COEF,  0x3050 },
1634			{ }
1635		},
1636		.chained = true,
1637		.chain_id = ALC260_FIXUP_GPIO1_TOGGLE,
1638	},
1639	[ALC260_FIXUP_HP_B1900] = {
1640		.type = HDA_FIXUP_FUNC,
1641		.v.func = alc260_fixup_gpio1_toggle,
1642		.chained = true,
1643		.chain_id = ALC260_FIXUP_COEF,
1644	},
1645	[ALC260_FIXUP_KN1] = {
1646		.type = HDA_FIXUP_FUNC,
1647		.v.func = alc260_fixup_kn1,
1648	},
1649	[ALC260_FIXUP_FSC_S7020] = {
1650		.type = HDA_FIXUP_FUNC,
1651		.v.func = alc260_fixup_fsc_s7020,
1652	},
1653	[ALC260_FIXUP_FSC_S7020_JWSE] = {
1654		.type = HDA_FIXUP_FUNC,
1655		.v.func = alc260_fixup_fsc_s7020_jwse,
1656		.chained = true,
1657		.chain_id = ALC260_FIXUP_FSC_S7020,
1658	},
1659	[ALC260_FIXUP_VAIO_PINS] = {
1660		.type = HDA_FIXUP_PINS,
1661		.v.pins = (const struct hda_pintbl[]) {
1662			/* Pin configs are missing completely on some VAIOs */
1663			{ 0x0f, 0x01211020 },
1664			{ 0x10, 0x0001003f },
1665			{ 0x11, 0x411111f0 },
1666			{ 0x12, 0x01a15930 },
1667			{ 0x13, 0x411111f0 },
1668			{ 0x14, 0x411111f0 },
1669			{ 0x15, 0x411111f0 },
1670			{ 0x16, 0x411111f0 },
1671			{ 0x17, 0x411111f0 },
1672			{ 0x18, 0x411111f0 },
1673			{ 0x19, 0x411111f0 },
1674			{ }
1675		}
1676	},
1677};
1678
1679static const struct snd_pci_quirk alc260_fixup_tbl[] = {
1680	SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1),
1681	SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
1682	SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
1683	SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
1684	SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
1685	SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_FIXUP_VAIO_PINS),
1686	SND_PCI_QUIRK(0x104d, 0x81e2, "Sony VAIO TX", ALC260_FIXUP_HP_PIN_0F),
1687	SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020),
1688	SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
1689	SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1),
1690	SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
1691	SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
1692	{}
1693};
1694
1695static const struct hda_model_fixup alc260_fixup_models[] = {
1696	{.id = ALC260_FIXUP_GPIO1, .name = "gpio1"},
1697	{.id = ALC260_FIXUP_COEF, .name = "coef"},
1698	{.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"},
1699	{.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"},
1700	{}
1701};
1702
1703/*
1704 */
1705static int patch_alc260(struct hda_codec *codec)
1706{
1707	struct alc_spec *spec;
1708	int err;
1709
1710	err = alc_alloc_spec(codec, 0x07);
1711	if (err < 0)
1712		return err;
1713
1714	spec = codec->spec;
1715	/* as quite a few machines require HP amp for speaker outputs,
1716	 * it's easier to enable it unconditionally; even if it's unneeded,
1717	 * it's almost harmless.
1718	 */
1719	spec->gen.prefer_hp_amp = 1;
1720	spec->gen.beep_nid = 0x01;
1721
1722	snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl,
1723			   alc260_fixups);
1724	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
1725
1726	/* automatic parse from the BIOS config */
1727	err = alc260_parse_auto_config(codec);
1728	if (err < 0)
1729		goto error;
1730
1731	if (!spec->gen.no_analog)
1732		set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
1733
1734	codec->patch_ops = alc_patch_ops;
1735	spec->shutup = alc_eapd_shutup;
1736
1737	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
1738
1739	return 0;
1740
1741 error:
1742	alc_free(codec);
1743	return err;
1744}
1745
1746
1747/*
1748 * ALC882/883/885/888/889 support
1749 *
1750 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
1751 * configuration.  Each pin widget can choose any input DACs and a mixer.
1752 * Each ADC is connected from a mixer of all inputs.  This makes possible
1753 * 6-channel independent captures.
1754 *
1755 * In addition, an independent DAC for the multi-playback (not used in this
1756 * driver yet).
1757 */
1758
1759/*
1760 * Pin config fixes
1761 */
1762enum {
1763	ALC882_FIXUP_ABIT_AW9D_MAX,
1764	ALC882_FIXUP_LENOVO_Y530,
1765	ALC882_FIXUP_PB_M5210,
1766	ALC882_FIXUP_ACER_ASPIRE_7736,
1767	ALC882_FIXUP_ASUS_W90V,
1768	ALC889_FIXUP_CD,
1769	ALC889_FIXUP_FRONT_HP_NO_PRESENCE,
1770	ALC889_FIXUP_VAIO_TT,
1771	ALC888_FIXUP_EEE1601,
1772	ALC882_FIXUP_EAPD,
1773	ALC883_FIXUP_EAPD,
1774	ALC883_FIXUP_ACER_EAPD,
1775	ALC882_FIXUP_GPIO1,
1776	ALC882_FIXUP_GPIO2,
1777	ALC882_FIXUP_GPIO3,
1778	ALC889_FIXUP_COEF,
1779	ALC882_FIXUP_ASUS_W2JC,
1780	ALC882_FIXUP_ACER_ASPIRE_4930G,
1781	ALC882_FIXUP_ACER_ASPIRE_8930G,
1782	ALC882_FIXUP_ASPIRE_8930G_VERBS,
1783	ALC885_FIXUP_MACPRO_GPIO,
1784	ALC889_FIXUP_DAC_ROUTE,
1785	ALC889_FIXUP_MBP_VREF,
1786	ALC889_FIXUP_IMAC91_VREF,
1787	ALC889_FIXUP_MBA11_VREF,
1788	ALC889_FIXUP_MBA21_VREF,
1789	ALC889_FIXUP_MP11_VREF,
1790	ALC889_FIXUP_MP41_VREF,
1791	ALC882_FIXUP_INV_DMIC,
1792	ALC882_FIXUP_NO_PRIMARY_HP,
1793	ALC887_FIXUP_ASUS_BASS,
1794	ALC887_FIXUP_BASS_CHMAP,
1795};
1796
1797static void alc889_fixup_coef(struct hda_codec *codec,
1798			      const struct hda_fixup *fix, int action)
1799{
1800	if (action != HDA_FIXUP_ACT_INIT)
1801		return;
1802	alc_update_coef_idx(codec, 7, 0, 0x2030);
1803}
1804
1805/* toggle speaker-output according to the hp-jack state */
1806static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
1807{
1808	unsigned int gpiostate, gpiomask, gpiodir;
1809
1810	gpiostate = snd_hda_codec_read(codec, codec->core.afg, 0,
1811				       AC_VERB_GET_GPIO_DATA, 0);
1812
1813	if (!muted)
1814		gpiostate |= (1 << pin);
1815	else
1816		gpiostate &= ~(1 << pin);
1817
1818	gpiomask = snd_hda_codec_read(codec, codec->core.afg, 0,
1819				      AC_VERB_GET_GPIO_MASK, 0);
1820	gpiomask |= (1 << pin);
1821
1822	gpiodir = snd_hda_codec_read(codec, codec->core.afg, 0,
1823				     AC_VERB_GET_GPIO_DIRECTION, 0);
1824	gpiodir |= (1 << pin);
1825
1826
1827	snd_hda_codec_write(codec, codec->core.afg, 0,
1828			    AC_VERB_SET_GPIO_MASK, gpiomask);
1829	snd_hda_codec_write(codec, codec->core.afg, 0,
1830			    AC_VERB_SET_GPIO_DIRECTION, gpiodir);
1831
1832	msleep(1);
1833
1834	snd_hda_codec_write(codec, codec->core.afg, 0,
1835			    AC_VERB_SET_GPIO_DATA, gpiostate);
1836}
1837
1838/* set up GPIO at initialization */
1839static void alc885_fixup_macpro_gpio(struct hda_codec *codec,
1840				     const struct hda_fixup *fix, int action)
1841{
1842	if (action != HDA_FIXUP_ACT_INIT)
1843		return;
1844	alc882_gpio_mute(codec, 0, 0);
1845	alc882_gpio_mute(codec, 1, 0);
1846}
1847
1848/* Fix the connection of some pins for ALC889:
1849 * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't
1850 * work correctly (bko#42740)
1851 */
1852static void alc889_fixup_dac_route(struct hda_codec *codec,
1853				   const struct hda_fixup *fix, int action)
1854{
1855	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1856		/* fake the connections during parsing the tree */
1857		hda_nid_t conn1[2] = { 0x0c, 0x0d };
1858		hda_nid_t conn2[2] = { 0x0e, 0x0f };
1859		snd_hda_override_conn_list(codec, 0x14, 2, conn1);
1860		snd_hda_override_conn_list(codec, 0x15, 2, conn1);
1861		snd_hda_override_conn_list(codec, 0x18, 2, conn2);
1862		snd_hda_override_conn_list(codec, 0x1a, 2, conn2);
1863	} else if (action == HDA_FIXUP_ACT_PROBE) {
1864		/* restore the connections */
1865		hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 };
1866		snd_hda_override_conn_list(codec, 0x14, 5, conn);
1867		snd_hda_override_conn_list(codec, 0x15, 5, conn);
1868		snd_hda_override_conn_list(codec, 0x18, 5, conn);
1869		snd_hda_override_conn_list(codec, 0x1a, 5, conn);
1870	}
1871}
1872
1873/* Set VREF on HP pin */
1874static void alc889_fixup_mbp_vref(struct hda_codec *codec,
1875				  const struct hda_fixup *fix, int action)
1876{
1877	struct alc_spec *spec = codec->spec;
1878	static hda_nid_t nids[3] = { 0x14, 0x15, 0x19 };
1879	int i;
1880
1881	if (action != HDA_FIXUP_ACT_INIT)
1882		return;
1883	for (i = 0; i < ARRAY_SIZE(nids); i++) {
1884		unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]);
1885		if (get_defcfg_device(val) != AC_JACK_HP_OUT)
1886			continue;
1887		val = snd_hda_codec_get_pin_target(codec, nids[i]);
1888		val |= AC_PINCTL_VREF_80;
1889		snd_hda_set_pin_ctl(codec, nids[i], val);
1890		spec->gen.keep_vref_in_automute = 1;
1891		break;
1892	}
1893}
1894
1895static void alc889_fixup_mac_pins(struct hda_codec *codec,
1896				  const hda_nid_t *nids, int num_nids)
1897{
1898	struct alc_spec *spec = codec->spec;
1899	int i;
1900
1901	for (i = 0; i < num_nids; i++) {
1902		unsigned int val;
1903		val = snd_hda_codec_get_pin_target(codec, nids[i]);
1904		val |= AC_PINCTL_VREF_50;
1905		snd_hda_set_pin_ctl(codec, nids[i], val);
1906	}
1907	spec->gen.keep_vref_in_automute = 1;
1908}
1909
1910/* Set VREF on speaker pins on imac91 */
1911static void alc889_fixup_imac91_vref(struct hda_codec *codec,
1912				     const struct hda_fixup *fix, int action)
1913{
1914	static hda_nid_t nids[2] = { 0x18, 0x1a };
1915
1916	if (action == HDA_FIXUP_ACT_INIT)
1917		alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1918}
1919
1920/* Set VREF on speaker pins on mba11 */
1921static void alc889_fixup_mba11_vref(struct hda_codec *codec,
1922				    const struct hda_fixup *fix, int action)
1923{
1924	static hda_nid_t nids[1] = { 0x18 };
1925
1926	if (action == HDA_FIXUP_ACT_INIT)
1927		alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1928}
1929
1930/* Set VREF on speaker pins on mba21 */
1931static void alc889_fixup_mba21_vref(struct hda_codec *codec,
1932				    const struct hda_fixup *fix, int action)
1933{
1934	static hda_nid_t nids[2] = { 0x18, 0x19 };
1935
1936	if (action == HDA_FIXUP_ACT_INIT)
1937		alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1938}
1939
1940/* Don't take HP output as primary
1941 * Strangely, the speaker output doesn't work on Vaio Z and some Vaio
1942 * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05
1943 */
1944static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
1945				       const struct hda_fixup *fix, int action)
1946{
1947	struct alc_spec *spec = codec->spec;
1948	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1949		spec->gen.no_primary_hp = 1;
1950		spec->gen.no_multi_io = 1;
1951	}
1952}
1953
1954static void alc_fixup_bass_chmap(struct hda_codec *codec,
1955				 const struct hda_fixup *fix, int action);
1956
1957static const struct hda_fixup alc882_fixups[] = {
1958	[ALC882_FIXUP_ABIT_AW9D_MAX] = {
1959		.type = HDA_FIXUP_PINS,
1960		.v.pins = (const struct hda_pintbl[]) {
1961			{ 0x15, 0x01080104 }, /* side */
1962			{ 0x16, 0x01011012 }, /* rear */
1963			{ 0x17, 0x01016011 }, /* clfe */
1964			{ }
1965		}
1966	},
1967	[ALC882_FIXUP_LENOVO_Y530] = {
1968		.type = HDA_FIXUP_PINS,
1969		.v.pins = (const struct hda_pintbl[]) {
1970			{ 0x15, 0x99130112 }, /* rear int speakers */
1971			{ 0x16, 0x99130111 }, /* subwoofer */
1972			{ }
1973		}
1974	},
1975	[ALC882_FIXUP_PB_M5210] = {
1976		.type = HDA_FIXUP_PINCTLS,
1977		.v.pins = (const struct hda_pintbl[]) {
1978			{ 0x19, PIN_VREF50 },
1979			{}
1980		}
1981	},
1982	[ALC882_FIXUP_ACER_ASPIRE_7736] = {
1983		.type = HDA_FIXUP_FUNC,
1984		.v.func = alc_fixup_sku_ignore,
1985	},
1986	[ALC882_FIXUP_ASUS_W90V] = {
1987		.type = HDA_FIXUP_PINS,
1988		.v.pins = (const struct hda_pintbl[]) {
1989			{ 0x16, 0x99130110 }, /* fix sequence for CLFE */
1990			{ }
1991		}
1992	},
1993	[ALC889_FIXUP_CD] = {
1994		.type = HDA_FIXUP_PINS,
1995		.v.pins = (const struct hda_pintbl[]) {
1996			{ 0x1c, 0x993301f0 }, /* CD */
1997			{ }
1998		}
1999	},
2000	[ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = {
2001		.type = HDA_FIXUP_PINS,
2002		.v.pins = (const struct hda_pintbl[]) {
2003			{ 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */
2004			{ }
2005		},
2006		.chained = true,
2007		.chain_id = ALC889_FIXUP_CD,
2008	},
2009	[ALC889_FIXUP_VAIO_TT] = {
2010		.type = HDA_FIXUP_PINS,
2011		.v.pins = (const struct hda_pintbl[]) {
2012			{ 0x17, 0x90170111 }, /* hidden surround speaker */
2013			{ }
2014		}
2015	},
2016	[ALC888_FIXUP_EEE1601] = {
2017		.type = HDA_FIXUP_VERBS,
2018		.v.verbs = (const struct hda_verb[]) {
2019			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2020			{ 0x20, AC_VERB_SET_PROC_COEF,  0x0838 },
2021			{ }
2022		}
2023	},
2024	[ALC882_FIXUP_EAPD] = {
2025		.type = HDA_FIXUP_VERBS,
2026		.v.verbs = (const struct hda_verb[]) {
2027			/* change to EAPD mode */
2028			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2029			{ 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
2030			{ }
2031		}
2032	},
2033	[ALC883_FIXUP_EAPD] = {
2034		.type = HDA_FIXUP_VERBS,
2035		.v.verbs = (const struct hda_verb[]) {
2036			/* change to EAPD mode */
2037			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2038			{ 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2039			{ }
2040		}
2041	},
2042	[ALC883_FIXUP_ACER_EAPD] = {
2043		.type = HDA_FIXUP_VERBS,
2044		.v.verbs = (const struct hda_verb[]) {
2045			/* eanable EAPD on Acer laptops */
2046			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2047			{ 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2048			{ }
2049		}
2050	},
2051	[ALC882_FIXUP_GPIO1] = {
2052		.type = HDA_FIXUP_VERBS,
2053		.v.verbs = alc_gpio1_init_verbs,
2054	},
2055	[ALC882_FIXUP_GPIO2] = {
2056		.type = HDA_FIXUP_VERBS,
2057		.v.verbs = alc_gpio2_init_verbs,
2058	},
2059	[ALC882_FIXUP_GPIO3] = {
2060		.type = HDA_FIXUP_VERBS,
2061		.v.verbs = alc_gpio3_init_verbs,
2062	},
2063	[ALC882_FIXUP_ASUS_W2JC] = {
2064		.type = HDA_FIXUP_VERBS,
2065		.v.verbs = alc_gpio1_init_verbs,
2066		.chained = true,
2067		.chain_id = ALC882_FIXUP_EAPD,
2068	},
2069	[ALC889_FIXUP_COEF] = {
2070		.type = HDA_FIXUP_FUNC,
2071		.v.func = alc889_fixup_coef,
2072	},
2073	[ALC882_FIXUP_ACER_ASPIRE_4930G] = {
2074		.type = HDA_FIXUP_PINS,
2075		.v.pins = (const struct hda_pintbl[]) {
2076			{ 0x16, 0x99130111 }, /* CLFE speaker */
2077			{ 0x17, 0x99130112 }, /* surround speaker */
2078			{ }
2079		},
2080		.chained = true,
2081		.chain_id = ALC882_FIXUP_GPIO1,
2082	},
2083	[ALC882_FIXUP_ACER_ASPIRE_8930G] = {
2084		.type = HDA_FIXUP_PINS,
2085		.v.pins = (const struct hda_pintbl[]) {
2086			{ 0x16, 0x99130111 }, /* CLFE speaker */
2087			{ 0x1b, 0x99130112 }, /* surround speaker */
2088			{ }
2089		},
2090		.chained = true,
2091		.chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS,
2092	},
2093	[ALC882_FIXUP_ASPIRE_8930G_VERBS] = {
2094		/* additional init verbs for Acer Aspire 8930G */
2095		.type = HDA_FIXUP_VERBS,
2096		.v.verbs = (const struct hda_verb[]) {
2097			/* Enable all DACs */
2098			/* DAC DISABLE/MUTE 1? */
2099			/*  setting bits 1-5 disables DAC nids 0x02-0x06
2100			 *  apparently. Init=0x38 */
2101			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x03 },
2102			{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2103			/* DAC DISABLE/MUTE 2? */
2104			/*  some bit here disables the other DACs.
2105			 *  Init=0x4900 */
2106			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x08 },
2107			{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2108			/* DMIC fix
2109			 * This laptop has a stereo digital microphone.
2110			 * The mics are only 1cm apart which makes the stereo
2111			 * useless. However, either the mic or the ALC889
2112			 * makes the signal become a difference/sum signal
2113			 * instead of standard stereo, which is annoying.
2114			 * So instead we flip this bit which makes the
2115			 * codec replicate the sum signal to both channels,
2116			 * turning it into a normal mono mic.
2117			 */
2118			/* DMIC_CONTROL? Init value = 0x0001 */
2119			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2120			{ 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
2121			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2122			{ 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2123			{ }
2124		},
2125		.chained = true,
2126		.chain_id = ALC882_FIXUP_GPIO1,
2127	},
2128	[ALC885_FIXUP_MACPRO_GPIO] = {
2129		.type = HDA_FIXUP_FUNC,
2130		.v.func = alc885_fixup_macpro_gpio,
2131	},
2132	[ALC889_FIXUP_DAC_ROUTE] = {
2133		.type = HDA_FIXUP_FUNC,
2134		.v.func = alc889_fixup_dac_route,
2135	},
2136	[ALC889_FIXUP_MBP_VREF] = {
2137		.type = HDA_FIXUP_FUNC,
2138		.v.func = alc889_fixup_mbp_vref,
2139		.chained = true,
2140		.chain_id = ALC882_FIXUP_GPIO1,
2141	},
2142	[ALC889_FIXUP_IMAC91_VREF] = {
2143		.type = HDA_FIXUP_FUNC,
2144		.v.func = alc889_fixup_imac91_vref,
2145		.chained = true,
2146		.chain_id = ALC882_FIXUP_GPIO1,
2147	},
2148	[ALC889_FIXUP_MBA11_VREF] = {
2149		.type = HDA_FIXUP_FUNC,
2150		.v.func = alc889_fixup_mba11_vref,
2151		.chained = true,
2152		.chain_id = ALC889_FIXUP_MBP_VREF,
2153	},
2154	[ALC889_FIXUP_MBA21_VREF] = {
2155		.type = HDA_FIXUP_FUNC,
2156		.v.func = alc889_fixup_mba21_vref,
2157		.chained = true,
2158		.chain_id = ALC889_FIXUP_MBP_VREF,
2159	},
2160	[ALC889_FIXUP_MP11_VREF] = {
2161		.type = HDA_FIXUP_FUNC,
2162		.v.func = alc889_fixup_mba11_vref,
2163		.chained = true,
2164		.chain_id = ALC885_FIXUP_MACPRO_GPIO,
2165	},
2166	[ALC889_FIXUP_MP41_VREF] = {
2167		.type = HDA_FIXUP_FUNC,
2168		.v.func = alc889_fixup_mbp_vref,
2169		.chained = true,
2170		.chain_id = ALC885_FIXUP_MACPRO_GPIO,
2171	},
2172	[ALC882_FIXUP_INV_DMIC] = {
2173		.type = HDA_FIXUP_FUNC,
2174		.v.func = alc_fixup_inv_dmic,
2175	},
2176	[ALC882_FIXUP_NO_PRIMARY_HP] = {
2177		.type = HDA_FIXUP_FUNC,
2178		.v.func = alc882_fixup_no_primary_hp,
2179	},
2180	[ALC887_FIXUP_ASUS_BASS] = {
2181		.type = HDA_FIXUP_PINS,
2182		.v.pins = (const struct hda_pintbl[]) {
2183			{0x16, 0x99130130}, /* bass speaker */
2184			{}
2185		},
2186		.chained = true,
2187		.chain_id = ALC887_FIXUP_BASS_CHMAP,
2188	},
2189	[ALC887_FIXUP_BASS_CHMAP] = {
2190		.type = HDA_FIXUP_FUNC,
2191		.v.func = alc_fixup_bass_chmap,
2192	},
2193};
2194
2195static const struct snd_pci_quirk alc882_fixup_tbl[] = {
2196	SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD),
2197	SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2198	SND_PCI_QUIRK(0x1025, 0x0107, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2199	SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD),
2200	SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2201	SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD),
2202	SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD),
2203	SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
2204		      ALC882_FIXUP_ACER_ASPIRE_4930G),
2205	SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
2206		      ALC882_FIXUP_ACER_ASPIRE_4930G),
2207	SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
2208		      ALC882_FIXUP_ACER_ASPIRE_8930G),
2209	SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
2210		      ALC882_FIXUP_ACER_ASPIRE_8930G),
2211	SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
2212		      ALC882_FIXUP_ACER_ASPIRE_4930G),
2213	SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
2214		      ALC882_FIXUP_ACER_ASPIRE_4930G),
2215	SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
2216		      ALC882_FIXUP_ACER_ASPIRE_4930G),
2217	SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
2218	SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G",
2219		      ALC882_FIXUP_ACER_ASPIRE_4930G),
2220	SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
2221	SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G),
2222	SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
2223	SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
2224	SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
2225	SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC),
2226	SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
2227	SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS),
2228	SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
2229	SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
2230	SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
2231	SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP),
2232
2233	/* All Apple entries are in codec SSIDs */
2234	SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
2235	SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
2236	SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
2237	SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF),
2238	SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
2239	SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
2240	SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
2241	SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
2242	SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
2243	SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF),
2244	SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF),
2245	SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
2246	SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
2247	SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
2248	SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
2249	SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
2250	SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
2251	SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 4,1/5,1", ALC889_FIXUP_MP41_VREF),
2252	SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF),
2253	SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
2254	SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
2255	SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_MBA11_VREF),
2256
2257	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
2258	SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
2259	SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
2260	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
2261	SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
2262	SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
2263	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
2264	SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
2265	SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF),
2266	{}
2267};
2268
2269static const struct hda_model_fixup alc882_fixup_models[] = {
2270	{.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"},
2271	{.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
2272	{.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
2273	{.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"},
2274	{.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"},
2275	{}
2276};
2277
2278/*
2279 * BIOS auto configuration
2280 */
2281/* almost identical with ALC880 parser... */
2282static int alc882_parse_auto_config(struct hda_codec *codec)
2283{
2284	static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
2285	static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2286	return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids);
2287}
2288
2289/*
2290 */
2291static int patch_alc882(struct hda_codec *codec)
2292{
2293	struct alc_spec *spec;
2294	int err;
2295
2296	err = alc_alloc_spec(codec, 0x0b);
2297	if (err < 0)
2298		return err;
2299
2300	spec = codec->spec;
2301
2302	switch (codec->core.vendor_id) {
2303	case 0x10ec0882:
2304	case 0x10ec0885:
2305	case 0x10ec0900:
2306		break;
2307	default:
2308		/* ALC883 and variants */
2309		alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2310		break;
2311	}
2312
2313	snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl,
2314		       alc882_fixups);
2315	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
2316
2317	alc_auto_parse_customize_define(codec);
2318
2319	if (has_cdefine_beep(codec))
2320		spec->gen.beep_nid = 0x01;
2321
2322	/* automatic parse from the BIOS config */
2323	err = alc882_parse_auto_config(codec);
2324	if (err < 0)
2325		goto error;
2326
2327	if (!spec->gen.no_analog && spec->gen.beep_nid)
2328		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2329
2330	codec->patch_ops = alc_patch_ops;
2331
2332	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
2333
2334	return 0;
2335
2336 error:
2337	alc_free(codec);
2338	return err;
2339}
2340
2341
2342/*
2343 * ALC262 support
2344 */
2345static int alc262_parse_auto_config(struct hda_codec *codec)
2346{
2347	static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
2348	static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2349	return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids);
2350}
2351
2352/*
2353 * Pin config fixes
2354 */
2355enum {
2356	ALC262_FIXUP_FSC_H270,
2357	ALC262_FIXUP_FSC_S7110,
2358	ALC262_FIXUP_HP_Z200,
2359	ALC262_FIXUP_TYAN,
2360	ALC262_FIXUP_LENOVO_3000,
2361	ALC262_FIXUP_BENQ,
2362	ALC262_FIXUP_BENQ_T31,
2363	ALC262_FIXUP_INV_DMIC,
2364	ALC262_FIXUP_INTEL_BAYLEYBAY,
2365};
2366
2367static const struct hda_fixup alc262_fixups[] = {
2368	[ALC262_FIXUP_FSC_H270] = {
2369		.type = HDA_FIXUP_PINS,
2370		.v.pins = (const struct hda_pintbl[]) {
2371			{ 0x14, 0x99130110 }, /* speaker */
2372			{ 0x15, 0x0221142f }, /* front HP */
2373			{ 0x1b, 0x0121141f }, /* rear HP */
2374			{ }
2375		}
2376	},
2377	[ALC262_FIXUP_FSC_S7110] = {
2378		.type = HDA_FIXUP_PINS,
2379		.v.pins = (const struct hda_pintbl[]) {
2380			{ 0x15, 0x90170110 }, /* speaker */
2381			{ }
2382		},
2383		.chained = true,
2384		.chain_id = ALC262_FIXUP_BENQ,
2385	},
2386	[ALC262_FIXUP_HP_Z200] = {
2387		.type = HDA_FIXUP_PINS,
2388		.v.pins = (const struct hda_pintbl[]) {
2389			{ 0x16, 0x99130120 }, /* internal speaker */
2390			{ }
2391		}
2392	},
2393	[ALC262_FIXUP_TYAN] = {
2394		.type = HDA_FIXUP_PINS,
2395		.v.pins = (const struct hda_pintbl[]) {
2396			{ 0x14, 0x1993e1f0 }, /* int AUX */
2397			{ }
2398		}
2399	},
2400	[ALC262_FIXUP_LENOVO_3000] = {
2401		.type = HDA_FIXUP_PINCTLS,
2402		.v.pins = (const struct hda_pintbl[]) {
2403			{ 0x19, PIN_VREF50 },
2404			{}
2405		},
2406		.chained = true,
2407		.chain_id = ALC262_FIXUP_BENQ,
2408	},
2409	[ALC262_FIXUP_BENQ] = {
2410		.type = HDA_FIXUP_VERBS,
2411		.v.verbs = (const struct hda_verb[]) {
2412			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2413			{ 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2414			{}
2415		}
2416	},
2417	[ALC262_FIXUP_BENQ_T31] = {
2418		.type = HDA_FIXUP_VERBS,
2419		.v.verbs = (const struct hda_verb[]) {
2420			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2421			{ 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2422			{}
2423		}
2424	},
2425	[ALC262_FIXUP_INV_DMIC] = {
2426		.type = HDA_FIXUP_FUNC,
2427		.v.func = alc_fixup_inv_dmic,
2428	},
2429	[ALC262_FIXUP_INTEL_BAYLEYBAY] = {
2430		.type = HDA_FIXUP_FUNC,
2431		.v.func = alc_fixup_no_depop_delay,
2432	},
2433};
2434
2435static const struct snd_pci_quirk alc262_fixup_tbl[] = {
2436	SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200),
2437	SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110),
2438	SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
2439	SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN),
2440	SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
2441	SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
2442	SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
2443	SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31),
2444	SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY),
2445	{}
2446};
2447
2448static const struct hda_model_fixup alc262_fixup_models[] = {
2449	{.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"},
2450	{}
2451};
2452
2453/*
2454 */
2455static int patch_alc262(struct hda_codec *codec)
2456{
2457	struct alc_spec *spec;
2458	int err;
2459
2460	err = alc_alloc_spec(codec, 0x0b);
2461	if (err < 0)
2462		return err;
2463
2464	spec = codec->spec;
2465	spec->gen.shared_mic_vref_pin = 0x18;
2466
2467#if 0
2468	/* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
2469	 * under-run
2470	 */
2471	alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x80);
2472#endif
2473	alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2474
2475	snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl,
2476		       alc262_fixups);
2477	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
2478
2479	alc_auto_parse_customize_define(codec);
2480
2481	if (has_cdefine_beep(codec))
2482		spec->gen.beep_nid = 0x01;
2483
2484	/* automatic parse from the BIOS config */
2485	err = alc262_parse_auto_config(codec);
2486	if (err < 0)
2487		goto error;
2488
2489	if (!spec->gen.no_analog && spec->gen.beep_nid)
2490		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2491
2492	codec->patch_ops = alc_patch_ops;
2493	spec->shutup = alc_eapd_shutup;
2494
2495	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
2496
2497	return 0;
2498
2499 error:
2500	alc_free(codec);
2501	return err;
2502}
2503
2504/*
2505 *  ALC268
2506 */
2507/* bind Beep switches of both NID 0x0f and 0x10 */
2508static const struct hda_bind_ctls alc268_bind_beep_sw = {
2509	.ops = &snd_hda_bind_sw,
2510	.values = {
2511		HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
2512		HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
2513		0
2514	},
2515};
2516
2517static const struct snd_kcontrol_new alc268_beep_mixer[] = {
2518	HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
2519	HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
2520	{ }
2521};
2522
2523/* set PCBEEP vol = 0, mute connections */
2524static const struct hda_verb alc268_beep_init_verbs[] = {
2525	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2526	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2527	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2528	{ }
2529};
2530
2531enum {
2532	ALC268_FIXUP_INV_DMIC,
2533	ALC268_FIXUP_HP_EAPD,
2534	ALC268_FIXUP_SPDIF,
2535};
2536
2537static const struct hda_fixup alc268_fixups[] = {
2538	[ALC268_FIXUP_INV_DMIC] = {
2539		.type = HDA_FIXUP_FUNC,
2540		.v.func = alc_fixup_inv_dmic,
2541	},
2542	[ALC268_FIXUP_HP_EAPD] = {
2543		.type = HDA_FIXUP_VERBS,
2544		.v.verbs = (const struct hda_verb[]) {
2545			{0x15, AC_VERB_SET_EAPD_BTLENABLE, 0},
2546			{}
2547		}
2548	},
2549	[ALC268_FIXUP_SPDIF] = {
2550		.type = HDA_FIXUP_PINS,
2551		.v.pins = (const struct hda_pintbl[]) {
2552			{ 0x1e, 0x014b1180 }, /* enable SPDIF out */
2553			{}
2554		}
2555	},
2556};
2557
2558static const struct hda_model_fixup alc268_fixup_models[] = {
2559	{.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"},
2560	{.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"},
2561	{}
2562};
2563
2564static const struct snd_pci_quirk alc268_fixup_tbl[] = {
2565	SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF),
2566	SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC),
2567	/* below is codec SSID since multiple Toshiba laptops have the
2568	 * same PCI SSID 1179:ff00
2569	 */
2570	SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD),
2571	{}
2572};
2573
2574/*
2575 * BIOS auto configuration
2576 */
2577static int alc268_parse_auto_config(struct hda_codec *codec)
2578{
2579	static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2580	return alc_parse_auto_config(codec, NULL, alc268_ssids);
2581}
2582
2583/*
2584 */
2585static int patch_alc268(struct hda_codec *codec)
2586{
2587	struct alc_spec *spec;
2588	int err;
2589
2590	/* ALC268 has no aa-loopback mixer */
2591	err = alc_alloc_spec(codec, 0);
2592	if (err < 0)
2593		return err;
2594
2595	spec = codec->spec;
2596	spec->gen.beep_nid = 0x01;
2597
2598	snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups);
2599	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
2600
2601	/* automatic parse from the BIOS config */
2602	err = alc268_parse_auto_config(codec);
2603	if (err < 0)
2604		goto error;
2605
2606	if (err > 0 && !spec->gen.no_analog &&
2607	    spec->gen.autocfg.speaker_pins[0] != 0x1d) {
2608		add_mixer(spec, alc268_beep_mixer);
2609		snd_hda_add_verbs(codec, alc268_beep_init_verbs);
2610		if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
2611			/* override the amp caps for beep generator */
2612			snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
2613					  (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
2614					  (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
2615					  (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2616					  (0 << AC_AMPCAP_MUTE_SHIFT));
2617	}
2618
2619	codec->patch_ops = alc_patch_ops;
2620	spec->shutup = alc_eapd_shutup;
2621
2622	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
2623
2624	return 0;
2625
2626 error:
2627	alc_free(codec);
2628	return err;
2629}
2630
2631/*
2632 * ALC269
2633 */
2634
2635static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
2636	.rates = SNDRV_PCM_RATE_44100, /* fixed rate */
2637};
2638
2639static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
2640	.rates = SNDRV_PCM_RATE_44100, /* fixed rate */
2641};
2642
2643/* different alc269-variants */
2644enum {
2645	ALC269_TYPE_ALC269VA,
2646	ALC269_TYPE_ALC269VB,
2647	ALC269_TYPE_ALC269VC,
2648	ALC269_TYPE_ALC269VD,
2649	ALC269_TYPE_ALC280,
2650	ALC269_TYPE_ALC282,
2651	ALC269_TYPE_ALC283,
2652	ALC269_TYPE_ALC284,
2653	ALC269_TYPE_ALC285,
2654	ALC269_TYPE_ALC286,
2655	ALC269_TYPE_ALC298,
2656	ALC269_TYPE_ALC255,
2657	ALC269_TYPE_ALC256,
2658};
2659
2660/*
2661 * BIOS auto configuration
2662 */
2663static int alc269_parse_auto_config(struct hda_codec *codec)
2664{
2665	static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
2666	static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 };
2667	static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2668	struct alc_spec *spec = codec->spec;
2669	const hda_nid_t *ssids;
2670
2671	switch (spec->codec_variant) {
2672	case ALC269_TYPE_ALC269VA:
2673	case ALC269_TYPE_ALC269VC:
2674	case ALC269_TYPE_ALC280:
2675	case ALC269_TYPE_ALC284:
2676	case ALC269_TYPE_ALC285:
2677		ssids = alc269va_ssids;
2678		break;
2679	case ALC269_TYPE_ALC269VB:
2680	case ALC269_TYPE_ALC269VD:
2681	case ALC269_TYPE_ALC282:
2682	case ALC269_TYPE_ALC283:
2683	case ALC269_TYPE_ALC286:
2684	case ALC269_TYPE_ALC298:
2685	case ALC269_TYPE_ALC255:
2686	case ALC269_TYPE_ALC256:
2687		ssids = alc269_ssids;
2688		break;
2689	default:
2690		ssids = alc269_ssids;
2691		break;
2692	}
2693
2694	return alc_parse_auto_config(codec, alc269_ignore, ssids);
2695}
2696
2697static int find_ext_mic_pin(struct hda_codec *codec);
2698
2699static void alc286_shutup(struct hda_codec *codec)
2700{
2701	int i;
2702	int mic_pin = find_ext_mic_pin(codec);
2703	/* don't shut up pins when unloading the driver; otherwise it breaks
2704	 * the default pin setup at the next load of the driver
2705	 */
2706	if (codec->bus->shutdown)
2707		return;
2708	for (i = 0; i < codec->init_pins.used; i++) {
2709		struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
2710		/* use read here for syncing after issuing each verb */
2711		if (pin->nid != mic_pin)
2712			snd_hda_codec_read(codec, pin->nid, 0,
2713					AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
2714	}
2715	codec->pins_shutup = 1;
2716}
2717
2718static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
2719{
2720	alc_update_coef_idx(codec, 0x04, 1 << 11, power_up ? (1 << 11) : 0);
2721}
2722
2723static void alc269_shutup(struct hda_codec *codec)
2724{
2725	struct alc_spec *spec = codec->spec;
2726
2727	if (spec->codec_variant == ALC269_TYPE_ALC269VB)
2728		alc269vb_toggle_power_output(codec, 0);
2729	if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
2730			(alc_get_coef0(codec) & 0x00ff) == 0x018) {
2731		msleep(150);
2732	}
2733	snd_hda_shutup_pins(codec);
2734}
2735
2736static struct coef_fw alc282_coefs[] = {
2737	WRITE_COEF(0x03, 0x0002), /* Power Down Control */
2738	UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
2739	WRITE_COEF(0x07, 0x0200), /* DMIC control */
2740	UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
2741	UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
2742	WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
2743	WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
2744	WRITE_COEF(0x0e, 0x6e00), /* LDO1/2/3, DAC/ADC */
2745	UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
2746	UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
2747	WRITE_COEF(0x6f, 0x0), /* Class D test 4 */
2748	UPDATE_COEF(0x0c, 0xfe00, 0), /* IO power down directly */
2749	WRITE_COEF(0x34, 0xa0c0), /* ANC */
2750	UPDATE_COEF(0x16, 0x0008, 0), /* AGC MUX */
2751	UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
2752	UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
2753	WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
2754	WRITE_COEF(0x63, 0x2902), /* PLL */
2755	WRITE_COEF(0x68, 0xa080), /* capless control 2 */
2756	WRITE_COEF(0x69, 0x3400), /* capless control 3 */
2757	WRITE_COEF(0x6a, 0x2f3e), /* capless control 4 */
2758	WRITE_COEF(0x6b, 0x0), /* capless control 5 */
2759	UPDATE_COEF(0x6d, 0x0fff, 0x0900), /* class D test 2 */
2760	WRITE_COEF(0x6e, 0x110a), /* class D test 3 */
2761	UPDATE_COEF(0x70, 0x00f8, 0x00d8), /* class D test 5 */
2762	WRITE_COEF(0x71, 0x0014), /* class D test 6 */
2763	WRITE_COEF(0x72, 0xc2ba), /* classD OCP */
2764	UPDATE_COEF(0x77, 0x0f80, 0), /* classD pure DC test */
2765	WRITE_COEF(0x6c, 0xfc06), /* Class D amp control */
2766	{}
2767};
2768
2769static void alc282_restore_default_value(struct hda_codec *codec)
2770{
2771	alc_process_coef_fw(codec, alc282_coefs);
2772}
2773
2774static void alc282_init(struct hda_codec *codec)
2775{
2776	struct alc_spec *spec = codec->spec;
2777	hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2778	bool hp_pin_sense;
2779	int coef78;
2780
2781	alc282_restore_default_value(codec);
2782
2783	if (!hp_pin)
2784		return;
2785	hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2786	coef78 = alc_read_coef_idx(codec, 0x78);
2787
2788	/* Index 0x78 Direct Drive HP AMP LPM Control 1 */
2789	/* Headphone capless set to high power mode */
2790	alc_write_coef_idx(codec, 0x78, 0x9004);
2791
2792	if (hp_pin_sense)
2793		msleep(2);
2794
2795	snd_hda_codec_write(codec, hp_pin, 0,
2796			    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2797
2798	if (hp_pin_sense)
2799		msleep(85);
2800
2801	snd_hda_codec_write(codec, hp_pin, 0,
2802			    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2803
2804	if (hp_pin_sense)
2805		msleep(100);
2806
2807	/* Headphone capless set to normal mode */
2808	alc_write_coef_idx(codec, 0x78, coef78);
2809}
2810
2811static void alc282_shutup(struct hda_codec *codec)
2812{
2813	struct alc_spec *spec = codec->spec;
2814	hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2815	bool hp_pin_sense;
2816	int coef78;
2817
2818	if (!hp_pin) {
2819		alc269_shutup(codec);
2820		return;
2821	}
2822
2823	hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2824	coef78 = alc_read_coef_idx(codec, 0x78);
2825	alc_write_coef_idx(codec, 0x78, 0x9004);
2826
2827	if (hp_pin_sense)
2828		msleep(2);
2829
2830	snd_hda_codec_write(codec, hp_pin, 0,
2831			    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2832
2833	if (hp_pin_sense)
2834		msleep(85);
2835
2836	snd_hda_codec_write(codec, hp_pin, 0,
2837			    AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
2838
2839	if (hp_pin_sense)
2840		msleep(100);
2841
2842	alc_auto_setup_eapd(codec, false);
2843	snd_hda_shutup_pins(codec);
2844	alc_write_coef_idx(codec, 0x78, coef78);
2845}
2846
2847static struct coef_fw alc283_coefs[] = {
2848	WRITE_COEF(0x03, 0x0002), /* Power Down Control */
2849	UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
2850	WRITE_COEF(0x07, 0x0200), /* DMIC control */
2851	UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
2852	UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
2853	WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
2854	WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
2855	WRITE_COEF(0x0e, 0x6fc0), /* LDO1/2/3, DAC/ADC */
2856	UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
2857	UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
2858	WRITE_COEF(0x3a, 0x0), /* Class D test 4 */
2859	UPDATE_COEF(0x0c, 0xfe00, 0x0), /* IO power down directly */
2860	WRITE_COEF(0x22, 0xa0c0), /* ANC */
2861	UPDATE_COEFEX(0x53, 0x01, 0x000f, 0x0008), /* AGC MUX */
2862	UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
2863	UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
2864	WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
2865	WRITE_COEF(0x2e, 0x2902), /* PLL */
2866	WRITE_COEF(0x33, 0xa080), /* capless control 2 */
2867	WRITE_COEF(0x34, 0x3400), /* capless control 3 */
2868	WRITE_COEF(0x35, 0x2f3e), /* capless control 4 */
2869	WRITE_COEF(0x36, 0x0), /* capless control 5 */
2870	UPDATE_COEF(0x38, 0x0fff, 0x0900), /* class D test 2 */
2871	WRITE_COEF(0x39, 0x110a), /* class D test 3 */
2872	UPDATE_COEF(0x3b, 0x00f8, 0x00d8), /* class D test 5 */
2873	WRITE_COEF(0x3c, 0x0014), /* class D test 6 */
2874	WRITE_COEF(0x3d, 0xc2ba), /* classD OCP */
2875	UPDATE_COEF(0x42, 0x0f80, 0x0), /* classD pure DC test */
2876	WRITE_COEF(0x49, 0x0), /* test mode */
2877	UPDATE_COEF(0x40, 0xf800, 0x9800), /* Class D DC enable */
2878	UPDATE_COEF(0x42, 0xf000, 0x2000), /* DC offset */
2879	WRITE_COEF(0x37, 0xfc06), /* Class D amp control */
2880	UPDATE_COEF(0x1b, 0x8000, 0), /* HP JD control */
2881	{}
2882};
2883
2884static void alc283_restore_default_value(struct hda_codec *codec)
2885{
2886	alc_process_coef_fw(codec, alc283_coefs);
2887}
2888
2889static void alc283_init(struct hda_codec *codec)
2890{
2891	struct alc_spec *spec = codec->spec;
2892	hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2893	bool hp_pin_sense;
2894
2895	if (!spec->gen.autocfg.hp_outs) {
2896		if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
2897			hp_pin = spec->gen.autocfg.line_out_pins[0];
2898	}
2899
2900	alc283_restore_default_value(codec);
2901
2902	if (!hp_pin)
2903		return;
2904
2905	msleep(30);
2906	hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2907
2908	/* Index 0x43 Direct Drive HP AMP LPM Control 1 */
2909	/* Headphone capless set to high power mode */
2910	alc_write_coef_idx(codec, 0x43, 0x9004);
2911
2912	snd_hda_codec_write(codec, hp_pin, 0,
2913			    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2914
2915	if (hp_pin_sense)
2916		msleep(85);
2917
2918	snd_hda_codec_write(codec, hp_pin, 0,
2919			    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2920
2921	if (hp_pin_sense)
2922		msleep(85);
2923	/* Index 0x46 Combo jack auto switch control 2 */
2924	/* 3k pull low control for Headset jack. */
2925	alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
2926	/* Headphone capless set to normal mode */
2927	alc_write_coef_idx(codec, 0x43, 0x9614);
2928}
2929
2930static void alc283_shutup(struct hda_codec *codec)
2931{
2932	struct alc_spec *spec = codec->spec;
2933	hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2934	bool hp_pin_sense;
2935
2936	if (!spec->gen.autocfg.hp_outs) {
2937		if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
2938			hp_pin = spec->gen.autocfg.line_out_pins[0];
2939	}
2940
2941	if (!hp_pin) {
2942		alc269_shutup(codec);
2943		return;
2944	}
2945
2946	hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2947
2948	alc_write_coef_idx(codec, 0x43, 0x9004);
2949
2950	/*depop hp during suspend*/
2951	alc_write_coef_idx(codec, 0x06, 0x2100);
2952
2953	snd_hda_codec_write(codec, hp_pin, 0,
2954			    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2955
2956	if (hp_pin_sense)
2957		msleep(100);
2958
2959	snd_hda_codec_write(codec, hp_pin, 0,
2960			    AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
2961
2962	alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
2963
2964	if (hp_pin_sense)
2965		msleep(100);
2966	alc_auto_setup_eapd(codec, false);
2967	snd_hda_shutup_pins(codec);
2968	alc_write_coef_idx(codec, 0x43, 0x9614);
2969}
2970
2971static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg,
2972			     unsigned int val)
2973{
2974	snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
2975	snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */
2976	snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */
2977}
2978
2979static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg)
2980{
2981	unsigned int val;
2982
2983	snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
2984	val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
2985		& 0xffff;
2986	val |= snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
2987		<< 16;
2988	return val;
2989}
2990
2991static void alc5505_dsp_halt(struct hda_codec *codec)
2992{
2993	unsigned int val;
2994
2995	alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */
2996	alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */
2997	alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */
2998	alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */
2999	alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */
3000	alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */
3001	alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */
3002	val = alc5505_coef_get(codec, 0x6220);
3003	alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */
3004}
3005
3006static void alc5505_dsp_back_from_halt(struct hda_codec *codec)
3007{
3008	alc5505_coef_set(codec, 0x61b8, 0x04133302);
3009	alc5505_coef_set(codec, 0x61b0, 0x00005b16);
3010	alc5505_coef_set(codec, 0x61b4, 0x040a2b02);
3011	alc5505_coef_set(codec, 0x6230, 0xf80d4011);
3012	alc5505_coef_set(codec, 0x6220, 0x2002010f);
3013	alc5505_coef_set(codec, 0x880c, 0x00000004);
3014}
3015
3016static void alc5505_dsp_init(struct hda_codec *codec)
3017{
3018	unsigned int val;
3019
3020	alc5505_dsp_halt(codec);
3021	alc5505_dsp_back_from_halt(codec);
3022	alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */
3023	alc5505_coef_set(codec, 0x61b0, 0x5b16);
3024	alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */
3025	alc5505_coef_set(codec, 0x61b4, 0x04132b02);
3026	alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/
3027	alc5505_coef_set(codec, 0x61b8, 0x041f3302);
3028	snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */
3029	alc5505_coef_set(codec, 0x61b8, 0x041b3302);
3030	alc5505_coef_set(codec, 0x61b8, 0x04173302);
3031	alc5505_coef_set(codec, 0x61b8, 0x04163302);
3032	alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */
3033	alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */
3034	alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */
3035
3036	val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */
3037	if (val <= 3)
3038		alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */
3039	else
3040		alc5505_coef_set(codec, 0x6220, 0x6002018f);
3041
3042	alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/
3043	alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */
3044	alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */
3045	alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */
3046	alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */
3047	alc5505_coef_set(codec, 0x880c, 0x00000003);
3048	alc5505_coef_set(codec, 0x880c, 0x00000010);
3049
3050#ifdef HALT_REALTEK_ALC5505
3051	alc5505_dsp_halt(codec);
3052#endif
3053}
3054
3055#ifdef HALT_REALTEK_ALC5505
3056#define alc5505_dsp_suspend(codec)	/* NOP */
3057#define alc5505_dsp_resume(codec)	/* NOP */
3058#else
3059#define alc5505_dsp_suspend(codec)	alc5505_dsp_halt(codec)
3060#define alc5505_dsp_resume(codec)	alc5505_dsp_back_from_halt(codec)
3061#endif
3062
3063#ifdef CONFIG_PM
3064static int alc269_suspend(struct hda_codec *codec)
3065{
3066	struct alc_spec *spec = codec->spec;
3067
3068	if (spec->has_alc5505_dsp)
3069		alc5505_dsp_suspend(codec);
3070	return alc_suspend(codec);
3071}
3072
3073static int alc269_resume(struct hda_codec *codec)
3074{
3075	struct alc_spec *spec = codec->spec;
3076
3077	if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3078		alc269vb_toggle_power_output(codec, 0);
3079	if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
3080			(alc_get_coef0(codec) & 0x00ff) == 0x018) {
3081		msleep(150);
3082	}
3083
3084	codec->patch_ops.init(codec);
3085
3086	if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3087		alc269vb_toggle_power_output(codec, 1);
3088	if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
3089			(alc_get_coef0(codec) & 0x00ff) == 0x017) {
3090		msleep(200);
3091	}
3092
3093	regcache_sync(codec->core.regmap);
3094	hda_call_check_power_status(codec, 0x01);
3095
3096	/* on some machine, the BIOS will clear the codec gpio data when enter
3097	 * suspend, and won't restore the data after resume, so we restore it
3098	 * in the driver.
3099	 */
3100	if (spec->gpio_led)
3101		snd_hda_codec_write(codec, codec->core.afg, 0, AC_VERB_SET_GPIO_DATA,
3102			    spec->gpio_led);
3103
3104	if (spec->has_alc5505_dsp)
3105		alc5505_dsp_resume(codec);
3106
3107	return 0;
3108}
3109#endif /* CONFIG_PM */
3110
3111static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec,
3112						 const struct hda_fixup *fix, int action)
3113{
3114	struct alc_spec *spec = codec->spec;
3115
3116	if (action == HDA_FIXUP_ACT_PRE_PROBE)
3117		spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
3118}
3119
3120static void alc269_fixup_hweq(struct hda_codec *codec,
3121			       const struct hda_fixup *fix, int action)
3122{
3123	if (action == HDA_FIXUP_ACT_INIT)
3124		alc_update_coef_idx(codec, 0x1e, 0, 0x80);
3125}
3126
3127static void alc269_fixup_headset_mic(struct hda_codec *codec,
3128				       const struct hda_fixup *fix, int action)
3129{
3130	struct alc_spec *spec = codec->spec;
3131
3132	if (action == HDA_FIXUP_ACT_PRE_PROBE)
3133		spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3134}
3135
3136static void alc271_fixup_dmic(struct hda_codec *codec,
3137			      const struct hda_fixup *fix, int action)
3138{
3139	static const struct hda_verb verbs[] = {
3140		{0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
3141		{0x20, AC_VERB_SET_PROC_COEF, 0x4000},
3142		{}
3143	};
3144	unsigned int cfg;
3145
3146	if (strcmp(codec->core.chip_name, "ALC271X") &&
3147	    strcmp(codec->core.chip_name, "ALC269VB"))
3148		return;
3149	cfg = snd_hda_codec_get_pincfg(codec, 0x12);
3150	if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
3151		snd_hda_sequence_write(codec, verbs);
3152}
3153
3154static void alc269_fixup_pcm_44k(struct hda_codec *codec,
3155				 const struct hda_fixup *fix, int action)
3156{
3157	struct alc_spec *spec = codec->spec;
3158
3159	if (action != HDA_FIXUP_ACT_PROBE)
3160		return;
3161
3162	/* Due to a hardware problem on Lenovo Ideadpad, we need to
3163	 * fix the sample rate of analog I/O to 44.1kHz
3164	 */
3165	spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback;
3166	spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture;
3167}
3168
3169static void alc269_fixup_stereo_dmic(struct hda_codec *codec,
3170				     const struct hda_fixup *fix, int action)
3171{
3172	/* The digital-mic unit sends PDM (differential signal) instead of
3173	 * the standard PCM, thus you can't record a valid mono stream as is.
3174	 * Below is a workaround specific to ALC269 to control the dmic
3175	 * signal source as mono.
3176	 */
3177	if (action == HDA_FIXUP_ACT_INIT)
3178		alc_update_coef_idx(codec, 0x07, 0, 0x80);
3179}
3180
3181static void alc269_quanta_automute(struct hda_codec *codec)
3182{
3183	snd_hda_gen_update_outputs(codec);
3184
3185	alc_write_coef_idx(codec, 0x0c, 0x680);
3186	alc_write_coef_idx(codec, 0x0c, 0x480);
3187}
3188
3189static void alc269_fixup_quanta_mute(struct hda_codec *codec,
3190				     const struct hda_fixup *fix, int action)
3191{
3192	struct alc_spec *spec = codec->spec;
3193	if (action != HDA_FIXUP_ACT_PROBE)
3194		return;
3195	spec->gen.automute_hook = alc269_quanta_automute;
3196}
3197
3198static void alc269_x101_hp_automute_hook(struct hda_codec *codec,
3199					 struct hda_jack_callback *jack)
3200{
3201	struct alc_spec *spec = codec->spec;
3202	int vref;
3203	msleep(200);
3204	snd_hda_gen_hp_automute(codec, jack);
3205
3206	vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
3207	msleep(100);
3208	snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3209			    vref);
3210	msleep(500);
3211	snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3212			    vref);
3213}
3214
3215static void alc269_fixup_x101_headset_mic(struct hda_codec *codec,
3216				     const struct hda_fixup *fix, int action)
3217{
3218	struct alc_spec *spec = codec->spec;
3219	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3220		spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3221		spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook;
3222	}
3223}
3224
3225
3226/* update mute-LED according to the speaker mute state via mic VREF pin */
3227static void alc269_fixup_mic_mute_hook(void *private_data, int enabled)
3228{
3229	struct hda_codec *codec = private_data;
3230	struct alc_spec *spec = codec->spec;
3231	unsigned int pinval;
3232
3233	if (spec->mute_led_polarity)
3234		enabled = !enabled;
3235	pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid);
3236	pinval &= ~AC_PINCTL_VREFEN;
3237	pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80;
3238	if (spec->mute_led_nid)
3239		snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval);
3240}
3241
3242/* Make sure the led works even in runtime suspend */
3243static unsigned int led_power_filter(struct hda_codec *codec,
3244						  hda_nid_t nid,
3245						  unsigned int power_state)
3246{
3247	struct alc_spec *spec = codec->spec;
3248
3249	if (power_state != AC_PWRST_D3 || nid == 0 ||
3250	    (nid != spec->mute_led_nid && nid != spec->cap_mute_led_nid))
3251		return power_state;
3252
3253	/* Set pin ctl again, it might have just been set to 0 */
3254	snd_hda_set_pin_ctl(codec, nid,
3255			    snd_hda_codec_get_pin_target(codec, nid));
3256
3257	return snd_hda_gen_path_power_filter(codec, nid, power_state);
3258}
3259
3260static void alc269_fixup_hp_mute_led(struct hda_codec *codec,
3261				     const struct hda_fixup *fix, int action)
3262{
3263	struct alc_spec *spec = codec->spec;
3264	const struct dmi_device *dev = NULL;
3265
3266	if (action != HDA_FIXUP_ACT_PRE_PROBE)
3267		return;
3268
3269	while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
3270		int pol, pin;
3271		if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2)
3272			continue;
3273		if (pin < 0x0a || pin >= 0x10)
3274			break;
3275		spec->mute_led_polarity = pol;
3276		spec->mute_led_nid = pin - 0x0a + 0x18;
3277		spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3278		spec->gen.vmaster_mute_enum = 1;
3279		codec->power_filter = led_power_filter;
3280		codec_dbg(codec,
3281			  "Detected mute LED for %x:%d\n", spec->mute_led_nid,
3282			   spec->mute_led_polarity);
3283		break;
3284	}
3285}
3286
3287static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec,
3288				const struct hda_fixup *fix, int action)
3289{
3290	struct alc_spec *spec = codec->spec;
3291	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3292		spec->mute_led_polarity = 0;
3293		spec->mute_led_nid = 0x18;
3294		spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3295		spec->gen.vmaster_mute_enum = 1;
3296		codec->power_filter = led_power_filter;
3297	}
3298}
3299
3300static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec,
3301				const struct hda_fixup *fix, int action)
3302{
3303	struct alc_spec *spec = codec->spec;
3304	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3305		spec->mute_led_polarity = 0;
3306		spec->mute_led_nid = 0x19;
3307		spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3308		spec->gen.vmaster_mute_enum = 1;
3309		codec->power_filter = led_power_filter;
3310	}
3311}
3312
3313/* update LED status via GPIO */
3314static void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask,
3315				bool enabled)
3316{
3317	struct alc_spec *spec = codec->spec;
3318	unsigned int oldval = spec->gpio_led;
3319
3320	if (spec->mute_led_polarity)
3321		enabled = !enabled;
3322
3323	if (enabled)
3324		spec->gpio_led &= ~mask;
3325	else
3326		spec->gpio_led |= mask;
3327	if (spec->gpio_led != oldval)
3328		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
3329				    spec->gpio_led);
3330}
3331
3332/* turn on/off mute LED via GPIO per vmaster hook */
3333static void alc_fixup_gpio_mute_hook(void *private_data, int enabled)
3334{
3335	struct hda_codec *codec = private_data;
3336	struct alc_spec *spec = codec->spec;
3337
3338	alc_update_gpio_led(codec, spec->gpio_mute_led_mask, enabled);
3339}
3340
3341/* turn on/off mic-mute LED via GPIO per capture hook */
3342static void alc_fixup_gpio_mic_mute_hook(struct hda_codec *codec,
3343					 struct snd_kcontrol *kcontrol,
3344					 struct snd_ctl_elem_value *ucontrol)
3345{
3346	struct alc_spec *spec = codec->spec;
3347
3348	if (ucontrol)
3349		alc_update_gpio_led(codec, spec->gpio_mic_led_mask,
3350				    ucontrol->value.integer.value[0] ||
3351				    ucontrol->value.integer.value[1]);
3352}
3353
3354static void alc269_fixup_hp_gpio_led(struct hda_codec *codec,
3355				const struct hda_fixup *fix, int action)
3356{
3357	struct alc_spec *spec = codec->spec;
3358	static const struct hda_verb gpio_init[] = {
3359		{ 0x01, AC_VERB_SET_GPIO_MASK, 0x18 },
3360		{ 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 },
3361		{}
3362	};
3363
3364	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3365		spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3366		spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook;
3367		spec->gpio_led = 0;
3368		spec->mute_led_polarity = 0;
3369		spec->gpio_mute_led_mask = 0x08;
3370		spec->gpio_mic_led_mask = 0x10;
3371		snd_hda_add_verbs(codec, gpio_init);
3372	}
3373}
3374
3375static void alc286_fixup_hp_gpio_led(struct hda_codec *codec,
3376				const struct hda_fixup *fix, int action)
3377{
3378	struct alc_spec *spec = codec->spec;
3379	static const struct hda_verb gpio_init[] = {
3380		{ 0x01, AC_VERB_SET_GPIO_MASK, 0x22 },
3381		{ 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x22 },
3382		{}
3383	};
3384
3385	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3386		spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3387		spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook;
3388		spec->gpio_led = 0;
3389		spec->mute_led_polarity = 0;
3390		spec->gpio_mute_led_mask = 0x02;
3391		spec->gpio_mic_led_mask = 0x20;
3392		snd_hda_add_verbs(codec, gpio_init);
3393	}
3394}
3395
3396/* turn on/off mic-mute LED per capture hook */
3397static void alc269_fixup_hp_cap_mic_mute_hook(struct hda_codec *codec,
3398					       struct snd_kcontrol *kcontrol,
3399					       struct snd_ctl_elem_value *ucontrol)
3400{
3401	struct alc_spec *spec = codec->spec;
3402	unsigned int pinval, enable, disable;
3403
3404	pinval = snd_hda_codec_get_pin_target(codec, spec->cap_mute_led_nid);
3405	pinval &= ~AC_PINCTL_VREFEN;
3406	enable  = pinval | AC_PINCTL_VREF_80;
3407	disable = pinval | AC_PINCTL_VREF_HIZ;
3408
3409	if (!ucontrol)
3410		return;
3411
3412	if (ucontrol->value.integer.value[0] ||
3413	    ucontrol->value.integer.value[1])
3414		pinval = disable;
3415	else
3416		pinval = enable;
3417
3418	if (spec->cap_mute_led_nid)
3419		snd_hda_set_pin_ctl_cache(codec, spec->cap_mute_led_nid, pinval);
3420}
3421
3422static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec,
3423				const struct hda_fixup *fix, int action)
3424{
3425	struct alc_spec *spec = codec->spec;
3426	static const struct hda_verb gpio_init[] = {
3427		{ 0x01, AC_VERB_SET_GPIO_MASK, 0x08 },
3428		{ 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x08 },
3429		{}
3430	};
3431
3432	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3433		spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3434		spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook;
3435		spec->gpio_led = 0;
3436		spec->mute_led_polarity = 0;
3437		spec->gpio_mute_led_mask = 0x08;
3438		spec->cap_mute_led_nid = 0x18;
3439		snd_hda_add_verbs(codec, gpio_init);
3440		codec->power_filter = led_power_filter;
3441	}
3442}
3443
3444static void alc280_fixup_hp_gpio4(struct hda_codec *codec,
3445				   const struct hda_fixup *fix, int action)
3446{
3447	/* Like hp_gpio_mic1_led, but also needs GPIO4 low to enable headphone amp */
3448	struct alc_spec *spec = codec->spec;
3449	static const struct hda_verb gpio_init[] = {
3450		{ 0x01, AC_VERB_SET_GPIO_MASK, 0x18 },
3451		{ 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 },
3452		{}
3453	};
3454
3455	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3456		spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3457		spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook;
3458		spec->gpio_led = 0;
3459		spec->mute_led_polarity = 0;
3460		spec->gpio_mute_led_mask = 0x08;
3461		spec->cap_mute_led_nid = 0x18;
3462		snd_hda_add_verbs(codec, gpio_init);
3463		codec->power_filter = led_power_filter;
3464	}
3465}
3466
3467static void gpio2_mic_hotkey_event(struct hda_codec *codec,
3468				   struct hda_jack_callback *event)
3469{
3470	struct alc_spec *spec = codec->spec;
3471
3472	/* GPIO2 just toggles on a keypress/keyrelease cycle. Therefore
3473	   send both key on and key off event for every interrupt. */
3474	input_report_key(spec->kb_dev, KEY_MICMUTE, 1);
3475	input_sync(spec->kb_dev);
3476	input_report_key(spec->kb_dev, KEY_MICMUTE, 0);
3477	input_sync(spec->kb_dev);
3478}
3479
3480static int alc_register_micmute_input_device(struct hda_codec *codec)
3481{
3482	struct alc_spec *spec = codec->spec;
3483
3484	spec->kb_dev = input_allocate_device();
3485	if (!spec->kb_dev) {
3486		codec_err(codec, "Out of memory (input_allocate_device)\n");
3487		return -ENOMEM;
3488	}
3489	spec->kb_dev->name = "Microphone Mute Button";
3490	spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY);
3491	spec->kb_dev->keybit[BIT_WORD(KEY_MICMUTE)] = BIT_MASK(KEY_MICMUTE);
3492
3493	if (input_register_device(spec->kb_dev)) {
3494		codec_err(codec, "input_register_device failed\n");
3495		input_free_device(spec->kb_dev);
3496		spec->kb_dev = NULL;
3497		return -ENOMEM;
3498	}
3499
3500	return 0;
3501}
3502
3503static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
3504					     const struct hda_fixup *fix, int action)
3505{
3506	/* GPIO1 = set according to SKU external amp
3507	   GPIO2 = mic mute hotkey
3508	   GPIO3 = mute LED
3509	   GPIO4 = mic mute LED */
3510	static const struct hda_verb gpio_init[] = {
3511		{ 0x01, AC_VERB_SET_GPIO_MASK, 0x1e },
3512		{ 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x1a },
3513		{ 0x01, AC_VERB_SET_GPIO_DATA, 0x02 },
3514		{}
3515	};
3516
3517	struct alc_spec *spec = codec->spec;
3518
3519	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3520		if (alc_register_micmute_input_device(codec) != 0)
3521			return;
3522
3523		snd_hda_add_verbs(codec, gpio_init);
3524		snd_hda_codec_write_cache(codec, codec->core.afg, 0,
3525					  AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x04);
3526		snd_hda_jack_detect_enable_callback(codec, codec->core.afg,
3527						    gpio2_mic_hotkey_event);
3528
3529		spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3530		spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook;
3531		spec->gpio_led = 0;
3532		spec->mute_led_polarity = 0;
3533		spec->gpio_mute_led_mask = 0x08;
3534		spec->gpio_mic_led_mask = 0x10;
3535		return;
3536	}
3537
3538	if (!spec->kb_dev)
3539		return;
3540
3541	switch (action) {
3542	case HDA_FIXUP_ACT_PROBE:
3543		spec->init_amp = ALC_INIT_DEFAULT;
3544		break;
3545	case HDA_FIXUP_ACT_FREE:
3546		input_unregister_device(spec->kb_dev);
3547		spec->kb_dev = NULL;
3548	}
3549}
3550
3551static void alc233_fixup_lenovo_line2_mic_hotkey(struct hda_codec *codec,
3552					     const struct hda_fixup *fix, int action)
3553{
3554	/* Line2 = mic mute hotkey
3555	   GPIO2 = mic mute LED */
3556	static const struct hda_verb gpio_init[] = {
3557		{ 0x01, AC_VERB_SET_GPIO_MASK, 0x04 },
3558		{ 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 },
3559		{}
3560	};
3561
3562	struct alc_spec *spec = codec->spec;
3563
3564	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3565		if (alc_register_micmute_input_device(codec) != 0)
3566			return;
3567
3568		snd_hda_add_verbs(codec, gpio_init);
3569		snd_hda_jack_detect_enable_callback(codec, 0x1b,
3570						    gpio2_mic_hotkey_event);
3571
3572		spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook;
3573		spec->gpio_led = 0;
3574		spec->mute_led_polarity = 0;
3575		spec->gpio_mic_led_mask = 0x04;
3576		return;
3577	}
3578
3579	if (!spec->kb_dev)
3580		return;
3581
3582	switch (action) {
3583	case HDA_FIXUP_ACT_PROBE:
3584		spec->init_amp = ALC_INIT_DEFAULT;
3585		break;
3586	case HDA_FIXUP_ACT_FREE:
3587		input_unregister_device(spec->kb_dev);
3588		spec->kb_dev = NULL;
3589	}
3590}
3591
3592static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
3593				const struct hda_fixup *fix, int action)
3594{
3595	struct alc_spec *spec = codec->spec;
3596
3597	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3598		spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3599		spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook;
3600		spec->mute_led_polarity = 0;
3601		spec->mute_led_nid = 0x1a;
3602		spec->cap_mute_led_nid = 0x18;
3603		spec->gen.vmaster_mute_enum = 1;
3604		codec->power_filter = led_power_filter;
3605	}
3606}
3607
3608static void alc_headset_mode_unplugged(struct hda_codec *codec)
3609{
3610	static struct coef_fw coef0255[] = {
3611		WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
3612		UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
3613		WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
3614		WRITE_COEFEX(0x57, 0x03, 0x8aa6), /* Direct Drive HP Amp control */
3615		{}
3616	};
3617	static struct coef_fw coef0255_1[] = {
3618		WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
3619		{}
3620	};
3621	static struct coef_fw coef0256[] = {
3622		WRITE_COEF(0x1b, 0x0c4b), /* LDO and MISC control */
3623		{}
3624	};
3625	static struct coef_fw coef0233[] = {
3626		WRITE_COEF(0x1b, 0x0c0b),
3627		WRITE_COEF(0x45, 0xc429),
3628		UPDATE_COEF(0x35, 0x4000, 0),
3629		WRITE_COEF(0x06, 0x2104),
3630		WRITE_COEF(0x1a, 0x0001),
3631		WRITE_COEF(0x26, 0x0004),
3632		WRITE_COEF(0x32, 0x42a3),
3633		{}
3634	};
3635	static struct coef_fw coef0288[] = {
3636		UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
3637		UPDATE_COEF(0x50, 0x2000, 0x2000),
3638		UPDATE_COEF(0x56, 0x0006, 0x0006),
3639		UPDATE_COEF(0x66, 0x0008, 0),
3640		UPDATE_COEF(0x67, 0x2000, 0),
3641		{}
3642	};
3643	static struct coef_fw coef0292[] = {
3644		WRITE_COEF(0x76, 0x000e),
3645		WRITE_COEF(0x6c, 0x2400),
3646		WRITE_COEF(0x18, 0x7308),
3647		WRITE_COEF(0x6b, 0xc429),
3648		{}
3649	};
3650	static struct coef_fw coef0293[] = {
3651		UPDATE_COEF(0x10, 7<<8, 6<<8), /* SET Line1 JD to 0 */
3652		UPDATE_COEFEX(0x57, 0x05, 1<<15|1<<13, 0x0), /* SET charge pump by verb */
3653		UPDATE_COEFEX(0x57, 0x03, 1<<10, 1<<10), /* SET EN_OSW to 1 */
3654		UPDATE_COEF(0x1a, 1<<3, 1<<3), /* Combo JD gating with LINE1-VREFO */
3655		WRITE_COEF(0x45, 0xc429), /* Set to TRS type */
3656		UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
3657		{}
3658	};
3659	static struct coef_fw coef0668[] = {
3660		WRITE_COEF(0x15, 0x0d40),
3661		WRITE_COEF(0xb7, 0x802b),
3662		{}
3663	};
3664
3665	switch (codec->core.vendor_id) {
3666	case 0x10ec0255:
3667		alc_process_coef_fw(codec, coef0255_1);
3668		alc_process_coef_fw(codec, coef0255);
3669		break;
3670	case 0x10ec0256:
3671		alc_process_coef_fw(codec, coef0256);
3672		alc_process_coef_fw(codec, coef0255);
3673		break;
3674	case 0x10ec0233:
3675	case 0x10ec0283:
3676		alc_process_coef_fw(codec, coef0233);
3677		break;
3678	case 0x10ec0286:
3679	case 0x10ec0288:
3680		alc_process_coef_fw(codec, coef0288);
3681		break;
3682	case 0x10ec0292:
3683		alc_process_coef_fw(codec, coef0292);
3684		break;
3685	case 0x10ec0293:
3686		alc_process_coef_fw(codec, coef0293);
3687		break;
3688	case 0x10ec0668:
3689		alc_process_coef_fw(codec, coef0668);
3690		break;
3691	}
3692	codec_dbg(codec, "Headset jack set to unplugged mode.\n");
3693}
3694
3695
3696static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
3697				    hda_nid_t mic_pin)
3698{
3699	static struct coef_fw coef0255[] = {
3700		WRITE_COEFEX(0x57, 0x03, 0x8aa6),
3701		WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
3702		{}
3703	};
3704	static struct coef_fw coef0233[] = {
3705		UPDATE_COEF(0x35, 0, 1<<14),
3706		WRITE_COEF(0x06, 0x2100),
3707		WRITE_COEF(0x1a, 0x0021),
3708		WRITE_COEF(0x26, 0x008c),
3709		{}
3710	};
3711	static struct coef_fw coef0288[] = {
3712		UPDATE_COEF(0x50, 0x2000, 0),
3713		UPDATE_COEF(0x56, 0x0006, 0),
3714		UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
3715		UPDATE_COEF(0x66, 0x0008, 0x0008),
3716		UPDATE_COEF(0x67, 0x2000, 0x2000),
3717		{}
3718	};
3719	static struct coef_fw coef0292[] = {
3720		WRITE_COEF(0x19, 0xa208),
3721		WRITE_COEF(0x2e, 0xacf0),
3722		{}
3723	};
3724	static struct coef_fw coef0293[] = {
3725		UPDATE_COEFEX(0x57, 0x05, 0, 1<<15|1<<13), /* SET charge pump by verb */
3726		UPDATE_COEFEX(0x57, 0x03, 1<<10, 0), /* SET EN_OSW to 0 */
3727		UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
3728		{}
3729	};
3730	static struct coef_fw coef0688[] = {
3731		WRITE_COEF(0xb7, 0x802b),
3732		WRITE_COEF(0xb5, 0x1040),
3733		UPDATE_COEF(0xc3, 0, 1<<12),
3734		{}
3735	};
3736
3737	switch (codec->core.vendor_id) {
3738	case 0x10ec0255:
3739	case 0x10ec0256:
3740		alc_write_coef_idx(codec, 0x45, 0xc489);
3741		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3742		alc_process_coef_fw(codec, coef0255);
3743		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3744		break;
3745	case 0x10ec0233:
3746	case 0x10ec0283:
3747		alc_write_coef_idx(codec, 0x45, 0xc429);
3748		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3749		alc_process_coef_fw(codec, coef0233);
3750		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3751		break;
3752	case 0x10ec0286:
3753	case 0x10ec0288:
3754		alc_update_coef_idx(codec, 0x4f, 0x000c, 0);
3755		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3756		alc_process_coef_fw(codec, coef0288);
3757		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3758		break;
3759	case 0x10ec0292:
3760		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3761		alc_process_coef_fw(codec, coef0292);
3762		break;
3763	case 0x10ec0293:
3764		/* Set to TRS mode */
3765		alc_write_coef_idx(codec, 0x45, 0xc429);
3766		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3767		alc_process_coef_fw(codec, coef0293);
3768		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3769		break;
3770	case 0x10ec0662:
3771		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3772		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3773		break;
3774	case 0x10ec0668:
3775		alc_write_coef_idx(codec, 0x11, 0x0001);
3776		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3777		alc_process_coef_fw(codec, coef0688);
3778		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3779		break;
3780	}
3781	codec_dbg(codec, "Headset jack set to mic-in mode.\n");
3782}
3783
3784static void alc_headset_mode_default(struct hda_codec *codec)
3785{
3786	static struct coef_fw coef0225[] = {
3787		UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
3788		{}
3789	};
3790	static struct coef_fw coef0255[] = {
3791		WRITE_COEF(0x45, 0xc089),
3792		WRITE_COEF(0x45, 0xc489),
3793		WRITE_COEFEX(0x57, 0x03, 0x8ea6),
3794		WRITE_COEF(0x49, 0x0049),
3795		{}
3796	};
3797	static struct coef_fw coef0233[] = {
3798		WRITE_COEF(0x06, 0x2100),
3799		WRITE_COEF(0x32, 0x4ea3),
3800		{}
3801	};
3802	static struct coef_fw coef0288[] = {
3803		UPDATE_COEF(0x4f, 0xfcc0, 0xc400), /* Set to TRS type */
3804		UPDATE_COEF(0x50, 0x2000, 0x2000),
3805		UPDATE_COEF(0x56, 0x0006, 0x0006),
3806		UPDATE_COEF(0x66, 0x0008, 0),
3807		UPDATE_COEF(0x67, 0x2000, 0),
3808		{}
3809	};
3810	static struct coef_fw coef0292[] = {
3811		WRITE_COEF(0x76, 0x000e),
3812		WRITE_COEF(0x6c, 0x2400),
3813		WRITE_COEF(0x6b, 0xc429),
3814		WRITE_COEF(0x18, 0x7308),
3815		{}
3816	};
3817	static struct coef_fw coef0293[] = {
3818		UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
3819		WRITE_COEF(0x45, 0xC429), /* Set to TRS type */
3820		UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
3821		{}
3822	};
3823	static struct coef_fw coef0688[] = {
3824		WRITE_COEF(0x11, 0x0041),
3825		WRITE_COEF(0x15, 0x0d40),
3826		WRITE_COEF(0xb7, 0x802b),
3827		{}
3828	};
3829
3830	switch (codec->core.vendor_id) {
3831	case 0x10ec0225:
3832		alc_process_coef_fw(codec, coef0225);
3833		break;
3834	case 0x10ec0255:
3835	case 0x10ec0256:
3836		alc_process_coef_fw(codec, coef0255);
3837		break;
3838	case 0x10ec0233:
3839	case 0x10ec0283:
3840		alc_process_coef_fw(codec, coef0233);
3841		break;
3842	case 0x10ec0286:
3843	case 0x10ec0288:
3844		alc_process_coef_fw(codec, coef0288);
3845		break;
3846	case 0x10ec0292:
3847		alc_process_coef_fw(codec, coef0292);
3848		break;
3849	case 0x10ec0293:
3850		alc_process_coef_fw(codec, coef0293);
3851		break;
3852	case 0x10ec0668:
3853		alc_process_coef_fw(codec, coef0688);
3854		break;
3855	}
3856	codec_dbg(codec, "Headset jack set to headphone (default) mode.\n");
3857}
3858
3859/* Iphone type */
3860static void alc_headset_mode_ctia(struct hda_codec *codec)
3861{
3862	static struct coef_fw coef0255[] = {
3863		WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
3864		WRITE_COEF(0x1b, 0x0c2b),
3865		WRITE_COEFEX(0x57, 0x03, 0x8ea6),
3866		{}
3867	};
3868	static struct coef_fw coef0256[] = {
3869		WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
3870		WRITE_COEF(0x1b, 0x0c6b),
3871		WRITE_COEFEX(0x57, 0x03, 0x8ea6),
3872		{}
3873	};
3874	static struct coef_fw coef0233[] = {
3875		WRITE_COEF(0x45, 0xd429),
3876		WRITE_COEF(0x1b, 0x0c2b),
3877		WRITE_COEF(0x32, 0x4ea3),
3878		{}
3879	};
3880	static struct coef_fw coef0288[] = {
3881		UPDATE_COEF(0x50, 0x2000, 0x2000),
3882		UPDATE_COEF(0x56, 0x0006, 0x0006),
3883		UPDATE_COEF(0x66, 0x0008, 0),
3884		UPDATE_COEF(0x67, 0x2000, 0),
3885		{}
3886	};
3887	static struct coef_fw coef0292[] = {
3888		WRITE_COEF(0x6b, 0xd429),
3889		WRITE_COEF(0x76, 0x0008),
3890		WRITE_COEF(0x18, 0x7388),
3891		{}
3892	};
3893	static struct coef_fw coef0293[] = {
3894		WRITE_COEF(0x45, 0xd429), /* Set to ctia type */
3895		UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
3896		{}
3897	};
3898	static struct coef_fw coef0688[] = {
3899		WRITE_COEF(0x11, 0x0001),
3900		WRITE_COEF(0x15, 0x0d60),
3901		WRITE_COEF(0xc3, 0x0000),
3902		{}
3903	};
3904
3905	switch (codec->core.vendor_id) {
3906	case 0x10ec0255:
3907		alc_process_coef_fw(codec, coef0255);
3908		break;
3909	case 0x10ec0256:
3910		alc_process_coef_fw(codec, coef0256);
3911		break;
3912	case 0x10ec0233:
3913	case 0x10ec0283:
3914		alc_process_coef_fw(codec, coef0233);
3915		break;
3916	case 0x10ec0286:
3917	case 0x10ec0288:
3918		alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
3919		msleep(300);
3920		alc_process_coef_fw(codec, coef0288);
3921		break;
3922	case 0x10ec0292:
3923		alc_process_coef_fw(codec, coef0292);
3924		break;
3925	case 0x10ec0293:
3926		alc_process_coef_fw(codec, coef0293);
3927		break;
3928	case 0x10ec0668:
3929		alc_process_coef_fw(codec, coef0688);
3930		break;
3931	}
3932	codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n");
3933}
3934
3935/* Nokia type */
3936static void alc_headset_mode_omtp(struct hda_codec *codec)
3937{
3938	static struct coef_fw coef0255[] = {
3939		WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
3940		WRITE_COEF(0x1b, 0x0c2b),
3941		WRITE_COEFEX(0x57, 0x03, 0x8ea6),
3942		{}
3943	};
3944	static struct coef_fw coef0256[] = {
3945		WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
3946		WRITE_COEF(0x1b, 0x0c6b),
3947		WRITE_COEFEX(0x57, 0x03, 0x8ea6),
3948		{}
3949	};
3950	static struct coef_fw coef0233[] = {
3951		WRITE_COEF(0x45, 0xe429),
3952		WRITE_COEF(0x1b, 0x0c2b),
3953		WRITE_COEF(0x32, 0x4ea3),
3954		{}
3955	};
3956	static struct coef_fw coef0288[] = {
3957		UPDATE_COEF(0x50, 0x2000, 0x2000),
3958		UPDATE_COEF(0x56, 0x0006, 0x0006),
3959		UPDATE_COEF(0x66, 0x0008, 0),
3960		UPDATE_COEF(0x67, 0x2000, 0),
3961		{}
3962	};
3963	static struct coef_fw coef0292[] = {
3964		WRITE_COEF(0x6b, 0xe429),
3965		WRITE_COEF(0x76, 0x0008),
3966		WRITE_COEF(0x18, 0x7388),
3967		{}
3968	};
3969	static struct coef_fw coef0293[] = {
3970		WRITE_COEF(0x45, 0xe429), /* Set to omtp type */
3971		UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
3972		{}
3973	};
3974	static struct coef_fw coef0688[] = {
3975		WRITE_COEF(0x11, 0x0001),
3976		WRITE_COEF(0x15, 0x0d50),
3977		WRITE_COEF(0xc3, 0x0000),
3978		{}
3979	};
3980
3981	switch (codec->core.vendor_id) {
3982	case 0x10ec0255:
3983		alc_process_coef_fw(codec, coef0255);
3984		break;
3985	case 0x10ec0256:
3986		alc_process_coef_fw(codec, coef0256);
3987		break;
3988	case 0x10ec0233:
3989	case 0x10ec0283:
3990		alc_process_coef_fw(codec, coef0233);
3991		break;
3992	case 0x10ec0286:
3993	case 0x10ec0288:
3994		alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
3995		msleep(300);
3996		alc_process_coef_fw(codec, coef0288);
3997		break;
3998	case 0x10ec0292:
3999		alc_process_coef_fw(codec, coef0292);
4000		break;
4001	case 0x10ec0293:
4002		alc_process_coef_fw(codec, coef0293);
4003		break;
4004	case 0x10ec0668:
4005		alc_process_coef_fw(codec, coef0688);
4006		break;
4007	}
4008	codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n");
4009}
4010
4011static void alc_determine_headset_type(struct hda_codec *codec)
4012{
4013	int val;
4014	bool is_ctia = false;
4015	struct alc_spec *spec = codec->spec;
4016	static struct coef_fw coef0255[] = {
4017		WRITE_COEF(0x45, 0xd089), /* combo jack auto switch control(Check type)*/
4018		WRITE_COEF(0x49, 0x0149), /* combo jack auto switch control(Vref
4019 conteol) */
4020		{}
4021	};
4022	static struct coef_fw coef0288[] = {
4023		UPDATE_COEF(0x4f, 0xfcc0, 0xd400), /* Check Type */
4024		{}
4025	};
4026	static struct coef_fw coef0293[] = {
4027		UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */
4028		WRITE_COEF(0x45, 0xD429), /* Set to ctia type */
4029		{}
4030	};
4031	static struct coef_fw coef0688[] = {
4032		WRITE_COEF(0x11, 0x0001),
4033		WRITE_COEF(0xb7, 0x802b),
4034		WRITE_COEF(0x15, 0x0d60),
4035		WRITE_COEF(0xc3, 0x0c00),
4036		{}
4037	};
4038
4039	switch (codec->core.vendor_id) {
4040	case 0x10ec0255:
4041	case 0x10ec0256:
4042		alc_process_coef_fw(codec, coef0255);
4043		msleep(300);
4044		val = alc_read_coef_idx(codec, 0x46);
4045		is_ctia = (val & 0x0070) == 0x0070;
4046		break;
4047	case 0x10ec0233:
4048	case 0x10ec0283:
4049		alc_write_coef_idx(codec, 0x45, 0xd029);
4050		msleep(300);
4051		val = alc_read_coef_idx(codec, 0x46);
4052		is_ctia = (val & 0x0070) == 0x0070;
4053		break;
4054	case 0x10ec0286:
4055	case 0x10ec0288:
4056		alc_process_coef_fw(codec, coef0288);
4057		msleep(350);
4058		val = alc_read_coef_idx(codec, 0x50);
4059		is_ctia = (val & 0x0070) == 0x0070;
4060		break;
4061	case 0x10ec0292:
4062		alc_write_coef_idx(codec, 0x6b, 0xd429);
4063		msleep(300);
4064		val = alc_read_coef_idx(codec, 0x6c);
4065		is_ctia = (val & 0x001c) == 0x001c;
4066		break;
4067	case 0x10ec0293:
4068		alc_process_coef_fw(codec, coef0293);
4069		msleep(300);
4070		val = alc_read_coef_idx(codec, 0x46);
4071		is_ctia = (val & 0x0070) == 0x0070;
4072		break;
4073	case 0x10ec0668:
4074		alc_process_coef_fw(codec, coef0688);
4075		msleep(300);
4076		val = alc_read_coef_idx(codec, 0xbe);
4077		is_ctia = (val & 0x1c02) == 0x1c02;
4078		break;
4079	}
4080
4081	codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n",
4082		    is_ctia ? "yes" : "no");
4083	spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP;
4084}
4085
4086static void alc_update_headset_mode(struct hda_codec *codec)
4087{
4088	struct alc_spec *spec = codec->spec;
4089
4090	hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]];
4091	hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
4092
4093	int new_headset_mode;
4094
4095	if (!snd_hda_jack_detect(codec, hp_pin))
4096		new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED;
4097	else if (mux_pin == spec->headset_mic_pin)
4098		new_headset_mode = ALC_HEADSET_MODE_HEADSET;
4099	else if (mux_pin == spec->headphone_mic_pin)
4100		new_headset_mode = ALC_HEADSET_MODE_MIC;
4101	else
4102		new_headset_mode = ALC_HEADSET_MODE_HEADPHONE;
4103
4104	if (new_headset_mode == spec->current_headset_mode) {
4105		snd_hda_gen_update_outputs(codec);
4106		return;
4107	}
4108
4109	switch (new_headset_mode) {
4110	case ALC_HEADSET_MODE_UNPLUGGED:
4111		alc_headset_mode_unplugged(codec);
4112		spec->gen.hp_jack_present = false;
4113		break;
4114	case ALC_HEADSET_MODE_HEADSET:
4115		if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN)
4116			alc_determine_headset_type(codec);
4117		if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA)
4118			alc_headset_mode_ctia(codec);
4119		else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP)
4120			alc_headset_mode_omtp(codec);
4121		spec->gen.hp_jack_present = true;
4122		break;
4123	case ALC_HEADSET_MODE_MIC:
4124		alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin);
4125		spec->gen.hp_jack_present = false;
4126		break;
4127	case ALC_HEADSET_MODE_HEADPHONE:
4128		alc_headset_mode_default(codec);
4129		spec->gen.hp_jack_present = true;
4130		break;
4131	}
4132	if (new_headset_mode != ALC_HEADSET_MODE_MIC) {
4133		snd_hda_set_pin_ctl_cache(codec, hp_pin,
4134					  AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
4135		if (spec->headphone_mic_pin && spec->headphone_mic_pin != hp_pin)
4136			snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin,
4137						  PIN_VREFHIZ);
4138	}
4139	spec->current_headset_mode = new_headset_mode;
4140
4141	snd_hda_gen_update_outputs(codec);
4142}
4143
4144static void alc_update_headset_mode_hook(struct hda_codec *codec,
4145					 struct snd_kcontrol *kcontrol,
4146					 struct snd_ctl_elem_value *ucontrol)
4147{
4148	alc_update_headset_mode(codec);
4149}
4150
4151static void alc_update_headset_jack_cb(struct hda_codec *codec,
4152				       struct hda_jack_callback *jack)
4153{
4154	struct alc_spec *spec = codec->spec;
4155	spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
4156	snd_hda_gen_hp_automute(codec, jack);
4157}
4158
4159static void alc_probe_headset_mode(struct hda_codec *codec)
4160{
4161	int i;
4162	struct alc_spec *spec = codec->spec;
4163	struct auto_pin_cfg *cfg = &spec->gen.autocfg;
4164
4165	/* Find mic pins */
4166	for (i = 0; i < cfg->num_inputs; i++) {
4167		if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin)
4168			spec->headset_mic_pin = cfg->inputs[i].pin;
4169		if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin)
4170			spec->headphone_mic_pin = cfg->inputs[i].pin;
4171	}
4172
4173	spec->gen.cap_sync_hook = alc_update_headset_mode_hook;
4174	spec->gen.automute_hook = alc_update_headset_mode;
4175	spec->gen.hp_automute_hook = alc_update_headset_jack_cb;
4176}
4177
4178static void alc_fixup_headset_mode(struct hda_codec *codec,
4179				const struct hda_fixup *fix, int action)
4180{
4181	struct alc_spec *spec = codec->spec;
4182
4183	switch (action) {
4184	case HDA_FIXUP_ACT_PRE_PROBE:
4185		spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC;
4186		break;
4187	case HDA_FIXUP_ACT_PROBE:
4188		alc_probe_headset_mode(codec);
4189		break;
4190	case HDA_FIXUP_ACT_INIT:
4191		spec->current_headset_mode = 0;
4192		alc_update_headset_mode(codec);
4193		break;
4194	}
4195}
4196
4197static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
4198				const struct hda_fixup *fix, int action)
4199{
4200	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4201		struct alc_spec *spec = codec->spec;
4202		spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
4203	}
4204	else
4205		alc_fixup_headset_mode(codec, fix, action);
4206}
4207
4208static void alc255_set_default_jack_type(struct hda_codec *codec)
4209{
4210	/* Set to iphone type */
4211	static struct coef_fw alc255fw[] = {
4212		WRITE_COEF(0x1b, 0x880b),
4213		WRITE_COEF(0x45, 0xd089),
4214		WRITE_COEF(0x1b, 0x080b),
4215		WRITE_COEF(0x46, 0x0004),
4216		WRITE_COEF(0x1b, 0x0c0b),
4217		{}
4218	};
4219	static struct coef_fw alc256fw[] = {
4220		WRITE_COEF(0x1b, 0x884b),
4221		WRITE_COEF(0x45, 0xd089),
4222		WRITE_COEF(0x1b, 0x084b),
4223		WRITE_COEF(0x46, 0x0004),
4224		WRITE_COEF(0x1b, 0x0c4b),
4225		{}
4226	};
4227	switch (codec->core.vendor_id) {
4228	case 0x10ec0255:
4229		alc_process_coef_fw(codec, alc255fw);
4230		break;
4231	case 0x10ec0256:
4232		alc_process_coef_fw(codec, alc256fw);
4233		break;
4234	}
4235	msleep(30);
4236}
4237
4238static void alc_fixup_headset_mode_alc255(struct hda_codec *codec,
4239				const struct hda_fixup *fix, int action)
4240{
4241	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4242		alc255_set_default_jack_type(codec);
4243	}
4244	alc_fixup_headset_mode(codec, fix, action);
4245}
4246
4247static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec,
4248				const struct hda_fixup *fix, int action)
4249{
4250	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4251		struct alc_spec *spec = codec->spec;
4252		spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
4253		alc255_set_default_jack_type(codec);
4254	}
4255	else
4256		alc_fixup_headset_mode(codec, fix, action);
4257}
4258
4259static void alc288_update_headset_jack_cb(struct hda_codec *codec,
4260				       struct hda_jack_callback *jack)
4261{
4262	struct alc_spec *spec = codec->spec;
4263	int present;
4264
4265	alc_update_headset_jack_cb(codec, jack);
4266	/* Headset Mic enable or disable, only for Dell Dino */
4267	present = spec->gen.hp_jack_present ? 0x40 : 0;
4268	snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
4269				present);
4270}
4271
4272static void alc_fixup_headset_mode_dell_alc288(struct hda_codec *codec,
4273				const struct hda_fixup *fix, int action)
4274{
4275	alc_fixup_headset_mode(codec, fix, action);
4276	if (action == HDA_FIXUP_ACT_PROBE) {
4277		struct alc_spec *spec = codec->spec;
4278		spec->gen.hp_automute_hook = alc288_update_headset_jack_cb;
4279	}
4280}
4281
4282static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec,
4283					const struct hda_fixup *fix, int action)
4284{
4285	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4286		struct alc_spec *spec = codec->spec;
4287		spec->gen.auto_mute_via_amp = 1;
4288	}
4289}
4290
4291static void alc_no_shutup(struct hda_codec *codec)
4292{
4293}
4294
4295static void alc_fixup_no_shutup(struct hda_codec *codec,
4296				const struct hda_fixup *fix, int action)
4297{
4298	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4299		struct alc_spec *spec = codec->spec;
4300		spec->shutup = alc_no_shutup;
4301	}
4302}
4303
4304static void alc_fixup_disable_aamix(struct hda_codec *codec,
4305				    const struct hda_fixup *fix, int action)
4306{
4307	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4308		struct alc_spec *spec = codec->spec;
4309		/* Disable AA-loopback as it causes white noise */
4310		spec->gen.mixer_nid = 0;
4311	}
4312}
4313
4314/* fixup for Thinkpad docks: add dock pins, avoid HP parser fixup */
4315static void alc_fixup_tpt440_dock(struct hda_codec *codec,
4316				  const struct hda_fixup *fix, int action)
4317{
4318	static const struct hda_pintbl pincfgs[] = {
4319		{ 0x16, 0x21211010 }, /* dock headphone */
4320		{ 0x19, 0x21a11010 }, /* dock mic */
4321		{ }
4322	};
4323	struct alc_spec *spec = codec->spec;
4324
4325	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4326		spec->shutup = alc_no_shutup; /* reduce click noise */
4327		spec->reboot_notify = alc_d3_at_reboot; /* reduce noise */
4328		spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
4329		codec->power_save_node = 0; /* avoid click noises */
4330		snd_hda_apply_pincfgs(codec, pincfgs);
4331	}
4332}
4333
4334static void alc_shutup_dell_xps13(struct hda_codec *codec)
4335{
4336	struct alc_spec *spec = codec->spec;
4337	int hp_pin = spec->gen.autocfg.hp_pins[0];
4338
4339	/* Prevent pop noises when headphones are plugged in */
4340	snd_hda_codec_write(codec, hp_pin, 0,
4341			    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
4342	msleep(20);
4343}
4344
4345static void alc_fixup_dell_xps13(struct hda_codec *codec,
4346				const struct hda_fixup *fix, int action)
4347{
4348	struct alc_spec *spec = codec->spec;
4349	struct hda_input_mux *imux = &spec->gen.input_mux;
4350	int i;
4351
4352	switch (action) {
4353	case HDA_FIXUP_ACT_PRE_PROBE:
4354		/* mic pin 0x19 must be initialized with Vref Hi-Z, otherwise
4355		 * it causes a click noise at start up
4356		 */
4357		snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
4358		break;
4359	case HDA_FIXUP_ACT_PROBE:
4360		spec->shutup = alc_shutup_dell_xps13;
4361
4362		/* Make the internal mic the default input source. */
4363		for (i = 0; i < imux->num_items; i++) {
4364			if (spec->gen.imux_pins[i] == 0x12) {
4365				spec->gen.cur_mux[0] = i;
4366				break;
4367			}
4368		}
4369		break;
4370	}
4371}
4372
4373static void alc_fixup_headset_mode_alc662(struct hda_codec *codec,
4374				const struct hda_fixup *fix, int action)
4375{
4376	struct alc_spec *spec = codec->spec;
4377
4378	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4379		spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
4380		spec->gen.hp_mic = 1; /* Mic-in is same pin as headphone */
4381
4382		/* Disable boost for mic-in permanently. (This code is only called
4383		   from quirks that guarantee that the headphone is at NID 0x1b.) */
4384		snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000);
4385		snd_hda_override_wcaps(codec, 0x1b, get_wcaps(codec, 0x1b) & ~AC_WCAP_IN_AMP);
4386	} else
4387		alc_fixup_headset_mode(codec, fix, action);
4388}
4389
4390static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
4391				const struct hda_fixup *fix, int action)
4392{
4393	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4394		alc_write_coef_idx(codec, 0xc4, 0x8000);
4395		alc_update_coef_idx(codec, 0xc2, ~0xfe, 0);
4396		snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
4397	}
4398	alc_fixup_headset_mode(codec, fix, action);
4399}
4400
4401/* Returns the nid of the external mic input pin, or 0 if it cannot be found. */
4402static int find_ext_mic_pin(struct hda_codec *codec)
4403{
4404	struct alc_spec *spec = codec->spec;
4405	struct auto_pin_cfg *cfg = &spec->gen.autocfg;
4406	hda_nid_t nid;
4407	unsigned int defcfg;
4408	int i;
4409
4410	for (i = 0; i < cfg->num_inputs; i++) {
4411		if (cfg->inputs[i].type != AUTO_PIN_MIC)
4412			continue;
4413		nid = cfg->inputs[i].pin;
4414		defcfg = snd_hda_codec_get_pincfg(codec, nid);
4415		if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT)
4416			continue;
4417		return nid;
4418	}
4419
4420	return 0;
4421}
4422
4423static void alc271_hp_gate_mic_jack(struct hda_codec *codec,
4424				    const struct hda_fixup *fix,
4425				    int action)
4426{
4427	struct alc_spec *spec = codec->spec;
4428
4429	if (action == HDA_FIXUP_ACT_PROBE) {
4430		int mic_pin = find_ext_mic_pin(codec);
4431		int hp_pin = spec->gen.autocfg.hp_pins[0];
4432
4433		if (snd_BUG_ON(!mic_pin || !hp_pin))
4434			return;
4435		snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin);
4436	}
4437}
4438
4439static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec,
4440					     const struct hda_fixup *fix,
4441					     int action)
4442{
4443	struct alc_spec *spec = codec->spec;
4444	struct auto_pin_cfg *cfg = &spec->gen.autocfg;
4445	int i;
4446
4447	/* The mic boosts on level 2 and 3 are too noisy
4448	   on the internal mic input.
4449	   Therefore limit the boost to 0 or 1. */
4450
4451	if (action != HDA_FIXUP_ACT_PROBE)
4452		return;
4453
4454	for (i = 0; i < cfg->num_inputs; i++) {
4455		hda_nid_t nid = cfg->inputs[i].pin;
4456		unsigned int defcfg;
4457		if (cfg->inputs[i].type != AUTO_PIN_MIC)
4458			continue;
4459		defcfg = snd_hda_codec_get_pincfg(codec, nid);
4460		if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT)
4461			continue;
4462
4463		snd_hda_override_amp_caps(codec, nid, HDA_INPUT,
4464					  (0x00 << AC_AMPCAP_OFFSET_SHIFT) |
4465					  (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4466					  (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) |
4467					  (0 << AC_AMPCAP_MUTE_SHIFT));
4468	}
4469}
4470
4471static void alc283_hp_automute_hook(struct hda_codec *codec,
4472				    struct hda_jack_callback *jack)
4473{
4474	struct alc_spec *spec = codec->spec;
4475	int vref;
4476
4477	msleep(200);
4478	snd_hda_gen_hp_automute(codec, jack);
4479
4480	vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
4481
4482	msleep(600);
4483	snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4484			    vref);
4485}
4486
4487static void alc283_fixup_chromebook(struct hda_codec *codec,
4488				    const struct hda_fixup *fix, int action)
4489{
4490	struct alc_spec *spec = codec->spec;
4491
4492	switch (action) {
4493	case HDA_FIXUP_ACT_PRE_PROBE:
4494		snd_hda_override_wcaps(codec, 0x03, 0);
4495		/* Disable AA-loopback as it causes white noise */
4496		spec->gen.mixer_nid = 0;
4497		break;
4498	case HDA_FIXUP_ACT_INIT:
4499		/* MIC2-VREF control */
4500		/* Set to manual mode */
4501		alc_update_coef_idx(codec, 0x06, 0x000c, 0);
4502		/* Enable Line1 input control by verb */
4503		alc_update_coef_idx(codec, 0x1a, 0, 1 << 4);
4504		break;
4505	}
4506}
4507
4508static void alc283_fixup_sense_combo_jack(struct hda_codec *codec,
4509				    const struct hda_fixup *fix, int action)
4510{
4511	struct alc_spec *spec = codec->spec;
4512
4513	switch (action) {
4514	case HDA_FIXUP_ACT_PRE_PROBE:
4515		spec->gen.hp_automute_hook = alc283_hp_automute_hook;
4516		break;
4517	case HDA_FIXUP_ACT_INIT:
4518		/* MIC2-VREF control */
4519		/* Set to manual mode */
4520		alc_update_coef_idx(codec, 0x06, 0x000c, 0);
4521		break;
4522	}
4523}
4524
4525/* mute tablet speaker pin (0x14) via dock plugging in addition */
4526static void asus_tx300_automute(struct hda_codec *codec)
4527{
4528	struct alc_spec *spec = codec->spec;
4529	snd_hda_gen_update_outputs(codec);
4530	if (snd_hda_jack_detect(codec, 0x1b))
4531		spec->gen.mute_bits |= (1ULL << 0x14);
4532}
4533
4534static void alc282_fixup_asus_tx300(struct hda_codec *codec,
4535				    const struct hda_fixup *fix, int action)
4536{
4537	struct alc_spec *spec = codec->spec;
4538	/* TX300 needs to set up GPIO2 for the speaker amp */
4539	static const struct hda_verb gpio2_verbs[] = {
4540		{ 0x01, AC_VERB_SET_GPIO_MASK, 0x04 },
4541		{ 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 },
4542		{ 0x01, AC_VERB_SET_GPIO_DATA, 0x04 },
4543		{}
4544	};
4545	static const struct hda_pintbl dock_pins[] = {
4546		{ 0x1b, 0x21114000 }, /* dock speaker pin */
4547		{}
4548	};
4549	struct snd_kcontrol *kctl;
4550
4551	switch (action) {
4552	case HDA_FIXUP_ACT_PRE_PROBE:
4553		snd_hda_add_verbs(codec, gpio2_verbs);
4554		snd_hda_apply_pincfgs(codec, dock_pins);
4555		spec->gen.auto_mute_via_amp = 1;
4556		spec->gen.automute_hook = asus_tx300_automute;
4557		snd_hda_jack_detect_enable_callback(codec, 0x1b,
4558						    snd_hda_gen_hp_automute);
4559		break;
4560	case HDA_FIXUP_ACT_BUILD:
4561		/* this is a bit tricky; give more sane names for the main
4562		 * (tablet) speaker and the dock speaker, respectively
4563		 */
4564		kctl = snd_hda_find_mixer_ctl(codec, "Speaker Playback Switch");
4565		if (kctl)
4566			strcpy(kctl->id.name, "Dock Speaker Playback Switch");
4567		kctl = snd_hda_find_mixer_ctl(codec, "Bass Speaker Playback Switch");
4568		if (kctl)
4569			strcpy(kctl->id.name, "Speaker Playback Switch");
4570		break;
4571	}
4572}
4573
4574static void alc290_fixup_mono_speakers(struct hda_codec *codec,
4575				       const struct hda_fixup *fix, int action)
4576{
4577	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4578		/* DAC node 0x03 is giving mono output. We therefore want to
4579		   make sure 0x14 (front speaker) and 0x15 (headphones) use the
4580		   stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */
4581		hda_nid_t conn1[2] = { 0x0c };
4582		snd_hda_override_conn_list(codec, 0x14, 1, conn1);
4583		snd_hda_override_conn_list(codec, 0x15, 1, conn1);
4584	}
4585}
4586
4587/* for hda_fixup_thinkpad_acpi() */
4588#include "thinkpad_helper.c"
4589
4590/* for dell wmi mic mute led */
4591#include "dell_wmi_helper.c"
4592
4593enum {
4594	ALC269_FIXUP_SONY_VAIO,
4595	ALC275_FIXUP_SONY_VAIO_GPIO2,
4596	ALC269_FIXUP_DELL_M101Z,
4597	ALC269_FIXUP_SKU_IGNORE,
4598	ALC269_FIXUP_ASUS_G73JW,
4599	ALC269_FIXUP_LENOVO_EAPD,
4600	ALC275_FIXUP_SONY_HWEQ,
4601	ALC275_FIXUP_SONY_DISABLE_AAMIX,
4602	ALC271_FIXUP_DMIC,
4603	ALC269_FIXUP_PCM_44K,
4604	ALC269_FIXUP_STEREO_DMIC,
4605	ALC269_FIXUP_HEADSET_MIC,
4606	ALC269_FIXUP_QUANTA_MUTE,
4607	ALC269_FIXUP_LIFEBOOK,
4608	ALC269_FIXUP_LIFEBOOK_EXTMIC,
4609	ALC269_FIXUP_LIFEBOOK_HP_PIN,
4610	ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT,
4611	ALC269_FIXUP_AMIC,
4612	ALC269_FIXUP_DMIC,
4613	ALC269VB_FIXUP_AMIC,
4614	ALC269VB_FIXUP_DMIC,
4615	ALC269_FIXUP_HP_MUTE_LED,
4616	ALC269_FIXUP_HP_MUTE_LED_MIC1,
4617	ALC269_FIXUP_HP_MUTE_LED_MIC2,
4618	ALC269_FIXUP_HP_GPIO_LED,
4619	ALC269_FIXUP_HP_GPIO_MIC1_LED,
4620	ALC269_FIXUP_HP_LINE1_MIC1_LED,
4621	ALC269_FIXUP_INV_DMIC,
4622	ALC269_FIXUP_LENOVO_DOCK,
4623	ALC269_FIXUP_NO_SHUTUP,
4624	ALC286_FIXUP_SONY_MIC_NO_PRESENCE,
4625	ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
4626	ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
4627	ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
4628	ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
4629	ALC269_FIXUP_HEADSET_MODE,
4630	ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC,
4631	ALC269_FIXUP_ASPIRE_HEADSET_MIC,
4632	ALC269_FIXUP_ASUS_X101_FUNC,
4633	ALC269_FIXUP_ASUS_X101_VERB,
4634	ALC269_FIXUP_ASUS_X101,
4635	ALC271_FIXUP_AMIC_MIC2,
4636	ALC271_FIXUP_HP_GATE_MIC_JACK,
4637	ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572,
4638	ALC269_FIXUP_ACER_AC700,
4639	ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
4640	ALC269VB_FIXUP_ASUS_ZENBOOK,
4641	ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A,
4642	ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED,
4643	ALC269VB_FIXUP_ORDISSIMO_EVE2,
4644	ALC283_FIXUP_CHROME_BOOK,
4645	ALC283_FIXUP_SENSE_COMBO_JACK,
4646	ALC282_FIXUP_ASUS_TX300,
4647	ALC283_FIXUP_INT_MIC,
4648	ALC290_FIXUP_MONO_SPEAKERS,
4649	ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
4650	ALC290_FIXUP_SUBWOOFER,
4651	ALC290_FIXUP_SUBWOOFER_HSJACK,
4652	ALC269_FIXUP_THINKPAD_ACPI,
4653	ALC269_FIXUP_DMIC_THINKPAD_ACPI,
4654	ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
4655	ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
4656	ALC255_FIXUP_HEADSET_MODE,
4657	ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC,
4658	ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
4659	ALC292_FIXUP_TPT440_DOCK,
4660	ALC292_FIXUP_TPT440,
4661	ALC283_FIXUP_BXBT2807_MIC,
4662	ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED,
4663	ALC282_FIXUP_ASPIRE_V5_PINS,
4664	ALC280_FIXUP_HP_GPIO4,
4665	ALC286_FIXUP_HP_GPIO_LED,
4666	ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY,
4667	ALC280_FIXUP_HP_DOCK_PINS,
4668	ALC288_FIXUP_DELL_HEADSET_MODE,
4669	ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
4670	ALC288_FIXUP_DELL_XPS_13_GPIO6,
4671	ALC288_FIXUP_DELL_XPS_13,
4672	ALC288_FIXUP_DISABLE_AAMIX,
4673	ALC292_FIXUP_DELL_E7X,
4674	ALC292_FIXUP_DISABLE_AAMIX,
4675	ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK,
4676	ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
4677	ALC275_FIXUP_DELL_XPS,
4678	ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE,
4679	ALC293_FIXUP_LENOVO_SPK_NOISE,
4680	ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
4681	ALC255_FIXUP_DELL_SPK_NOISE,
4682	ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
4683	ALC280_FIXUP_HP_HEADSET_MIC,
4684	ALC221_FIXUP_HP_FRONT_MIC,
4685	ALC292_FIXUP_TPT460,
4686};
4687
4688static const struct hda_fixup alc269_fixups[] = {
4689	[ALC269_FIXUP_SONY_VAIO] = {
4690		.type = HDA_FIXUP_PINCTLS,
4691		.v.pins = (const struct hda_pintbl[]) {
4692			{0x19, PIN_VREFGRD},
4693			{}
4694		}
4695	},
4696	[ALC275_FIXUP_SONY_VAIO_GPIO2] = {
4697		.type = HDA_FIXUP_VERBS,
4698		.v.verbs = (const struct hda_verb[]) {
4699			{0x01, AC_VERB_SET_GPIO_MASK, 0x04},
4700			{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
4701			{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4702			{ }
4703		},
4704		.chained = true,
4705		.chain_id = ALC269_FIXUP_SONY_VAIO
4706	},
4707	[ALC269_FIXUP_DELL_M101Z] = {
4708		.type = HDA_FIXUP_VERBS,
4709		.v.verbs = (const struct hda_verb[]) {
4710			/* Enables internal speaker */
4711			{0x20, AC_VERB_SET_COEF_INDEX, 13},
4712			{0x20, AC_VERB_SET_PROC_COEF, 0x4040},
4713			{}
4714		}
4715	},
4716	[ALC269_FIXUP_SKU_IGNORE] = {
4717		.type = HDA_FIXUP_FUNC,
4718		.v.func = alc_fixup_sku_ignore,
4719	},
4720	[ALC269_FIXUP_ASUS_G73JW] = {
4721		.type = HDA_FIXUP_PINS,
4722		.v.pins = (const struct hda_pintbl[]) {
4723			{ 0x17, 0x99130111 }, /* subwoofer */
4724			{ }
4725		}
4726	},
4727	[ALC269_FIXUP_LENOVO_EAPD] = {
4728		.type = HDA_FIXUP_VERBS,
4729		.v.verbs = (const struct hda_verb[]) {
4730			{0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
4731			{}
4732		}
4733	},
4734	[ALC275_FIXUP_SONY_HWEQ] = {
4735		.type = HDA_FIXUP_FUNC,
4736		.v.func = alc269_fixup_hweq,
4737		.chained = true,
4738		.chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
4739	},
4740	[ALC275_FIXUP_SONY_DISABLE_AAMIX] = {
4741		.type = HDA_FIXUP_FUNC,
4742		.v.func = alc_fixup_disable_aamix,
4743		.chained = true,
4744		.chain_id = ALC269_FIXUP_SONY_VAIO
4745	},
4746	[ALC271_FIXUP_DMIC] = {
4747		.type = HDA_FIXUP_FUNC,
4748		.v.func = alc271_fixup_dmic,
4749	},
4750	[ALC269_FIXUP_PCM_44K] = {
4751		.type = HDA_FIXUP_FUNC,
4752		.v.func = alc269_fixup_pcm_44k,
4753		.chained = true,
4754		.chain_id = ALC269_FIXUP_QUANTA_MUTE
4755	},
4756	[ALC269_FIXUP_STEREO_DMIC] = {
4757		.type = HDA_FIXUP_FUNC,
4758		.v.func = alc269_fixup_stereo_dmic,
4759	},
4760	[ALC269_FIXUP_HEADSET_MIC] = {
4761		.type = HDA_FIXUP_FUNC,
4762		.v.func = alc269_fixup_headset_mic,
4763	},
4764	[ALC269_FIXUP_QUANTA_MUTE] = {
4765		.type = HDA_FIXUP_FUNC,
4766		.v.func = alc269_fixup_quanta_mute,
4767	},
4768	[ALC269_FIXUP_LIFEBOOK] = {
4769		.type = HDA_FIXUP_PINS,
4770		.v.pins = (const struct hda_pintbl[]) {
4771			{ 0x1a, 0x2101103f }, /* dock line-out */
4772			{ 0x1b, 0x23a11040 }, /* dock mic-in */
4773			{ }
4774		},
4775		.chained = true,
4776		.chain_id = ALC269_FIXUP_QUANTA_MUTE
4777	},
4778	[ALC269_FIXUP_LIFEBOOK_EXTMIC] = {
4779		.type = HDA_FIXUP_PINS,
4780		.v.pins = (const struct hda_pintbl[]) {
4781			{ 0x19, 0x01a1903c }, /* headset mic, with jack detect */
4782			{ }
4783		},
4784	},
4785	[ALC269_FIXUP_LIFEBOOK_HP_PIN] = {
4786		.type = HDA_FIXUP_PINS,
4787		.v.pins = (const struct hda_pintbl[]) {
4788			{ 0x21, 0x0221102f }, /* HP out */
4789			{ }
4790		},
4791	},
4792	[ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT] = {
4793		.type = HDA_FIXUP_FUNC,
4794		.v.func = alc269_fixup_pincfg_no_hp_to_lineout,
4795	},
4796	[ALC269_FIXUP_AMIC] = {
4797		.type = HDA_FIXUP_PINS,
4798		.v.pins = (const struct hda_pintbl[]) {
4799			{ 0x14, 0x99130110 }, /* speaker */
4800			{ 0x15, 0x0121401f }, /* HP out */
4801			{ 0x18, 0x01a19c20 }, /* mic */
4802			{ 0x19, 0x99a3092f }, /* int-mic */
4803			{ }
4804		},
4805	},
4806	[ALC269_FIXUP_DMIC] = {
4807		.type = HDA_FIXUP_PINS,
4808		.v.pins = (const struct hda_pintbl[]) {
4809			{ 0x12, 0x99a3092f }, /* int-mic */
4810			{ 0x14, 0x99130110 }, /* speaker */
4811			{ 0x15, 0x0121401f }, /* HP out */
4812			{ 0x18, 0x01a19c20 }, /* mic */
4813			{ }
4814		},
4815	},
4816	[ALC269VB_FIXUP_AMIC] = {
4817		.type = HDA_FIXUP_PINS,
4818		.v.pins = (const struct hda_pintbl[]) {
4819			{ 0x14, 0x99130110 }, /* speaker */
4820			{ 0x18, 0x01a19c20 }, /* mic */
4821			{ 0x19, 0x99a3092f }, /* int-mic */
4822			{ 0x21, 0x0121401f }, /* HP out */
4823			{ }
4824		},
4825	},
4826	[ALC269VB_FIXUP_DMIC] = {
4827		.type = HDA_FIXUP_PINS,
4828		.v.pins = (const struct hda_pintbl[]) {
4829			{ 0x12, 0x99a3092f }, /* int-mic */
4830			{ 0x14, 0x99130110 }, /* speaker */
4831			{ 0x18, 0x01a19c20 }, /* mic */
4832			{ 0x21, 0x0121401f }, /* HP out */
4833			{ }
4834		},
4835	},
4836	[ALC269_FIXUP_HP_MUTE_LED] = {
4837		.type = HDA_FIXUP_FUNC,
4838		.v.func = alc269_fixup_hp_mute_led,
4839	},
4840	[ALC269_FIXUP_HP_MUTE_LED_MIC1] = {
4841		.type = HDA_FIXUP_FUNC,
4842		.v.func = alc269_fixup_hp_mute_led_mic1,
4843	},
4844	[ALC269_FIXUP_HP_MUTE_LED_MIC2] = {
4845		.type = HDA_FIXUP_FUNC,
4846		.v.func = alc269_fixup_hp_mute_led_mic2,
4847	},
4848	[ALC269_FIXUP_HP_GPIO_LED] = {
4849		.type = HDA_FIXUP_FUNC,
4850		.v.func = alc269_fixup_hp_gpio_led,
4851	},
4852	[ALC269_FIXUP_HP_GPIO_MIC1_LED] = {
4853		.type = HDA_FIXUP_FUNC,
4854		.v.func = alc269_fixup_hp_gpio_mic1_led,
4855	},
4856	[ALC269_FIXUP_HP_LINE1_MIC1_LED] = {
4857		.type = HDA_FIXUP_FUNC,
4858		.v.func = alc269_fixup_hp_line1_mic1_led,
4859	},
4860	[ALC269_FIXUP_INV_DMIC] = {
4861		.type = HDA_FIXUP_FUNC,
4862		.v.func = alc_fixup_inv_dmic,
4863	},
4864	[ALC269_FIXUP_NO_SHUTUP] = {
4865		.type = HDA_FIXUP_FUNC,
4866		.v.func = alc_fixup_no_shutup,
4867	},
4868	[ALC269_FIXUP_LENOVO_DOCK] = {
4869		.type = HDA_FIXUP_PINS,
4870		.v.pins = (const struct hda_pintbl[]) {
4871			{ 0x19, 0x23a11040 }, /* dock mic */
4872			{ 0x1b, 0x2121103f }, /* dock headphone */
4873			{ }
4874		},
4875		.chained = true,
4876		.chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT
4877	},
4878	[ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = {
4879		.type = HDA_FIXUP_FUNC,
4880		.v.func = alc269_fixup_pincfg_no_hp_to_lineout,
4881		.chained = true,
4882		.chain_id = ALC269_FIXUP_THINKPAD_ACPI,
4883	},
4884	[ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = {
4885		.type = HDA_FIXUP_PINS,
4886		.v.pins = (const struct hda_pintbl[]) {
4887			{ 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4888			{ 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
4889			{ }
4890		},
4891		.chained = true,
4892		.chain_id = ALC269_FIXUP_HEADSET_MODE
4893	},
4894	[ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = {
4895		.type = HDA_FIXUP_PINS,
4896		.v.pins = (const struct hda_pintbl[]) {
4897			{ 0x16, 0x21014020 }, /* dock line out */
4898			{ 0x19, 0x21a19030 }, /* dock mic */
4899			{ 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4900			{ }
4901		},
4902		.chained = true,
4903		.chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
4904	},
4905	[ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = {
4906		.type = HDA_FIXUP_PINS,
4907		.v.pins = (const struct hda_pintbl[]) {
4908			{ 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4909			{ }
4910		},
4911		.chained = true,
4912		.chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
4913	},
4914	[ALC269_FIXUP_HEADSET_MODE] = {
4915		.type = HDA_FIXUP_FUNC,
4916		.v.func = alc_fixup_headset_mode,
4917		.chained = true,
4918		.chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
4919	},
4920	[ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
4921		.type = HDA_FIXUP_FUNC,
4922		.v.func = alc_fixup_headset_mode_no_hp_mic,
4923	},
4924	[ALC269_FIXUP_ASPIRE_HEADSET_MIC] = {
4925		.type = HDA_FIXUP_PINS,
4926		.v.pins = (const struct hda_pintbl[]) {
4927			{ 0x19, 0x01a1913c }, /* headset mic w/o jack detect */
4928			{ }
4929		},
4930		.chained = true,
4931		.chain_id = ALC269_FIXUP_HEADSET_MODE,
4932	},
4933	[ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = {
4934		.type = HDA_FIXUP_PINS,
4935		.v.pins = (const struct hda_pintbl[]) {
4936			{ 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4937			{ }
4938		},
4939		.chained = true,
4940		.chain_id = ALC269_FIXUP_HEADSET_MIC
4941	},
4942	[ALC269_FIXUP_ASUS_X101_FUNC] = {
4943		.type = HDA_FIXUP_FUNC,
4944		.v.func = alc269_fixup_x101_headset_mic,
4945	},
4946	[ALC269_FIXUP_ASUS_X101_VERB] = {
4947		.type = HDA_FIXUP_VERBS,
4948		.v.verbs = (const struct hda_verb[]) {
4949			{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4950			{0x20, AC_VERB_SET_COEF_INDEX, 0x08},
4951			{0x20, AC_VERB_SET_PROC_COEF,  0x0310},
4952			{ }
4953		},
4954		.chained = true,
4955		.chain_id = ALC269_FIXUP_ASUS_X101_FUNC
4956	},
4957	[ALC269_FIXUP_ASUS_X101] = {
4958		.type = HDA_FIXUP_PINS,
4959		.v.pins = (const struct hda_pintbl[]) {
4960			{ 0x18, 0x04a1182c }, /* Headset mic */
4961			{ }
4962		},
4963		.chained = true,
4964		.chain_id = ALC269_FIXUP_ASUS_X101_VERB
4965	},
4966	[ALC271_FIXUP_AMIC_MIC2] = {
4967		.type = HDA_FIXUP_PINS,
4968		.v.pins = (const struct hda_pintbl[]) {
4969			{ 0x14, 0x99130110 }, /* speaker */
4970			{ 0x19, 0x01a19c20 }, /* mic */
4971			{ 0x1b, 0x99a7012f }, /* int-mic */
4972			{ 0x21, 0x0121401f }, /* HP out */
4973			{ }
4974		},
4975	},
4976	[ALC271_FIXUP_HP_GATE_MIC_JACK] = {
4977		.type = HDA_FIXUP_FUNC,
4978		.v.func = alc271_hp_gate_mic_jack,
4979		.chained = true,
4980		.chain_id = ALC271_FIXUP_AMIC_MIC2,
4981	},
4982	[ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = {
4983		.type = HDA_FIXUP_FUNC,
4984		.v.func = alc269_fixup_limit_int_mic_boost,
4985		.chained = true,
4986		.chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK,
4987	},
4988	[ALC269_FIXUP_ACER_AC700] = {
4989		.type = HDA_FIXUP_PINS,
4990		.v.pins = (const struct hda_pintbl[]) {
4991			{ 0x12, 0x99a3092f }, /* int-mic */
4992			{ 0x14, 0x99130110 }, /* speaker */
4993			{ 0x18, 0x03a11c20 }, /* mic */
4994			{ 0x1e, 0x0346101e }, /* SPDIF1 */
4995			{ 0x21, 0x0321101f }, /* HP out */
4996			{ }
4997		},
4998		.chained = true,
4999		.chain_id = ALC271_FIXUP_DMIC,
5000	},
5001	[ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = {
5002		.type = HDA_FIXUP_FUNC,
5003		.v.func = alc269_fixup_limit_int_mic_boost,
5004		.chained = true,
5005		.chain_id = ALC269_FIXUP_THINKPAD_ACPI,
5006	},
5007	[ALC269VB_FIXUP_ASUS_ZENBOOK] = {
5008		.type = HDA_FIXUP_FUNC,
5009		.v.func = alc269_fixup_limit_int_mic_boost,
5010		.chained = true,
5011		.chain_id = ALC269VB_FIXUP_DMIC,
5012	},
5013	[ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = {
5014		.type = HDA_FIXUP_VERBS,
5015		.v.verbs = (const struct hda_verb[]) {
5016			/* class-D output amp +5dB */
5017			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x12 },
5018			{ 0x20, AC_VERB_SET_PROC_COEF, 0x2800 },
5019			{}
5020		},
5021		.chained = true,
5022		.chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK,
5023	},
5024	[ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = {
5025		.type = HDA_FIXUP_FUNC,
5026		.v.func = alc269_fixup_limit_int_mic_boost,
5027		.chained = true,
5028		.chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1,
5029	},
5030	[ALC269VB_FIXUP_ORDISSIMO_EVE2] = {
5031		.type = HDA_FIXUP_PINS,
5032		.v.pins = (const struct hda_pintbl[]) {
5033			{ 0x12, 0x99a3092f }, /* int-mic */
5034			{ 0x18, 0x03a11d20 }, /* mic */
5035			{ 0x19, 0x411111f0 }, /* Unused bogus pin */
5036			{ }
5037		},
5038	},
5039	[ALC283_FIXUP_CHROME_BOOK] = {
5040		.type = HDA_FIXUP_FUNC,
5041		.v.func = alc283_fixup_chromebook,
5042	},
5043	[ALC283_FIXUP_SENSE_COMBO_JACK] = {
5044		.type = HDA_FIXUP_FUNC,
5045		.v.func = alc283_fixup_sense_combo_jack,
5046		.chained = true,
5047		.chain_id = ALC283_FIXUP_CHROME_BOOK,
5048	},
5049	[ALC282_FIXUP_ASUS_TX300] = {
5050		.type = HDA_FIXUP_FUNC,
5051		.v.func = alc282_fixup_asus_tx300,
5052	},
5053	[ALC283_FIXUP_INT_MIC] = {
5054		.type = HDA_FIXUP_VERBS,
5055		.v.verbs = (const struct hda_verb[]) {
5056			{0x20, AC_VERB_SET_COEF_INDEX, 0x1a},
5057			{0x20, AC_VERB_SET_PROC_COEF, 0x0011},
5058			{ }
5059		},
5060		.chained = true,
5061		.chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
5062	},
5063	[ALC290_FIXUP_SUBWOOFER_HSJACK] = {
5064		.type = HDA_FIXUP_PINS,
5065		.v.pins = (const struct hda_pintbl[]) {
5066			{ 0x17, 0x90170112 }, /* subwoofer */
5067			{ }
5068		},
5069		.chained = true,
5070		.chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
5071	},
5072	[ALC290_FIXUP_SUBWOOFER] = {
5073		.type = HDA_FIXUP_PINS,
5074		.v.pins = (const struct hda_pintbl[]) {
5075			{ 0x17, 0x90170112 }, /* subwoofer */
5076			{ }
5077		},
5078		.chained = true,
5079		.chain_id = ALC290_FIXUP_MONO_SPEAKERS,
5080	},
5081	[ALC290_FIXUP_MONO_SPEAKERS] = {
5082		.type = HDA_FIXUP_FUNC,
5083		.v.func = alc290_fixup_mono_speakers,
5084	},
5085	[ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = {
5086		.type = HDA_FIXUP_FUNC,
5087		.v.func = alc290_fixup_mono_speakers,
5088		.chained = true,
5089		.chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
5090	},
5091	[ALC269_FIXUP_THINKPAD_ACPI] = {
5092		.type = HDA_FIXUP_FUNC,
5093		.v.func = hda_fixup_thinkpad_acpi,
5094	},
5095	[ALC269_FIXUP_DMIC_THINKPAD_ACPI] = {
5096		.type = HDA_FIXUP_FUNC,
5097		.v.func = alc_fixup_inv_dmic,
5098		.chained = true,
5099		.chain_id = ALC269_FIXUP_THINKPAD_ACPI,
5100	},
5101	[ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5102		.type = HDA_FIXUP_PINS,
5103		.v.pins = (const struct hda_pintbl[]) {
5104			{ 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5105			{ 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5106			{ }
5107		},
5108		.chained = true,
5109		.chain_id = ALC255_FIXUP_HEADSET_MODE
5110	},
5111	[ALC255_FIXUP_DELL2_MIC_NO_PRESENCE] = {
5112		.type = HDA_FIXUP_PINS,
5113		.v.pins = (const struct hda_pintbl[]) {
5114			{ 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5115			{ }
5116		},
5117		.chained = true,
5118		.chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
5119	},
5120	[ALC255_FIXUP_HEADSET_MODE] = {
5121		.type = HDA_FIXUP_FUNC,
5122		.v.func = alc_fixup_headset_mode_alc255,
5123		.chained = true,
5124		.chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
5125	},
5126	[ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
5127		.type = HDA_FIXUP_FUNC,
5128		.v.func = alc_fixup_headset_mode_alc255_no_hp_mic,
5129	},
5130	[ALC293_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5131		.type = HDA_FIXUP_PINS,
5132		.v.pins = (const struct hda_pintbl[]) {
5133			{ 0x18, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5134			{ 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5135			{ }
5136		},
5137		.chained = true,
5138		.chain_id = ALC269_FIXUP_HEADSET_MODE
5139	},
5140	[ALC292_FIXUP_TPT440_DOCK] = {
5141		.type = HDA_FIXUP_FUNC,
5142		.v.func = alc_fixup_tpt440_dock,
5143		.chained = true,
5144		.chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
5145	},
5146	[ALC292_FIXUP_TPT440] = {
5147		.type = HDA_FIXUP_FUNC,
5148		.v.func = alc_fixup_disable_aamix,
5149		.chained = true,
5150		.chain_id = ALC292_FIXUP_TPT440_DOCK,
5151	},
5152	[ALC283_FIXUP_BXBT2807_MIC] = {
5153		.type = HDA_FIXUP_PINS,
5154		.v.pins = (const struct hda_pintbl[]) {
5155			{ 0x19, 0x04a110f0 },
5156			{ },
5157		},
5158	},
5159	[ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED] = {
5160		.type = HDA_FIXUP_FUNC,
5161		.v.func = alc_fixup_dell_wmi,
5162	},
5163	[ALC282_FIXUP_ASPIRE_V5_PINS] = {
5164		.type = HDA_FIXUP_PINS,
5165		.v.pins = (const struct hda_pintbl[]) {
5166			{ 0x12, 0x90a60130 },
5167			{ 0x14, 0x90170110 },
5168			{ 0x17, 0x40000008 },
5169			{ 0x18, 0x411111f0 },
5170			{ 0x19, 0x01a1913c },
5171			{ 0x1a, 0x411111f0 },
5172			{ 0x1b, 0x411111f0 },
5173			{ 0x1d, 0x40f89b2d },
5174			{ 0x1e, 0x411111f0 },
5175			{ 0x21, 0x0321101f },
5176			{ },
5177		},
5178	},
5179	[ALC280_FIXUP_HP_GPIO4] = {
5180		.type = HDA_FIXUP_FUNC,
5181		.v.func = alc280_fixup_hp_gpio4,
5182	},
5183	[ALC286_FIXUP_HP_GPIO_LED] = {
5184		.type = HDA_FIXUP_FUNC,
5185		.v.func = alc286_fixup_hp_gpio_led,
5186	},
5187	[ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY] = {
5188		.type = HDA_FIXUP_FUNC,
5189		.v.func = alc280_fixup_hp_gpio2_mic_hotkey,
5190	},
5191	[ALC280_FIXUP_HP_DOCK_PINS] = {
5192		.type = HDA_FIXUP_PINS,
5193		.v.pins = (const struct hda_pintbl[]) {
5194			{ 0x1b, 0x21011020 }, /* line-out */
5195			{ 0x1a, 0x01a1903c }, /* headset mic */
5196			{ 0x18, 0x2181103f }, /* line-in */
5197			{ },
5198		},
5199		.chained = true,
5200		.chain_id = ALC280_FIXUP_HP_GPIO4
5201	},
5202	[ALC288_FIXUP_DELL_HEADSET_MODE] = {
5203		.type = HDA_FIXUP_FUNC,
5204		.v.func = alc_fixup_headset_mode_dell_alc288,
5205		.chained = true,
5206		.chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
5207	},
5208	[ALC288_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5209		.type = HDA_FIXUP_PINS,
5210		.v.pins = (const struct hda_pintbl[]) {
5211			{ 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5212			{ 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5213			{ }
5214		},
5215		.chained = true,
5216		.chain_id = ALC288_FIXUP_DELL_HEADSET_MODE
5217	},
5218	[ALC288_FIXUP_DELL_XPS_13_GPIO6] = {
5219		.type = HDA_FIXUP_VERBS,
5220		.v.verbs = (const struct hda_verb[]) {
5221			{0x01, AC_VERB_SET_GPIO_MASK, 0x40},
5222			{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x40},
5223			{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5224			{ }
5225		},
5226		.chained = true,
5227		.chain_id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE
5228	},
5229	[ALC288_FIXUP_DISABLE_AAMIX] = {
5230		.type = HDA_FIXUP_FUNC,
5231		.v.func = alc_fixup_disable_aamix,
5232		.chained = true,
5233		.chain_id = ALC288_FIXUP_DELL_XPS_13_GPIO6
5234	},
5235	[ALC288_FIXUP_DELL_XPS_13] = {
5236		.type = HDA_FIXUP_FUNC,
5237		.v.func = alc_fixup_dell_xps13,
5238		.chained = true,
5239		.chain_id = ALC288_FIXUP_DISABLE_AAMIX
5240	},
5241	[ALC292_FIXUP_DISABLE_AAMIX] = {
5242		.type = HDA_FIXUP_FUNC,
5243		.v.func = alc_fixup_disable_aamix,
5244		.chained = true,
5245		.chain_id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE
5246	},
5247	[ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK] = {
5248		.type = HDA_FIXUP_FUNC,
5249		.v.func = alc_fixup_disable_aamix,
5250		.chained = true,
5251		.chain_id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE
5252	},
5253	[ALC292_FIXUP_DELL_E7X] = {
5254		.type = HDA_FIXUP_FUNC,
5255		.v.func = alc_fixup_dell_xps13,
5256		.chained = true,
5257		.chain_id = ALC292_FIXUP_DISABLE_AAMIX
5258	},
5259	[ALC298_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5260		.type = HDA_FIXUP_PINS,
5261		.v.pins = (const struct hda_pintbl[]) {
5262			{ 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5263			{ 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5264			{ }
5265		},
5266		.chained = true,
5267		.chain_id = ALC269_FIXUP_HEADSET_MODE
5268	},
5269	[ALC275_FIXUP_DELL_XPS] = {
5270		.type = HDA_FIXUP_VERBS,
5271		.v.verbs = (const struct hda_verb[]) {
5272			/* Enables internal speaker */
5273			{0x20, AC_VERB_SET_COEF_INDEX, 0x1f},
5274			{0x20, AC_VERB_SET_PROC_COEF, 0x00c0},
5275			{0x20, AC_VERB_SET_COEF_INDEX, 0x30},
5276			{0x20, AC_VERB_SET_PROC_COEF, 0x00b1},
5277			{}
5278		}
5279	},
5280	[ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE] = {
5281		.type = HDA_FIXUP_VERBS,
5282		.v.verbs = (const struct hda_verb[]) {
5283			/* Disable pass-through path for FRONT 14h */
5284			{0x20, AC_VERB_SET_COEF_INDEX, 0x36},
5285			{0x20, AC_VERB_SET_PROC_COEF, 0x1737},
5286			{}
5287		},
5288		.chained = true,
5289		.chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
5290	},
5291	[ALC293_FIXUP_LENOVO_SPK_NOISE] = {
5292		.type = HDA_FIXUP_FUNC,
5293		.v.func = alc_fixup_disable_aamix,
5294		.chained = true,
5295		.chain_id = ALC269_FIXUP_THINKPAD_ACPI
5296	},
5297	[ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY] = {
5298		.type = HDA_FIXUP_FUNC,
5299		.v.func = alc233_fixup_lenovo_line2_mic_hotkey,
5300	},
5301	[ALC255_FIXUP_DELL_SPK_NOISE] = {
5302		.type = HDA_FIXUP_FUNC,
5303		.v.func = alc_fixup_disable_aamix,
5304		.chained = true,
5305		.chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
5306	},
5307	[ALC225_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5308		.type = HDA_FIXUP_VERBS,
5309		.v.verbs = (const struct hda_verb[]) {
5310			/* Disable pass-through path for FRONT 14h */
5311			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
5312			{ 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
5313			{}
5314		},
5315		.chained = true,
5316		.chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
5317	},
5318	[ALC280_FIXUP_HP_HEADSET_MIC] = {
5319		.type = HDA_FIXUP_FUNC,
5320		.v.func = alc_fixup_disable_aamix,
5321		.chained = true,
5322		.chain_id = ALC269_FIXUP_HEADSET_MIC,
5323	},
5324	[ALC221_FIXUP_HP_FRONT_MIC] = {
5325		.type = HDA_FIXUP_PINS,
5326		.v.pins = (const struct hda_pintbl[]) {
5327			{ 0x19, 0x02a19020 }, /* Front Mic */
5328			{ }
5329		},
5330	},
5331	[ALC292_FIXUP_TPT460] = {
5332		.type = HDA_FIXUP_FUNC,
5333		.v.func = alc_fixup_tpt440_dock,
5334		.chained = true,
5335		.chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE,
5336	},
5337};
5338
5339static const struct snd_pci_quirk alc269_fixup_tbl[] = {
5340	SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC),
5341	SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
5342	SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
5343	SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
5344	SND_PCI_QUIRK(0x1025, 0x072d, "Acer Aspire V5-571G", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
5345	SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
5346	SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
5347	SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
5348	SND_PCI_QUIRK(0x1025, 0x0762, "Acer Aspire E1-472", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
5349	SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
5350	SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
5351	SND_PCI_QUIRK(0x1025, 0x106d, "Acer Cloudbook 14", ALC283_FIXUP_CHROME_BOOK),
5352	SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
5353	SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS),
5354	SND_PCI_QUIRK(0x1028, 0x05bd, "Dell Latitude E6440", ALC292_FIXUP_DELL_E7X),
5355	SND_PCI_QUIRK(0x1028, 0x05be, "Dell Latitude E6540", ALC292_FIXUP_DELL_E7X),
5356	SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X),
5357	SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X),
5358	SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
5359	SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
5360	SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
5361	SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
5362	SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
5363	SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
5364	SND_PCI_QUIRK(0x1028, 0x062c, "Dell Latitude E5550", ALC292_FIXUP_DELL_E7X),
5365	SND_PCI_QUIRK(0x1028, 0x062e, "Dell Latitude E7450", ALC292_FIXUP_DELL_E7X),
5366	SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK),
5367	SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5368	SND_PCI_QUIRK(0x1028, 0x064b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5369	SND_PCI_QUIRK(0x1028, 0x0665, "Dell XPS 13", ALC288_FIXUP_DELL_XPS_13),
5370	SND_PCI_QUIRK(0x1028, 0x0669, "Dell Optiplex 9020m", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
5371	SND_PCI_QUIRK(0x1028, 0x069a, "Dell Vostro 5480", ALC290_FIXUP_SUBWOOFER_HSJACK),
5372	SND_PCI_QUIRK(0x1028, 0x06c7, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
5373	SND_PCI_QUIRK(0x1028, 0x06d9, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5374	SND_PCI_QUIRK(0x1028, 0x06da, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5375	SND_PCI_QUIRK(0x1028, 0x06db, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
5376	SND_PCI_QUIRK(0x1028, 0x06dd, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
5377	SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
5378	SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
5379	SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
5380	SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13 9350", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
5381	SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE),
5382	SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
5383	SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5384	SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5385	SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
5386	SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
5387	SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
5388	SND_PCI_QUIRK(0x103c, 0x225f, "HP", ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY),
5389	/* ALC282 */
5390	SND_PCI_QUIRK(0x103c, 0x21f9, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5391	SND_PCI_QUIRK(0x103c, 0x2210, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5392	SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5393	SND_PCI_QUIRK(0x103c, 0x2236, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
5394	SND_PCI_QUIRK(0x103c, 0x2237, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
5395	SND_PCI_QUIRK(0x103c, 0x2238, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
5396	SND_PCI_QUIRK(0x103c, 0x2239, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
5397	SND_PCI_QUIRK(0x103c, 0x224b, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
5398	SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5399	SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5400	SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5401	SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5402	SND_PCI_QUIRK(0x103c, 0x2271, "HP", ALC286_FIXUP_HP_GPIO_LED),
5403	SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC280_FIXUP_HP_DOCK_PINS),
5404	SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC280_FIXUP_HP_DOCK_PINS),
5405	SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5406	SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5407	SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5408	SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5409	SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5410	SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5411	SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5412	/* ALC290 */
5413	SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5414	SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5415	SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5416	SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5417	SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5418	SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5419	SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5420	SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5421	SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5422	SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5423	SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5424	SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5425	SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5426	SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5427	SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5428	SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5429	SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5430	SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5431	SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5432	SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5433	SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5434	SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5435	SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5436	SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5437	SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5438	SND_PCI_QUIRK(0x103c, 0x2334, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5439	SND_PCI_QUIRK(0x103c, 0x2335, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5440	SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5441	SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5442	SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC),
5443	SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC),
5444	SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
5445	SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5446	SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5447	SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
5448	SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
5449	SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
5450	SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
5451	SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
5452	SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5453	SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
5454	SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
5455	SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
5456	SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
5457	SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101),
5458	SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
5459	SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
5460	SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
5461	SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
5462	SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
5463	SND_PCI_QUIRK(0x104d, 0x9099, "Sony VAIO S13", ALC275_FIXUP_SONY_DISABLE_AAMIX),
5464	SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
5465	SND_PCI_QUIRK(0x10cf, 0x159f, "Lifebook E780", ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT),
5466	SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN),
5467	SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN),
5468	SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
5469	SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC),
5470	SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_BXBT2807_MIC),
5471	SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
5472	SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
5473	SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
5474	SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
5475	SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
5476	SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK),
5477	SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
5478	SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
5479	SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
5480	SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
5481	SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
5482	SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad T440s", ALC292_FIXUP_TPT440),
5483	SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK),
5484	SND_PCI_QUIRK(0x17aa, 0x2210, "Thinkpad T540p", ALC292_FIXUP_TPT440_DOCK),
5485	SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK),
5486	SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad X240", ALC292_FIXUP_TPT440_DOCK),
5487	SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5488	SND_PCI_QUIRK(0x17aa, 0x2218, "Thinkpad X1 Carbon 2nd", ALC292_FIXUP_TPT440_DOCK),
5489	SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
5490	SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
5491	SND_PCI_QUIRK(0x17aa, 0x2231, "Thinkpad T560", ALC292_FIXUP_TPT460),
5492	SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC292_FIXUP_TPT460),
5493	SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
5494	SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
5495	SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
5496	SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
5497	SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
5498	SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5499	SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC),
5500	SND_PCI_QUIRK(0x17aa, 0x501e, "Thinkpad L440", ALC292_FIXUP_TPT440_DOCK),
5501	SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5502	SND_PCI_QUIRK(0x17aa, 0x5034, "Thinkpad T450", ALC292_FIXUP_TPT440_DOCK),
5503	SND_PCI_QUIRK(0x17aa, 0x5036, "Thinkpad T450s", ALC292_FIXUP_TPT440_DOCK),
5504	SND_PCI_QUIRK(0x17aa, 0x503c, "Thinkpad L450", ALC292_FIXUP_TPT440_DOCK),
5505	SND_PCI_QUIRK(0x17aa, 0x504a, "ThinkPad X260", ALC292_FIXUP_TPT440_DOCK),
5506	SND_PCI_QUIRK(0x17aa, 0x504b, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
5507	SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5508	SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
5509	SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
5510	SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
5511
5512#if 0
5513	/* Below is a quirk table taken from the old code.
5514	 * Basically the device should work as is without the fixup table.
5515	 * If BIOS doesn't give a proper info, enable the corresponding
5516	 * fixup entry.
5517	 */
5518	SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
5519		      ALC269_FIXUP_AMIC),
5520	SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
5521	SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
5522	SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
5523	SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
5524	SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC),
5525	SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC),
5526	SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC),
5527	SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC),
5528	SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC),
5529	SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC),
5530	SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC),
5531	SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC),
5532	SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC),
5533	SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC),
5534	SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC),
5535	SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC),
5536	SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC),
5537	SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC),
5538	SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC),
5539	SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC),
5540	SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC),
5541	SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC),
5542	SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC),
5543	SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC),
5544	SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC),
5545	SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC),
5546	SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC),
5547	SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC),
5548	SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC),
5549	SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC),
5550	SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC),
5551	SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC),
5552	SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC),
5553	SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC),
5554	SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC),
5555	SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC),
5556	SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC),
5557	SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC),
5558	SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC),
5559#endif
5560	{}
5561};
5562
5563static const struct snd_pci_quirk alc269_fixup_vendor_tbl[] = {
5564	SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
5565	SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
5566	SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
5567	SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI),
5568	{}
5569};
5570
5571static const struct hda_model_fixup alc269_fixup_models[] = {
5572	{.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
5573	{.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
5574	{.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"},
5575	{.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"},
5576	{.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"},
5577	{.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"},
5578	{.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
5579	{.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
5580	{.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
5581	{.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"},
5582	{.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"},
5583	{.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
5584	{.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"},
5585	{.id = ALC292_FIXUP_TPT440, .name = "tpt440"},
5586	{.id = ALC292_FIXUP_TPT460, .name = "tpt460"},
5587	{}
5588};
5589#define ALC225_STANDARD_PINS \
5590	{0x12, 0xb7a60130}, \
5591	{0x21, 0x04211020}
5592
5593#define ALC255_STANDARD_PINS \
5594	{0x18, 0x411111f0}, \
5595	{0x19, 0x411111f0}, \
5596	{0x1a, 0x411111f0}, \
5597	{0x1b, 0x411111f0}, \
5598	{0x1e, 0x411111f0}
5599
5600#define ALC256_STANDARD_PINS \
5601	{0x12, 0x90a60140}, \
5602	{0x14, 0x90170110}, \
5603	{0x19, 0x411111f0}, \
5604	{0x1a, 0x411111f0}, \
5605	{0x1b, 0x411111f0}, \
5606	{0x1d, 0x40700001}, \
5607	{0x1e, 0x411111f0}, \
5608	{0x21, 0x02211020}
5609
5610#define ALC282_STANDARD_PINS \
5611	{0x14, 0x90170110}, \
5612	{0x18, 0x411111f0}, \
5613	{0x1a, 0x411111f0}, \
5614	{0x1b, 0x411111f0}, \
5615	{0x1e, 0x411111f0}
5616
5617#define ALC288_STANDARD_PINS \
5618	{0x17, 0x411111f0}, \
5619	{0x18, 0x411111f0}, \
5620	{0x19, 0x411111f0}, \
5621	{0x1a, 0x411111f0}, \
5622	{0x1e, 0x411111f0}
5623
5624#define ALC290_STANDARD_PINS \
5625	{0x12, 0x99a30130}, \
5626	{0x13, 0x40000000}, \
5627	{0x16, 0x411111f0}, \
5628	{0x17, 0x411111f0}, \
5629	{0x19, 0x411111f0}, \
5630	{0x1b, 0x411111f0}, \
5631	{0x1e, 0x411111f0}
5632
5633#define ALC292_STANDARD_PINS \
5634	{0x14, 0x90170110}, \
5635	{0x15, 0x0221401f}, \
5636	{0x1a, 0x411111f0}, \
5637	{0x1b, 0x411111f0}, \
5638	{0x1d, 0x40700001}, \
5639	{0x1e, 0x411111f0}
5640
5641#define ALC298_STANDARD_PINS \
5642	{0x18, 0x411111f0}, \
5643	{0x19, 0x411111f0}, \
5644	{0x1a, 0x411111f0}, \
5645	{0x1e, 0x411111f0}, \
5646	{0x1f, 0x411111f0}
5647
5648static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
5649	SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
5650		ALC225_STANDARD_PINS,
5651		{0x14, 0x901701a0}),
5652	SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
5653		ALC225_STANDARD_PINS,
5654		{0x14, 0x901701b0}),
5655	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
5656		ALC255_STANDARD_PINS,
5657		{0x12, 0x40300000},
5658		{0x14, 0x90170110},
5659		{0x17, 0x411111f0},
5660		{0x1d, 0x40538029},
5661		{0x21, 0x02211020}),
5662	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5663		ALC255_STANDARD_PINS,
5664		{0x12, 0x90a60140},
5665		{0x14, 0x90170110},
5666		{0x17, 0x40000000},
5667		{0x1d, 0x40700001},
5668		{0x21, 0x02211020}),
5669	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5670		ALC255_STANDARD_PINS,
5671		{0x12, 0x90a60160},
5672		{0x14, 0x90170120},
5673		{0x17, 0x40000000},
5674		{0x1d, 0x40700001},
5675		{0x21, 0x02211030}),
5676	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5677		{0x12, 0x40000000},
5678		{0x14, 0x90170130},
5679		{0x17, 0x411111f0},
5680		{0x18, 0x411111f0},
5681		{0x19, 0x411111f0},
5682		{0x1a, 0x411111f0},
5683		{0x1b, 0x01014020},
5684		{0x1d, 0x4054c029},
5685		{0x1e, 0x411111f0},
5686		{0x21, 0x0221103f}),
5687	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5688		{0x12, 0x90a60160},
5689		{0x14, 0x90170120},
5690		{0x17, 0x90170140},
5691		{0x18, 0x40000000},
5692		{0x19, 0x411111f0},
5693		{0x1a, 0x411111f0},
5694		{0x1b, 0x411111f0},
5695		{0x1d, 0x41163b05},
5696		{0x1e, 0x411111f0},
5697		{0x21, 0x0321102f}),
5698	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5699		ALC255_STANDARD_PINS,
5700		{0x12, 0x90a60160},
5701		{0x14, 0x90170130},
5702		{0x17, 0x40000000},
5703		{0x1d, 0x40700001},
5704		{0x21, 0x02211040}),
5705	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5706		ALC255_STANDARD_PINS,
5707		{0x12, 0x90a60160},
5708		{0x14, 0x90170140},
5709		{0x17, 0x40000000},
5710		{0x1d, 0x40700001},
5711		{0x21, 0x02211050}),
5712	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5713		ALC255_STANDARD_PINS,
5714		{0x12, 0x90a60170},
5715		{0x14, 0x90170120},
5716		{0x17, 0x40000000},
5717		{0x1d, 0x40700001},
5718		{0x21, 0x02211030}),
5719	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5720		ALC255_STANDARD_PINS,
5721		{0x12, 0x90a60170},
5722		{0x14, 0x90170130},
5723		{0x17, 0x40000000},
5724		{0x1d, 0x40700001},
5725		{0x21, 0x02211040}),
5726	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5727		ALC255_STANDARD_PINS,
5728		{0x12, 0x90a60170},
5729		{0x14, 0x90171130},
5730		{0x21, 0x02211040}),
5731	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5732		{0x12, 0x90a60170},
5733		{0x14, 0x90170140},
5734		{0x17, 0x40000000},
5735		{0x1d, 0x40700001},
5736		{0x21, 0x02211050}),
5737	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5548", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5738		ALC255_STANDARD_PINS,
5739		{0x12, 0x90a60180},
5740		{0x14, 0x90170130},
5741		{0x17, 0x40000000},
5742		{0x1d, 0x40700001},
5743		{0x21, 0x02211040}),
5744	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5565", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5745		{0x12, 0x90a60180},
5746		{0x14, 0x90170120},
5747		{0x21, 0x02211030}),
5748	SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5749		ALC255_STANDARD_PINS,
5750		{0x12, 0x90a60160},
5751		{0x14, 0x90170120},
5752		{0x17, 0x40000000},
5753		{0x1d, 0x40700001},
5754		{0x21, 0x02211030}),
5755	SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5756		ALC256_STANDARD_PINS,
5757		{0x13, 0x40000000}),
5758	SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5759		ALC256_STANDARD_PINS,
5760		{0x13, 0x411111f0}),
5761	SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
5762		{0x12, 0x90a60130},
5763		{0x13, 0x40000000},
5764		{0x14, 0x90170110},
5765		{0x15, 0x0421101f},
5766		{0x16, 0x411111f0},
5767		{0x17, 0x411111f0},
5768		{0x18, 0x411111f0},
5769		{0x19, 0x411111f0},
5770		{0x1a, 0x04a11020},
5771		{0x1b, 0x411111f0},
5772		{0x1d, 0x40748605},
5773		{0x1e, 0x411111f0}),
5774	SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED,
5775		{0x12, 0x90a60140},
5776		{0x13, 0x40000000},
5777		{0x14, 0x90170110},
5778		{0x15, 0x0421101f},
5779		{0x16, 0x411111f0},
5780		{0x17, 0x411111f0},
5781		{0x18, 0x02811030},
5782		{0x19, 0x411111f0},
5783		{0x1a, 0x04a1103f},
5784		{0x1b, 0x02011020},
5785		{0x1d, 0x40700001},
5786		{0x1e, 0x411111f0}),
5787	SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP 15 Touchsmart", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5788		ALC282_STANDARD_PINS,
5789		{0x12, 0x99a30130},
5790		{0x17, 0x40000000},
5791		{0x19, 0x03a11020},
5792		{0x1d, 0x40f41905},
5793		{0x21, 0x0321101f}),
5794	SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5795		ALC282_STANDARD_PINS,
5796		{0x12, 0x99a30130},
5797		{0x17, 0x40020008},
5798		{0x19, 0x03a11020},
5799		{0x1d, 0x40e00001},
5800		{0x21, 0x03211040}),
5801	SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5802		ALC282_STANDARD_PINS,
5803		{0x12, 0x99a30130},
5804		{0x17, 0x40000000},
5805		{0x19, 0x03a11030},
5806		{0x1d, 0x40e00001},
5807		{0x21, 0x03211020}),
5808	SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5809		ALC282_STANDARD_PINS,
5810		{0x12, 0x99a30130},
5811		{0x17, 0x40000000},
5812		{0x19, 0x03a11030},
5813		{0x1d, 0x40f00001},
5814		{0x21, 0x03211020}),
5815	SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5816		ALC282_STANDARD_PINS,
5817		{0x12, 0x99a30130},
5818		{0x17, 0x40000000},
5819		{0x19, 0x04a11020},
5820		{0x1d, 0x40f00001},
5821		{0x21, 0x0421101f}),
5822	SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5823		ALC282_STANDARD_PINS,
5824		{0x12, 0x99a30130},
5825		{0x17, 0x40000000},
5826		{0x19, 0x03a11030},
5827		{0x1d, 0x40f00001},
5828		{0x21, 0x04211020}),
5829	SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED,
5830		ALC282_STANDARD_PINS,
5831		{0x12, 0x90a60140},
5832		{0x17, 0x40000000},
5833		{0x19, 0x04a11030},
5834		{0x1d, 0x40f00001},
5835		{0x21, 0x04211020}),
5836	SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
5837		ALC282_STANDARD_PINS,
5838		{0x12, 0x90a60130},
5839		{0x17, 0x40020008},
5840		{0x19, 0x411111f0},
5841		{0x1d, 0x40e00001},
5842		{0x21, 0x0321101f}),
5843	SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
5844		{0x12, 0x90a60160},
5845		{0x14, 0x90170120},
5846		{0x17, 0x40000000},
5847		{0x18, 0x411111f0},
5848		{0x19, 0x411111f0},
5849		{0x1a, 0x411111f0},
5850		{0x1b, 0x411111f0},
5851		{0x1d, 0x40700001},
5852		{0x1e, 0x411111f0},
5853		{0x21, 0x02211030}),
5854	SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
5855		ALC282_STANDARD_PINS,
5856		{0x12, 0x90a60130},
5857		{0x17, 0x40020008},
5858		{0x19, 0x03a11020},
5859		{0x1d, 0x40e00001},
5860		{0x21, 0x0321101f}),
5861	SND_HDA_PIN_QUIRK(0x10ec0288, 0x1028, "Dell", ALC288_FIXUP_DELL_XPS_13_GPIO6,
5862		ALC288_STANDARD_PINS,
5863		{0x12, 0x90a60120},
5864		{0x13, 0x40000000},
5865		{0x14, 0x90170110},
5866		{0x1d, 0x4076832d},
5867		{0x21, 0x0321101f}),
5868	SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5869		ALC290_STANDARD_PINS,
5870		{0x14, 0x411111f0},
5871		{0x15, 0x04211040},
5872		{0x18, 0x90170112},
5873		{0x1a, 0x04a11020},
5874		{0x1d, 0x4075812d}),
5875	SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5876		ALC290_STANDARD_PINS,
5877		{0x14, 0x411111f0},
5878		{0x15, 0x04211040},
5879		{0x18, 0x90170110},
5880		{0x1a, 0x04a11020},
5881		{0x1d, 0x4075812d}),
5882	SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5883		ALC290_STANDARD_PINS,
5884		{0x14, 0x411111f0},
5885		{0x15, 0x0421101f},
5886		{0x18, 0x411111f0},
5887		{0x1a, 0x04a11020},
5888		{0x1d, 0x4075812d}),
5889	SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5890		ALC290_STANDARD_PINS,
5891		{0x14, 0x411111f0},
5892		{0x15, 0x04211020},
5893		{0x18, 0x411111f0},
5894		{0x1a, 0x04a11040},
5895		{0x1d, 0x4076a12d}),
5896	SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5897		ALC290_STANDARD_PINS,
5898		{0x14, 0x90170110},
5899		{0x15, 0x04211020},
5900		{0x18, 0x411111f0},
5901		{0x1a, 0x04a11040},
5902		{0x1d, 0x4076a12d}),
5903	SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5904		ALC290_STANDARD_PINS,
5905		{0x14, 0x90170110},
5906		{0x15, 0x04211020},
5907		{0x18, 0x411111f0},
5908		{0x1a, 0x04a11020},
5909		{0x1d, 0x4076a12d}),
5910	SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5911		ALC290_STANDARD_PINS,
5912		{0x14, 0x90170110},
5913		{0x15, 0x0421101f},
5914		{0x18, 0x411111f0},
5915		{0x1a, 0x04a11020},
5916		{0x1d, 0x4075812d}),
5917	SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
5918		ALC292_STANDARD_PINS,
5919		{0x12, 0x90a60140},
5920		{0x13, 0x411111f0},
5921		{0x16, 0x01014020},
5922		{0x18, 0x411111f0},
5923		{0x19, 0x01a19030}),
5924	SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
5925		ALC292_STANDARD_PINS,
5926		{0x12, 0x90a60140},
5927		{0x13, 0x411111f0},
5928		{0x16, 0x01014020},
5929		{0x18, 0x02a19031},
5930		{0x19, 0x01a1903e}),
5931	SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
5932		ALC292_STANDARD_PINS,
5933		{0x12, 0x90a60140},
5934		{0x13, 0x411111f0},
5935		{0x16, 0x411111f0},
5936		{0x18, 0x411111f0},
5937		{0x19, 0x411111f0}),
5938	SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
5939		ALC292_STANDARD_PINS,
5940		{0x12, 0x40000000},
5941		{0x13, 0x90a60140},
5942		{0x16, 0x21014020},
5943		{0x18, 0x411111f0},
5944		{0x19, 0x21a19030}),
5945	SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
5946		ALC292_STANDARD_PINS,
5947		{0x12, 0x40000000},
5948		{0x13, 0x90a60140},
5949		{0x16, 0x411111f0},
5950		{0x18, 0x411111f0},
5951		{0x19, 0x411111f0}),
5952	SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
5953		ALC298_STANDARD_PINS,
5954		{0x12, 0x90a60130},
5955		{0x13, 0x40000000},
5956		{0x14, 0x411111f0},
5957		{0x17, 0x90170140},
5958		{0x1d, 0x4068a36d},
5959		{0x21, 0x03211020}),
5960	{}
5961};
5962
5963static void alc269_fill_coef(struct hda_codec *codec)
5964{
5965	struct alc_spec *spec = codec->spec;
5966	int val;
5967
5968	if (spec->codec_variant != ALC269_TYPE_ALC269VB)
5969		return;
5970
5971	if ((alc_get_coef0(codec) & 0x00ff) < 0x015) {
5972		alc_write_coef_idx(codec, 0xf, 0x960b);
5973		alc_write_coef_idx(codec, 0xe, 0x8817);
5974	}
5975
5976	if ((alc_get_coef0(codec) & 0x00ff) == 0x016) {
5977		alc_write_coef_idx(codec, 0xf, 0x960b);
5978		alc_write_coef_idx(codec, 0xe, 0x8814);
5979	}
5980
5981	if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
5982		/* Power up output pin */
5983		alc_update_coef_idx(codec, 0x04, 0, 1<<11);
5984	}
5985
5986	if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
5987		val = alc_read_coef_idx(codec, 0xd);
5988		if (val != -1 && (val & 0x0c00) >> 10 != 0x1) {
5989			/* Capless ramp up clock control */
5990			alc_write_coef_idx(codec, 0xd, val | (1<<10));
5991		}
5992		val = alc_read_coef_idx(codec, 0x17);
5993		if (val != -1 && (val & 0x01c0) >> 6 != 0x4) {
5994			/* Class D power on reset */
5995			alc_write_coef_idx(codec, 0x17, val | (1<<7));
5996		}
5997	}
5998
5999	/* HP */
6000	alc_update_coef_idx(codec, 0x4, 0, 1<<11);
6001}
6002
6003/*
6004 */
6005static int patch_alc269(struct hda_codec *codec)
6006{
6007	struct alc_spec *spec;
6008	int err;
6009
6010	err = alc_alloc_spec(codec, 0x0b);
6011	if (err < 0)
6012		return err;
6013
6014	spec = codec->spec;
6015	spec->gen.shared_mic_vref_pin = 0x18;
6016	codec->power_save_node = 1;
6017
6018	snd_hda_pick_fixup(codec, alc269_fixup_models,
6019		       alc269_fixup_tbl, alc269_fixups);
6020	snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups);
6021	snd_hda_pick_fixup(codec, NULL,	alc269_fixup_vendor_tbl,
6022			   alc269_fixups);
6023	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
6024
6025	alc_auto_parse_customize_define(codec);
6026
6027	if (has_cdefine_beep(codec))
6028		spec->gen.beep_nid = 0x01;
6029
6030	switch (codec->core.vendor_id) {
6031	case 0x10ec0269:
6032		spec->codec_variant = ALC269_TYPE_ALC269VA;
6033		switch (alc_get_coef0(codec) & 0x00f0) {
6034		case 0x0010:
6035			if (codec->bus->pci &&
6036			    codec->bus->pci->subsystem_vendor == 0x1025 &&
6037			    spec->cdefine.platform_type == 1)
6038				err = alc_codec_rename(codec, "ALC271X");
6039			spec->codec_variant = ALC269_TYPE_ALC269VB;
6040			break;
6041		case 0x0020:
6042			if (codec->bus->pci &&
6043			    codec->bus->pci->subsystem_vendor == 0x17aa &&
6044			    codec->bus->pci->subsystem_device == 0x21f3)
6045				err = alc_codec_rename(codec, "ALC3202");
6046			spec->codec_variant = ALC269_TYPE_ALC269VC;
6047			break;
6048		case 0x0030:
6049			spec->codec_variant = ALC269_TYPE_ALC269VD;
6050			break;
6051		default:
6052			alc_fix_pll_init(codec, 0x20, 0x04, 15);
6053		}
6054		if (err < 0)
6055			goto error;
6056		spec->init_hook = alc269_fill_coef;
6057		alc269_fill_coef(codec);
6058		break;
6059
6060	case 0x10ec0280:
6061	case 0x10ec0290:
6062		spec->codec_variant = ALC269_TYPE_ALC280;
6063		break;
6064	case 0x10ec0282:
6065		spec->codec_variant = ALC269_TYPE_ALC282;
6066		spec->shutup = alc282_shutup;
6067		spec->init_hook = alc282_init;
6068		break;
6069	case 0x10ec0233:
6070	case 0x10ec0283:
6071		spec->codec_variant = ALC269_TYPE_ALC283;
6072		spec->shutup = alc283_shutup;
6073		spec->init_hook = alc283_init;
6074		break;
6075	case 0x10ec0284:
6076	case 0x10ec0292:
6077		spec->codec_variant = ALC269_TYPE_ALC284;
6078		break;
6079	case 0x10ec0285:
6080	case 0x10ec0293:
6081		spec->codec_variant = ALC269_TYPE_ALC285;
6082		break;
6083	case 0x10ec0286:
6084	case 0x10ec0288:
6085		spec->codec_variant = ALC269_TYPE_ALC286;
6086		spec->shutup = alc286_shutup;
6087		break;
6088	case 0x10ec0298:
6089		spec->codec_variant = ALC269_TYPE_ALC298;
6090		break;
6091	case 0x10ec0255:
6092		spec->codec_variant = ALC269_TYPE_ALC255;
6093		break;
6094	case 0x10ec0256:
6095		spec->codec_variant = ALC269_TYPE_ALC256;
6096		spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */
6097		alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/
6098		break;
6099	}
6100
6101	if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
6102		spec->has_alc5505_dsp = 1;
6103		spec->init_hook = alc5505_dsp_init;
6104	}
6105
6106	/* automatic parse from the BIOS config */
6107	err = alc269_parse_auto_config(codec);
6108	if (err < 0)
6109		goto error;
6110
6111	if (!spec->gen.no_analog && spec->gen.beep_nid && spec->gen.mixer_nid)
6112		set_beep_amp(spec, spec->gen.mixer_nid, 0x04, HDA_INPUT);
6113
6114	codec->patch_ops = alc_patch_ops;
6115	codec->patch_ops.stream_pm = snd_hda_gen_stream_pm;
6116#ifdef CONFIG_PM
6117	codec->patch_ops.suspend = alc269_suspend;
6118	codec->patch_ops.resume = alc269_resume;
6119#endif
6120	if (!spec->shutup)
6121		spec->shutup = alc269_shutup;
6122
6123	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
6124
6125	return 0;
6126
6127 error:
6128	alc_free(codec);
6129	return err;
6130}
6131
6132/*
6133 * ALC861
6134 */
6135
6136static int alc861_parse_auto_config(struct hda_codec *codec)
6137{
6138	static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
6139	static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 };
6140	return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
6141}
6142
6143/* Pin config fixes */
6144enum {
6145	ALC861_FIXUP_FSC_AMILO_PI1505,
6146	ALC861_FIXUP_AMP_VREF_0F,
6147	ALC861_FIXUP_NO_JACK_DETECT,
6148	ALC861_FIXUP_ASUS_A6RP,
6149	ALC660_FIXUP_ASUS_W7J,
6150};
6151
6152/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
6153static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
6154			const struct hda_fixup *fix, int action)
6155{
6156	struct alc_spec *spec = codec->spec;
6157	unsigned int val;
6158
6159	if (action != HDA_FIXUP_ACT_INIT)
6160		return;
6161	val = snd_hda_codec_get_pin_target(codec, 0x0f);
6162	if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
6163		val |= AC_PINCTL_IN_EN;
6164	val |= AC_PINCTL_VREF_50;
6165	snd_hda_set_pin_ctl(codec, 0x0f, val);
6166	spec->gen.keep_vref_in_automute = 1;
6167}
6168
6169/* suppress the jack-detection */
6170static void alc_fixup_no_jack_detect(struct hda_codec *codec,
6171				     const struct hda_fixup *fix, int action)
6172{
6173	if (action == HDA_FIXUP_ACT_PRE_PROBE)
6174		codec->no_jack_detect = 1;
6175}
6176
6177static const struct hda_fixup alc861_fixups[] = {
6178	[ALC861_FIXUP_FSC_AMILO_PI1505] = {
6179		.type = HDA_FIXUP_PINS,
6180		.v.pins = (const struct hda_pintbl[]) {
6181			{ 0x0b, 0x0221101f }, /* HP */
6182			{ 0x0f, 0x90170310 }, /* speaker */
6183			{ }
6184		}
6185	},
6186	[ALC861_FIXUP_AMP_VREF_0F] = {
6187		.type = HDA_FIXUP_FUNC,
6188		.v.func = alc861_fixup_asus_amp_vref_0f,
6189	},
6190	[ALC861_FIXUP_NO_JACK_DETECT] = {
6191		.type = HDA_FIXUP_FUNC,
6192		.v.func = alc_fixup_no_jack_detect,
6193	},
6194	[ALC861_FIXUP_ASUS_A6RP] = {
6195		.type = HDA_FIXUP_FUNC,
6196		.v.func = alc861_fixup_asus_amp_vref_0f,
6197		.chained = true,
6198		.chain_id = ALC861_FIXUP_NO_JACK_DETECT,
6199	},
6200	[ALC660_FIXUP_ASUS_W7J] = {
6201		.type = HDA_FIXUP_VERBS,
6202		.v.verbs = (const struct hda_verb[]) {
6203			/* ASUS W7J needs a magic pin setup on unused NID 0x10
6204			 * for enabling outputs
6205			 */
6206			{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6207			{ }
6208		},
6209	}
6210};
6211
6212static const struct snd_pci_quirk alc861_fixup_tbl[] = {
6213	SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J),
6214	SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J),
6215	SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
6216	SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
6217	SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
6218	SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F),
6219	SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F),
6220	SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
6221	{}
6222};
6223
6224/*
6225 */
6226static int patch_alc861(struct hda_codec *codec)
6227{
6228	struct alc_spec *spec;
6229	int err;
6230
6231	err = alc_alloc_spec(codec, 0x15);
6232	if (err < 0)
6233		return err;
6234
6235	spec = codec->spec;
6236	spec->gen.beep_nid = 0x23;
6237
6238	snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
6239	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
6240
6241	/* automatic parse from the BIOS config */
6242	err = alc861_parse_auto_config(codec);
6243	if (err < 0)
6244		goto error;
6245
6246	if (!spec->gen.no_analog)
6247		set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
6248
6249	codec->patch_ops = alc_patch_ops;
6250#ifdef CONFIG_PM
6251	spec->power_hook = alc_power_eapd;
6252#endif
6253
6254	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
6255
6256	return 0;
6257
6258 error:
6259	alc_free(codec);
6260	return err;
6261}
6262
6263/*
6264 * ALC861-VD support
6265 *
6266 * Based on ALC882
6267 *
6268 * In addition, an independent DAC
6269 */
6270static int alc861vd_parse_auto_config(struct hda_codec *codec)
6271{
6272	static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
6273	static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 };
6274	return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids);
6275}
6276
6277enum {
6278	ALC660VD_FIX_ASUS_GPIO1,
6279	ALC861VD_FIX_DALLAS,
6280};
6281
6282/* exclude VREF80 */
6283static void alc861vd_fixup_dallas(struct hda_codec *codec,
6284				  const struct hda_fixup *fix, int action)
6285{
6286	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
6287		snd_hda_override_pin_caps(codec, 0x18, 0x00000734);
6288		snd_hda_override_pin_caps(codec, 0x19, 0x0000073c);
6289	}
6290}
6291
6292static const struct hda_fixup alc861vd_fixups[] = {
6293	[ALC660VD_FIX_ASUS_GPIO1] = {
6294		.type = HDA_FIXUP_VERBS,
6295		.v.verbs = (const struct hda_verb[]) {
6296			/* reset GPIO1 */
6297			{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6298			{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6299			{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6300			{ }
6301		}
6302	},
6303	[ALC861VD_FIX_DALLAS] = {
6304		.type = HDA_FIXUP_FUNC,
6305		.v.func = alc861vd_fixup_dallas,
6306	},
6307};
6308
6309static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
6310	SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS),
6311	SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
6312	SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS),
6313	{}
6314};
6315
6316/*
6317 */
6318static int patch_alc861vd(struct hda_codec *codec)
6319{
6320	struct alc_spec *spec;
6321	int err;
6322
6323	err = alc_alloc_spec(codec, 0x0b);
6324	if (err < 0)
6325		return err;
6326
6327	spec = codec->spec;
6328	spec->gen.beep_nid = 0x23;
6329
6330	snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
6331	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
6332
6333	/* automatic parse from the BIOS config */
6334	err = alc861vd_parse_auto_config(codec);
6335	if (err < 0)
6336		goto error;
6337
6338	if (!spec->gen.no_analog)
6339		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
6340
6341	codec->patch_ops = alc_patch_ops;
6342
6343	spec->shutup = alc_eapd_shutup;
6344
6345	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
6346
6347	return 0;
6348
6349 error:
6350	alc_free(codec);
6351	return err;
6352}
6353
6354/*
6355 * ALC662 support
6356 *
6357 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
6358 * configuration.  Each pin widget can choose any input DACs and a mixer.
6359 * Each ADC is connected from a mixer of all inputs.  This makes possible
6360 * 6-channel independent captures.
6361 *
6362 * In addition, an independent DAC for the multi-playback (not used in this
6363 * driver yet).
6364 */
6365
6366/*
6367 * BIOS auto configuration
6368 */
6369
6370static int alc662_parse_auto_config(struct hda_codec *codec)
6371{
6372	static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
6373	static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 };
6374	static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 };
6375	const hda_nid_t *ssids;
6376
6377	if (codec->core.vendor_id == 0x10ec0272 || codec->core.vendor_id == 0x10ec0663 ||
6378	    codec->core.vendor_id == 0x10ec0665 || codec->core.vendor_id == 0x10ec0670 ||
6379	    codec->core.vendor_id == 0x10ec0671)
6380		ssids = alc663_ssids;
6381	else
6382		ssids = alc662_ssids;
6383	return alc_parse_auto_config(codec, alc662_ignore, ssids);
6384}
6385
6386static void alc272_fixup_mario(struct hda_codec *codec,
6387			       const struct hda_fixup *fix, int action)
6388{
6389	if (action != HDA_FIXUP_ACT_PRE_PROBE)
6390		return;
6391	if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
6392				      (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
6393				      (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
6394				      (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
6395				      (0 << AC_AMPCAP_MUTE_SHIFT)))
6396		codec_warn(codec, "failed to override amp caps for NID 0x2\n");
6397}
6398
6399static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = {
6400	{ .channels = 2,
6401	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
6402	{ .channels = 4,
6403	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
6404		   SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */
6405	{ }
6406};
6407
6408/* override the 2.1 chmap */
6409static void alc_fixup_bass_chmap(struct hda_codec *codec,
6410				    const struct hda_fixup *fix, int action)
6411{
6412	if (action == HDA_FIXUP_ACT_BUILD) {
6413		struct alc_spec *spec = codec->spec;
6414		spec->gen.pcm_rec[0]->stream[0].chmap = asus_pcm_2_1_chmaps;
6415	}
6416}
6417
6418/* avoid D3 for keeping GPIO up */
6419static unsigned int gpio_led_power_filter(struct hda_codec *codec,
6420					  hda_nid_t nid,
6421					  unsigned int power_state)
6422{
6423	struct alc_spec *spec = codec->spec;
6424	if (nid == codec->core.afg && power_state == AC_PWRST_D3 && spec->gpio_led)
6425		return AC_PWRST_D0;
6426	return power_state;
6427}
6428
6429static void alc662_fixup_led_gpio1(struct hda_codec *codec,
6430				   const struct hda_fixup *fix, int action)
6431{
6432	struct alc_spec *spec = codec->spec;
6433	static const struct hda_verb gpio_init[] = {
6434		{ 0x01, AC_VERB_SET_GPIO_MASK, 0x01 },
6435		{ 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01 },
6436		{}
6437	};
6438
6439	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
6440		spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
6441		spec->gpio_led = 0;
6442		spec->mute_led_polarity = 1;
6443		spec->gpio_mute_led_mask = 0x01;
6444		snd_hda_add_verbs(codec, gpio_init);
6445		codec->power_filter = gpio_led_power_filter;
6446	}
6447}
6448
6449static struct coef_fw alc668_coefs[] = {
6450	WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03,    0x0),
6451	WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06,    0x0), WRITE_COEF(0x07, 0x0f80),
6452	WRITE_COEF(0x08, 0x0031), WRITE_COEF(0x0a, 0x0060), WRITE_COEF(0x0b,    0x0),
6453	WRITE_COEF(0x0c, 0x7cf7), WRITE_COEF(0x0d, 0x1080), WRITE_COEF(0x0e, 0x7f7f),
6454	WRITE_COEF(0x0f, 0xcccc), WRITE_COEF(0x10, 0xddcc), WRITE_COEF(0x11, 0x0001),
6455	WRITE_COEF(0x13,    0x0), WRITE_COEF(0x14, 0x2aa0), WRITE_COEF(0x17, 0xa940),
6456	WRITE_COEF(0x19,    0x0), WRITE_COEF(0x1a,    0x0), WRITE_COEF(0x1b,    0x0),
6457	WRITE_COEF(0x1c,    0x0), WRITE_COEF(0x1d,    0x0), WRITE_COEF(0x1e, 0x7418),
6458	WRITE_COEF(0x1f, 0x0804), WRITE_COEF(0x20, 0x4200), WRITE_COEF(0x21, 0x0468),
6459	WRITE_COEF(0x22, 0x8ccc), WRITE_COEF(0x23, 0x0250), WRITE_COEF(0x24, 0x7418),
6460	WRITE_COEF(0x27,    0x0), WRITE_COEF(0x28, 0x8ccc), WRITE_COEF(0x2a, 0xff00),
6461	WRITE_COEF(0x2b, 0x8000), WRITE_COEF(0xa7, 0xff00), WRITE_COEF(0xa8, 0x8000),
6462	WRITE_COEF(0xaa, 0x2e17), WRITE_COEF(0xab, 0xa0c0), WRITE_COEF(0xac,    0x0),
6463	WRITE_COEF(0xad,    0x0), WRITE_COEF(0xae, 0x2ac6), WRITE_COEF(0xaf, 0xa480),
6464	WRITE_COEF(0xb0,    0x0), WRITE_COEF(0xb1,    0x0), WRITE_COEF(0xb2,    0x0),
6465	WRITE_COEF(0xb3,    0x0), WRITE_COEF(0xb4,    0x0), WRITE_COEF(0xb5, 0x1040),
6466	WRITE_COEF(0xb6, 0xd697), WRITE_COEF(0xb7, 0x902b), WRITE_COEF(0xb8, 0xd697),
6467	WRITE_COEF(0xb9, 0x902b), WRITE_COEF(0xba, 0xb8ba), WRITE_COEF(0xbb, 0xaaab),
6468	WRITE_COEF(0xbc, 0xaaaf), WRITE_COEF(0xbd, 0x6aaa), WRITE_COEF(0xbe, 0x1c02),
6469	WRITE_COEF(0xc0, 0x00ff), WRITE_COEF(0xc1, 0x0fa6),
6470	{}
6471};
6472
6473static void alc668_restore_default_value(struct hda_codec *codec)
6474{
6475	alc_process_coef_fw(codec, alc668_coefs);
6476}
6477
6478enum {
6479	ALC662_FIXUP_ASPIRE,
6480	ALC662_FIXUP_LED_GPIO1,
6481	ALC662_FIXUP_IDEAPAD,
6482	ALC272_FIXUP_MARIO,
6483	ALC662_FIXUP_CZC_P10T,
6484	ALC662_FIXUP_SKU_IGNORE,
6485	ALC662_FIXUP_HP_RP5800,
6486	ALC662_FIXUP_ASUS_MODE1,
6487	ALC662_FIXUP_ASUS_MODE2,
6488	ALC662_FIXUP_ASUS_MODE3,
6489	ALC662_FIXUP_ASUS_MODE4,
6490	ALC662_FIXUP_ASUS_MODE5,
6491	ALC662_FIXUP_ASUS_MODE6,
6492	ALC662_FIXUP_ASUS_MODE7,
6493	ALC662_FIXUP_ASUS_MODE8,
6494	ALC662_FIXUP_NO_JACK_DETECT,
6495	ALC662_FIXUP_ZOTAC_Z68,
6496	ALC662_FIXUP_INV_DMIC,
6497	ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
6498	ALC668_FIXUP_DELL_MIC_NO_PRESENCE,
6499	ALC662_FIXUP_HEADSET_MODE,
6500	ALC668_FIXUP_HEADSET_MODE,
6501	ALC662_FIXUP_BASS_MODE4_CHMAP,
6502	ALC662_FIXUP_BASS_16,
6503	ALC662_FIXUP_BASS_1A,
6504	ALC662_FIXUP_BASS_CHMAP,
6505	ALC668_FIXUP_AUTO_MUTE,
6506	ALC668_FIXUP_DELL_DISABLE_AAMIX,
6507	ALC668_FIXUP_DELL_XPS13,
6508	ALC662_FIXUP_ASUS_Nx50,
6509	ALC668_FIXUP_ASUS_Nx51,
6510};
6511
6512static const struct hda_fixup alc662_fixups[] = {
6513	[ALC662_FIXUP_ASPIRE] = {
6514		.type = HDA_FIXUP_PINS,
6515		.v.pins = (const struct hda_pintbl[]) {
6516			{ 0x15, 0x99130112 }, /* subwoofer */
6517			{ }
6518		}
6519	},
6520	[ALC662_FIXUP_LED_GPIO1] = {
6521		.type = HDA_FIXUP_FUNC,
6522		.v.func = alc662_fixup_led_gpio1,
6523	},
6524	[ALC662_FIXUP_IDEAPAD] = {
6525		.type = HDA_FIXUP_PINS,
6526		.v.pins = (const struct hda_pintbl[]) {
6527			{ 0x17, 0x99130112 }, /* subwoofer */
6528			{ }
6529		},
6530		.chained = true,
6531		.chain_id = ALC662_FIXUP_LED_GPIO1,
6532	},
6533	[ALC272_FIXUP_MARIO] = {
6534		.type = HDA_FIXUP_FUNC,
6535		.v.func = alc272_fixup_mario,
6536	},
6537	[ALC662_FIXUP_CZC_P10T] = {
6538		.type = HDA_FIXUP_VERBS,
6539		.v.verbs = (const struct hda_verb[]) {
6540			{0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
6541			{}
6542		}
6543	},
6544	[ALC662_FIXUP_SKU_IGNORE] = {
6545		.type = HDA_FIXUP_FUNC,
6546		.v.func = alc_fixup_sku_ignore,
6547	},
6548	[ALC662_FIXUP_HP_RP5800] = {
6549		.type = HDA_FIXUP_PINS,
6550		.v.pins = (const struct hda_pintbl[]) {
6551			{ 0x14, 0x0221201f }, /* HP out */
6552			{ }
6553		},
6554		.chained = true,
6555		.chain_id = ALC662_FIXUP_SKU_IGNORE
6556	},
6557	[ALC662_FIXUP_ASUS_MODE1] = {
6558		.type = HDA_FIXUP_PINS,
6559		.v.pins = (const struct hda_pintbl[]) {
6560			{ 0x14, 0x99130110 }, /* speaker */
6561			{ 0x18, 0x01a19c20 }, /* mic */
6562			{ 0x19, 0x99a3092f }, /* int-mic */
6563			{ 0x21, 0x0121401f }, /* HP out */
6564			{ }
6565		},
6566		.chained = true,
6567		.chain_id = ALC662_FIXUP_SKU_IGNORE
6568	},
6569	[ALC662_FIXUP_ASUS_MODE2] = {
6570		.type = HDA_FIXUP_PINS,
6571		.v.pins = (const struct hda_pintbl[]) {
6572			{ 0x14, 0x99130110 }, /* speaker */
6573			{ 0x18, 0x01a19820 }, /* mic */
6574			{ 0x19, 0x99a3092f }, /* int-mic */
6575			{ 0x1b, 0x0121401f }, /* HP out */
6576			{ }
6577		},
6578		.chained = true,
6579		.chain_id = ALC662_FIXUP_SKU_IGNORE
6580	},
6581	[ALC662_FIXUP_ASUS_MODE3] = {
6582		.type = HDA_FIXUP_PINS,
6583		.v.pins = (const struct hda_pintbl[]) {
6584			{ 0x14, 0x99130110 }, /* speaker */
6585			{ 0x15, 0x0121441f }, /* HP */
6586			{ 0x18, 0x01a19840 }, /* mic */
6587			{ 0x19, 0x99a3094f }, /* int-mic */
6588			{ 0x21, 0x01211420 }, /* HP2 */
6589			{ }
6590		},
6591		.chained = true,
6592		.chain_id = ALC662_FIXUP_SKU_IGNORE
6593	},
6594	[ALC662_FIXUP_ASUS_MODE4] = {
6595		.type = HDA_FIXUP_PINS,
6596		.v.pins = (const struct hda_pintbl[]) {
6597			{ 0x14, 0x99130110 }, /* speaker */
6598			{ 0x16, 0x99130111 }, /* speaker */
6599			{ 0x18, 0x01a19840 }, /* mic */
6600			{ 0x19, 0x99a3094f }, /* int-mic */
6601			{ 0x21, 0x0121441f }, /* HP */
6602			{ }
6603		},
6604		.chained = true,
6605		.chain_id = ALC662_FIXUP_SKU_IGNORE
6606	},
6607	[ALC662_FIXUP_ASUS_MODE5] = {
6608		.type = HDA_FIXUP_PINS,
6609		.v.pins = (const struct hda_pintbl[]) {
6610			{ 0x14, 0x99130110 }, /* speaker */
6611			{ 0x15, 0x0121441f }, /* HP */
6612			{ 0x16, 0x99130111 }, /* speaker */
6613			{ 0x18, 0x01a19840 }, /* mic */
6614			{ 0x19, 0x99a3094f }, /* int-mic */
6615			{ }
6616		},
6617		.chained = true,
6618		.chain_id = ALC662_FIXUP_SKU_IGNORE
6619	},
6620	[ALC662_FIXUP_ASUS_MODE6] = {
6621		.type = HDA_FIXUP_PINS,
6622		.v.pins = (const struct hda_pintbl[]) {
6623			{ 0x14, 0x99130110 }, /* speaker */
6624			{ 0x15, 0x01211420 }, /* HP2 */
6625			{ 0x18, 0x01a19840 }, /* mic */
6626			{ 0x19, 0x99a3094f }, /* int-mic */
6627			{ 0x1b, 0x0121441f }, /* HP */
6628			{ }
6629		},
6630		.chained = true,
6631		.chain_id = ALC662_FIXUP_SKU_IGNORE
6632	},
6633	[ALC662_FIXUP_ASUS_MODE7] = {
6634		.type = HDA_FIXUP_PINS,
6635		.v.pins = (const struct hda_pintbl[]) {
6636			{ 0x14, 0x99130110 }, /* speaker */
6637			{ 0x17, 0x99130111 }, /* speaker */
6638			{ 0x18, 0x01a19840 }, /* mic */
6639			{ 0x19, 0x99a3094f }, /* int-mic */
6640			{ 0x1b, 0x01214020 }, /* HP */
6641			{ 0x21, 0x0121401f }, /* HP */
6642			{ }
6643		},
6644		.chained = true,
6645		.chain_id = ALC662_FIXUP_SKU_IGNORE
6646	},
6647	[ALC662_FIXUP_ASUS_MODE8] = {
6648		.type = HDA_FIXUP_PINS,
6649		.v.pins = (const struct hda_pintbl[]) {
6650			{ 0x14, 0x99130110 }, /* speaker */
6651			{ 0x12, 0x99a30970 }, /* int-mic */
6652			{ 0x15, 0x01214020 }, /* HP */
6653			{ 0x17, 0x99130111 }, /* speaker */
6654			{ 0x18, 0x01a19840 }, /* mic */
6655			{ 0x21, 0x0121401f }, /* HP */
6656			{ }
6657		},
6658		.chained = true,
6659		.chain_id = ALC662_FIXUP_SKU_IGNORE
6660	},
6661	[ALC662_FIXUP_NO_JACK_DETECT] = {
6662		.type = HDA_FIXUP_FUNC,
6663		.v.func = alc_fixup_no_jack_detect,
6664	},
6665	[ALC662_FIXUP_ZOTAC_Z68] = {
6666		.type = HDA_FIXUP_PINS,
6667		.v.pins = (const struct hda_pintbl[]) {
6668			{ 0x1b, 0x02214020 }, /* Front HP */
6669			{ }
6670		}
6671	},
6672	[ALC662_FIXUP_INV_DMIC] = {
6673		.type = HDA_FIXUP_FUNC,
6674		.v.func = alc_fixup_inv_dmic,
6675	},
6676	[ALC668_FIXUP_DELL_XPS13] = {
6677		.type = HDA_FIXUP_FUNC,
6678		.v.func = alc_fixup_dell_xps13,
6679		.chained = true,
6680		.chain_id = ALC668_FIXUP_DELL_DISABLE_AAMIX
6681	},
6682	[ALC668_FIXUP_DELL_DISABLE_AAMIX] = {
6683		.type = HDA_FIXUP_FUNC,
6684		.v.func = alc_fixup_disable_aamix,
6685		.chained = true,
6686		.chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
6687	},
6688	[ALC668_FIXUP_AUTO_MUTE] = {
6689		.type = HDA_FIXUP_FUNC,
6690		.v.func = alc_fixup_auto_mute_via_amp,
6691		.chained = true,
6692		.chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
6693	},
6694	[ALC662_FIXUP_DELL_MIC_NO_PRESENCE] = {
6695		.type = HDA_FIXUP_PINS,
6696		.v.pins = (const struct hda_pintbl[]) {
6697			{ 0x19, 0x03a1113c }, /* use as headset mic, without its own jack detect */
6698			/* headphone mic by setting pin control of 0x1b (headphone out) to in + vref_50 */
6699			{ }
6700		},
6701		.chained = true,
6702		.chain_id = ALC662_FIXUP_HEADSET_MODE
6703	},
6704	[ALC662_FIXUP_HEADSET_MODE] = {
6705		.type = HDA_FIXUP_FUNC,
6706		.v.func = alc_fixup_headset_mode_alc662,
6707	},
6708	[ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = {
6709		.type = HDA_FIXUP_PINS,
6710		.v.pins = (const struct hda_pintbl[]) {
6711			{ 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
6712			{ 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
6713			{ }
6714		},
6715		.chained = true,
6716		.chain_id = ALC668_FIXUP_HEADSET_MODE
6717	},
6718	[ALC668_FIXUP_HEADSET_MODE] = {
6719		.type = HDA_FIXUP_FUNC,
6720		.v.func = alc_fixup_headset_mode_alc668,
6721	},
6722	[ALC662_FIXUP_BASS_MODE4_CHMAP] = {
6723		.type = HDA_FIXUP_FUNC,
6724		.v.func = alc_fixup_bass_chmap,
6725		.chained = true,
6726		.chain_id = ALC662_FIXUP_ASUS_MODE4
6727	},
6728	[ALC662_FIXUP_BASS_16] = {
6729		.type = HDA_FIXUP_PINS,
6730		.v.pins = (const struct hda_pintbl[]) {
6731			{0x16, 0x80106111}, /* bass speaker */
6732			{}
6733		},
6734		.chained = true,
6735		.chain_id = ALC662_FIXUP_BASS_CHMAP,
6736	},
6737	[ALC662_FIXUP_BASS_1A] = {
6738		.type = HDA_FIXUP_PINS,
6739		.v.pins = (const struct hda_pintbl[]) {
6740			{0x1a, 0x80106111}, /* bass speaker */
6741			{}
6742		},
6743		.chained = true,
6744		.chain_id = ALC662_FIXUP_BASS_CHMAP,
6745	},
6746	[ALC662_FIXUP_BASS_CHMAP] = {
6747		.type = HDA_FIXUP_FUNC,
6748		.v.func = alc_fixup_bass_chmap,
6749	},
6750	[ALC662_FIXUP_ASUS_Nx50] = {
6751		.type = HDA_FIXUP_FUNC,
6752		.v.func = alc_fixup_auto_mute_via_amp,
6753		.chained = true,
6754		.chain_id = ALC662_FIXUP_BASS_1A
6755	},
6756	[ALC668_FIXUP_ASUS_Nx51] = {
6757		.type = HDA_FIXUP_PINS,
6758		.v.pins = (const struct hda_pintbl[]) {
6759			{0x1a, 0x90170151}, /* bass speaker */
6760			{}
6761		},
6762		.chained = true,
6763		.chain_id = ALC662_FIXUP_BASS_CHMAP,
6764	},
6765};
6766
6767static const struct snd_pci_quirk alc662_fixup_tbl[] = {
6768	SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
6769	SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
6770	SND_PCI_QUIRK(0x1025, 0x0241, "Packard Bell DOTS", ALC662_FIXUP_INV_DMIC),
6771	SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
6772	SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
6773	SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
6774	SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC),
6775	SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
6776	SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
6777	SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
6778	SND_PCI_QUIRK(0x1028, 0x05fe, "Dell XPS 15", ALC668_FIXUP_DELL_XPS13),
6779	SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_XPS13),
6780	SND_PCI_QUIRK(0x1028, 0x060d, "Dell M3800", ALC668_FIXUP_DELL_XPS13),
6781	SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
6782	SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
6783	SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
6784	SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
6785	SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
6786	SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
6787	SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE),
6788	SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_ASUS_Nx50),
6789	SND_PCI_QUIRK(0x1043, 0x13df, "Asus N550JX", ALC662_FIXUP_BASS_1A),
6790	SND_PCI_QUIRK(0x1043, 0x129d, "Asus N750", ALC662_FIXUP_ASUS_Nx50),
6791	SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
6792	SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
6793	SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51),
6794	SND_PCI_QUIRK(0x1043, 0x17bd, "ASUS N751", ALC668_FIXUP_ASUS_Nx51),
6795	SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
6796	SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
6797	SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
6798	SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
6799	SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
6800	SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
6801	SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
6802	SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
6803	SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
6804
6805#if 0
6806	/* Below is a quirk table taken from the old code.
6807	 * Basically the device should work as is without the fixup table.
6808	 * If BIOS doesn't give a proper info, enable the corresponding
6809	 * fixup entry.
6810	 */
6811	SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1),
6812	SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3),
6813	SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1),
6814	SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3),
6815	SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
6816	SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6817	SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
6818	SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1),
6819	SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1),
6820	SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6821	SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7),
6822	SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7),
6823	SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8),
6824	SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3),
6825	SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1),
6826	SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6827	SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2),
6828	SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1),
6829	SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6830	SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
6831	SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
6832	SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6833	SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1),
6834	SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3),
6835	SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2),
6836	SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6837	SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5),
6838	SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
6839	SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6840	SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1),
6841	SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6842	SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6843	SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3),
6844	SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3),
6845	SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1),
6846	SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1),
6847	SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1),
6848	SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1),
6849	SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1),
6850	SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6851	SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2),
6852	SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1),
6853	SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
6854	SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3),
6855	SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1),
6856	SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1),
6857	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1),
6858	SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2),
6859	SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
6860	SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4),
6861#endif
6862	{}
6863};
6864
6865static const struct hda_model_fixup alc662_fixup_models[] = {
6866	{.id = ALC272_FIXUP_MARIO, .name = "mario"},
6867	{.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"},
6868	{.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"},
6869	{.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"},
6870	{.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"},
6871	{.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"},
6872	{.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
6873	{.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
6874	{.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
6875	{.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"},
6876	{.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
6877	{}
6878};
6879
6880static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
6881	SND_HDA_PIN_QUIRK(0x10ec0662, 0x1028, "Dell", ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
6882		{0x12, 0x4004c000},
6883		{0x14, 0x01014010},
6884		{0x15, 0x411111f0},
6885		{0x16, 0x411111f0},
6886		{0x18, 0x01a19020},
6887		{0x19, 0x411111f0},
6888		{0x1a, 0x0181302f},
6889		{0x1b, 0x0221401f},
6890		{0x1c, 0x411111f0},
6891		{0x1d, 0x4054c601},
6892		{0x1e, 0x411111f0}),
6893	SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
6894		{0x12, 0x99a30130},
6895		{0x14, 0x90170110},
6896		{0x15, 0x0321101f},
6897		{0x16, 0x03011020},
6898		{0x18, 0x40000008},
6899		{0x19, 0x411111f0},
6900		{0x1a, 0x411111f0},
6901		{0x1b, 0x411111f0},
6902		{0x1d, 0x41000001},
6903		{0x1e, 0x411111f0},
6904		{0x1f, 0x411111f0}),
6905	SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
6906		{0x12, 0x99a30140},
6907		{0x14, 0x90170110},
6908		{0x15, 0x0321101f},
6909		{0x16, 0x03011020},
6910		{0x18, 0x40000008},
6911		{0x19, 0x411111f0},
6912		{0x1a, 0x411111f0},
6913		{0x1b, 0x411111f0},
6914		{0x1d, 0x41000001},
6915		{0x1e, 0x411111f0},
6916		{0x1f, 0x411111f0}),
6917	SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
6918		{0x12, 0x99a30150},
6919		{0x14, 0x90170110},
6920		{0x15, 0x0321101f},
6921		{0x16, 0x03011020},
6922		{0x18, 0x40000008},
6923		{0x19, 0x411111f0},
6924		{0x1a, 0x411111f0},
6925		{0x1b, 0x411111f0},
6926		{0x1d, 0x41000001},
6927		{0x1e, 0x411111f0},
6928		{0x1f, 0x411111f0}),
6929	SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
6930		{0x12, 0x411111f0},
6931		{0x14, 0x90170110},
6932		{0x15, 0x0321101f},
6933		{0x16, 0x03011020},
6934		{0x18, 0x40000008},
6935		{0x19, 0x411111f0},
6936		{0x1a, 0x411111f0},
6937		{0x1b, 0x411111f0},
6938		{0x1d, 0x41000001},
6939		{0x1e, 0x411111f0},
6940		{0x1f, 0x411111f0}),
6941	SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell XPS 15", ALC668_FIXUP_AUTO_MUTE,
6942		{0x12, 0x90a60130},
6943		{0x14, 0x90170110},
6944		{0x15, 0x0321101f},
6945		{0x16, 0x40000000},
6946		{0x18, 0x411111f0},
6947		{0x19, 0x411111f0},
6948		{0x1a, 0x411111f0},
6949		{0x1b, 0x411111f0},
6950		{0x1d, 0x40d6832d},
6951		{0x1e, 0x411111f0},
6952		{0x1f, 0x411111f0}),
6953	{}
6954};
6955
6956/*
6957 */
6958static int patch_alc662(struct hda_codec *codec)
6959{
6960	struct alc_spec *spec;
6961	int err;
6962
6963	err = alc_alloc_spec(codec, 0x0b);
6964	if (err < 0)
6965		return err;
6966
6967	spec = codec->spec;
6968
6969	/* handle multiple HPs as is */
6970	spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
6971
6972	alc_fix_pll_init(codec, 0x20, 0x04, 15);
6973
6974	switch (codec->core.vendor_id) {
6975	case 0x10ec0668:
6976		spec->init_hook = alc668_restore_default_value;
6977		break;
6978	}
6979
6980	snd_hda_pick_fixup(codec, alc662_fixup_models,
6981		       alc662_fixup_tbl, alc662_fixups);
6982	snd_hda_pick_pin_fixup(codec, alc662_pin_fixup_tbl, alc662_fixups);
6983	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
6984
6985	alc_auto_parse_customize_define(codec);
6986
6987	if (has_cdefine_beep(codec))
6988		spec->gen.beep_nid = 0x01;
6989
6990	if ((alc_get_coef0(codec) & (1 << 14)) &&
6991	    codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 &&
6992	    spec->cdefine.platform_type == 1) {
6993		err = alc_codec_rename(codec, "ALC272X");
6994		if (err < 0)
6995			goto error;
6996	}
6997
6998	/* automatic parse from the BIOS config */
6999	err = alc662_parse_auto_config(codec);
7000	if (err < 0)
7001		goto error;
7002
7003	if (!spec->gen.no_analog && spec->gen.beep_nid) {
7004		switch (codec->core.vendor_id) {
7005		case 0x10ec0662:
7006			set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
7007			break;
7008		case 0x10ec0272:
7009		case 0x10ec0663:
7010		case 0x10ec0665:
7011		case 0x10ec0668:
7012			set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
7013			break;
7014		case 0x10ec0273:
7015			set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
7016			break;
7017		}
7018	}
7019
7020	codec->patch_ops = alc_patch_ops;
7021	spec->shutup = alc_eapd_shutup;
7022
7023	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
7024
7025	return 0;
7026
7027 error:
7028	alc_free(codec);
7029	return err;
7030}
7031
7032/*
7033 * ALC680 support
7034 */
7035
7036static int alc680_parse_auto_config(struct hda_codec *codec)
7037{
7038	return alc_parse_auto_config(codec, NULL, NULL);
7039}
7040
7041/*
7042 */
7043static int patch_alc680(struct hda_codec *codec)
7044{
7045	int err;
7046
7047	/* ALC680 has no aa-loopback mixer */
7048	err = alc_alloc_spec(codec, 0);
7049	if (err < 0)
7050		return err;
7051
7052	/* automatic parse from the BIOS config */
7053	err = alc680_parse_auto_config(codec);
7054	if (err < 0) {
7055		alc_free(codec);
7056		return err;
7057	}
7058
7059	codec->patch_ops = alc_patch_ops;
7060
7061	return 0;
7062}
7063
7064/*
7065 * patch entries
7066 */
7067static const struct hda_codec_preset snd_hda_preset_realtek[] = {
7068	{ .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
7069	{ .id = 0x10ec0231, .name = "ALC231", .patch = patch_alc269 },
7070	{ .id = 0x10ec0233, .name = "ALC233", .patch = patch_alc269 },
7071	{ .id = 0x10ec0235, .name = "ALC233", .patch = patch_alc269 },
7072	{ .id = 0x10ec0255, .name = "ALC255", .patch = patch_alc269 },
7073	{ .id = 0x10ec0256, .name = "ALC256", .patch = patch_alc269 },
7074	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
7075	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
7076	{ .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
7077	{ .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
7078	{ .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
7079	{ .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
7080	{ .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
7081	{ .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
7082	{ .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
7083	{ .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 },
7084	{ .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 },
7085	{ .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 },
7086	{ .id = 0x10ec0284, .name = "ALC284", .patch = patch_alc269 },
7087	{ .id = 0x10ec0285, .name = "ALC285", .patch = patch_alc269 },
7088	{ .id = 0x10ec0286, .name = "ALC286", .patch = patch_alc269 },
7089	{ .id = 0x10ec0288, .name = "ALC288", .patch = patch_alc269 },
7090	{ .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 },
7091	{ .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 },
7092	{ .id = 0x10ec0293, .name = "ALC293", .patch = patch_alc269 },
7093	{ .id = 0x10ec0298, .name = "ALC298", .patch = patch_alc269 },
7094	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
7095	  .patch = patch_alc861 },
7096	{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
7097	{ .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
7098	{ .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
7099	{ .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
7100	  .patch = patch_alc882 },
7101	{ .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
7102	  .patch = patch_alc662 },
7103	{ .id = 0x10ec0662, .rev = 0x100300, .name = "ALC662 rev3",
7104	  .patch = patch_alc662 },
7105	{ .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
7106	{ .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
7107	{ .id = 0x10ec0667, .name = "ALC667", .patch = patch_alc662 },
7108	{ .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 },
7109	{ .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
7110	{ .id = 0x10ec0671, .name = "ALC671", .patch = patch_alc662 },
7111	{ .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
7112	{ .id = 0x10ec0867, .name = "ALC891", .patch = patch_alc882 },
7113	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
7114	{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
7115	{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
7116	{ .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
7117	  .patch = patch_alc882 },
7118	{ .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
7119	  .patch = patch_alc882 },
7120	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
7121	{ .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
7122	{ .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
7123	  .patch = patch_alc882 },
7124	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 },
7125	{ .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
7126	{ .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
7127	{ .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 },
7128	{ .id = 0x10ec0900, .name = "ALC1150", .patch = patch_alc882 },
7129	{} /* terminator */
7130};
7131
7132MODULE_ALIAS("snd-hda-codec-id:10ec*");
7133
7134MODULE_LICENSE("GPL");
7135MODULE_DESCRIPTION("Realtek HD-audio codec");
7136
7137static struct hda_codec_driver realtek_driver = {
7138	.preset = snd_hda_preset_realtek,
7139};
7140
7141module_hda_codec_driver(realtek_driver);
7142