patch_realtek.c revision 80f1aff93c34feff6ad229ff2a1307e82cb5b132
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 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@physics.adelaide.edu.au>
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 <sound/core.h>
31#include <sound/jack.h>
32#include "hda_codec.h"
33#include "hda_local.h"
34#include "hda_beep.h"
35
36#define ALC880_FRONT_EVENT		0x01
37#define ALC880_DCVOL_EVENT		0x02
38#define ALC880_HP_EVENT			0x04
39#define ALC880_MIC_EVENT		0x08
40
41/* ALC880 board config type */
42enum {
43	ALC880_3ST,
44	ALC880_3ST_DIG,
45	ALC880_5ST,
46	ALC880_5ST_DIG,
47	ALC880_W810,
48	ALC880_Z71V,
49	ALC880_6ST,
50	ALC880_6ST_DIG,
51	ALC880_F1734,
52	ALC880_ASUS,
53	ALC880_ASUS_DIG,
54	ALC880_ASUS_W1V,
55	ALC880_ASUS_DIG2,
56	ALC880_FUJITSU,
57	ALC880_UNIWILL_DIG,
58	ALC880_UNIWILL,
59	ALC880_UNIWILL_P53,
60	ALC880_CLEVO,
61	ALC880_TCL_S700,
62	ALC880_LG,
63	ALC880_LG_LW,
64	ALC880_MEDION_RIM,
65#ifdef CONFIG_SND_DEBUG
66	ALC880_TEST,
67#endif
68	ALC880_AUTO,
69	ALC880_MODEL_LAST /* last tag */
70};
71
72/* ALC260 models */
73enum {
74	ALC260_BASIC,
75	ALC260_HP,
76	ALC260_HP_DC7600,
77	ALC260_HP_3013,
78	ALC260_FUJITSU_S702X,
79	ALC260_ACER,
80	ALC260_WILL,
81	ALC260_REPLACER_672V,
82	ALC260_FAVORIT100,
83#ifdef CONFIG_SND_DEBUG
84	ALC260_TEST,
85#endif
86	ALC260_AUTO,
87	ALC260_MODEL_LAST /* last tag */
88};
89
90/* ALC262 models */
91enum {
92	ALC262_BASIC,
93	ALC262_HIPPO,
94	ALC262_HIPPO_1,
95	ALC262_FUJITSU,
96	ALC262_HP_BPC,
97	ALC262_HP_BPC_D7000_WL,
98	ALC262_HP_BPC_D7000_WF,
99	ALC262_HP_TC_T5735,
100	ALC262_HP_RP5700,
101	ALC262_BENQ_ED8,
102	ALC262_SONY_ASSAMD,
103	ALC262_BENQ_T31,
104	ALC262_ULTRA,
105	ALC262_LENOVO_3000,
106	ALC262_NEC,
107	ALC262_TOSHIBA_S06,
108	ALC262_TOSHIBA_RX1,
109	ALC262_TYAN,
110	ALC262_AUTO,
111	ALC262_MODEL_LAST /* last tag */
112};
113
114/* ALC268 models */
115enum {
116	ALC267_QUANTA_IL1,
117	ALC268_3ST,
118	ALC268_TOSHIBA,
119	ALC268_ACER,
120	ALC268_ACER_DMIC,
121	ALC268_ACER_ASPIRE_ONE,
122	ALC268_DELL,
123	ALC268_ZEPTO,
124#ifdef CONFIG_SND_DEBUG
125	ALC268_TEST,
126#endif
127	ALC268_AUTO,
128	ALC268_MODEL_LAST /* last tag */
129};
130
131/* ALC269 models */
132enum {
133	ALC269_BASIC,
134	ALC269_QUANTA_FL1,
135	ALC269_AMIC,
136	ALC269_DMIC,
137	ALC269VB_AMIC,
138	ALC269VB_DMIC,
139	ALC269_FUJITSU,
140	ALC269_LIFEBOOK,
141	ALC271_ACER,
142	ALC269_AUTO,
143	ALC269_MODEL_LAST /* last tag */
144};
145
146/* ALC861 models */
147enum {
148	ALC861_3ST,
149	ALC660_3ST,
150	ALC861_3ST_DIG,
151	ALC861_6ST_DIG,
152	ALC861_UNIWILL_M31,
153	ALC861_TOSHIBA,
154	ALC861_ASUS,
155	ALC861_ASUS_LAPTOP,
156	ALC861_AUTO,
157	ALC861_MODEL_LAST,
158};
159
160/* ALC861-VD models */
161enum {
162	ALC660VD_3ST,
163	ALC660VD_3ST_DIG,
164	ALC660VD_ASUS_V1S,
165	ALC861VD_3ST,
166	ALC861VD_3ST_DIG,
167	ALC861VD_6ST_DIG,
168	ALC861VD_LENOVO,
169	ALC861VD_DALLAS,
170	ALC861VD_HP,
171	ALC861VD_AUTO,
172	ALC861VD_MODEL_LAST,
173};
174
175/* ALC662 models */
176enum {
177	ALC662_3ST_2ch_DIG,
178	ALC662_3ST_6ch_DIG,
179	ALC662_3ST_6ch,
180	ALC662_5ST_DIG,
181	ALC662_LENOVO_101E,
182	ALC662_ASUS_EEEPC_P701,
183	ALC662_ASUS_EEEPC_EP20,
184	ALC663_ASUS_M51VA,
185	ALC663_ASUS_G71V,
186	ALC663_ASUS_H13,
187	ALC663_ASUS_G50V,
188	ALC662_ECS,
189	ALC663_ASUS_MODE1,
190	ALC662_ASUS_MODE2,
191	ALC663_ASUS_MODE3,
192	ALC663_ASUS_MODE4,
193	ALC663_ASUS_MODE5,
194	ALC663_ASUS_MODE6,
195	ALC663_ASUS_MODE7,
196	ALC663_ASUS_MODE8,
197	ALC272_DELL,
198	ALC272_DELL_ZM1,
199	ALC272_SAMSUNG_NC10,
200	ALC662_AUTO,
201	ALC662_MODEL_LAST,
202};
203
204/* ALC882 models */
205enum {
206	ALC882_3ST_DIG,
207	ALC882_6ST_DIG,
208	ALC882_ARIMA,
209	ALC882_W2JC,
210	ALC882_TARGA,
211	ALC882_ASUS_A7J,
212	ALC882_ASUS_A7M,
213	ALC885_MACPRO,
214	ALC885_MBA21,
215	ALC885_MBP3,
216	ALC885_MB5,
217	ALC885_MACMINI3,
218	ALC885_IMAC24,
219	ALC885_IMAC91,
220	ALC883_3ST_2ch_DIG,
221	ALC883_3ST_6ch_DIG,
222	ALC883_3ST_6ch,
223	ALC883_6ST_DIG,
224	ALC883_TARGA_DIG,
225	ALC883_TARGA_2ch_DIG,
226	ALC883_TARGA_8ch_DIG,
227	ALC883_ACER,
228	ALC883_ACER_ASPIRE,
229	ALC888_ACER_ASPIRE_4930G,
230	ALC888_ACER_ASPIRE_6530G,
231	ALC888_ACER_ASPIRE_8930G,
232	ALC888_ACER_ASPIRE_7730G,
233	ALC883_MEDION,
234	ALC883_MEDION_WIM2160,
235	ALC883_LAPTOP_EAPD,
236	ALC883_LENOVO_101E_2ch,
237	ALC883_LENOVO_NB0763,
238	ALC888_LENOVO_MS7195_DIG,
239	ALC888_LENOVO_SKY,
240	ALC883_HAIER_W66,
241	ALC888_3ST_HP,
242	ALC888_6ST_DELL,
243	ALC883_MITAC,
244	ALC883_CLEVO_M540R,
245	ALC883_CLEVO_M720,
246	ALC883_FUJITSU_PI2515,
247	ALC888_FUJITSU_XA3530,
248	ALC883_3ST_6ch_INTEL,
249	ALC889A_INTEL,
250	ALC889_INTEL,
251	ALC888_ASUS_M90V,
252	ALC888_ASUS_EEE1601,
253	ALC889A_MB31,
254	ALC1200_ASUS_P5Q,
255	ALC883_SONY_VAIO_TT,
256	ALC882_AUTO,
257	ALC882_MODEL_LAST,
258};
259
260/* ALC680 models */
261enum {
262	ALC680_BASE,
263	ALC680_AUTO,
264	ALC680_MODEL_LAST,
265};
266
267/* for GPIO Poll */
268#define GPIO_MASK	0x03
269
270/* extra amp-initialization sequence types */
271enum {
272	ALC_INIT_NONE,
273	ALC_INIT_DEFAULT,
274	ALC_INIT_GPIO1,
275	ALC_INIT_GPIO2,
276	ALC_INIT_GPIO3,
277};
278
279struct alc_mic_route {
280	hda_nid_t pin;
281	unsigned char mux_idx;
282	unsigned char amix_idx;
283};
284
285#define MUX_IDX_UNDEF	((unsigned char)-1)
286
287struct alc_customize_define {
288	unsigned int  sku_cfg;
289	unsigned char port_connectivity;
290	unsigned char check_sum;
291	unsigned char customization;
292	unsigned char external_amp;
293	unsigned int  enable_pcbeep:1;
294	unsigned int  platform_type:1;
295	unsigned int  swap:1;
296	unsigned int  override:1;
297	unsigned int  fixup:1; /* Means that this sku is set by driver, not read from hw */
298};
299
300struct alc_fixup;
301
302struct alc_multi_io {
303	hda_nid_t pin;		/* multi-io widget pin NID */
304	hda_nid_t dac;		/* DAC to be connected */
305	unsigned int ctl_in;	/* cached input-pin control value */
306};
307
308enum {
309	ALC_AUTOMUTE_PIN,	/* change the pin control */
310	ALC_AUTOMUTE_AMP,	/* mute/unmute the pin AMP */
311	ALC_AUTOMUTE_MIXER,	/* mute/unmute mixer widget AMP */
312};
313
314struct alc_spec {
315	/* codec parameterization */
316	const struct snd_kcontrol_new *mixers[5];	/* mixer arrays */
317	unsigned int num_mixers;
318	const struct snd_kcontrol_new *cap_mixer;	/* capture mixer */
319	unsigned int beep_amp;	/* beep amp value, set via set_beep_amp() */
320
321	const struct hda_verb *init_verbs[10];	/* initialization verbs
322						 * don't forget NULL
323						 * termination!
324						 */
325	unsigned int num_init_verbs;
326
327	char stream_name_analog[32];	/* analog PCM stream */
328	const struct hda_pcm_stream *stream_analog_playback;
329	const struct hda_pcm_stream *stream_analog_capture;
330	const struct hda_pcm_stream *stream_analog_alt_playback;
331	const struct hda_pcm_stream *stream_analog_alt_capture;
332
333	char stream_name_digital[32];	/* digital PCM stream */
334	const struct hda_pcm_stream *stream_digital_playback;
335	const struct hda_pcm_stream *stream_digital_capture;
336
337	/* playback */
338	struct hda_multi_out multiout;	/* playback set-up
339					 * max_channels, dacs must be set
340					 * dig_out_nid and hp_nid are optional
341					 */
342	hda_nid_t alt_dac_nid;
343	hda_nid_t slave_dig_outs[3];	/* optional - for auto-parsing */
344	int dig_out_type;
345
346	/* capture */
347	unsigned int num_adc_nids;
348	const hda_nid_t *adc_nids;
349	const hda_nid_t *capsrc_nids;
350	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
351
352	/* capture setup for dynamic dual-adc switch */
353	unsigned int cur_adc_idx;
354	hda_nid_t cur_adc;
355	unsigned int cur_adc_stream_tag;
356	unsigned int cur_adc_format;
357
358	/* capture source */
359	unsigned int num_mux_defs;
360	const struct hda_input_mux *input_mux;
361	unsigned int cur_mux[3];
362	struct alc_mic_route ext_mic;
363	struct alc_mic_route dock_mic;
364	struct alc_mic_route int_mic;
365
366	/* channel model */
367	const struct hda_channel_mode *channel_mode;
368	int num_channel_mode;
369	int need_dac_fix;
370	int const_channel_count;
371	int ext_channel_count;
372
373	/* PCM information */
374	struct hda_pcm pcm_rec[3];	/* used in alc_build_pcms() */
375
376	/* dynamic controls, init_verbs and input_mux */
377	struct auto_pin_cfg autocfg;
378	struct alc_customize_define cdefine;
379	struct snd_array kctls;
380	struct hda_input_mux private_imux[3];
381	hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
382	hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
383	hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
384
385	/* hooks */
386	void (*init_hook)(struct hda_codec *codec);
387	void (*unsol_event)(struct hda_codec *codec, unsigned int res);
388#ifdef CONFIG_SND_HDA_POWER_SAVE
389	void (*power_hook)(struct hda_codec *codec);
390#endif
391	void (*shutup)(struct hda_codec *codec);
392
393	/* for pin sensing */
394	unsigned int jack_present: 1;
395	unsigned int line_jack_present:1;
396	unsigned int master_mute:1;
397	unsigned int auto_mic:1;
398	unsigned int automute:1;	/* HP automute enabled */
399	unsigned int detect_line:1;	/* Line-out detection enabled */
400	unsigned int automute_lines:1;	/* automute line-out as well; NOP when automute_hp_lo isn't set */
401	unsigned int automute_hp_lo:1;	/* both HP and LO available */
402
403	/* other flags */
404	unsigned int no_analog :1; /* digital I/O only */
405	unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
406	unsigned int single_input_src:1;
407
408	/* auto-mute control */
409	int automute_mode;
410	hda_nid_t automute_mixer_nid[AUTO_CFG_MAX_OUTS];
411
412	int init_amp;
413	int codec_variant;	/* flag for other variants */
414
415	/* for virtual master */
416	hda_nid_t vmaster_nid;
417#ifdef CONFIG_SND_HDA_POWER_SAVE
418	struct hda_loopback_check loopback;
419#endif
420
421	/* for PLL fix */
422	hda_nid_t pll_nid;
423	unsigned int pll_coef_idx, pll_coef_bit;
424
425	/* fix-up list */
426	int fixup_id;
427	const struct alc_fixup *fixup_list;
428	const char *fixup_name;
429
430	/* multi-io */
431	int multi_ios;
432	struct alc_multi_io multi_io[4];
433};
434
435/*
436 * configuration template - to be copied to the spec instance
437 */
438struct alc_config_preset {
439	const struct snd_kcontrol_new *mixers[5]; /* should be identical size
440					     * with spec
441					     */
442	const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
443	const struct hda_verb *init_verbs[5];
444	unsigned int num_dacs;
445	const hda_nid_t *dac_nids;
446	hda_nid_t dig_out_nid;		/* optional */
447	hda_nid_t hp_nid;		/* optional */
448	const hda_nid_t *slave_dig_outs;
449	unsigned int num_adc_nids;
450	const hda_nid_t *adc_nids;
451	const hda_nid_t *capsrc_nids;
452	hda_nid_t dig_in_nid;
453	unsigned int num_channel_mode;
454	const struct hda_channel_mode *channel_mode;
455	int need_dac_fix;
456	int const_channel_count;
457	unsigned int num_mux_defs;
458	const struct hda_input_mux *input_mux;
459	void (*unsol_event)(struct hda_codec *, unsigned int);
460	void (*setup)(struct hda_codec *);
461	void (*init_hook)(struct hda_codec *);
462#ifdef CONFIG_SND_HDA_POWER_SAVE
463	const struct hda_amp_list *loopbacks;
464	void (*power_hook)(struct hda_codec *codec);
465#endif
466};
467
468
469/*
470 * input MUX handling
471 */
472static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
473			     struct snd_ctl_elem_info *uinfo)
474{
475	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
476	struct alc_spec *spec = codec->spec;
477	unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
478	if (mux_idx >= spec->num_mux_defs)
479		mux_idx = 0;
480	if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
481		mux_idx = 0;
482	return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
483}
484
485static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
486			    struct snd_ctl_elem_value *ucontrol)
487{
488	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
489	struct alc_spec *spec = codec->spec;
490	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
491
492	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
493	return 0;
494}
495
496static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
497			    struct snd_ctl_elem_value *ucontrol)
498{
499	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
500	struct alc_spec *spec = codec->spec;
501	const struct hda_input_mux *imux;
502	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
503	unsigned int mux_idx;
504	hda_nid_t nid = spec->capsrc_nids ?
505		spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
506	unsigned int type;
507
508	mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
509	imux = &spec->input_mux[mux_idx];
510	if (!imux->num_items && mux_idx > 0)
511		imux = &spec->input_mux[0];
512	if (!imux->num_items)
513		return 0;
514
515	type = get_wcaps_type(get_wcaps(codec, nid));
516	if (type == AC_WID_AUD_MIX) {
517		/* Matrix-mixer style (e.g. ALC882) */
518		unsigned int *cur_val = &spec->cur_mux[adc_idx];
519		unsigned int i, idx;
520
521		idx = ucontrol->value.enumerated.item[0];
522		if (idx >= imux->num_items)
523			idx = imux->num_items - 1;
524		if (*cur_val == idx)
525			return 0;
526		for (i = 0; i < imux->num_items; i++) {
527			unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
528			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
529						 imux->items[i].index,
530						 HDA_AMP_MUTE, v);
531		}
532		*cur_val = idx;
533		return 1;
534	} else {
535		/* MUX style (e.g. ALC880) */
536		return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
537					     &spec->cur_mux[adc_idx]);
538	}
539}
540
541/*
542 * channel mode setting
543 */
544static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
545			    struct snd_ctl_elem_info *uinfo)
546{
547	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
548	struct alc_spec *spec = codec->spec;
549	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
550				    spec->num_channel_mode);
551}
552
553static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
554			   struct snd_ctl_elem_value *ucontrol)
555{
556	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
557	struct alc_spec *spec = codec->spec;
558	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
559				   spec->num_channel_mode,
560				   spec->ext_channel_count);
561}
562
563static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
564			   struct snd_ctl_elem_value *ucontrol)
565{
566	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
567	struct alc_spec *spec = codec->spec;
568	int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
569				      spec->num_channel_mode,
570				      &spec->ext_channel_count);
571	if (err >= 0 && !spec->const_channel_count) {
572		spec->multiout.max_channels = spec->ext_channel_count;
573		if (spec->need_dac_fix)
574			spec->multiout.num_dacs = spec->multiout.max_channels / 2;
575	}
576	return err;
577}
578
579/*
580 * Control the mode of pin widget settings via the mixer.  "pc" is used
581 * instead of "%" to avoid consequences of accidentally treating the % as
582 * being part of a format specifier.  Maximum allowed length of a value is
583 * 63 characters plus NULL terminator.
584 *
585 * Note: some retasking pin complexes seem to ignore requests for input
586 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
587 * are requested.  Therefore order this list so that this behaviour will not
588 * cause problems when mixer clients move through the enum sequentially.
589 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
590 * March 2006.
591 */
592static const char * const alc_pin_mode_names[] = {
593	"Mic 50pc bias", "Mic 80pc bias",
594	"Line in", "Line out", "Headphone out",
595};
596static const unsigned char alc_pin_mode_values[] = {
597	PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
598};
599/* The control can present all 5 options, or it can limit the options based
600 * in the pin being assumed to be exclusively an input or an output pin.  In
601 * addition, "input" pins may or may not process the mic bias option
602 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
603 * accept requests for bias as of chip versions up to March 2006) and/or
604 * wiring in the computer.
605 */
606#define ALC_PIN_DIR_IN              0x00
607#define ALC_PIN_DIR_OUT             0x01
608#define ALC_PIN_DIR_INOUT           0x02
609#define ALC_PIN_DIR_IN_NOMICBIAS    0x03
610#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
611
612/* Info about the pin modes supported by the different pin direction modes.
613 * For each direction the minimum and maximum values are given.
614 */
615static const signed char alc_pin_mode_dir_info[5][2] = {
616	{ 0, 2 },    /* ALC_PIN_DIR_IN */
617	{ 3, 4 },    /* ALC_PIN_DIR_OUT */
618	{ 0, 4 },    /* ALC_PIN_DIR_INOUT */
619	{ 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
620	{ 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
621};
622#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
623#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
624#define alc_pin_mode_n_items(_dir) \
625	(alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
626
627static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
628			     struct snd_ctl_elem_info *uinfo)
629{
630	unsigned int item_num = uinfo->value.enumerated.item;
631	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
632
633	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
634	uinfo->count = 1;
635	uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
636
637	if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
638		item_num = alc_pin_mode_min(dir);
639	strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
640	return 0;
641}
642
643static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
644			    struct snd_ctl_elem_value *ucontrol)
645{
646	unsigned int i;
647	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
648	hda_nid_t nid = kcontrol->private_value & 0xffff;
649	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
650	long *valp = ucontrol->value.integer.value;
651	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
652						 AC_VERB_GET_PIN_WIDGET_CONTROL,
653						 0x00);
654
655	/* Find enumerated value for current pinctl setting */
656	i = alc_pin_mode_min(dir);
657	while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
658		i++;
659	*valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
660	return 0;
661}
662
663static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
664			    struct snd_ctl_elem_value *ucontrol)
665{
666	signed int change;
667	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
668	hda_nid_t nid = kcontrol->private_value & 0xffff;
669	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
670	long val = *ucontrol->value.integer.value;
671	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
672						 AC_VERB_GET_PIN_WIDGET_CONTROL,
673						 0x00);
674
675	if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
676		val = alc_pin_mode_min(dir);
677
678	change = pinctl != alc_pin_mode_values[val];
679	if (change) {
680		/* Set pin mode to that requested */
681		snd_hda_codec_write_cache(codec, nid, 0,
682					  AC_VERB_SET_PIN_WIDGET_CONTROL,
683					  alc_pin_mode_values[val]);
684
685		/* Also enable the retasking pin's input/output as required
686		 * for the requested pin mode.  Enum values of 2 or less are
687		 * input modes.
688		 *
689		 * Dynamically switching the input/output buffers probably
690		 * reduces noise slightly (particularly on input) so we'll
691		 * do it.  However, having both input and output buffers
692		 * enabled simultaneously doesn't seem to be problematic if
693		 * this turns out to be necessary in the future.
694		 */
695		if (val <= 2) {
696			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
697						 HDA_AMP_MUTE, HDA_AMP_MUTE);
698			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
699						 HDA_AMP_MUTE, 0);
700		} else {
701			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
702						 HDA_AMP_MUTE, HDA_AMP_MUTE);
703			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
704						 HDA_AMP_MUTE, 0);
705		}
706	}
707	return change;
708}
709
710#define ALC_PIN_MODE(xname, nid, dir) \
711	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
712	  .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
713	  .info = alc_pin_mode_info, \
714	  .get = alc_pin_mode_get, \
715	  .put = alc_pin_mode_put, \
716	  .private_value = nid | (dir<<16) }
717
718/* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
719 * together using a mask with more than one bit set.  This control is
720 * currently used only by the ALC260 test model.  At this stage they are not
721 * needed for any "production" models.
722 */
723#ifdef CONFIG_SND_DEBUG
724#define alc_gpio_data_info	snd_ctl_boolean_mono_info
725
726static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
727			     struct snd_ctl_elem_value *ucontrol)
728{
729	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
730	hda_nid_t nid = kcontrol->private_value & 0xffff;
731	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
732	long *valp = ucontrol->value.integer.value;
733	unsigned int val = snd_hda_codec_read(codec, nid, 0,
734					      AC_VERB_GET_GPIO_DATA, 0x00);
735
736	*valp = (val & mask) != 0;
737	return 0;
738}
739static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
740			     struct snd_ctl_elem_value *ucontrol)
741{
742	signed int change;
743	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
744	hda_nid_t nid = kcontrol->private_value & 0xffff;
745	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
746	long val = *ucontrol->value.integer.value;
747	unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
748						    AC_VERB_GET_GPIO_DATA,
749						    0x00);
750
751	/* Set/unset the masked GPIO bit(s) as needed */
752	change = (val == 0 ? 0 : mask) != (gpio_data & mask);
753	if (val == 0)
754		gpio_data &= ~mask;
755	else
756		gpio_data |= mask;
757	snd_hda_codec_write_cache(codec, nid, 0,
758				  AC_VERB_SET_GPIO_DATA, gpio_data);
759
760	return change;
761}
762#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
763	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
764	  .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
765	  .info = alc_gpio_data_info, \
766	  .get = alc_gpio_data_get, \
767	  .put = alc_gpio_data_put, \
768	  .private_value = nid | (mask<<16) }
769#endif   /* CONFIG_SND_DEBUG */
770
771/* A switch control to allow the enabling of the digital IO pins on the
772 * ALC260.  This is incredibly simplistic; the intention of this control is
773 * to provide something in the test model allowing digital outputs to be
774 * identified if present.  If models are found which can utilise these
775 * outputs a more complete mixer control can be devised for those models if
776 * necessary.
777 */
778#ifdef CONFIG_SND_DEBUG
779#define alc_spdif_ctrl_info	snd_ctl_boolean_mono_info
780
781static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
782			      struct snd_ctl_elem_value *ucontrol)
783{
784	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
785	hda_nid_t nid = kcontrol->private_value & 0xffff;
786	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
787	long *valp = ucontrol->value.integer.value;
788	unsigned int val = snd_hda_codec_read(codec, nid, 0,
789					      AC_VERB_GET_DIGI_CONVERT_1, 0x00);
790
791	*valp = (val & mask) != 0;
792	return 0;
793}
794static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
795			      struct snd_ctl_elem_value *ucontrol)
796{
797	signed int change;
798	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
799	hda_nid_t nid = kcontrol->private_value & 0xffff;
800	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
801	long val = *ucontrol->value.integer.value;
802	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
803						    AC_VERB_GET_DIGI_CONVERT_1,
804						    0x00);
805
806	/* Set/unset the masked control bit(s) as needed */
807	change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
808	if (val==0)
809		ctrl_data &= ~mask;
810	else
811		ctrl_data |= mask;
812	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
813				  ctrl_data);
814
815	return change;
816}
817#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
818	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
819	  .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
820	  .info = alc_spdif_ctrl_info, \
821	  .get = alc_spdif_ctrl_get, \
822	  .put = alc_spdif_ctrl_put, \
823	  .private_value = nid | (mask<<16) }
824#endif   /* CONFIG_SND_DEBUG */
825
826/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
827 * Again, this is only used in the ALC26x test models to help identify when
828 * the EAPD line must be asserted for features to work.
829 */
830#ifdef CONFIG_SND_DEBUG
831#define alc_eapd_ctrl_info	snd_ctl_boolean_mono_info
832
833static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
834			      struct snd_ctl_elem_value *ucontrol)
835{
836	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
837	hda_nid_t nid = kcontrol->private_value & 0xffff;
838	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
839	long *valp = ucontrol->value.integer.value;
840	unsigned int val = snd_hda_codec_read(codec, nid, 0,
841					      AC_VERB_GET_EAPD_BTLENABLE, 0x00);
842
843	*valp = (val & mask) != 0;
844	return 0;
845}
846
847static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
848			      struct snd_ctl_elem_value *ucontrol)
849{
850	int change;
851	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
852	hda_nid_t nid = kcontrol->private_value & 0xffff;
853	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
854	long val = *ucontrol->value.integer.value;
855	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
856						    AC_VERB_GET_EAPD_BTLENABLE,
857						    0x00);
858
859	/* Set/unset the masked control bit(s) as needed */
860	change = (!val ? 0 : mask) != (ctrl_data & mask);
861	if (!val)
862		ctrl_data &= ~mask;
863	else
864		ctrl_data |= mask;
865	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
866				  ctrl_data);
867
868	return change;
869}
870
871#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
872	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
873	  .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
874	  .info = alc_eapd_ctrl_info, \
875	  .get = alc_eapd_ctrl_get, \
876	  .put = alc_eapd_ctrl_put, \
877	  .private_value = nid | (mask<<16) }
878#endif   /* CONFIG_SND_DEBUG */
879
880/*
881 * set up the input pin config (depending on the given auto-pin type)
882 */
883static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
884			      int auto_pin_type)
885{
886	unsigned int val = PIN_IN;
887
888	if (auto_pin_type == AUTO_PIN_MIC) {
889		unsigned int pincap;
890		unsigned int oldval;
891		oldval = snd_hda_codec_read(codec, nid, 0,
892					    AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
893		pincap = snd_hda_query_pin_caps(codec, nid);
894		pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
895		/* if the default pin setup is vref50, we give it priority */
896		if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
897			val = PIN_VREF80;
898		else if (pincap & AC_PINCAP_VREF_50)
899			val = PIN_VREF50;
900		else if (pincap & AC_PINCAP_VREF_100)
901			val = PIN_VREF100;
902		else if (pincap & AC_PINCAP_VREF_GRD)
903			val = PIN_VREFGRD;
904	}
905	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
906}
907
908static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
909{
910	struct alc_spec *spec = codec->spec;
911	struct auto_pin_cfg *cfg = &spec->autocfg;
912
913	if (!cfg->line_outs) {
914		while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
915		       cfg->line_out_pins[cfg->line_outs])
916			cfg->line_outs++;
917	}
918	if (!cfg->speaker_outs) {
919		while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
920		       cfg->speaker_pins[cfg->speaker_outs])
921			cfg->speaker_outs++;
922	}
923	if (!cfg->hp_outs) {
924		while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
925		       cfg->hp_pins[cfg->hp_outs])
926			cfg->hp_outs++;
927	}
928}
929
930/*
931 */
932static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
933{
934	if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
935		return;
936	spec->mixers[spec->num_mixers++] = mix;
937}
938
939static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
940{
941	if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
942		return;
943	spec->init_verbs[spec->num_init_verbs++] = verb;
944}
945
946/*
947 * set up from the preset table
948 */
949static void setup_preset(struct hda_codec *codec,
950			 const struct alc_config_preset *preset)
951{
952	struct alc_spec *spec = codec->spec;
953	int i;
954
955	for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
956		add_mixer(spec, preset->mixers[i]);
957	spec->cap_mixer = preset->cap_mixer;
958	for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
959	     i++)
960		add_verb(spec, preset->init_verbs[i]);
961
962	spec->channel_mode = preset->channel_mode;
963	spec->num_channel_mode = preset->num_channel_mode;
964	spec->need_dac_fix = preset->need_dac_fix;
965	spec->const_channel_count = preset->const_channel_count;
966
967	if (preset->const_channel_count)
968		spec->multiout.max_channels = preset->const_channel_count;
969	else
970		spec->multiout.max_channels = spec->channel_mode[0].channels;
971	spec->ext_channel_count = spec->channel_mode[0].channels;
972
973	spec->multiout.num_dacs = preset->num_dacs;
974	spec->multiout.dac_nids = preset->dac_nids;
975	spec->multiout.dig_out_nid = preset->dig_out_nid;
976	spec->multiout.slave_dig_outs = preset->slave_dig_outs;
977	spec->multiout.hp_nid = preset->hp_nid;
978
979	spec->num_mux_defs = preset->num_mux_defs;
980	if (!spec->num_mux_defs)
981		spec->num_mux_defs = 1;
982	spec->input_mux = preset->input_mux;
983
984	spec->num_adc_nids = preset->num_adc_nids;
985	spec->adc_nids = preset->adc_nids;
986	spec->capsrc_nids = preset->capsrc_nids;
987	spec->dig_in_nid = preset->dig_in_nid;
988
989	spec->unsol_event = preset->unsol_event;
990	spec->init_hook = preset->init_hook;
991#ifdef CONFIG_SND_HDA_POWER_SAVE
992	spec->power_hook = preset->power_hook;
993	spec->loopback.amplist = preset->loopbacks;
994#endif
995
996	if (preset->setup)
997		preset->setup(codec);
998
999	alc_fixup_autocfg_pin_nums(codec);
1000}
1001
1002/* Enable GPIO mask and set output */
1003static const struct hda_verb alc_gpio1_init_verbs[] = {
1004	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
1005	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
1006	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
1007	{ }
1008};
1009
1010static const struct hda_verb alc_gpio2_init_verbs[] = {
1011	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
1012	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
1013	{0x01, AC_VERB_SET_GPIO_DATA, 0x02},
1014	{ }
1015};
1016
1017static const struct hda_verb alc_gpio3_init_verbs[] = {
1018	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
1019	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
1020	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
1021	{ }
1022};
1023
1024/*
1025 * Fix hardware PLL issue
1026 * On some codecs, the analog PLL gating control must be off while
1027 * the default value is 1.
1028 */
1029static void alc_fix_pll(struct hda_codec *codec)
1030{
1031	struct alc_spec *spec = codec->spec;
1032	unsigned int val;
1033
1034	if (!spec->pll_nid)
1035		return;
1036	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1037			    spec->pll_coef_idx);
1038	val = snd_hda_codec_read(codec, spec->pll_nid, 0,
1039				 AC_VERB_GET_PROC_COEF, 0);
1040	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1041			    spec->pll_coef_idx);
1042	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
1043			    val & ~(1 << spec->pll_coef_bit));
1044}
1045
1046static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1047			     unsigned int coef_idx, unsigned int coef_bit)
1048{
1049	struct alc_spec *spec = codec->spec;
1050	spec->pll_nid = nid;
1051	spec->pll_coef_idx = coef_idx;
1052	spec->pll_coef_bit = coef_bit;
1053	alc_fix_pll(codec);
1054}
1055
1056static int alc_init_jacks(struct hda_codec *codec)
1057{
1058#ifdef CONFIG_SND_HDA_INPUT_JACK
1059	struct alc_spec *spec = codec->spec;
1060	int err;
1061	unsigned int hp_nid = spec->autocfg.hp_pins[0];
1062	unsigned int mic_nid = spec->ext_mic.pin;
1063	unsigned int dock_nid = spec->dock_mic.pin;
1064
1065	if (hp_nid) {
1066		err = snd_hda_input_jack_add(codec, hp_nid,
1067					     SND_JACK_HEADPHONE, NULL);
1068		if (err < 0)
1069			return err;
1070		snd_hda_input_jack_report(codec, hp_nid);
1071	}
1072
1073	if (mic_nid) {
1074		err = snd_hda_input_jack_add(codec, mic_nid,
1075					     SND_JACK_MICROPHONE, NULL);
1076		if (err < 0)
1077			return err;
1078		snd_hda_input_jack_report(codec, mic_nid);
1079	}
1080	if (dock_nid) {
1081		err = snd_hda_input_jack_add(codec, dock_nid,
1082					     SND_JACK_MICROPHONE, NULL);
1083		if (err < 0)
1084			return err;
1085		snd_hda_input_jack_report(codec, dock_nid);
1086	}
1087#endif /* CONFIG_SND_HDA_INPUT_JACK */
1088	return 0;
1089}
1090
1091static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
1092{
1093	int i, present = 0;
1094
1095	for (i = 0; i < num_pins; i++) {
1096		hda_nid_t nid = pins[i];
1097		if (!nid)
1098			break;
1099		snd_hda_input_jack_report(codec, nid);
1100		present |= snd_hda_jack_detect(codec, nid);
1101	}
1102	return present;
1103}
1104
1105static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
1106			bool mute, bool hp_out)
1107{
1108	struct alc_spec *spec = codec->spec;
1109	unsigned int mute_bits = mute ? HDA_AMP_MUTE : 0;
1110	unsigned int pin_bits = mute ? 0 : (hp_out ? PIN_HP : PIN_OUT);
1111	int i;
1112
1113	for (i = 0; i < num_pins; i++) {
1114		hda_nid_t nid = pins[i];
1115		if (!nid)
1116			break;
1117		switch (spec->automute_mode) {
1118		case ALC_AUTOMUTE_PIN:
1119			snd_hda_codec_write(codec, nid, 0,
1120					    AC_VERB_SET_PIN_WIDGET_CONTROL,
1121					    pin_bits);
1122			break;
1123		case ALC_AUTOMUTE_AMP:
1124			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1125						 HDA_AMP_MUTE, mute_bits);
1126			break;
1127		case ALC_AUTOMUTE_MIXER:
1128			nid = spec->automute_mixer_nid[i];
1129			if (!nid)
1130				break;
1131			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
1132						 HDA_AMP_MUTE, mute_bits);
1133			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 1,
1134						 HDA_AMP_MUTE, mute_bits);
1135			break;
1136		}
1137	}
1138}
1139
1140/* Toggle internal speakers muting */
1141static void update_speakers(struct hda_codec *codec)
1142{
1143	struct alc_spec *spec = codec->spec;
1144	int on;
1145
1146	/* Control HP pins/amps depending on master_mute state;
1147	 * in general, HP pins/amps control should be enabled in all cases,
1148	 * but currently set only for master_mute, just to be safe
1149	 */
1150	do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1151		    spec->autocfg.hp_pins, spec->master_mute, true);
1152
1153	if (!spec->automute)
1154		on = 0;
1155	else
1156		on = spec->jack_present | spec->line_jack_present;
1157	on |= spec->master_mute;
1158	do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins),
1159		    spec->autocfg.speaker_pins, on, false);
1160
1161	/* toggle line-out mutes if needed, too */
1162	/* if LO is a copy of either HP or Speaker, don't need to handle it */
1163	if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] ||
1164	    spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0])
1165		return;
1166	if (!spec->automute || (spec->automute_hp_lo && !spec->automute_lines))
1167		on = 0;
1168	else
1169		on = spec->jack_present;
1170	on |= spec->master_mute;
1171	do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1172		    spec->autocfg.line_out_pins, on, false);
1173}
1174
1175static void alc_hp_automute(struct hda_codec *codec)
1176{
1177	struct alc_spec *spec = codec->spec;
1178
1179	if (!spec->automute)
1180		return;
1181	spec->jack_present =
1182		detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1183			     spec->autocfg.hp_pins);
1184	update_speakers(codec);
1185}
1186
1187static void alc_line_automute(struct hda_codec *codec)
1188{
1189	struct alc_spec *spec = codec->spec;
1190
1191	if (!spec->automute || !spec->detect_line)
1192		return;
1193	spec->line_jack_present =
1194		detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1195			     spec->autocfg.line_out_pins);
1196	update_speakers(codec);
1197}
1198
1199static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1200				hda_nid_t nid)
1201{
1202	hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1203	int i, nums;
1204
1205	nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1206	for (i = 0; i < nums; i++)
1207		if (conn[i] == nid)
1208			return i;
1209	return -1;
1210}
1211
1212/* switch the current ADC according to the jack state */
1213static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1214{
1215	struct alc_spec *spec = codec->spec;
1216	unsigned int present;
1217	hda_nid_t new_adc;
1218
1219	present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1220	if (present)
1221		spec->cur_adc_idx = 1;
1222	else
1223		spec->cur_adc_idx = 0;
1224	new_adc = spec->adc_nids[spec->cur_adc_idx];
1225	if (spec->cur_adc && spec->cur_adc != new_adc) {
1226		/* stream is running, let's swap the current ADC */
1227		__snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
1228		spec->cur_adc = new_adc;
1229		snd_hda_codec_setup_stream(codec, new_adc,
1230					   spec->cur_adc_stream_tag, 0,
1231					   spec->cur_adc_format);
1232	}
1233}
1234
1235static void alc_mic_automute(struct hda_codec *codec)
1236{
1237	struct alc_spec *spec = codec->spec;
1238	struct alc_mic_route *dead1, *dead2, *alive;
1239	unsigned int present, type;
1240	hda_nid_t cap_nid;
1241
1242	if (!spec->auto_mic)
1243		return;
1244	if (!spec->int_mic.pin || !spec->ext_mic.pin)
1245		return;
1246	if (snd_BUG_ON(!spec->adc_nids))
1247		return;
1248
1249	if (spec->dual_adc_switch) {
1250		alc_dual_mic_adc_auto_switch(codec);
1251		return;
1252	}
1253
1254	cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1255
1256	alive = &spec->int_mic;
1257	dead1 = &spec->ext_mic;
1258	dead2 = &spec->dock_mic;
1259
1260	present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1261	if (present) {
1262		alive = &spec->ext_mic;
1263		dead1 = &spec->int_mic;
1264		dead2 = &spec->dock_mic;
1265	}
1266	if (!present && spec->dock_mic.pin > 0) {
1267		present = snd_hda_jack_detect(codec, spec->dock_mic.pin);
1268		if (present) {
1269			alive = &spec->dock_mic;
1270			dead1 = &spec->int_mic;
1271			dead2 = &spec->ext_mic;
1272		}
1273		snd_hda_input_jack_report(codec, spec->dock_mic.pin);
1274	}
1275
1276	type = get_wcaps_type(get_wcaps(codec, cap_nid));
1277	if (type == AC_WID_AUD_MIX) {
1278		/* Matrix-mixer style (e.g. ALC882) */
1279		snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1280					 alive->mux_idx,
1281					 HDA_AMP_MUTE, 0);
1282		if (dead1->pin > 0)
1283			snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1284						 dead1->mux_idx,
1285						 HDA_AMP_MUTE, HDA_AMP_MUTE);
1286		if (dead2->pin > 0)
1287			snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1288						 dead2->mux_idx,
1289						 HDA_AMP_MUTE, HDA_AMP_MUTE);
1290	} else {
1291		/* MUX style (e.g. ALC880) */
1292		snd_hda_codec_write_cache(codec, cap_nid, 0,
1293					  AC_VERB_SET_CONNECT_SEL,
1294					  alive->mux_idx);
1295	}
1296	snd_hda_input_jack_report(codec, spec->ext_mic.pin);
1297
1298	/* FIXME: analog mixer */
1299}
1300
1301/* unsolicited event for HP jack sensing */
1302static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1303{
1304	if (codec->vendor_id == 0x10ec0880)
1305		res >>= 28;
1306	else
1307		res >>= 26;
1308	switch (res) {
1309	case ALC880_HP_EVENT:
1310		alc_hp_automute(codec);
1311		break;
1312	case ALC880_FRONT_EVENT:
1313		alc_line_automute(codec);
1314		break;
1315	case ALC880_MIC_EVENT:
1316		alc_mic_automute(codec);
1317		break;
1318	}
1319}
1320
1321static void alc_inithook(struct hda_codec *codec)
1322{
1323	alc_hp_automute(codec);
1324	alc_line_automute(codec);
1325	alc_mic_automute(codec);
1326}
1327
1328/* additional initialization for ALC888 variants */
1329static void alc888_coef_init(struct hda_codec *codec)
1330{
1331	unsigned int tmp;
1332
1333	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1334	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1335	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1336	if ((tmp & 0xf0) == 0x20)
1337		/* alc888S-VC */
1338		snd_hda_codec_read(codec, 0x20, 0,
1339				   AC_VERB_SET_PROC_COEF, 0x830);
1340	 else
1341		 /* alc888-VB */
1342		 snd_hda_codec_read(codec, 0x20, 0,
1343				    AC_VERB_SET_PROC_COEF, 0x3030);
1344}
1345
1346static void alc889_coef_init(struct hda_codec *codec)
1347{
1348	unsigned int tmp;
1349
1350	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1351	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1352	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1353	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1354}
1355
1356/* turn on/off EAPD control (only if available) */
1357static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1358{
1359	if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1360		return;
1361	if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1362		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1363				    on ? 2 : 0);
1364}
1365
1366/* turn on/off EAPD controls of the codec */
1367static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
1368{
1369	/* We currently only handle front, HP */
1370	switch (codec->vendor_id) {
1371	case 0x10ec0260:
1372		set_eapd(codec, 0x0f, on);
1373		set_eapd(codec, 0x10, on);
1374		break;
1375	case 0x10ec0262:
1376	case 0x10ec0267:
1377	case 0x10ec0268:
1378	case 0x10ec0269:
1379	case 0x10ec0270:
1380	case 0x10ec0272:
1381	case 0x10ec0660:
1382	case 0x10ec0662:
1383	case 0x10ec0663:
1384	case 0x10ec0665:
1385	case 0x10ec0862:
1386	case 0x10ec0889:
1387	case 0x10ec0892:
1388		set_eapd(codec, 0x14, on);
1389		set_eapd(codec, 0x15, on);
1390		break;
1391	}
1392}
1393
1394/* generic shutup callback;
1395 * just turning off EPAD and a little pause for avoiding pop-noise
1396 */
1397static void alc_eapd_shutup(struct hda_codec *codec)
1398{
1399	alc_auto_setup_eapd(codec, false);
1400	msleep(200);
1401}
1402
1403static void alc_auto_init_amp(struct hda_codec *codec, int type)
1404{
1405	unsigned int tmp;
1406
1407	switch (type) {
1408	case ALC_INIT_GPIO1:
1409		snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1410		break;
1411	case ALC_INIT_GPIO2:
1412		snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1413		break;
1414	case ALC_INIT_GPIO3:
1415		snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1416		break;
1417	case ALC_INIT_DEFAULT:
1418		alc_auto_setup_eapd(codec, true);
1419		switch (codec->vendor_id) {
1420		case 0x10ec0260:
1421			snd_hda_codec_write(codec, 0x1a, 0,
1422					    AC_VERB_SET_COEF_INDEX, 7);
1423			tmp = snd_hda_codec_read(codec, 0x1a, 0,
1424						 AC_VERB_GET_PROC_COEF, 0);
1425			snd_hda_codec_write(codec, 0x1a, 0,
1426					    AC_VERB_SET_COEF_INDEX, 7);
1427			snd_hda_codec_write(codec, 0x1a, 0,
1428					    AC_VERB_SET_PROC_COEF,
1429					    tmp | 0x2010);
1430			break;
1431		case 0x10ec0262:
1432		case 0x10ec0880:
1433		case 0x10ec0882:
1434		case 0x10ec0883:
1435		case 0x10ec0885:
1436		case 0x10ec0887:
1437		/*case 0x10ec0889:*/ /* this causes an SPDIF problem */
1438			alc889_coef_init(codec);
1439			break;
1440		case 0x10ec0888:
1441			alc888_coef_init(codec);
1442			break;
1443#if 0 /* XXX: This may cause the silent output on speaker on some machines */
1444		case 0x10ec0267:
1445		case 0x10ec0268:
1446			snd_hda_codec_write(codec, 0x20, 0,
1447					    AC_VERB_SET_COEF_INDEX, 7);
1448			tmp = snd_hda_codec_read(codec, 0x20, 0,
1449						 AC_VERB_GET_PROC_COEF, 0);
1450			snd_hda_codec_write(codec, 0x20, 0,
1451					    AC_VERB_SET_COEF_INDEX, 7);
1452			snd_hda_codec_write(codec, 0x20, 0,
1453					    AC_VERB_SET_PROC_COEF,
1454					    tmp | 0x3000);
1455			break;
1456#endif /* XXX */
1457		}
1458		break;
1459	}
1460}
1461
1462static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
1463				  struct snd_ctl_elem_info *uinfo)
1464{
1465	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1466	struct alc_spec *spec = codec->spec;
1467	static const char * const texts2[] = {
1468		"Disabled", "Enabled"
1469	};
1470	static const char * const texts3[] = {
1471		"Disabled", "Speaker Only", "Line-Out+Speaker"
1472	};
1473	const char * const *texts;
1474
1475	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1476	uinfo->count = 1;
1477	if (spec->automute_hp_lo) {
1478		uinfo->value.enumerated.items = 3;
1479		texts = texts3;
1480	} else {
1481		uinfo->value.enumerated.items = 2;
1482		texts = texts2;
1483	}
1484	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1485		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1486	strcpy(uinfo->value.enumerated.name,
1487	       texts[uinfo->value.enumerated.item]);
1488	return 0;
1489}
1490
1491static int alc_automute_mode_get(struct snd_kcontrol *kcontrol,
1492				 struct snd_ctl_elem_value *ucontrol)
1493{
1494	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1495	struct alc_spec *spec = codec->spec;
1496	unsigned int val;
1497	if (!spec->automute)
1498		val = 0;
1499	else if (!spec->automute_hp_lo || !spec->automute_lines)
1500		val = 1;
1501	else
1502		val = 2;
1503	ucontrol->value.enumerated.item[0] = val;
1504	return 0;
1505}
1506
1507static int alc_automute_mode_put(struct snd_kcontrol *kcontrol,
1508				 struct snd_ctl_elem_value *ucontrol)
1509{
1510	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1511	struct alc_spec *spec = codec->spec;
1512
1513	switch (ucontrol->value.enumerated.item[0]) {
1514	case 0:
1515		if (!spec->automute)
1516			return 0;
1517		spec->automute = 0;
1518		break;
1519	case 1:
1520		if (spec->automute &&
1521		    (!spec->automute_hp_lo || !spec->automute_lines))
1522			return 0;
1523		spec->automute = 1;
1524		spec->automute_lines = 0;
1525		break;
1526	case 2:
1527		if (!spec->automute_hp_lo)
1528			return -EINVAL;
1529		if (spec->automute && spec->automute_lines)
1530			return 0;
1531		spec->automute = 1;
1532		spec->automute_lines = 1;
1533		break;
1534	default:
1535		return -EINVAL;
1536	}
1537	update_speakers(codec);
1538	return 1;
1539}
1540
1541static const struct snd_kcontrol_new alc_automute_mode_enum = {
1542	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1543	.name = "Auto-Mute Mode",
1544	.info = alc_automute_mode_info,
1545	.get = alc_automute_mode_get,
1546	.put = alc_automute_mode_put,
1547};
1548
1549static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec);
1550
1551static int alc_add_automute_mode_enum(struct hda_codec *codec)
1552{
1553	struct alc_spec *spec = codec->spec;
1554	struct snd_kcontrol_new *knew;
1555
1556	knew = alc_kcontrol_new(spec);
1557	if (!knew)
1558		return -ENOMEM;
1559	*knew = alc_automute_mode_enum;
1560	knew->name = kstrdup("Auto-Mute Mode", GFP_KERNEL);
1561	if (!knew->name)
1562		return -ENOMEM;
1563	return 0;
1564}
1565
1566static void alc_init_auto_hp(struct hda_codec *codec)
1567{
1568	struct alc_spec *spec = codec->spec;
1569	struct auto_pin_cfg *cfg = &spec->autocfg;
1570	int present = 0;
1571	int i;
1572
1573	if (cfg->hp_pins[0])
1574		present++;
1575	if (cfg->line_out_pins[0])
1576		present++;
1577	if (cfg->speaker_pins[0])
1578		present++;
1579	if (present < 2) /* need two different output types */
1580		return;
1581	if (present == 3)
1582		spec->automute_hp_lo = 1; /* both HP and LO automute */
1583
1584	if (!cfg->speaker_pins[0] &&
1585	    cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
1586		memcpy(cfg->speaker_pins, cfg->line_out_pins,
1587		       sizeof(cfg->speaker_pins));
1588		cfg->speaker_outs = cfg->line_outs;
1589	}
1590
1591	if (!cfg->hp_pins[0] &&
1592	    cfg->line_out_type == AUTO_PIN_HP_OUT) {
1593		memcpy(cfg->hp_pins, cfg->line_out_pins,
1594		       sizeof(cfg->hp_pins));
1595		cfg->hp_outs = cfg->line_outs;
1596	}
1597
1598	for (i = 0; i < cfg->hp_outs; i++) {
1599		hda_nid_t nid = cfg->hp_pins[i];
1600		if (!is_jack_detectable(codec, nid))
1601			continue;
1602		snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1603			    nid);
1604		snd_hda_codec_write_cache(codec, nid, 0,
1605				  AC_VERB_SET_UNSOLICITED_ENABLE,
1606				  AC_USRSP_EN | ALC880_HP_EVENT);
1607		spec->automute = 1;
1608		spec->automute_mode = ALC_AUTOMUTE_PIN;
1609	}
1610	if (spec->automute && cfg->line_out_pins[0] &&
1611	    cfg->speaker_pins[0] &&
1612	    cfg->line_out_pins[0] != cfg->hp_pins[0] &&
1613	    cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
1614		for (i = 0; i < cfg->line_outs; i++) {
1615			hda_nid_t nid = cfg->line_out_pins[i];
1616			if (!is_jack_detectable(codec, nid))
1617				continue;
1618			snd_printdd("realtek: Enable Line-Out auto-muting "
1619				    "on NID 0x%x\n", nid);
1620			snd_hda_codec_write_cache(codec, nid, 0,
1621					AC_VERB_SET_UNSOLICITED_ENABLE,
1622					AC_USRSP_EN | ALC880_FRONT_EVENT);
1623			spec->detect_line = 1;
1624		}
1625		spec->automute_lines = spec->detect_line;
1626	}
1627
1628	if (spec->automute) {
1629		/* create a control for automute mode */
1630		alc_add_automute_mode_enum(codec);
1631		spec->unsol_event = alc_sku_unsol_event;
1632	}
1633}
1634
1635static void alc_init_auto_mic(struct hda_codec *codec)
1636{
1637	struct alc_spec *spec = codec->spec;
1638	struct auto_pin_cfg *cfg = &spec->autocfg;
1639	hda_nid_t fixed, ext, dock;
1640	int i;
1641
1642	fixed = ext = dock = 0;
1643	for (i = 0; i < cfg->num_inputs; i++) {
1644		hda_nid_t nid = cfg->inputs[i].pin;
1645		unsigned int defcfg;
1646		defcfg = snd_hda_codec_get_pincfg(codec, nid);
1647		switch (snd_hda_get_input_pin_attr(defcfg)) {
1648		case INPUT_PIN_ATTR_INT:
1649			if (fixed)
1650				return; /* already occupied */
1651			if (cfg->inputs[i].type != AUTO_PIN_MIC)
1652				return; /* invalid type */
1653			fixed = nid;
1654			break;
1655		case INPUT_PIN_ATTR_UNUSED:
1656			return; /* invalid entry */
1657		case INPUT_PIN_ATTR_DOCK:
1658			if (dock)
1659				return; /* already occupied */
1660			if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
1661				return; /* invalid type */
1662			dock = nid;
1663			break;
1664		default:
1665			if (ext)
1666				return; /* already occupied */
1667			if (cfg->inputs[i].type != AUTO_PIN_MIC)
1668				return; /* invalid type */
1669			ext = nid;
1670			break;
1671		}
1672	}
1673	if (!ext && dock) {
1674		ext = dock;
1675		dock = 0;
1676	}
1677	if (!ext || !fixed)
1678		return;
1679	if (!is_jack_detectable(codec, ext))
1680		return; /* no unsol support */
1681	if (dock && !is_jack_detectable(codec, dock))
1682		return; /* no unsol support */
1683	snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n",
1684		    ext, fixed, dock);
1685	spec->ext_mic.pin = ext;
1686	spec->dock_mic.pin = dock;
1687	spec->int_mic.pin = fixed;
1688	spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1689	spec->dock_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1690	spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1691	spec->auto_mic = 1;
1692	snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1693				  AC_VERB_SET_UNSOLICITED_ENABLE,
1694				  AC_USRSP_EN | ALC880_MIC_EVENT);
1695	spec->unsol_event = alc_sku_unsol_event;
1696}
1697
1698/* Could be any non-zero and even value. When used as fixup, tells
1699 * the driver to ignore any present sku defines.
1700 */
1701#define ALC_FIXUP_SKU_IGNORE (2)
1702
1703static int alc_auto_parse_customize_define(struct hda_codec *codec)
1704{
1705	unsigned int ass, tmp, i;
1706	unsigned nid = 0;
1707	struct alc_spec *spec = codec->spec;
1708
1709	spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1710
1711	if (spec->cdefine.fixup) {
1712		ass = spec->cdefine.sku_cfg;
1713		if (ass == ALC_FIXUP_SKU_IGNORE)
1714			return -1;
1715		goto do_sku;
1716	}
1717
1718	ass = codec->subsystem_id & 0xffff;
1719	if (ass != codec->bus->pci->subsystem_device && (ass & 1))
1720		goto do_sku;
1721
1722	nid = 0x1d;
1723	if (codec->vendor_id == 0x10ec0260)
1724		nid = 0x17;
1725	ass = snd_hda_codec_get_pincfg(codec, nid);
1726
1727	if (!(ass & 1)) {
1728		printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1729		       codec->chip_name, ass);
1730		return -1;
1731	}
1732
1733	/* check sum */
1734	tmp = 0;
1735	for (i = 1; i < 16; i++) {
1736		if ((ass >> i) & 1)
1737			tmp++;
1738	}
1739	if (((ass >> 16) & 0xf) != tmp)
1740		return -1;
1741
1742	spec->cdefine.port_connectivity = ass >> 30;
1743	spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1744	spec->cdefine.check_sum = (ass >> 16) & 0xf;
1745	spec->cdefine.customization = ass >> 8;
1746do_sku:
1747	spec->cdefine.sku_cfg = ass;
1748	spec->cdefine.external_amp = (ass & 0x38) >> 3;
1749	spec->cdefine.platform_type = (ass & 0x4) >> 2;
1750	spec->cdefine.swap = (ass & 0x2) >> 1;
1751	spec->cdefine.override = ass & 0x1;
1752
1753	snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1754		   nid, spec->cdefine.sku_cfg);
1755	snd_printd("SKU: port_connectivity=0x%x\n",
1756		   spec->cdefine.port_connectivity);
1757	snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1758	snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1759	snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1760	snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1761	snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1762	snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1763	snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1764
1765	return 0;
1766}
1767
1768/* check subsystem ID and set up device-specific initialization;
1769 * return 1 if initialized, 0 if invalid SSID
1770 */
1771/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1772 *	31 ~ 16 :	Manufacture ID
1773 *	15 ~ 8	:	SKU ID
1774 *	7  ~ 0	:	Assembly ID
1775 *	port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1776 */
1777static int alc_subsystem_id(struct hda_codec *codec,
1778			    hda_nid_t porta, hda_nid_t porte,
1779			    hda_nid_t portd, hda_nid_t porti)
1780{
1781	unsigned int ass, tmp, i;
1782	unsigned nid;
1783	struct alc_spec *spec = codec->spec;
1784
1785	if (spec->cdefine.fixup) {
1786		ass = spec->cdefine.sku_cfg;
1787		if (ass == ALC_FIXUP_SKU_IGNORE)
1788			return 0;
1789		goto do_sku;
1790	}
1791
1792	ass = codec->subsystem_id & 0xffff;
1793	if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1794		goto do_sku;
1795
1796	/* invalid SSID, check the special NID pin defcfg instead */
1797	/*
1798	 * 31~30	: port connectivity
1799	 * 29~21	: reserve
1800	 * 20		: PCBEEP input
1801	 * 19~16	: Check sum (15:1)
1802	 * 15~1		: Custom
1803	 * 0		: override
1804	*/
1805	nid = 0x1d;
1806	if (codec->vendor_id == 0x10ec0260)
1807		nid = 0x17;
1808	ass = snd_hda_codec_get_pincfg(codec, nid);
1809	snd_printd("realtek: No valid SSID, "
1810		   "checking pincfg 0x%08x for NID 0x%x\n",
1811		   ass, nid);
1812	if (!(ass & 1))
1813		return 0;
1814	if ((ass >> 30) != 1)	/* no physical connection */
1815		return 0;
1816
1817	/* check sum */
1818	tmp = 0;
1819	for (i = 1; i < 16; i++) {
1820		if ((ass >> i) & 1)
1821			tmp++;
1822	}
1823	if (((ass >> 16) & 0xf) != tmp)
1824		return 0;
1825do_sku:
1826	snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1827		   ass & 0xffff, codec->vendor_id);
1828	/*
1829	 * 0 : override
1830	 * 1 :	Swap Jack
1831	 * 2 : 0 --> Desktop, 1 --> Laptop
1832	 * 3~5 : External Amplifier control
1833	 * 7~6 : Reserved
1834	*/
1835	tmp = (ass & 0x38) >> 3;	/* external Amp control */
1836	switch (tmp) {
1837	case 1:
1838		spec->init_amp = ALC_INIT_GPIO1;
1839		break;
1840	case 3:
1841		spec->init_amp = ALC_INIT_GPIO2;
1842		break;
1843	case 7:
1844		spec->init_amp = ALC_INIT_GPIO3;
1845		break;
1846	case 5:
1847	default:
1848		spec->init_amp = ALC_INIT_DEFAULT;
1849		break;
1850	}
1851
1852	/* is laptop or Desktop and enable the function "Mute internal speaker
1853	 * when the external headphone out jack is plugged"
1854	 */
1855	if (!(ass & 0x8000))
1856		return 1;
1857	/*
1858	 * 10~8 : Jack location
1859	 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1860	 * 14~13: Resvered
1861	 * 15   : 1 --> enable the function "Mute internal speaker
1862	 *	        when the external headphone out jack is plugged"
1863	 */
1864	if (!spec->autocfg.hp_pins[0] &&
1865	    !(spec->autocfg.line_out_pins[0] &&
1866	      spec->autocfg.line_out_type == AUTO_PIN_HP_OUT)) {
1867		hda_nid_t nid;
1868		tmp = (ass >> 11) & 0x3;	/* HP to chassis */
1869		if (tmp == 0)
1870			nid = porta;
1871		else if (tmp == 1)
1872			nid = porte;
1873		else if (tmp == 2)
1874			nid = portd;
1875		else if (tmp == 3)
1876			nid = porti;
1877		else
1878			return 1;
1879		for (i = 0; i < spec->autocfg.line_outs; i++)
1880			if (spec->autocfg.line_out_pins[i] == nid)
1881				return 1;
1882		spec->autocfg.hp_pins[0] = nid;
1883	}
1884	return 1;
1885}
1886
1887static void alc_ssid_check(struct hda_codec *codec,
1888			   hda_nid_t porta, hda_nid_t porte,
1889			   hda_nid_t portd, hda_nid_t porti)
1890{
1891	if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
1892		struct alc_spec *spec = codec->spec;
1893		snd_printd("realtek: "
1894			   "Enable default setup for auto mode as fallback\n");
1895		spec->init_amp = ALC_INIT_DEFAULT;
1896	}
1897
1898	alc_init_auto_hp(codec);
1899	alc_init_auto_mic(codec);
1900}
1901
1902/*
1903 * Fix-up pin default configurations and add default verbs
1904 */
1905
1906struct alc_pincfg {
1907	hda_nid_t nid;
1908	u32 val;
1909};
1910
1911struct alc_model_fixup {
1912	const int id;
1913	const char *name;
1914};
1915
1916struct alc_fixup {
1917	int type;
1918	bool chained;
1919	int chain_id;
1920	union {
1921		unsigned int sku;
1922		const struct alc_pincfg *pins;
1923		const struct hda_verb *verbs;
1924		void (*func)(struct hda_codec *codec,
1925			     const struct alc_fixup *fix,
1926			     int action);
1927	} v;
1928};
1929
1930enum {
1931	ALC_FIXUP_INVALID,
1932	ALC_FIXUP_SKU,
1933	ALC_FIXUP_PINS,
1934	ALC_FIXUP_VERBS,
1935	ALC_FIXUP_FUNC,
1936};
1937
1938enum {
1939	ALC_FIXUP_ACT_PRE_PROBE,
1940	ALC_FIXUP_ACT_PROBE,
1941	ALC_FIXUP_ACT_INIT,
1942};
1943
1944static void alc_apply_fixup(struct hda_codec *codec, int action)
1945{
1946	struct alc_spec *spec = codec->spec;
1947	int id = spec->fixup_id;
1948#ifdef CONFIG_SND_DEBUG_VERBOSE
1949	const char *modelname = spec->fixup_name;
1950#endif
1951	int depth = 0;
1952
1953	if (!spec->fixup_list)
1954		return;
1955
1956	while (id >= 0) {
1957		const struct alc_fixup *fix = spec->fixup_list + id;
1958		const struct alc_pincfg *cfg;
1959
1960		switch (fix->type) {
1961		case ALC_FIXUP_SKU:
1962			if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
1963				break;;
1964			snd_printdd(KERN_INFO "hda_codec: %s: "
1965				    "Apply sku override for %s\n",
1966				    codec->chip_name, modelname);
1967			spec->cdefine.sku_cfg = fix->v.sku;
1968			spec->cdefine.fixup = 1;
1969			break;
1970		case ALC_FIXUP_PINS:
1971			cfg = fix->v.pins;
1972			if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
1973				break;
1974			snd_printdd(KERN_INFO "hda_codec: %s: "
1975				    "Apply pincfg for %s\n",
1976				    codec->chip_name, modelname);
1977			for (; cfg->nid; cfg++)
1978				snd_hda_codec_set_pincfg(codec, cfg->nid,
1979							 cfg->val);
1980			break;
1981		case ALC_FIXUP_VERBS:
1982			if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
1983				break;
1984			snd_printdd(KERN_INFO "hda_codec: %s: "
1985				    "Apply fix-verbs for %s\n",
1986				    codec->chip_name, modelname);
1987			add_verb(codec->spec, fix->v.verbs);
1988			break;
1989		case ALC_FIXUP_FUNC:
1990			if (!fix->v.func)
1991				break;
1992			snd_printdd(KERN_INFO "hda_codec: %s: "
1993				    "Apply fix-func for %s\n",
1994				    codec->chip_name, modelname);
1995			fix->v.func(codec, fix, action);
1996			break;
1997		default:
1998			snd_printk(KERN_ERR "hda_codec: %s: "
1999				   "Invalid fixup type %d\n",
2000				   codec->chip_name, fix->type);
2001			break;
2002		}
2003		if (!fix->chained)
2004			break;
2005		if (++depth > 10)
2006			break;
2007		id = fix->chain_id;
2008	}
2009}
2010
2011static void alc_pick_fixup(struct hda_codec *codec,
2012			   const struct alc_model_fixup *models,
2013			   const struct snd_pci_quirk *quirk,
2014			   const struct alc_fixup *fixlist)
2015{
2016	struct alc_spec *spec = codec->spec;
2017	int id = -1;
2018	const char *name = NULL;
2019
2020	if (codec->modelname && models) {
2021		while (models->name) {
2022			if (!strcmp(codec->modelname, models->name)) {
2023				id = models->id;
2024				name = models->name;
2025				break;
2026			}
2027			models++;
2028		}
2029	}
2030	if (id < 0) {
2031		quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
2032		if (quirk) {
2033			id = quirk->value;
2034#ifdef CONFIG_SND_DEBUG_VERBOSE
2035			name = quirk->name;
2036#endif
2037		}
2038	}
2039
2040	spec->fixup_id = id;
2041	if (id >= 0) {
2042		spec->fixup_list = fixlist;
2043		spec->fixup_name = name;
2044	}
2045}
2046
2047static int alc_read_coef_idx(struct hda_codec *codec,
2048			unsigned int coef_idx)
2049{
2050	unsigned int val;
2051	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2052		    		coef_idx);
2053	val = snd_hda_codec_read(codec, 0x20, 0,
2054			 	AC_VERB_GET_PROC_COEF, 0);
2055	return val;
2056}
2057
2058static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
2059							unsigned int coef_val)
2060{
2061	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2062			    coef_idx);
2063	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
2064			    coef_val);
2065}
2066
2067/* set right pin controls for digital I/O */
2068static void alc_auto_init_digital(struct hda_codec *codec)
2069{
2070	struct alc_spec *spec = codec->spec;
2071	int i;
2072	hda_nid_t pin;
2073
2074	for (i = 0; i < spec->autocfg.dig_outs; i++) {
2075		pin = spec->autocfg.dig_out_pins[i];
2076		if (pin) {
2077			snd_hda_codec_write(codec, pin, 0,
2078					    AC_VERB_SET_PIN_WIDGET_CONTROL,
2079					    PIN_OUT);
2080		}
2081	}
2082	pin = spec->autocfg.dig_in_pin;
2083	if (pin)
2084		snd_hda_codec_write(codec, pin, 0,
2085				    AC_VERB_SET_PIN_WIDGET_CONTROL,
2086				    PIN_IN);
2087}
2088
2089/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
2090static void alc_auto_parse_digital(struct hda_codec *codec)
2091{
2092	struct alc_spec *spec = codec->spec;
2093	int i, err, nums;
2094	hda_nid_t dig_nid;
2095
2096	/* support multiple SPDIFs; the secondary is set up as a slave */
2097	nums = 0;
2098	for (i = 0; i < spec->autocfg.dig_outs; i++) {
2099		err = snd_hda_get_connections(codec,
2100					      spec->autocfg.dig_out_pins[i],
2101					      &dig_nid, 1);
2102		if (err <= 0)
2103			continue;
2104		if (!nums) {
2105			spec->multiout.dig_out_nid = dig_nid;
2106			spec->dig_out_type = spec->autocfg.dig_out_type[0];
2107		} else {
2108			spec->multiout.slave_dig_outs = spec->slave_dig_outs;
2109			if (nums >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
2110				break;
2111			spec->slave_dig_outs[nums - 1] = dig_nid;
2112		}
2113		nums++;
2114	}
2115
2116	if (spec->autocfg.dig_in_pin) {
2117		dig_nid = codec->start_nid;
2118		for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
2119			unsigned int wcaps = get_wcaps(codec, dig_nid);
2120			if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
2121				continue;
2122			if (!(wcaps & AC_WCAP_DIGITAL))
2123				continue;
2124			if (!(wcaps & AC_WCAP_CONN_LIST))
2125				continue;
2126			err = get_connection_index(codec, dig_nid,
2127						   spec->autocfg.dig_in_pin);
2128			if (err >= 0) {
2129				spec->dig_in_nid = dig_nid;
2130				break;
2131			}
2132		}
2133	}
2134}
2135
2136/*
2137 * ALC888
2138 */
2139
2140/*
2141 * 2ch mode
2142 */
2143static const struct hda_verb alc888_4ST_ch2_intel_init[] = {
2144/* Mic-in jack as mic in */
2145	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2146	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2147/* Line-in jack as Line in */
2148	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2149	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2150/* Line-Out as Front */
2151	{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2152	{ } /* end */
2153};
2154
2155/*
2156 * 4ch mode
2157 */
2158static const struct hda_verb alc888_4ST_ch4_intel_init[] = {
2159/* Mic-in jack as mic in */
2160	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2161	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2162/* Line-in jack as Surround */
2163	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2164	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2165/* Line-Out as Front */
2166	{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2167	{ } /* end */
2168};
2169
2170/*
2171 * 6ch mode
2172 */
2173static const struct hda_verb alc888_4ST_ch6_intel_init[] = {
2174/* Mic-in jack as CLFE */
2175	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2176	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2177/* Line-in jack as Surround */
2178	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2179	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2180/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
2181	{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2182	{ } /* end */
2183};
2184
2185/*
2186 * 8ch mode
2187 */
2188static const struct hda_verb alc888_4ST_ch8_intel_init[] = {
2189/* Mic-in jack as CLFE */
2190	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2191	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2192/* Line-in jack as Surround */
2193	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2194	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2195/* Line-Out as Side */
2196	{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2197	{ } /* end */
2198};
2199
2200static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
2201	{ 2, alc888_4ST_ch2_intel_init },
2202	{ 4, alc888_4ST_ch4_intel_init },
2203	{ 6, alc888_4ST_ch6_intel_init },
2204	{ 8, alc888_4ST_ch8_intel_init },
2205};
2206
2207/*
2208 * ALC888 Fujitsu Siemens Amillo xa3530
2209 */
2210
2211static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
2212/* Front Mic: set to PIN_IN (empty by default) */
2213	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2214/* Connect Internal HP to Front */
2215	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2216	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2217	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2218/* Connect Bass HP to Front */
2219	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2220	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2221	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2222/* Connect Line-Out side jack (SPDIF) to Side */
2223	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2224	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2225	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2226/* Connect Mic jack to CLFE */
2227	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2228	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2229	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
2230/* Connect Line-in jack to Surround */
2231	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2232	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2233	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
2234/* Connect HP out jack to Front */
2235	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2236	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2237	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2238/* Enable unsolicited event for HP jack and Line-out jack */
2239	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2240	{0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2241	{}
2242};
2243
2244static void alc889_automute_setup(struct hda_codec *codec)
2245{
2246	struct alc_spec *spec = codec->spec;
2247
2248	spec->autocfg.hp_pins[0] = 0x15;
2249	spec->autocfg.speaker_pins[0] = 0x14;
2250	spec->autocfg.speaker_pins[1] = 0x16;
2251	spec->autocfg.speaker_pins[2] = 0x17;
2252	spec->autocfg.speaker_pins[3] = 0x19;
2253	spec->autocfg.speaker_pins[4] = 0x1a;
2254	spec->automute = 1;
2255	spec->automute_mode = ALC_AUTOMUTE_AMP;
2256}
2257
2258static void alc889_intel_init_hook(struct hda_codec *codec)
2259{
2260	alc889_coef_init(codec);
2261	alc_hp_automute(codec);
2262}
2263
2264static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
2265{
2266	struct alc_spec *spec = codec->spec;
2267
2268	spec->autocfg.hp_pins[0] = 0x17; /* line-out */
2269	spec->autocfg.hp_pins[1] = 0x1b; /* hp */
2270	spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
2271	spec->autocfg.speaker_pins[1] = 0x15; /* bass */
2272	spec->automute = 1;
2273	spec->automute_mode = ALC_AUTOMUTE_AMP;
2274}
2275
2276/*
2277 * ALC888 Acer Aspire 4930G model
2278 */
2279
2280static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
2281/* Front Mic: set to PIN_IN (empty by default) */
2282	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2283/* Unselect Front Mic by default in input mixer 3 */
2284	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2285/* Enable unsolicited event for HP jack */
2286	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2287/* Connect Internal HP to front */
2288	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2289	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2290	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2291/* Connect HP out to front */
2292	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2293	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2294	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2295	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2296	{ }
2297};
2298
2299/*
2300 * ALC888 Acer Aspire 6530G model
2301 */
2302
2303static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
2304/* Route to built-in subwoofer as well as speakers */
2305	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2306	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2307	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2308	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2309/* Bias voltage on for external mic port */
2310	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2311/* Front Mic: set to PIN_IN (empty by default) */
2312	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2313/* Unselect Front Mic by default in input mixer 3 */
2314	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2315/* Enable unsolicited event for HP jack */
2316	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2317/* Enable speaker output */
2318	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2319	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2320	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2321/* Enable headphone output */
2322	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2323	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2324	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2325	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2326	{ }
2327};
2328
2329/*
2330 *ALC888 Acer Aspire 7730G model
2331 */
2332
2333static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
2334/* Bias voltage on for external mic port */
2335	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2336/* Front Mic: set to PIN_IN (empty by default) */
2337	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2338/* Unselect Front Mic by default in input mixer 3 */
2339	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2340/* Enable unsolicited event for HP jack */
2341	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2342/* Enable speaker output */
2343	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2344	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2345	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2346/* Enable headphone output */
2347	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2348	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2349	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2350	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2351/*Enable internal subwoofer */
2352	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2353	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2354	{0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2355	{0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2356	{ }
2357};
2358
2359/*
2360 * ALC889 Acer Aspire 8930G model
2361 */
2362
2363static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
2364/* Front Mic: set to PIN_IN (empty by default) */
2365	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2366/* Unselect Front Mic by default in input mixer 3 */
2367	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2368/* Enable unsolicited event for HP jack */
2369	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2370/* Connect Internal Front to Front */
2371	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2372	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2373	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2374/* Connect Internal Rear to Rear */
2375	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2376	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2377	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2378/* Connect Internal CLFE to CLFE */
2379	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2380	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2381	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2382/* Connect HP out to Front */
2383	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2384	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2385	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2386/* Enable all DACs */
2387/*  DAC DISABLE/MUTE 1? */
2388/*  setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2389	{0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2390	{0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2391/*  DAC DISABLE/MUTE 2? */
2392/*  some bit here disables the other DACs. Init=0x4900 */
2393	{0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2394	{0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2395/* DMIC fix
2396 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2397 * which makes the stereo useless. However, either the mic or the ALC889
2398 * makes the signal become a difference/sum signal instead of standard
2399 * stereo, which is annoying. So instead we flip this bit which makes the
2400 * codec replicate the sum signal to both channels, turning it into a
2401 * normal mono mic.
2402 */
2403/*  DMIC_CONTROL? Init value = 0x0001 */
2404	{0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2405	{0x20, AC_VERB_SET_PROC_COEF, 0x0003},
2406	{ }
2407};
2408
2409static const struct hda_input_mux alc888_2_capture_sources[2] = {
2410	/* Front mic only available on one ADC */
2411	{
2412		.num_items = 4,
2413		.items = {
2414			{ "Mic", 0x0 },
2415			{ "Line", 0x2 },
2416			{ "CD", 0x4 },
2417			{ "Front Mic", 0xb },
2418		},
2419	},
2420	{
2421		.num_items = 3,
2422		.items = {
2423			{ "Mic", 0x0 },
2424			{ "Line", 0x2 },
2425			{ "CD", 0x4 },
2426		},
2427	}
2428};
2429
2430static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2431	/* Interal mic only available on one ADC */
2432	{
2433		.num_items = 5,
2434		.items = {
2435			{ "Mic", 0x0 },
2436			{ "Line In", 0x2 },
2437			{ "CD", 0x4 },
2438			{ "Input Mix", 0xa },
2439			{ "Internal Mic", 0xb },
2440		},
2441	},
2442	{
2443		.num_items = 4,
2444		.items = {
2445			{ "Mic", 0x0 },
2446			{ "Line In", 0x2 },
2447			{ "CD", 0x4 },
2448			{ "Input Mix", 0xa },
2449		},
2450	}
2451};
2452
2453static const struct hda_input_mux alc889_capture_sources[3] = {
2454	/* Digital mic only available on first "ADC" */
2455	{
2456		.num_items = 5,
2457		.items = {
2458			{ "Mic", 0x0 },
2459			{ "Line", 0x2 },
2460			{ "CD", 0x4 },
2461			{ "Front Mic", 0xb },
2462			{ "Input Mix", 0xa },
2463		},
2464	},
2465	{
2466		.num_items = 4,
2467		.items = {
2468			{ "Mic", 0x0 },
2469			{ "Line", 0x2 },
2470			{ "CD", 0x4 },
2471			{ "Input Mix", 0xa },
2472		},
2473	},
2474	{
2475		.num_items = 4,
2476		.items = {
2477			{ "Mic", 0x0 },
2478			{ "Line", 0x2 },
2479			{ "CD", 0x4 },
2480			{ "Input Mix", 0xa },
2481		},
2482	}
2483};
2484
2485static const struct snd_kcontrol_new alc888_base_mixer[] = {
2486	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2487	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2488	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2489	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2490	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2491		HDA_OUTPUT),
2492	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2493	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2494	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2495	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2496	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2497	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2498	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2499	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2500	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2501	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2502	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2503	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2504	{ } /* end */
2505};
2506
2507static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
2508	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2509	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2510	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2511	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2512	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2513		HDA_OUTPUT),
2514	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2515	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2516	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2517	HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
2518	HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
2519	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2520	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2521	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2522	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2523	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2524	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2525	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2526	{ } /* end */
2527};
2528
2529static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2530	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2531	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2532	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2533	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2534	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2535		HDA_OUTPUT),
2536	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2537	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2538	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2539	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2540	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2541	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2542	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2543	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2544	{ } /* end */
2545};
2546
2547
2548static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
2549{
2550	struct alc_spec *spec = codec->spec;
2551
2552	spec->autocfg.hp_pins[0] = 0x15;
2553	spec->autocfg.speaker_pins[0] = 0x14;
2554	spec->autocfg.speaker_pins[1] = 0x16;
2555	spec->autocfg.speaker_pins[2] = 0x17;
2556	spec->automute = 1;
2557	spec->automute_mode = ALC_AUTOMUTE_AMP;
2558}
2559
2560static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
2561{
2562	struct alc_spec *spec = codec->spec;
2563
2564	spec->autocfg.hp_pins[0] = 0x15;
2565	spec->autocfg.speaker_pins[0] = 0x14;
2566	spec->autocfg.speaker_pins[1] = 0x16;
2567	spec->autocfg.speaker_pins[2] = 0x17;
2568	spec->automute = 1;
2569	spec->automute_mode = ALC_AUTOMUTE_AMP;
2570}
2571
2572static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2573{
2574	struct alc_spec *spec = codec->spec;
2575
2576	spec->autocfg.hp_pins[0] = 0x15;
2577	spec->autocfg.speaker_pins[0] = 0x14;
2578	spec->autocfg.speaker_pins[1] = 0x16;
2579	spec->autocfg.speaker_pins[2] = 0x17;
2580	spec->automute = 1;
2581	spec->automute_mode = ALC_AUTOMUTE_AMP;
2582}
2583
2584static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
2585{
2586	struct alc_spec *spec = codec->spec;
2587
2588	spec->autocfg.hp_pins[0] = 0x15;
2589	spec->autocfg.speaker_pins[0] = 0x14;
2590	spec->autocfg.speaker_pins[1] = 0x16;
2591	spec->autocfg.speaker_pins[2] = 0x1b;
2592	spec->automute = 1;
2593	spec->automute_mode = ALC_AUTOMUTE_AMP;
2594}
2595
2596/*
2597 * ALC880 3-stack model
2598 *
2599 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
2600 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2601 *                 F-Mic = 0x1b, HP = 0x19
2602 */
2603
2604static const hda_nid_t alc880_dac_nids[4] = {
2605	/* front, rear, clfe, rear_surr */
2606	0x02, 0x05, 0x04, 0x03
2607};
2608
2609static const hda_nid_t alc880_adc_nids[3] = {
2610	/* ADC0-2 */
2611	0x07, 0x08, 0x09,
2612};
2613
2614/* The datasheet says the node 0x07 is connected from inputs,
2615 * but it shows zero connection in the real implementation on some devices.
2616 * Note: this is a 915GAV bug, fixed on 915GLV
2617 */
2618static const hda_nid_t alc880_adc_nids_alt[2] = {
2619	/* ADC1-2 */
2620	0x08, 0x09,
2621};
2622
2623#define ALC880_DIGOUT_NID	0x06
2624#define ALC880_DIGIN_NID	0x0a
2625
2626static const struct hda_input_mux alc880_capture_source = {
2627	.num_items = 4,
2628	.items = {
2629		{ "Mic", 0x0 },
2630		{ "Front Mic", 0x3 },
2631		{ "Line", 0x2 },
2632		{ "CD", 0x4 },
2633	},
2634};
2635
2636/* channel source setting (2/6 channel selection for 3-stack) */
2637/* 2ch mode */
2638static const struct hda_verb alc880_threestack_ch2_init[] = {
2639	/* set line-in to input, mute it */
2640	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2641	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2642	/* set mic-in to input vref 80%, mute it */
2643	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2644	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2645	{ } /* end */
2646};
2647
2648/* 6ch mode */
2649static const struct hda_verb alc880_threestack_ch6_init[] = {
2650	/* set line-in to output, unmute it */
2651	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2652	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2653	/* set mic-in to output, unmute it */
2654	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2655	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2656	{ } /* end */
2657};
2658
2659static const struct hda_channel_mode alc880_threestack_modes[2] = {
2660	{ 2, alc880_threestack_ch2_init },
2661	{ 6, alc880_threestack_ch6_init },
2662};
2663
2664static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
2665	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2666	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2667	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2668	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2669	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2670	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2671	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2672	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2673	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2674	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2675	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2676	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2677	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2678	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2679	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2680	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
2681	HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2682	{
2683		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2684		.name = "Channel Mode",
2685		.info = alc_ch_mode_info,
2686		.get = alc_ch_mode_get,
2687		.put = alc_ch_mode_put,
2688	},
2689	{ } /* end */
2690};
2691
2692/* capture mixer elements */
2693static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2694			    struct snd_ctl_elem_info *uinfo)
2695{
2696	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2697	struct alc_spec *spec = codec->spec;
2698	int err;
2699
2700	mutex_lock(&codec->control_mutex);
2701	kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2702						      HDA_INPUT);
2703	err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
2704	mutex_unlock(&codec->control_mutex);
2705	return err;
2706}
2707
2708static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2709			   unsigned int size, unsigned int __user *tlv)
2710{
2711	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2712	struct alc_spec *spec = codec->spec;
2713	int err;
2714
2715	mutex_lock(&codec->control_mutex);
2716	kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2717						      HDA_INPUT);
2718	err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
2719	mutex_unlock(&codec->control_mutex);
2720	return err;
2721}
2722
2723typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2724			     struct snd_ctl_elem_value *ucontrol);
2725
2726static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2727				 struct snd_ctl_elem_value *ucontrol,
2728				 getput_call_t func, bool check_adc_switch)
2729{
2730	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2731	struct alc_spec *spec = codec->spec;
2732	int i, err = 0;
2733
2734	mutex_lock(&codec->control_mutex);
2735	if (check_adc_switch && spec->dual_adc_switch) {
2736		for (i = 0; i < spec->num_adc_nids; i++) {
2737			kcontrol->private_value =
2738				HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
2739						    3, 0, HDA_INPUT);
2740			err = func(kcontrol, ucontrol);
2741			if (err < 0)
2742				goto error;
2743		}
2744	} else {
2745		i = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2746		kcontrol->private_value =
2747			HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
2748					    3, 0, HDA_INPUT);
2749		err = func(kcontrol, ucontrol);
2750	}
2751 error:
2752	mutex_unlock(&codec->control_mutex);
2753	return err;
2754}
2755
2756static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2757			   struct snd_ctl_elem_value *ucontrol)
2758{
2759	return alc_cap_getput_caller(kcontrol, ucontrol,
2760				     snd_hda_mixer_amp_volume_get, false);
2761}
2762
2763static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2764			   struct snd_ctl_elem_value *ucontrol)
2765{
2766	return alc_cap_getput_caller(kcontrol, ucontrol,
2767				     snd_hda_mixer_amp_volume_put, true);
2768}
2769
2770/* capture mixer elements */
2771#define alc_cap_sw_info		snd_ctl_boolean_stereo_info
2772
2773static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2774			  struct snd_ctl_elem_value *ucontrol)
2775{
2776	return alc_cap_getput_caller(kcontrol, ucontrol,
2777				     snd_hda_mixer_amp_switch_get, false);
2778}
2779
2780static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2781			  struct snd_ctl_elem_value *ucontrol)
2782{
2783	return alc_cap_getput_caller(kcontrol, ucontrol,
2784				     snd_hda_mixer_amp_switch_put, true);
2785}
2786
2787#define _DEFINE_CAPMIX(num) \
2788	{ \
2789		.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2790		.name = "Capture Switch", \
2791		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2792		.count = num, \
2793		.info = alc_cap_sw_info, \
2794		.get = alc_cap_sw_get, \
2795		.put = alc_cap_sw_put, \
2796	}, \
2797	{ \
2798		.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2799		.name = "Capture Volume", \
2800		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2801			   SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2802			   SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2803		.count = num, \
2804		.info = alc_cap_vol_info, \
2805		.get = alc_cap_vol_get, \
2806		.put = alc_cap_vol_put, \
2807		.tlv = { .c = alc_cap_vol_tlv }, \
2808	}
2809
2810#define _DEFINE_CAPSRC(num) \
2811	{ \
2812		.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2813		/* .name = "Capture Source", */ \
2814		.name = "Input Source", \
2815		.count = num, \
2816		.info = alc_mux_enum_info, \
2817		.get = alc_mux_enum_get, \
2818		.put = alc_mux_enum_put, \
2819	}
2820
2821#define DEFINE_CAPMIX(num) \
2822static const struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2823	_DEFINE_CAPMIX(num),				      \
2824	_DEFINE_CAPSRC(num),				      \
2825	{ } /* end */					      \
2826}
2827
2828#define DEFINE_CAPMIX_NOSRC(num) \
2829static const struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2830	_DEFINE_CAPMIX(num),					    \
2831	{ } /* end */						    \
2832}
2833
2834/* up to three ADCs */
2835DEFINE_CAPMIX(1);
2836DEFINE_CAPMIX(2);
2837DEFINE_CAPMIX(3);
2838DEFINE_CAPMIX_NOSRC(1);
2839DEFINE_CAPMIX_NOSRC(2);
2840DEFINE_CAPMIX_NOSRC(3);
2841
2842/*
2843 * ALC880 5-stack model
2844 *
2845 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2846 *      Side = 0x02 (0xd)
2847 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2848 *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2849 */
2850
2851/* additional mixers to alc880_three_stack_mixer */
2852static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2853	HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2854	HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
2855	{ } /* end */
2856};
2857
2858/* channel source setting (6/8 channel selection for 5-stack) */
2859/* 6ch mode */
2860static const struct hda_verb alc880_fivestack_ch6_init[] = {
2861	/* set line-in to input, mute it */
2862	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2863	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2864	{ } /* end */
2865};
2866
2867/* 8ch mode */
2868static const struct hda_verb alc880_fivestack_ch8_init[] = {
2869	/* set line-in to output, unmute it */
2870	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2871	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2872	{ } /* end */
2873};
2874
2875static const struct hda_channel_mode alc880_fivestack_modes[2] = {
2876	{ 6, alc880_fivestack_ch6_init },
2877	{ 8, alc880_fivestack_ch8_init },
2878};
2879
2880
2881/*
2882 * ALC880 6-stack model
2883 *
2884 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2885 *      Side = 0x05 (0x0f)
2886 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2887 *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2888 */
2889
2890static const hda_nid_t alc880_6st_dac_nids[4] = {
2891	/* front, rear, clfe, rear_surr */
2892	0x02, 0x03, 0x04, 0x05
2893};
2894
2895static const struct hda_input_mux alc880_6stack_capture_source = {
2896	.num_items = 4,
2897	.items = {
2898		{ "Mic", 0x0 },
2899		{ "Front Mic", 0x1 },
2900		{ "Line", 0x2 },
2901		{ "CD", 0x4 },
2902	},
2903};
2904
2905/* fixed 8-channels */
2906static const struct hda_channel_mode alc880_sixstack_modes[1] = {
2907	{ 8, NULL },
2908};
2909
2910static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2911	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2912	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2913	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2914	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2915	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2916	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2917	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2918	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2919	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2920	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2921	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2922	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2923	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2924	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2925	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2926	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2927	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2928	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2929	{
2930		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2931		.name = "Channel Mode",
2932		.info = alc_ch_mode_info,
2933		.get = alc_ch_mode_get,
2934		.put = alc_ch_mode_put,
2935	},
2936	{ } /* end */
2937};
2938
2939
2940/*
2941 * ALC880 W810 model
2942 *
2943 * W810 has rear IO for:
2944 * Front (DAC 02)
2945 * Surround (DAC 03)
2946 * Center/LFE (DAC 04)
2947 * Digital out (06)
2948 *
2949 * The system also has a pair of internal speakers, and a headphone jack.
2950 * These are both connected to Line2 on the codec, hence to DAC 02.
2951 *
2952 * There is a variable resistor to control the speaker or headphone
2953 * volume. This is a hardware-only device without a software API.
2954 *
2955 * Plugging headphones in will disable the internal speakers. This is
2956 * implemented in hardware, not via the driver using jack sense. In
2957 * a similar fashion, plugging into the rear socket marked "front" will
2958 * disable both the speakers and headphones.
2959 *
2960 * For input, there's a microphone jack, and an "audio in" jack.
2961 * These may not do anything useful with this driver yet, because I
2962 * haven't setup any initialization verbs for these yet...
2963 */
2964
2965static const hda_nid_t alc880_w810_dac_nids[3] = {
2966	/* front, rear/surround, clfe */
2967	0x02, 0x03, 0x04
2968};
2969
2970/* fixed 6 channels */
2971static const struct hda_channel_mode alc880_w810_modes[1] = {
2972	{ 6, NULL }
2973};
2974
2975/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
2976static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2977	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2978	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2979	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2980	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2981	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2982	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2983	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2984	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2985	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2986	{ } /* end */
2987};
2988
2989
2990/*
2991 * Z710V model
2992 *
2993 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
2994 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2995 *                 Line = 0x1a
2996 */
2997
2998static const hda_nid_t alc880_z71v_dac_nids[1] = {
2999	0x02
3000};
3001#define ALC880_Z71V_HP_DAC	0x03
3002
3003/* fixed 2 channels */
3004static const struct hda_channel_mode alc880_2_jack_modes[1] = {
3005	{ 2, NULL }
3006};
3007
3008static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
3009	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3010	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3011	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3012	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
3013	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3014	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3015	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3016	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3017	{ } /* end */
3018};
3019
3020
3021/*
3022 * ALC880 F1734 model
3023 *
3024 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
3025 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
3026 */
3027
3028static const hda_nid_t alc880_f1734_dac_nids[1] = {
3029	0x03
3030};
3031#define ALC880_F1734_HP_DAC	0x02
3032
3033static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
3034	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3035	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3036	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3037	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3038	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3039	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3040	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3041	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3042	{ } /* end */
3043};
3044
3045static const struct hda_input_mux alc880_f1734_capture_source = {
3046	.num_items = 2,
3047	.items = {
3048		{ "Mic", 0x1 },
3049		{ "CD", 0x4 },
3050	},
3051};
3052
3053
3054/*
3055 * ALC880 ASUS model
3056 *
3057 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3058 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3059 *  Mic = 0x18, Line = 0x1a
3060 */
3061
3062#define alc880_asus_dac_nids	alc880_w810_dac_nids	/* identical with w810 */
3063#define alc880_asus_modes	alc880_threestack_modes	/* 2/6 channel mode */
3064
3065static const struct snd_kcontrol_new alc880_asus_mixer[] = {
3066	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3067	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3068	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3069	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3070	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3071	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3072	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3073	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3074	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3075	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3076	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3077	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3078	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3079	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3080	{
3081		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3082		.name = "Channel Mode",
3083		.info = alc_ch_mode_info,
3084		.get = alc_ch_mode_get,
3085		.put = alc_ch_mode_put,
3086	},
3087	{ } /* end */
3088};
3089
3090/*
3091 * ALC880 ASUS W1V model
3092 *
3093 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3094 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3095 *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
3096 */
3097
3098/* additional mixers to alc880_asus_mixer */
3099static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
3100	HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
3101	HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
3102	{ } /* end */
3103};
3104
3105/* TCL S700 */
3106static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
3107	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3108	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
3109	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
3110	HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
3111	HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
3112	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
3113	HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
3114	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
3115	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
3116	{ } /* end */
3117};
3118
3119/* Uniwill */
3120static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
3121	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3122	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3123	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3124	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3125	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3126	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3127	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3128	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3129	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3130	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3131	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3132	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3133	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3134	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3135	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3136	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3137	{
3138		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3139		.name = "Channel Mode",
3140		.info = alc_ch_mode_info,
3141		.get = alc_ch_mode_get,
3142		.put = alc_ch_mode_put,
3143	},
3144	{ } /* end */
3145};
3146
3147static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
3148	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3149	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3150	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3151	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3152	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3153	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3154	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3155	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3156	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3157	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3158	{ } /* end */
3159};
3160
3161static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
3162	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3163	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3164	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3165	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3166	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3167	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3168	{ } /* end */
3169};
3170
3171/*
3172 * virtual master controls
3173 */
3174
3175/*
3176 * slave controls for virtual master
3177 */
3178static const char * const alc_slave_vols[] = {
3179	"Front Playback Volume",
3180	"Surround Playback Volume",
3181	"Center Playback Volume",
3182	"LFE Playback Volume",
3183	"Side Playback Volume",
3184	"Headphone Playback Volume",
3185	"Speaker Playback Volume",
3186	"Mono Playback Volume",
3187	"Line-Out Playback Volume",
3188	NULL,
3189};
3190
3191static const char * const alc_slave_sws[] = {
3192	"Front Playback Switch",
3193	"Surround Playback Switch",
3194	"Center Playback Switch",
3195	"LFE Playback Switch",
3196	"Side Playback Switch",
3197	"Headphone Playback Switch",
3198	"Speaker Playback Switch",
3199	"Mono Playback Switch",
3200	"IEC958 Playback Switch",
3201	"Line-Out Playback Switch",
3202	NULL,
3203};
3204
3205/*
3206 * build control elements
3207 */
3208
3209#define NID_MAPPING		(-1)
3210
3211#define SUBDEV_SPEAKER_		(0 << 6)
3212#define SUBDEV_HP_		(1 << 6)
3213#define SUBDEV_LINE_		(2 << 6)
3214#define SUBDEV_SPEAKER(x)	(SUBDEV_SPEAKER_ | ((x) & 0x3f))
3215#define SUBDEV_HP(x)		(SUBDEV_HP_ | ((x) & 0x3f))
3216#define SUBDEV_LINE(x)		(SUBDEV_LINE_ | ((x) & 0x3f))
3217
3218static void alc_free_kctls(struct hda_codec *codec);
3219
3220#ifdef CONFIG_SND_HDA_INPUT_BEEP
3221/* additional beep mixers; the actual parameters are overwritten at build */
3222static const struct snd_kcontrol_new alc_beep_mixer[] = {
3223	HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
3224	HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
3225	{ } /* end */
3226};
3227#endif
3228
3229static int alc_build_controls(struct hda_codec *codec)
3230{
3231	struct alc_spec *spec = codec->spec;
3232	struct snd_kcontrol *kctl = NULL;
3233	const struct snd_kcontrol_new *knew;
3234	int i, j, err;
3235	unsigned int u;
3236	hda_nid_t nid;
3237
3238	for (i = 0; i < spec->num_mixers; i++) {
3239		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
3240		if (err < 0)
3241			return err;
3242	}
3243	if (spec->cap_mixer) {
3244		err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
3245		if (err < 0)
3246			return err;
3247	}
3248	if (spec->multiout.dig_out_nid) {
3249		err = snd_hda_create_spdif_out_ctls(codec,
3250						    spec->multiout.dig_out_nid);
3251		if (err < 0)
3252			return err;
3253		if (!spec->no_analog) {
3254			err = snd_hda_create_spdif_share_sw(codec,
3255							    &spec->multiout);
3256			if (err < 0)
3257				return err;
3258			spec->multiout.share_spdif = 1;
3259		}
3260	}
3261	if (spec->dig_in_nid) {
3262		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
3263		if (err < 0)
3264			return err;
3265	}
3266
3267#ifdef CONFIG_SND_HDA_INPUT_BEEP
3268	/* create beep controls if needed */
3269	if (spec->beep_amp) {
3270		const struct snd_kcontrol_new *knew;
3271		for (knew = alc_beep_mixer; knew->name; knew++) {
3272			struct snd_kcontrol *kctl;
3273			kctl = snd_ctl_new1(knew, codec);
3274			if (!kctl)
3275				return -ENOMEM;
3276			kctl->private_value = spec->beep_amp;
3277			err = snd_hda_ctl_add(codec, 0, kctl);
3278			if (err < 0)
3279				return err;
3280		}
3281	}
3282#endif
3283
3284	/* if we have no master control, let's create it */
3285	if (!spec->no_analog &&
3286	    !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
3287		unsigned int vmaster_tlv[4];
3288		snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
3289					HDA_OUTPUT, vmaster_tlv);
3290		err = snd_hda_add_vmaster(codec, "Master Playback Volume",
3291					  vmaster_tlv, alc_slave_vols);
3292		if (err < 0)
3293			return err;
3294	}
3295	if (!spec->no_analog &&
3296	    !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
3297		err = snd_hda_add_vmaster(codec, "Master Playback Switch",
3298					  NULL, alc_slave_sws);
3299		if (err < 0)
3300			return err;
3301	}
3302
3303	/* assign Capture Source enums to NID */
3304	if (spec->capsrc_nids || spec->adc_nids) {
3305		kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
3306		if (!kctl)
3307			kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3308		for (i = 0; kctl && i < kctl->count; i++) {
3309			const hda_nid_t *nids = spec->capsrc_nids;
3310			if (!nids)
3311				nids = spec->adc_nids;
3312			err = snd_hda_add_nid(codec, kctl, i, nids[i]);
3313			if (err < 0)
3314				return err;
3315		}
3316	}
3317	if (spec->cap_mixer) {
3318		const char *kname = kctl ? kctl->id.name : NULL;
3319		for (knew = spec->cap_mixer; knew->name; knew++) {
3320			if (kname && strcmp(knew->name, kname) == 0)
3321				continue;
3322			kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3323			for (i = 0; kctl && i < kctl->count; i++) {
3324				err = snd_hda_add_nid(codec, kctl, i,
3325						      spec->adc_nids[i]);
3326				if (err < 0)
3327					return err;
3328			}
3329		}
3330	}
3331
3332	/* other nid->control mapping */
3333	for (i = 0; i < spec->num_mixers; i++) {
3334		for (knew = spec->mixers[i]; knew->name; knew++) {
3335			if (knew->iface != NID_MAPPING)
3336				continue;
3337			kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3338			if (kctl == NULL)
3339				continue;
3340			u = knew->subdevice;
3341			for (j = 0; j < 4; j++, u >>= 8) {
3342				nid = u & 0x3f;
3343				if (nid == 0)
3344					continue;
3345				switch (u & 0xc0) {
3346				case SUBDEV_SPEAKER_:
3347					nid = spec->autocfg.speaker_pins[nid];
3348					break;
3349				case SUBDEV_LINE_:
3350					nid = spec->autocfg.line_out_pins[nid];
3351					break;
3352				case SUBDEV_HP_:
3353					nid = spec->autocfg.hp_pins[nid];
3354					break;
3355				default:
3356					continue;
3357				}
3358				err = snd_hda_add_nid(codec, kctl, 0, nid);
3359				if (err < 0)
3360					return err;
3361			}
3362			u = knew->private_value;
3363			for (j = 0; j < 4; j++, u >>= 8) {
3364				nid = u & 0xff;
3365				if (nid == 0)
3366					continue;
3367				err = snd_hda_add_nid(codec, kctl, 0, nid);
3368				if (err < 0)
3369					return err;
3370			}
3371		}
3372	}
3373
3374	alc_free_kctls(codec); /* no longer needed */
3375
3376	return 0;
3377}
3378
3379
3380/*
3381 * initialize the codec volumes, etc
3382 */
3383
3384/*
3385 * generic initialization of ADC, input mixers and output mixers
3386 */
3387static const struct hda_verb alc880_volume_init_verbs[] = {
3388	/*
3389	 * Unmute ADC0-2 and set the default input to mic-in
3390	 */
3391	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3392	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3393	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3394	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3395	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3396	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3397
3398	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3399	 * mixer widget
3400	 * Note: PASD motherboards uses the Line In 2 as the input for front
3401	 * panel mic (mic 2)
3402	 */
3403	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
3404	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3405	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3406	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3407	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3408	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3409	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3410	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3411
3412	/*
3413	 * Set up output mixers (0x0c - 0x0f)
3414	 */
3415	/* set vol=0 to output mixers */
3416	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3417	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3418	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3419	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3420	/* set up input amps for analog loopback */
3421	/* Amp Indices: DAC = 0, mixer = 1 */
3422	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3423	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3424	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3425	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3426	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3427	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3428	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3429	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3430
3431	{ }
3432};
3433
3434/*
3435 * 3-stack pin configuration:
3436 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3437 */
3438static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
3439	/*
3440	 * preset connection lists of input pins
3441	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3442	 */
3443	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3444	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3445	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3446
3447	/*
3448	 * Set pin mode and muting
3449	 */
3450	/* set front pin widgets 0x14 for output */
3451	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3452	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3453	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3454	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3455	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3456	/* Mic2 (as headphone out) for HP output */
3457	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3458	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3459	/* Line In pin widget for input */
3460	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3461	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3462	/* Line2 (as front mic) pin widget for input and vref at 80% */
3463	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3464	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3465	/* CD pin widget for input */
3466	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3467
3468	{ }
3469};
3470
3471/*
3472 * 5-stack pin configuration:
3473 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3474 * line-in/side = 0x1a, f-mic = 0x1b
3475 */
3476static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
3477	/*
3478	 * preset connection lists of input pins
3479	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3480	 */
3481	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3482	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
3483
3484	/*
3485	 * Set pin mode and muting
3486	 */
3487	/* set pin widgets 0x14-0x17 for output */
3488	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3489	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3490	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3491	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3492	/* unmute pins for output (no gain on this amp) */
3493	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3494	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3495	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3496	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3497
3498	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3499	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3500	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3501	/* Mic2 (as headphone out) for HP output */
3502	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3503	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3504	/* Line In pin widget for input */
3505	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3506	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3507	/* Line2 (as front mic) pin widget for input and vref at 80% */
3508	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3509	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3510	/* CD pin widget for input */
3511	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3512
3513	{ }
3514};
3515
3516/*
3517 * W810 pin configuration:
3518 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3519 */
3520static const struct hda_verb alc880_pin_w810_init_verbs[] = {
3521	/* hphone/speaker input selector: front DAC */
3522	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
3523
3524	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3525	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3526	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3527	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3528	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3529	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3530
3531	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3532	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3533
3534	{ }
3535};
3536
3537/*
3538 * Z71V pin configuration:
3539 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3540 */
3541static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
3542	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3543	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3544	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3545	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3546
3547	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3548	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3549	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3550	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3551
3552	{ }
3553};
3554
3555/*
3556 * 6-stack pin configuration:
3557 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3558 * f-mic = 0x19, line = 0x1a, HP = 0x1b
3559 */
3560static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
3561	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3562
3563	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3564	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3565	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3566	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3567	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3568	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3569	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3570	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3571
3572	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3573	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3574	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3575	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3576	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3577	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3578	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3579	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3580	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3581
3582	{ }
3583};
3584
3585/*
3586 * Uniwill pin configuration:
3587 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3588 * line = 0x1a
3589 */
3590static const struct hda_verb alc880_uniwill_init_verbs[] = {
3591	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3592
3593	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3594	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3595	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3596	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3597	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3598	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3599	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3600	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3601	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3602	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3603	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3604	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3605	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3606	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3607
3608	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3609	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3610	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3611	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3612	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3613	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3614	/* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3615	/* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3616	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3617
3618	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3619	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3620
3621	{ }
3622};
3623
3624/*
3625* Uniwill P53
3626* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
3627 */
3628static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3629	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3630
3631	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3632	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3633	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3634	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3635	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3636	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3637	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3638	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3639	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3640	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3641	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3642	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3643
3644	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3645	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3646	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3647	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3648	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3649	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3650
3651	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3652	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3653
3654	{ }
3655};
3656
3657static const struct hda_verb alc880_beep_init_verbs[] = {
3658	{ 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3659	{ }
3660};
3661
3662/* auto-toggle front mic */
3663static void alc88x_simple_mic_automute(struct hda_codec *codec)
3664{
3665 	unsigned int present;
3666	unsigned char bits;
3667
3668	present = snd_hda_jack_detect(codec, 0x18);
3669	bits = present ? HDA_AMP_MUTE : 0;
3670	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
3671}
3672
3673static void alc880_uniwill_setup(struct hda_codec *codec)
3674{
3675	struct alc_spec *spec = codec->spec;
3676
3677	spec->autocfg.hp_pins[0] = 0x14;
3678	spec->autocfg.speaker_pins[0] = 0x15;
3679	spec->autocfg.speaker_pins[0] = 0x16;
3680	spec->automute = 1;
3681	spec->automute_mode = ALC_AUTOMUTE_AMP;
3682}
3683
3684static void alc880_uniwill_init_hook(struct hda_codec *codec)
3685{
3686	alc_hp_automute(codec);
3687	alc88x_simple_mic_automute(codec);
3688}
3689
3690static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3691				       unsigned int res)
3692{
3693	/* Looks like the unsol event is incompatible with the standard
3694	 * definition.  4bit tag is placed at 28 bit!
3695	 */
3696	switch (res >> 28) {
3697	case ALC880_MIC_EVENT:
3698		alc88x_simple_mic_automute(codec);
3699		break;
3700	default:
3701		alc_sku_unsol_event(codec, res);
3702		break;
3703	}
3704}
3705
3706static void alc880_uniwill_p53_setup(struct hda_codec *codec)
3707{
3708	struct alc_spec *spec = codec->spec;
3709
3710	spec->autocfg.hp_pins[0] = 0x14;
3711	spec->autocfg.speaker_pins[0] = 0x15;
3712	spec->automute = 1;
3713	spec->automute_mode = ALC_AUTOMUTE_AMP;
3714}
3715
3716static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3717{
3718	unsigned int present;
3719
3720	present = snd_hda_codec_read(codec, 0x21, 0,
3721				     AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3722	present &= HDA_AMP_VOLMASK;
3723	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3724				 HDA_AMP_VOLMASK, present);
3725	snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3726				 HDA_AMP_VOLMASK, present);
3727}
3728
3729static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3730					   unsigned int res)
3731{
3732	/* Looks like the unsol event is incompatible with the standard
3733	 * definition.  4bit tag is placed at 28 bit!
3734	 */
3735	if ((res >> 28) == ALC880_DCVOL_EVENT)
3736		alc880_uniwill_p53_dcvol_automute(codec);
3737	else
3738		alc_sku_unsol_event(codec, res);
3739}
3740
3741/*
3742 * F1734 pin configuration:
3743 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3744 */
3745static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
3746	{0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
3747	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3748	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3749	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3750	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3751
3752	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3753	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3754	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3755	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3756
3757	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3758	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3759	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3760	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3761	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3762	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3763	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3764	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3765	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3766
3767	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3768	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3769
3770	{ }
3771};
3772
3773/*
3774 * ASUS pin configuration:
3775 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3776 */
3777static const struct hda_verb alc880_pin_asus_init_verbs[] = {
3778	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3779	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3780	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3781	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3782
3783	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3784	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3785	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3786	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3787	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3788	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3789	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3790	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3791
3792	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3793	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3794	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3795	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3796	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3797	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3798	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3799	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3800	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3801
3802	{ }
3803};
3804
3805/* Enable GPIO mask and set output */
3806#define alc880_gpio1_init_verbs	alc_gpio1_init_verbs
3807#define alc880_gpio2_init_verbs	alc_gpio2_init_verbs
3808#define alc880_gpio3_init_verbs	alc_gpio3_init_verbs
3809
3810/* Clevo m520g init */
3811static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
3812	/* headphone output */
3813	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3814	/* line-out */
3815	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3816	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3817	/* Line-in */
3818	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3819	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3820	/* CD */
3821	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3822	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3823	/* Mic1 (rear panel) */
3824	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3825	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3826	/* Mic2 (front panel) */
3827	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3828	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3829	/* headphone */
3830	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3831	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3832        /* change to EAPD mode */
3833	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3834	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
3835
3836	{ }
3837};
3838
3839static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
3840	/* change to EAPD mode */
3841	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3842	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
3843
3844	/* Headphone output */
3845	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3846	/* Front output*/
3847	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3848	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3849
3850	/* Line In pin widget for input */
3851	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3852	/* CD pin widget for input */
3853	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3854	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3855	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3856
3857	/* change to EAPD mode */
3858	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3859	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
3860
3861	{ }
3862};
3863
3864/*
3865 * LG m1 express dual
3866 *
3867 * Pin assignment:
3868 *   Rear Line-In/Out (blue): 0x14
3869 *   Build-in Mic-In: 0x15
3870 *   Speaker-out: 0x17
3871 *   HP-Out (green): 0x1b
3872 *   Mic-In/Out (red): 0x19
3873 *   SPDIF-Out: 0x1e
3874 */
3875
3876/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3877static const hda_nid_t alc880_lg_dac_nids[3] = {
3878	0x05, 0x02, 0x03
3879};
3880
3881/* seems analog CD is not working */
3882static const struct hda_input_mux alc880_lg_capture_source = {
3883	.num_items = 3,
3884	.items = {
3885		{ "Mic", 0x1 },
3886		{ "Line", 0x5 },
3887		{ "Internal Mic", 0x6 },
3888	},
3889};
3890
3891/* 2,4,6 channel modes */
3892static const struct hda_verb alc880_lg_ch2_init[] = {
3893	/* set line-in and mic-in to input */
3894	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3895	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3896	{ }
3897};
3898
3899static const struct hda_verb alc880_lg_ch4_init[] = {
3900	/* set line-in to out and mic-in to input */
3901	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3902	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3903	{ }
3904};
3905
3906static const struct hda_verb alc880_lg_ch6_init[] = {
3907	/* set line-in and mic-in to output */
3908	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3909	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3910	{ }
3911};
3912
3913static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
3914	{ 2, alc880_lg_ch2_init },
3915	{ 4, alc880_lg_ch4_init },
3916	{ 6, alc880_lg_ch6_init },
3917};
3918
3919static const struct snd_kcontrol_new alc880_lg_mixer[] = {
3920	HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3921	HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
3922	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3923	HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3924	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3925	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3926	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3927	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3928	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3929	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3930	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3931	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3932	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3933	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3934	{
3935		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3936		.name = "Channel Mode",
3937		.info = alc_ch_mode_info,
3938		.get = alc_ch_mode_get,
3939		.put = alc_ch_mode_put,
3940	},
3941	{ } /* end */
3942};
3943
3944static const struct hda_verb alc880_lg_init_verbs[] = {
3945	/* set capture source to mic-in */
3946	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3947	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3948	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3949	/* mute all amp mixer inputs */
3950	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
3951	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3952	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3953	/* line-in to input */
3954	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3955	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3956	/* built-in mic */
3957	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3958	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3959	/* speaker-out */
3960	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3961	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3962	/* mic-in to input */
3963	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3964	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3965	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3966	/* HP-out */
3967	{0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3968	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3969	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3970	/* jack sense */
3971	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3972	{ }
3973};
3974
3975/* toggle speaker-output according to the hp-jack state */
3976static void alc880_lg_setup(struct hda_codec *codec)
3977{
3978	struct alc_spec *spec = codec->spec;
3979
3980	spec->autocfg.hp_pins[0] = 0x1b;
3981	spec->autocfg.speaker_pins[0] = 0x17;
3982	spec->automute = 1;
3983	spec->automute_mode = ALC_AUTOMUTE_AMP;
3984}
3985
3986/*
3987 * LG LW20
3988 *
3989 * Pin assignment:
3990 *   Speaker-out: 0x14
3991 *   Mic-In: 0x18
3992 *   Built-in Mic-In: 0x19
3993 *   Line-In: 0x1b
3994 *   HP-Out: 0x1a
3995 *   SPDIF-Out: 0x1e
3996 */
3997
3998static const struct hda_input_mux alc880_lg_lw_capture_source = {
3999	.num_items = 3,
4000	.items = {
4001		{ "Mic", 0x0 },
4002		{ "Internal Mic", 0x1 },
4003		{ "Line In", 0x2 },
4004	},
4005};
4006
4007#define alc880_lg_lw_modes alc880_threestack_modes
4008
4009static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
4010	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4011	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4012	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4013	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
4014	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
4015	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4016	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
4017	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
4018	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4019	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4020	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4021	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4022	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
4023	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
4024	{
4025		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4026		.name = "Channel Mode",
4027		.info = alc_ch_mode_info,
4028		.get = alc_ch_mode_get,
4029		.put = alc_ch_mode_put,
4030	},
4031	{ } /* end */
4032};
4033
4034static const struct hda_verb alc880_lg_lw_init_verbs[] = {
4035	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4036	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
4037	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
4038
4039	/* set capture source to mic-in */
4040	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4041	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4042	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4043	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
4044	/* speaker-out */
4045	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4046	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4047	/* HP-out */
4048	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4049	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4050	/* mic-in to input */
4051	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4052	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4053	/* built-in mic */
4054	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4055	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4056	/* jack sense */
4057	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4058	{ }
4059};
4060
4061/* toggle speaker-output according to the hp-jack state */
4062static void alc880_lg_lw_setup(struct hda_codec *codec)
4063{
4064	struct alc_spec *spec = codec->spec;
4065
4066	spec->autocfg.hp_pins[0] = 0x1b;
4067	spec->autocfg.speaker_pins[0] = 0x14;
4068	spec->automute = 1;
4069	spec->automute_mode = ALC_AUTOMUTE_AMP;
4070}
4071
4072static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
4073	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4074	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
4075	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4076	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4077	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4078	HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
4079	{ } /* end */
4080};
4081
4082static const struct hda_input_mux alc880_medion_rim_capture_source = {
4083	.num_items = 2,
4084	.items = {
4085		{ "Mic", 0x0 },
4086		{ "Internal Mic", 0x1 },
4087	},
4088};
4089
4090static const struct hda_verb alc880_medion_rim_init_verbs[] = {
4091	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4092
4093	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4094	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4095
4096	/* Mic1 (rear panel) pin widget for input and vref at 80% */
4097	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4098	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4099	/* Mic2 (as headphone out) for HP output */
4100	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4101	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4102	/* Internal Speaker */
4103	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4104	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4105
4106	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
4107	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
4108
4109	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4110	{ }
4111};
4112
4113/* toggle speaker-output according to the hp-jack state */
4114static void alc880_medion_rim_automute(struct hda_codec *codec)
4115{
4116	struct alc_spec *spec = codec->spec;
4117	alc_hp_automute(codec);
4118	/* toggle EAPD */
4119	if (spec->jack_present)
4120		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
4121	else
4122		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
4123}
4124
4125static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
4126					  unsigned int res)
4127{
4128	/* Looks like the unsol event is incompatible with the standard
4129	 * definition.  4bit tag is placed at 28 bit!
4130	 */
4131	if ((res >> 28) == ALC880_HP_EVENT)
4132		alc880_medion_rim_automute(codec);
4133}
4134
4135static void alc880_medion_rim_setup(struct hda_codec *codec)
4136{
4137	struct alc_spec *spec = codec->spec;
4138
4139	spec->autocfg.hp_pins[0] = 0x14;
4140	spec->autocfg.speaker_pins[0] = 0x1b;
4141	spec->automute = 1;
4142	spec->automute_mode = ALC_AUTOMUTE_AMP;
4143}
4144
4145#ifdef CONFIG_SND_HDA_POWER_SAVE
4146static const struct hda_amp_list alc880_loopbacks[] = {
4147	{ 0x0b, HDA_INPUT, 0 },
4148	{ 0x0b, HDA_INPUT, 1 },
4149	{ 0x0b, HDA_INPUT, 2 },
4150	{ 0x0b, HDA_INPUT, 3 },
4151	{ 0x0b, HDA_INPUT, 4 },
4152	{ } /* end */
4153};
4154
4155static const struct hda_amp_list alc880_lg_loopbacks[] = {
4156	{ 0x0b, HDA_INPUT, 1 },
4157	{ 0x0b, HDA_INPUT, 6 },
4158	{ 0x0b, HDA_INPUT, 7 },
4159	{ } /* end */
4160};
4161#endif
4162
4163/*
4164 * Common callbacks
4165 */
4166
4167static void alc_init_special_input_src(struct hda_codec *codec);
4168
4169static int alc_init(struct hda_codec *codec)
4170{
4171	struct alc_spec *spec = codec->spec;
4172	unsigned int i;
4173
4174	alc_fix_pll(codec);
4175	alc_auto_init_amp(codec, spec->init_amp);
4176
4177	for (i = 0; i < spec->num_init_verbs; i++)
4178		snd_hda_sequence_write(codec, spec->init_verbs[i]);
4179	alc_init_special_input_src(codec);
4180
4181	if (spec->init_hook)
4182		spec->init_hook(codec);
4183
4184	alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
4185
4186	hda_call_check_power_status(codec, 0x01);
4187	return 0;
4188}
4189
4190static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
4191{
4192	struct alc_spec *spec = codec->spec;
4193
4194	if (spec->unsol_event)
4195		spec->unsol_event(codec, res);
4196}
4197
4198#ifdef CONFIG_SND_HDA_POWER_SAVE
4199static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
4200{
4201	struct alc_spec *spec = codec->spec;
4202	return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
4203}
4204#endif
4205
4206/*
4207 * Analog playback callbacks
4208 */
4209static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
4210				    struct hda_codec *codec,
4211				    struct snd_pcm_substream *substream)
4212{
4213	struct alc_spec *spec = codec->spec;
4214	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
4215					     hinfo);
4216}
4217
4218static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4219				       struct hda_codec *codec,
4220				       unsigned int stream_tag,
4221				       unsigned int format,
4222				       struct snd_pcm_substream *substream)
4223{
4224	struct alc_spec *spec = codec->spec;
4225	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
4226						stream_tag, format, substream);
4227}
4228
4229static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4230				       struct hda_codec *codec,
4231				       struct snd_pcm_substream *substream)
4232{
4233	struct alc_spec *spec = codec->spec;
4234	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
4235}
4236
4237/*
4238 * Digital out
4239 */
4240static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
4241					struct hda_codec *codec,
4242					struct snd_pcm_substream *substream)
4243{
4244	struct alc_spec *spec = codec->spec;
4245	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
4246}
4247
4248static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4249					   struct hda_codec *codec,
4250					   unsigned int stream_tag,
4251					   unsigned int format,
4252					   struct snd_pcm_substream *substream)
4253{
4254	struct alc_spec *spec = codec->spec;
4255	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
4256					     stream_tag, format, substream);
4257}
4258
4259static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4260					   struct hda_codec *codec,
4261					   struct snd_pcm_substream *substream)
4262{
4263	struct alc_spec *spec = codec->spec;
4264	return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
4265}
4266
4267static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
4268					 struct hda_codec *codec,
4269					 struct snd_pcm_substream *substream)
4270{
4271	struct alc_spec *spec = codec->spec;
4272	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
4273}
4274
4275/*
4276 * Analog capture
4277 */
4278static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4279				      struct hda_codec *codec,
4280				      unsigned int stream_tag,
4281				      unsigned int format,
4282				      struct snd_pcm_substream *substream)
4283{
4284	struct alc_spec *spec = codec->spec;
4285
4286	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
4287				   stream_tag, 0, format);
4288	return 0;
4289}
4290
4291static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4292				      struct hda_codec *codec,
4293				      struct snd_pcm_substream *substream)
4294{
4295	struct alc_spec *spec = codec->spec;
4296
4297	snd_hda_codec_cleanup_stream(codec,
4298				     spec->adc_nids[substream->number + 1]);
4299	return 0;
4300}
4301
4302/* analog capture with dynamic dual-adc changes */
4303static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4304				       struct hda_codec *codec,
4305				       unsigned int stream_tag,
4306				       unsigned int format,
4307				       struct snd_pcm_substream *substream)
4308{
4309	struct alc_spec *spec = codec->spec;
4310	spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
4311	spec->cur_adc_stream_tag = stream_tag;
4312	spec->cur_adc_format = format;
4313	snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
4314	return 0;
4315}
4316
4317static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4318				       struct hda_codec *codec,
4319				       struct snd_pcm_substream *substream)
4320{
4321	struct alc_spec *spec = codec->spec;
4322	snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4323	spec->cur_adc = 0;
4324	return 0;
4325}
4326
4327static const struct hda_pcm_stream dualmic_pcm_analog_capture = {
4328	.substreams = 1,
4329	.channels_min = 2,
4330	.channels_max = 2,
4331	.nid = 0, /* fill later */
4332	.ops = {
4333		.prepare = dualmic_capture_pcm_prepare,
4334		.cleanup = dualmic_capture_pcm_cleanup
4335	},
4336};
4337
4338/*
4339 */
4340static const struct hda_pcm_stream alc880_pcm_analog_playback = {
4341	.substreams = 1,
4342	.channels_min = 2,
4343	.channels_max = 8,
4344	/* NID is set in alc_build_pcms */
4345	.ops = {
4346		.open = alc880_playback_pcm_open,
4347		.prepare = alc880_playback_pcm_prepare,
4348		.cleanup = alc880_playback_pcm_cleanup
4349	},
4350};
4351
4352static const struct hda_pcm_stream alc880_pcm_analog_capture = {
4353	.substreams = 1,
4354	.channels_min = 2,
4355	.channels_max = 2,
4356	/* NID is set in alc_build_pcms */
4357};
4358
4359static const struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
4360	.substreams = 1,
4361	.channels_min = 2,
4362	.channels_max = 2,
4363	/* NID is set in alc_build_pcms */
4364};
4365
4366static const struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
4367	.substreams = 2, /* can be overridden */
4368	.channels_min = 2,
4369	.channels_max = 2,
4370	/* NID is set in alc_build_pcms */
4371	.ops = {
4372		.prepare = alc880_alt_capture_pcm_prepare,
4373		.cleanup = alc880_alt_capture_pcm_cleanup
4374	},
4375};
4376
4377static const struct hda_pcm_stream alc880_pcm_digital_playback = {
4378	.substreams = 1,
4379	.channels_min = 2,
4380	.channels_max = 2,
4381	/* NID is set in alc_build_pcms */
4382	.ops = {
4383		.open = alc880_dig_playback_pcm_open,
4384		.close = alc880_dig_playback_pcm_close,
4385		.prepare = alc880_dig_playback_pcm_prepare,
4386		.cleanup = alc880_dig_playback_pcm_cleanup
4387	},
4388};
4389
4390static const struct hda_pcm_stream alc880_pcm_digital_capture = {
4391	.substreams = 1,
4392	.channels_min = 2,
4393	.channels_max = 2,
4394	/* NID is set in alc_build_pcms */
4395};
4396
4397/* Used by alc_build_pcms to flag that a PCM has no playback stream */
4398static const struct hda_pcm_stream alc_pcm_null_stream = {
4399	.substreams = 0,
4400	.channels_min = 0,
4401	.channels_max = 0,
4402};
4403
4404static int alc_build_pcms(struct hda_codec *codec)
4405{
4406	struct alc_spec *spec = codec->spec;
4407	struct hda_pcm *info = spec->pcm_rec;
4408	int i;
4409
4410	codec->num_pcms = 1;
4411	codec->pcm_info = info;
4412
4413	if (spec->no_analog)
4414		goto skip_analog;
4415
4416	snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4417		 "%s Analog", codec->chip_name);
4418	info->name = spec->stream_name_analog;
4419
4420	if (spec->stream_analog_playback) {
4421		if (snd_BUG_ON(!spec->multiout.dac_nids))
4422			return -EINVAL;
4423		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
4424		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4425	}
4426	if (spec->stream_analog_capture) {
4427		if (snd_BUG_ON(!spec->adc_nids))
4428			return -EINVAL;
4429		info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
4430		info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4431	}
4432
4433	if (spec->channel_mode) {
4434		info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4435		for (i = 0; i < spec->num_channel_mode; i++) {
4436			if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4437				info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4438			}
4439		}
4440	}
4441
4442 skip_analog:
4443	/* SPDIF for stream index #1 */
4444	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
4445		snprintf(spec->stream_name_digital,
4446			 sizeof(spec->stream_name_digital),
4447			 "%s Digital", codec->chip_name);
4448		codec->num_pcms = 2;
4449	        codec->slave_dig_outs = spec->multiout.slave_dig_outs;
4450		info = spec->pcm_rec + 1;
4451		info->name = spec->stream_name_digital;
4452		if (spec->dig_out_type)
4453			info->pcm_type = spec->dig_out_type;
4454		else
4455			info->pcm_type = HDA_PCM_TYPE_SPDIF;
4456		if (spec->multiout.dig_out_nid &&
4457		    spec->stream_digital_playback) {
4458			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4459			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4460		}
4461		if (spec->dig_in_nid &&
4462		    spec->stream_digital_capture) {
4463			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4464			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4465		}
4466		/* FIXME: do we need this for all Realtek codec models? */
4467		codec->spdif_status_reset = 1;
4468	}
4469
4470	if (spec->no_analog)
4471		return 0;
4472
4473	/* If the use of more than one ADC is requested for the current
4474	 * model, configure a second analog capture-only PCM.
4475	 */
4476	/* Additional Analaog capture for index #2 */
4477	if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4478	    (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
4479		codec->num_pcms = 3;
4480		info = spec->pcm_rec + 2;
4481		info->name = spec->stream_name_analog;
4482		if (spec->alt_dac_nid) {
4483			info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4484				*spec->stream_analog_alt_playback;
4485			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4486				spec->alt_dac_nid;
4487		} else {
4488			info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4489				alc_pcm_null_stream;
4490			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4491		}
4492		if (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture) {
4493			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4494				*spec->stream_analog_alt_capture;
4495			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4496				spec->adc_nids[1];
4497			info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4498				spec->num_adc_nids - 1;
4499		} else {
4500			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4501				alc_pcm_null_stream;
4502			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
4503		}
4504	}
4505
4506	return 0;
4507}
4508
4509static inline void alc_shutup(struct hda_codec *codec)
4510{
4511	struct alc_spec *spec = codec->spec;
4512
4513	if (spec && spec->shutup)
4514		spec->shutup(codec);
4515	snd_hda_shutup_pins(codec);
4516}
4517
4518static void alc_free_kctls(struct hda_codec *codec)
4519{
4520	struct alc_spec *spec = codec->spec;
4521
4522	if (spec->kctls.list) {
4523		struct snd_kcontrol_new *kctl = spec->kctls.list;
4524		int i;
4525		for (i = 0; i < spec->kctls.used; i++)
4526			kfree(kctl[i].name);
4527	}
4528	snd_array_free(&spec->kctls);
4529}
4530
4531static void alc_free(struct hda_codec *codec)
4532{
4533	struct alc_spec *spec = codec->spec;
4534
4535	if (!spec)
4536		return;
4537
4538	alc_shutup(codec);
4539	snd_hda_input_jack_free(codec);
4540	alc_free_kctls(codec);
4541	kfree(spec);
4542	snd_hda_detach_beep_device(codec);
4543}
4544
4545#ifdef CONFIG_SND_HDA_POWER_SAVE
4546static void alc_power_eapd(struct hda_codec *codec)
4547{
4548	alc_auto_setup_eapd(codec, false);
4549}
4550
4551static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4552{
4553	struct alc_spec *spec = codec->spec;
4554	alc_shutup(codec);
4555	if (spec && spec->power_hook)
4556		spec->power_hook(codec);
4557	return 0;
4558}
4559#endif
4560
4561#ifdef SND_HDA_NEEDS_RESUME
4562static int alc_resume(struct hda_codec *codec)
4563{
4564	msleep(150); /* to avoid pop noise */
4565	codec->patch_ops.init(codec);
4566	snd_hda_codec_resume_amp(codec);
4567	snd_hda_codec_resume_cache(codec);
4568	hda_call_check_power_status(codec, 0x01);
4569	return 0;
4570}
4571#endif
4572
4573/*
4574 */
4575static const struct hda_codec_ops alc_patch_ops = {
4576	.build_controls = alc_build_controls,
4577	.build_pcms = alc_build_pcms,
4578	.init = alc_init,
4579	.free = alc_free,
4580	.unsol_event = alc_unsol_event,
4581#ifdef SND_HDA_NEEDS_RESUME
4582	.resume = alc_resume,
4583#endif
4584#ifdef CONFIG_SND_HDA_POWER_SAVE
4585	.suspend = alc_suspend,
4586	.check_power_status = alc_check_power_status,
4587#endif
4588	.reboot_notify = alc_shutup,
4589};
4590
4591/* replace the codec chip_name with the given string */
4592static int alc_codec_rename(struct hda_codec *codec, const char *name)
4593{
4594	kfree(codec->chip_name);
4595	codec->chip_name = kstrdup(name, GFP_KERNEL);
4596	if (!codec->chip_name) {
4597		alc_free(codec);
4598		return -ENOMEM;
4599	}
4600	return 0;
4601}
4602
4603/*
4604 * Test configuration for debugging
4605 *
4606 * Almost all inputs/outputs are enabled.  I/O pins can be configured via
4607 * enum controls.
4608 */
4609#ifdef CONFIG_SND_DEBUG
4610static const hda_nid_t alc880_test_dac_nids[4] = {
4611	0x02, 0x03, 0x04, 0x05
4612};
4613
4614static const struct hda_input_mux alc880_test_capture_source = {
4615	.num_items = 7,
4616	.items = {
4617		{ "In-1", 0x0 },
4618		{ "In-2", 0x1 },
4619		{ "In-3", 0x2 },
4620		{ "In-4", 0x3 },
4621		{ "CD", 0x4 },
4622		{ "Front", 0x5 },
4623		{ "Surround", 0x6 },
4624	},
4625};
4626
4627static const struct hda_channel_mode alc880_test_modes[4] = {
4628	{ 2, NULL },
4629	{ 4, NULL },
4630	{ 6, NULL },
4631	{ 8, NULL },
4632};
4633
4634static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4635				 struct snd_ctl_elem_info *uinfo)
4636{
4637	static const char * const texts[] = {
4638		"N/A", "Line Out", "HP Out",
4639		"In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4640	};
4641	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4642	uinfo->count = 1;
4643	uinfo->value.enumerated.items = 8;
4644	if (uinfo->value.enumerated.item >= 8)
4645		uinfo->value.enumerated.item = 7;
4646	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4647	return 0;
4648}
4649
4650static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4651				struct snd_ctl_elem_value *ucontrol)
4652{
4653	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4654	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4655	unsigned int pin_ctl, item = 0;
4656
4657	pin_ctl = snd_hda_codec_read(codec, nid, 0,
4658				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4659	if (pin_ctl & AC_PINCTL_OUT_EN) {
4660		if (pin_ctl & AC_PINCTL_HP_EN)
4661			item = 2;
4662		else
4663			item = 1;
4664	} else if (pin_ctl & AC_PINCTL_IN_EN) {
4665		switch (pin_ctl & AC_PINCTL_VREFEN) {
4666		case AC_PINCTL_VREF_HIZ: item = 3; break;
4667		case AC_PINCTL_VREF_50:  item = 4; break;
4668		case AC_PINCTL_VREF_GRD: item = 5; break;
4669		case AC_PINCTL_VREF_80:  item = 6; break;
4670		case AC_PINCTL_VREF_100: item = 7; break;
4671		}
4672	}
4673	ucontrol->value.enumerated.item[0] = item;
4674	return 0;
4675}
4676
4677static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4678				struct snd_ctl_elem_value *ucontrol)
4679{
4680	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4681	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4682	static const unsigned int ctls[] = {
4683		0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4684		AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4685		AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4686		AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4687		AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4688		AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4689	};
4690	unsigned int old_ctl, new_ctl;
4691
4692	old_ctl = snd_hda_codec_read(codec, nid, 0,
4693				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4694	new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4695	if (old_ctl != new_ctl) {
4696		int val;
4697		snd_hda_codec_write_cache(codec, nid, 0,
4698					  AC_VERB_SET_PIN_WIDGET_CONTROL,
4699					  new_ctl);
4700		val = ucontrol->value.enumerated.item[0] >= 3 ?
4701			HDA_AMP_MUTE : 0;
4702		snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4703					 HDA_AMP_MUTE, val);
4704		return 1;
4705	}
4706	return 0;
4707}
4708
4709static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4710				 struct snd_ctl_elem_info *uinfo)
4711{
4712	static const char * const texts[] = {
4713		"Front", "Surround", "CLFE", "Side"
4714	};
4715	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4716	uinfo->count = 1;
4717	uinfo->value.enumerated.items = 4;
4718	if (uinfo->value.enumerated.item >= 4)
4719		uinfo->value.enumerated.item = 3;
4720	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4721	return 0;
4722}
4723
4724static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4725				struct snd_ctl_elem_value *ucontrol)
4726{
4727	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4728	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4729	unsigned int sel;
4730
4731	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4732	ucontrol->value.enumerated.item[0] = sel & 3;
4733	return 0;
4734}
4735
4736static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4737				struct snd_ctl_elem_value *ucontrol)
4738{
4739	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4740	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4741	unsigned int sel;
4742
4743	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4744	if (ucontrol->value.enumerated.item[0] != sel) {
4745		sel = ucontrol->value.enumerated.item[0] & 3;
4746		snd_hda_codec_write_cache(codec, nid, 0,
4747					  AC_VERB_SET_CONNECT_SEL, sel);
4748		return 1;
4749	}
4750	return 0;
4751}
4752
4753#define PIN_CTL_TEST(xname,nid) {			\
4754		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
4755			.name = xname,		       \
4756			.subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4757			.info = alc_test_pin_ctl_info, \
4758			.get = alc_test_pin_ctl_get,   \
4759			.put = alc_test_pin_ctl_put,   \
4760			.private_value = nid	       \
4761			}
4762
4763#define PIN_SRC_TEST(xname,nid) {			\
4764		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
4765			.name = xname,		       \
4766			.subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4767			.info = alc_test_pin_src_info, \
4768			.get = alc_test_pin_src_get,   \
4769			.put = alc_test_pin_src_put,   \
4770			.private_value = nid	       \
4771			}
4772
4773static const struct snd_kcontrol_new alc880_test_mixer[] = {
4774	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4775	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4776	HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4777	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4778	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4779	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4780	HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4781	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4782	PIN_CTL_TEST("Front Pin Mode", 0x14),
4783	PIN_CTL_TEST("Surround Pin Mode", 0x15),
4784	PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4785	PIN_CTL_TEST("Side Pin Mode", 0x17),
4786	PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4787	PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4788	PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4789	PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4790	PIN_SRC_TEST("In-1 Pin Source", 0x18),
4791	PIN_SRC_TEST("In-2 Pin Source", 0x19),
4792	PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4793	PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4794	HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4795	HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4796	HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4797	HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4798	HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4799	HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4800	HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4801	HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4802	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4803	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
4804	{
4805		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4806		.name = "Channel Mode",
4807		.info = alc_ch_mode_info,
4808		.get = alc_ch_mode_get,
4809		.put = alc_ch_mode_put,
4810	},
4811	{ } /* end */
4812};
4813
4814static const struct hda_verb alc880_test_init_verbs[] = {
4815	/* Unmute inputs of 0x0c - 0x0f */
4816	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4817	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4818	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4819	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4820	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4821	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4822	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4823	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4824	/* Vol output for 0x0c-0x0f */
4825	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4826	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4827	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4828	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4829	/* Set output pins 0x14-0x17 */
4830	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4831	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4832	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4833	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4834	/* Unmute output pins 0x14-0x17 */
4835	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4836	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4837	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4838	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4839	/* Set input pins 0x18-0x1c */
4840	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4841	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4842	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4843	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4844	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4845	/* Mute input pins 0x18-0x1b */
4846	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4847	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4848	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4849	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4850	/* ADC set up */
4851	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4852	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4853	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4854	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4855	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4856	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4857	/* Analog input/passthru */
4858	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4859	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4860	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4861	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4862	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4863	{ }
4864};
4865#endif
4866
4867/*
4868 */
4869
4870static const char * const alc880_models[ALC880_MODEL_LAST] = {
4871	[ALC880_3ST]		= "3stack",
4872	[ALC880_TCL_S700]	= "tcl",
4873	[ALC880_3ST_DIG]	= "3stack-digout",
4874	[ALC880_CLEVO]		= "clevo",
4875	[ALC880_5ST]		= "5stack",
4876	[ALC880_5ST_DIG]	= "5stack-digout",
4877	[ALC880_W810]		= "w810",
4878	[ALC880_Z71V]		= "z71v",
4879	[ALC880_6ST]		= "6stack",
4880	[ALC880_6ST_DIG]	= "6stack-digout",
4881	[ALC880_ASUS]		= "asus",
4882	[ALC880_ASUS_W1V]	= "asus-w1v",
4883	[ALC880_ASUS_DIG]	= "asus-dig",
4884	[ALC880_ASUS_DIG2]	= "asus-dig2",
4885	[ALC880_UNIWILL_DIG]	= "uniwill",
4886	[ALC880_UNIWILL_P53]	= "uniwill-p53",
4887	[ALC880_FUJITSU]	= "fujitsu",
4888	[ALC880_F1734]		= "F1734",
4889	[ALC880_LG]		= "lg",
4890	[ALC880_LG_LW]		= "lg-lw",
4891	[ALC880_MEDION_RIM]	= "medion",
4892#ifdef CONFIG_SND_DEBUG
4893	[ALC880_TEST]		= "test",
4894#endif
4895	[ALC880_AUTO]		= "auto",
4896};
4897
4898static const struct snd_pci_quirk alc880_cfg_tbl[] = {
4899	SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
4900	SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4901	SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4902	SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4903	SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4904	SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4905	SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4906	SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4907	SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
4908	SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4909	SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4910	SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4911	SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4912	SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4913	SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4914	SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4915	SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4916	/* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4917	SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4918	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
4919	SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
4920	SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4921	SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4922	SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
4923	SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
4924	SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
4925	SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4926	SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
4927	SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4928	SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
4929	SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4930	SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4931	SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4932	SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
4933	SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4934	SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
4935	SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
4936	SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
4937	SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
4938	SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
4939	SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4940	SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
4941	SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
4942	SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
4943	SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
4944	SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
4945	SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
4946	SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
4947	SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
4948	SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
4949	SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
4950	SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4951	SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
4952	SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
4953	SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
4954	SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4955	SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4956	SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4957	SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
4958	SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4959	SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
4960	SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
4961	SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
4962	SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4963	SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
4964	SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4965	SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4966	SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
4967	/* default Intel */
4968	SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
4969	SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4970	SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
4971	{}
4972};
4973
4974/*
4975 * ALC880 codec presets
4976 */
4977static const struct alc_config_preset alc880_presets[] = {
4978	[ALC880_3ST] = {
4979		.mixers = { alc880_three_stack_mixer },
4980		.init_verbs = { alc880_volume_init_verbs,
4981				alc880_pin_3stack_init_verbs },
4982		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
4983		.dac_nids = alc880_dac_nids,
4984		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4985		.channel_mode = alc880_threestack_modes,
4986		.need_dac_fix = 1,
4987		.input_mux = &alc880_capture_source,
4988	},
4989	[ALC880_3ST_DIG] = {
4990		.mixers = { alc880_three_stack_mixer },
4991		.init_verbs = { alc880_volume_init_verbs,
4992				alc880_pin_3stack_init_verbs },
4993		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
4994		.dac_nids = alc880_dac_nids,
4995		.dig_out_nid = ALC880_DIGOUT_NID,
4996		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4997		.channel_mode = alc880_threestack_modes,
4998		.need_dac_fix = 1,
4999		.input_mux = &alc880_capture_source,
5000	},
5001	[ALC880_TCL_S700] = {
5002		.mixers = { alc880_tcl_s700_mixer },
5003		.init_verbs = { alc880_volume_init_verbs,
5004				alc880_pin_tcl_S700_init_verbs,
5005				alc880_gpio2_init_verbs },
5006		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
5007		.dac_nids = alc880_dac_nids,
5008		.adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
5009		.num_adc_nids = 1, /* single ADC */
5010		.hp_nid = 0x03,
5011		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5012		.channel_mode = alc880_2_jack_modes,
5013		.input_mux = &alc880_capture_source,
5014	},
5015	[ALC880_5ST] = {
5016		.mixers = { alc880_three_stack_mixer,
5017			    alc880_five_stack_mixer},
5018		.init_verbs = { alc880_volume_init_verbs,
5019				alc880_pin_5stack_init_verbs },
5020		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
5021		.dac_nids = alc880_dac_nids,
5022		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5023		.channel_mode = alc880_fivestack_modes,
5024		.input_mux = &alc880_capture_source,
5025	},
5026	[ALC880_5ST_DIG] = {
5027		.mixers = { alc880_three_stack_mixer,
5028			    alc880_five_stack_mixer },
5029		.init_verbs = { alc880_volume_init_verbs,
5030				alc880_pin_5stack_init_verbs },
5031		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
5032		.dac_nids = alc880_dac_nids,
5033		.dig_out_nid = ALC880_DIGOUT_NID,
5034		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5035		.channel_mode = alc880_fivestack_modes,
5036		.input_mux = &alc880_capture_source,
5037	},
5038	[ALC880_6ST] = {
5039		.mixers = { alc880_six_stack_mixer },
5040		.init_verbs = { alc880_volume_init_verbs,
5041				alc880_pin_6stack_init_verbs },
5042		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5043		.dac_nids = alc880_6st_dac_nids,
5044		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5045		.channel_mode = alc880_sixstack_modes,
5046		.input_mux = &alc880_6stack_capture_source,
5047	},
5048	[ALC880_6ST_DIG] = {
5049		.mixers = { alc880_six_stack_mixer },
5050		.init_verbs = { alc880_volume_init_verbs,
5051				alc880_pin_6stack_init_verbs },
5052		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5053		.dac_nids = alc880_6st_dac_nids,
5054		.dig_out_nid = ALC880_DIGOUT_NID,
5055		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5056		.channel_mode = alc880_sixstack_modes,
5057		.input_mux = &alc880_6stack_capture_source,
5058	},
5059	[ALC880_W810] = {
5060		.mixers = { alc880_w810_base_mixer },
5061		.init_verbs = { alc880_volume_init_verbs,
5062				alc880_pin_w810_init_verbs,
5063				alc880_gpio2_init_verbs },
5064		.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
5065		.dac_nids = alc880_w810_dac_nids,
5066		.dig_out_nid = ALC880_DIGOUT_NID,
5067		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5068		.channel_mode = alc880_w810_modes,
5069		.input_mux = &alc880_capture_source,
5070	},
5071	[ALC880_Z71V] = {
5072		.mixers = { alc880_z71v_mixer },
5073		.init_verbs = { alc880_volume_init_verbs,
5074				alc880_pin_z71v_init_verbs },
5075		.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
5076		.dac_nids = alc880_z71v_dac_nids,
5077		.dig_out_nid = ALC880_DIGOUT_NID,
5078		.hp_nid = 0x03,
5079		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5080		.channel_mode = alc880_2_jack_modes,
5081		.input_mux = &alc880_capture_source,
5082	},
5083	[ALC880_F1734] = {
5084		.mixers = { alc880_f1734_mixer },
5085		.init_verbs = { alc880_volume_init_verbs,
5086				alc880_pin_f1734_init_verbs },
5087		.num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
5088		.dac_nids = alc880_f1734_dac_nids,
5089		.hp_nid = 0x02,
5090		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5091		.channel_mode = alc880_2_jack_modes,
5092		.input_mux = &alc880_f1734_capture_source,
5093		.unsol_event = alc880_uniwill_p53_unsol_event,
5094		.setup = alc880_uniwill_p53_setup,
5095		.init_hook = alc_hp_automute,
5096	},
5097	[ALC880_ASUS] = {
5098		.mixers = { alc880_asus_mixer },
5099		.init_verbs = { alc880_volume_init_verbs,
5100				alc880_pin_asus_init_verbs,
5101				alc880_gpio1_init_verbs },
5102		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5103		.dac_nids = alc880_asus_dac_nids,
5104		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5105		.channel_mode = alc880_asus_modes,
5106		.need_dac_fix = 1,
5107		.input_mux = &alc880_capture_source,
5108	},
5109	[ALC880_ASUS_DIG] = {
5110		.mixers = { alc880_asus_mixer },
5111		.init_verbs = { alc880_volume_init_verbs,
5112				alc880_pin_asus_init_verbs,
5113				alc880_gpio1_init_verbs },
5114		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5115		.dac_nids = alc880_asus_dac_nids,
5116		.dig_out_nid = ALC880_DIGOUT_NID,
5117		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5118		.channel_mode = alc880_asus_modes,
5119		.need_dac_fix = 1,
5120		.input_mux = &alc880_capture_source,
5121	},
5122	[ALC880_ASUS_DIG2] = {
5123		.mixers = { alc880_asus_mixer },
5124		.init_verbs = { alc880_volume_init_verbs,
5125				alc880_pin_asus_init_verbs,
5126				alc880_gpio2_init_verbs }, /* use GPIO2 */
5127		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5128		.dac_nids = alc880_asus_dac_nids,
5129		.dig_out_nid = ALC880_DIGOUT_NID,
5130		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5131		.channel_mode = alc880_asus_modes,
5132		.need_dac_fix = 1,
5133		.input_mux = &alc880_capture_source,
5134	},
5135	[ALC880_ASUS_W1V] = {
5136		.mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
5137		.init_verbs = { alc880_volume_init_verbs,
5138				alc880_pin_asus_init_verbs,
5139				alc880_gpio1_init_verbs },
5140		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5141		.dac_nids = alc880_asus_dac_nids,
5142		.dig_out_nid = ALC880_DIGOUT_NID,
5143		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5144		.channel_mode = alc880_asus_modes,
5145		.need_dac_fix = 1,
5146		.input_mux = &alc880_capture_source,
5147	},
5148	[ALC880_UNIWILL_DIG] = {
5149		.mixers = { alc880_asus_mixer },
5150		.init_verbs = { alc880_volume_init_verbs,
5151				alc880_pin_asus_init_verbs },
5152		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5153		.dac_nids = alc880_asus_dac_nids,
5154		.dig_out_nid = ALC880_DIGOUT_NID,
5155		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5156		.channel_mode = alc880_asus_modes,
5157		.need_dac_fix = 1,
5158		.input_mux = &alc880_capture_source,
5159	},
5160	[ALC880_UNIWILL] = {
5161		.mixers = { alc880_uniwill_mixer },
5162		.init_verbs = { alc880_volume_init_verbs,
5163				alc880_uniwill_init_verbs },
5164		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5165		.dac_nids = alc880_asus_dac_nids,
5166		.dig_out_nid = ALC880_DIGOUT_NID,
5167		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5168		.channel_mode = alc880_threestack_modes,
5169		.need_dac_fix = 1,
5170		.input_mux = &alc880_capture_source,
5171		.unsol_event = alc880_uniwill_unsol_event,
5172		.setup = alc880_uniwill_setup,
5173		.init_hook = alc880_uniwill_init_hook,
5174	},
5175	[ALC880_UNIWILL_P53] = {
5176		.mixers = { alc880_uniwill_p53_mixer },
5177		.init_verbs = { alc880_volume_init_verbs,
5178				alc880_uniwill_p53_init_verbs },
5179		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5180		.dac_nids = alc880_asus_dac_nids,
5181		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5182		.channel_mode = alc880_threestack_modes,
5183		.input_mux = &alc880_capture_source,
5184		.unsol_event = alc880_uniwill_p53_unsol_event,
5185		.setup = alc880_uniwill_p53_setup,
5186		.init_hook = alc_hp_automute,
5187	},
5188	[ALC880_FUJITSU] = {
5189		.mixers = { alc880_fujitsu_mixer },
5190		.init_verbs = { alc880_volume_init_verbs,
5191				alc880_uniwill_p53_init_verbs,
5192	       			alc880_beep_init_verbs },
5193		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
5194		.dac_nids = alc880_dac_nids,
5195		.dig_out_nid = ALC880_DIGOUT_NID,
5196		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5197		.channel_mode = alc880_2_jack_modes,
5198		.input_mux = &alc880_capture_source,
5199		.unsol_event = alc880_uniwill_p53_unsol_event,
5200		.setup = alc880_uniwill_p53_setup,
5201		.init_hook = alc_hp_automute,
5202	},
5203	[ALC880_CLEVO] = {
5204		.mixers = { alc880_three_stack_mixer },
5205		.init_verbs = { alc880_volume_init_verbs,
5206				alc880_pin_clevo_init_verbs },
5207		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
5208		.dac_nids = alc880_dac_nids,
5209		.hp_nid = 0x03,
5210		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5211		.channel_mode = alc880_threestack_modes,
5212		.need_dac_fix = 1,
5213		.input_mux = &alc880_capture_source,
5214	},
5215	[ALC880_LG] = {
5216		.mixers = { alc880_lg_mixer },
5217		.init_verbs = { alc880_volume_init_verbs,
5218				alc880_lg_init_verbs },
5219		.num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
5220		.dac_nids = alc880_lg_dac_nids,
5221		.dig_out_nid = ALC880_DIGOUT_NID,
5222		.num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
5223		.channel_mode = alc880_lg_ch_modes,
5224		.need_dac_fix = 1,
5225		.input_mux = &alc880_lg_capture_source,
5226		.unsol_event = alc_sku_unsol_event,
5227		.setup = alc880_lg_setup,
5228		.init_hook = alc_hp_automute,
5229#ifdef CONFIG_SND_HDA_POWER_SAVE
5230		.loopbacks = alc880_lg_loopbacks,
5231#endif
5232	},
5233	[ALC880_LG_LW] = {
5234		.mixers = { alc880_lg_lw_mixer },
5235		.init_verbs = { alc880_volume_init_verbs,
5236				alc880_lg_lw_init_verbs },
5237		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
5238		.dac_nids = alc880_dac_nids,
5239		.dig_out_nid = ALC880_DIGOUT_NID,
5240		.num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
5241		.channel_mode = alc880_lg_lw_modes,
5242		.input_mux = &alc880_lg_lw_capture_source,
5243		.unsol_event = alc_sku_unsol_event,
5244		.setup = alc880_lg_lw_setup,
5245		.init_hook = alc_hp_automute,
5246	},
5247	[ALC880_MEDION_RIM] = {
5248		.mixers = { alc880_medion_rim_mixer },
5249		.init_verbs = { alc880_volume_init_verbs,
5250				alc880_medion_rim_init_verbs,
5251				alc_gpio2_init_verbs },
5252		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
5253		.dac_nids = alc880_dac_nids,
5254		.dig_out_nid = ALC880_DIGOUT_NID,
5255		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5256		.channel_mode = alc880_2_jack_modes,
5257		.input_mux = &alc880_medion_rim_capture_source,
5258		.unsol_event = alc880_medion_rim_unsol_event,
5259		.setup = alc880_medion_rim_setup,
5260		.init_hook = alc880_medion_rim_automute,
5261	},
5262#ifdef CONFIG_SND_DEBUG
5263	[ALC880_TEST] = {
5264		.mixers = { alc880_test_mixer },
5265		.init_verbs = { alc880_test_init_verbs },
5266		.num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
5267		.dac_nids = alc880_test_dac_nids,
5268		.dig_out_nid = ALC880_DIGOUT_NID,
5269		.num_channel_mode = ARRAY_SIZE(alc880_test_modes),
5270		.channel_mode = alc880_test_modes,
5271		.input_mux = &alc880_test_capture_source,
5272	},
5273#endif
5274};
5275
5276/*
5277 * Automatic parse of I/O pins from the BIOS configuration
5278 */
5279
5280enum {
5281	ALC_CTL_WIDGET_VOL,
5282	ALC_CTL_WIDGET_MUTE,
5283	ALC_CTL_BIND_MUTE,
5284};
5285static const struct snd_kcontrol_new alc880_control_templates[] = {
5286	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
5287	HDA_CODEC_MUTE(NULL, 0, 0, 0),
5288	HDA_BIND_MUTE(NULL, 0, 0, 0),
5289};
5290
5291static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
5292{
5293	snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
5294	return snd_array_new(&spec->kctls);
5295}
5296
5297/* add dynamic controls */
5298static int add_control(struct alc_spec *spec, int type, const char *name,
5299		       int cidx, unsigned long val)
5300{
5301	struct snd_kcontrol_new *knew;
5302
5303	knew = alc_kcontrol_new(spec);
5304	if (!knew)
5305		return -ENOMEM;
5306	*knew = alc880_control_templates[type];
5307	knew->name = kstrdup(name, GFP_KERNEL);
5308	if (!knew->name)
5309		return -ENOMEM;
5310	knew->index = cidx;
5311	if (get_amp_nid_(val))
5312		knew->subdevice = HDA_SUBDEV_AMP_FLAG;
5313	knew->private_value = val;
5314	return 0;
5315}
5316
5317static int add_control_with_pfx(struct alc_spec *spec, int type,
5318				const char *pfx, const char *dir,
5319				const char *sfx, int cidx, unsigned long val)
5320{
5321	char name[32];
5322	snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
5323	return add_control(spec, type, name, cidx, val);
5324}
5325
5326#define add_pb_vol_ctrl(spec, type, pfx, val)			\
5327	add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5328#define add_pb_sw_ctrl(spec, type, pfx, val)			\
5329	add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5330#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val)			\
5331	add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5332#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val)			\
5333	add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
5334
5335#define alc880_is_fixed_pin(nid)	((nid) >= 0x14 && (nid) <= 0x17)
5336#define alc880_fixed_pin_idx(nid)	((nid) - 0x14)
5337#define alc880_is_multi_pin(nid)	((nid) >= 0x18)
5338#define alc880_multi_pin_idx(nid)	((nid) - 0x18)
5339#define alc880_idx_to_dac(nid)		((nid) + 0x02)
5340#define alc880_dac_to_idx(nid)		((nid) - 0x02)
5341#define alc880_idx_to_mixer(nid)	((nid) + 0x0c)
5342#define alc880_idx_to_selector(nid)	((nid) + 0x10)
5343#define ALC880_PIN_CD_NID		0x1c
5344
5345/* fill in the dac_nids table from the parsed pin configuration */
5346static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5347				     const struct auto_pin_cfg *cfg)
5348{
5349	hda_nid_t nid;
5350	int assigned[4];
5351	int i, j;
5352
5353	memset(assigned, 0, sizeof(assigned));
5354	spec->multiout.dac_nids = spec->private_dac_nids;
5355
5356	/* check the pins hardwired to audio widget */
5357	for (i = 0; i < cfg->line_outs; i++) {
5358		nid = cfg->line_out_pins[i];
5359		if (alc880_is_fixed_pin(nid)) {
5360			int idx = alc880_fixed_pin_idx(nid);
5361			spec->private_dac_nids[i] = alc880_idx_to_dac(idx);
5362			assigned[idx] = 1;
5363		}
5364	}
5365	/* left pins can be connect to any audio widget */
5366	for (i = 0; i < cfg->line_outs; i++) {
5367		nid = cfg->line_out_pins[i];
5368		if (alc880_is_fixed_pin(nid))
5369			continue;
5370		/* search for an empty channel */
5371		for (j = 0; j < cfg->line_outs; j++) {
5372			if (!assigned[j]) {
5373				spec->private_dac_nids[i] =
5374					alc880_idx_to_dac(j);
5375				assigned[j] = 1;
5376				break;
5377			}
5378		}
5379	}
5380	spec->multiout.num_dacs = cfg->line_outs;
5381	return 0;
5382}
5383
5384static const char *alc_get_line_out_pfx(struct alc_spec *spec,
5385					bool can_be_master)
5386{
5387	struct auto_pin_cfg *cfg = &spec->autocfg;
5388
5389	if (cfg->line_outs == 1 && !spec->multi_ios &&
5390	    !cfg->hp_outs && !cfg->speaker_outs && can_be_master)
5391		return "Master";
5392
5393	switch (cfg->line_out_type) {
5394	case AUTO_PIN_SPEAKER_OUT:
5395		if (cfg->line_outs == 1)
5396			return "Speaker";
5397		break;
5398	case AUTO_PIN_HP_OUT:
5399		return "Headphone";
5400	default:
5401		if (cfg->line_outs == 1 && !spec->multi_ios)
5402			return "PCM";
5403		break;
5404	}
5405	return NULL;
5406}
5407
5408/* add playback controls from the parsed DAC table */
5409static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5410					     const struct auto_pin_cfg *cfg)
5411{
5412	static const char * const chname[4] = {
5413		"Front", "Surround", NULL /*CLFE*/, "Side"
5414	};
5415	const char *pfx = alc_get_line_out_pfx(spec, false);
5416	hda_nid_t nid;
5417	int i, err, noutputs;
5418
5419	noutputs = cfg->line_outs;
5420	if (spec->multi_ios > 0)
5421		noutputs += spec->multi_ios;
5422
5423	for (i = 0; i < noutputs; i++) {
5424		if (!spec->multiout.dac_nids[i])
5425			continue;
5426		nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
5427		if (!pfx && i == 2) {
5428			/* Center/LFE */
5429			err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5430					      "Center",
5431					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
5432							      HDA_OUTPUT));
5433			if (err < 0)
5434				return err;
5435			err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5436					      "LFE",
5437					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
5438							      HDA_OUTPUT));
5439			if (err < 0)
5440				return err;
5441			err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5442					     "Center",
5443					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
5444							      HDA_INPUT));
5445			if (err < 0)
5446				return err;
5447			err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5448					     "LFE",
5449					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
5450							      HDA_INPUT));
5451			if (err < 0)
5452				return err;
5453		} else {
5454			const char *name = pfx;
5455			int index = i;
5456			if (!name) {
5457				name = chname[i];
5458				index = 0;
5459			}
5460			err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5461						name, index,
5462					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5463							      HDA_OUTPUT));
5464			if (err < 0)
5465				return err;
5466			err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5467					       name, index,
5468					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5469							      HDA_INPUT));
5470			if (err < 0)
5471				return err;
5472		}
5473	}
5474	return 0;
5475}
5476
5477/* add playback controls for speaker and HP outputs */
5478static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5479					const char *pfx)
5480{
5481	hda_nid_t nid;
5482	int err;
5483
5484	if (!pin)
5485		return 0;
5486
5487	if (alc880_is_fixed_pin(pin)) {
5488		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
5489		/* specify the DAC as the extra output */
5490		if (!spec->multiout.hp_nid)
5491			spec->multiout.hp_nid = nid;
5492		else
5493			spec->multiout.extra_out_nid[0] = nid;
5494		/* control HP volume/switch on the output mixer amp */
5495		nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
5496		err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
5497				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5498		if (err < 0)
5499			return err;
5500		err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
5501				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5502		if (err < 0)
5503			return err;
5504	} else if (alc880_is_multi_pin(pin)) {
5505		/* set manual connection */
5506		/* we have only a switch on HP-out PIN */
5507		err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
5508				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5509		if (err < 0)
5510			return err;
5511	}
5512	return 0;
5513}
5514
5515/* create input playback/capture controls for the given pin */
5516static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
5517			    const char *ctlname, int ctlidx,
5518			    int idx, hda_nid_t mix_nid)
5519{
5520	int err;
5521
5522	err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
5523			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5524	if (err < 0)
5525		return err;
5526	err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
5527			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5528	if (err < 0)
5529		return err;
5530	return 0;
5531}
5532
5533static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5534{
5535	unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5536	return (pincap & AC_PINCAP_IN) != 0;
5537}
5538
5539/* create playback/capture controls for input pins */
5540static int alc_auto_create_input_ctls(struct hda_codec *codec,
5541				      const struct auto_pin_cfg *cfg,
5542				      hda_nid_t mixer,
5543				      hda_nid_t cap1, hda_nid_t cap2)
5544{
5545	struct alc_spec *spec = codec->spec;
5546	struct hda_input_mux *imux = &spec->private_imux[0];
5547	int i, err, idx, type_idx = 0;
5548	const char *prev_label = NULL;
5549
5550	for (i = 0; i < cfg->num_inputs; i++) {
5551		hda_nid_t pin;
5552		const char *label;
5553
5554		pin = cfg->inputs[i].pin;
5555		if (!alc_is_input_pin(codec, pin))
5556			continue;
5557
5558		label = hda_get_autocfg_input_label(codec, cfg, i);
5559		if (prev_label && !strcmp(label, prev_label))
5560			type_idx++;
5561		else
5562			type_idx = 0;
5563		prev_label = label;
5564
5565		if (mixer) {
5566			idx = get_connection_index(codec, mixer, pin);
5567			if (idx >= 0) {
5568				err = new_analog_input(spec, pin,
5569						       label, type_idx,
5570						       idx, mixer);
5571				if (err < 0)
5572					return err;
5573			}
5574		}
5575
5576		if (!cap1)
5577			continue;
5578		idx = get_connection_index(codec, cap1, pin);
5579		if (idx < 0 && cap2)
5580			idx = get_connection_index(codec, cap2, pin);
5581		if (idx >= 0)
5582			snd_hda_add_imux_item(imux, label, idx, NULL);
5583	}
5584	return 0;
5585}
5586
5587static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5588						const struct auto_pin_cfg *cfg)
5589{
5590	return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5591}
5592
5593static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5594			       unsigned int pin_type)
5595{
5596	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5597			    pin_type);
5598	/* unmute pin */
5599	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5600			    AMP_OUT_UNMUTE);
5601}
5602
5603static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5604					      hda_nid_t nid, int pin_type,
5605					      int dac_idx)
5606{
5607	alc_set_pin_output(codec, nid, pin_type);
5608	/* need the manual connection? */
5609	if (alc880_is_multi_pin(nid)) {
5610		struct alc_spec *spec = codec->spec;
5611		int idx = alc880_multi_pin_idx(nid);
5612		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5613				    AC_VERB_SET_CONNECT_SEL,
5614				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5615	}
5616}
5617
5618static int get_pin_type(int line_out_type)
5619{
5620	if (line_out_type == AUTO_PIN_HP_OUT)
5621		return PIN_HP;
5622	else
5623		return PIN_OUT;
5624}
5625
5626static void alc880_auto_init_multi_out(struct hda_codec *codec)
5627{
5628	struct alc_spec *spec = codec->spec;
5629	int i;
5630
5631	for (i = 0; i < spec->autocfg.line_outs; i++) {
5632		hda_nid_t nid = spec->autocfg.line_out_pins[i];
5633		int pin_type = get_pin_type(spec->autocfg.line_out_type);
5634		alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
5635	}
5636}
5637
5638static void alc880_auto_init_extra_out(struct hda_codec *codec)
5639{
5640	struct alc_spec *spec = codec->spec;
5641	hda_nid_t pin;
5642
5643	pin = spec->autocfg.speaker_pins[0];
5644	if (pin) /* connect to front */
5645		alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
5646	pin = spec->autocfg.hp_pins[0];
5647	if (pin) /* connect to front */
5648		alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5649}
5650
5651static void alc880_auto_init_analog_input(struct hda_codec *codec)
5652{
5653	struct alc_spec *spec = codec->spec;
5654	struct auto_pin_cfg *cfg = &spec->autocfg;
5655	int i;
5656
5657	for (i = 0; i < cfg->num_inputs; i++) {
5658		hda_nid_t nid = cfg->inputs[i].pin;
5659		if (alc_is_input_pin(codec, nid)) {
5660			alc_set_input_pin(codec, nid, cfg->inputs[i].type);
5661			if (nid != ALC880_PIN_CD_NID &&
5662			    (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
5663				snd_hda_codec_write(codec, nid, 0,
5664						    AC_VERB_SET_AMP_GAIN_MUTE,
5665						    AMP_OUT_MUTE);
5666		}
5667	}
5668}
5669
5670static void alc880_auto_init_input_src(struct hda_codec *codec)
5671{
5672	struct alc_spec *spec = codec->spec;
5673	int c;
5674
5675	for (c = 0; c < spec->num_adc_nids; c++) {
5676		unsigned int mux_idx;
5677		const struct hda_input_mux *imux;
5678		mux_idx = c >= spec->num_mux_defs ? 0 : c;
5679		imux = &spec->input_mux[mux_idx];
5680		if (!imux->num_items && mux_idx > 0)
5681			imux = &spec->input_mux[0];
5682		if (imux)
5683			snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5684					    AC_VERB_SET_CONNECT_SEL,
5685					    imux->items[0].index);
5686	}
5687}
5688
5689static int alc_auto_add_multi_channel_mode(struct hda_codec *codec);
5690
5691/* parse the BIOS configuration and set up the alc_spec */
5692/* return 1 if successful, 0 if the proper config is not found,
5693 * or a negative error code
5694 */
5695static int alc880_parse_auto_config(struct hda_codec *codec)
5696{
5697	struct alc_spec *spec = codec->spec;
5698	int err;
5699	static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
5700
5701	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5702					   alc880_ignore);
5703	if (err < 0)
5704		return err;
5705	if (!spec->autocfg.line_outs)
5706		return 0; /* can't find valid BIOS pin config */
5707
5708	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5709	if (err < 0)
5710		return err;
5711	err = alc_auto_add_multi_channel_mode(codec);
5712	if (err < 0)
5713		return err;
5714	err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5715	if (err < 0)
5716		return err;
5717	err = alc880_auto_create_extra_out(spec,
5718					   spec->autocfg.speaker_pins[0],
5719					   "Speaker");
5720	if (err < 0)
5721		return err;
5722	err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5723					   "Headphone");
5724	if (err < 0)
5725		return err;
5726	err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
5727	if (err < 0)
5728		return err;
5729
5730	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5731
5732	alc_auto_parse_digital(codec);
5733
5734	if (spec->kctls.list)
5735		add_mixer(spec, spec->kctls.list);
5736
5737	add_verb(spec, alc880_volume_init_verbs);
5738
5739	spec->num_mux_defs = 1;
5740	spec->input_mux = &spec->private_imux[0];
5741
5742	alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
5743
5744	return 1;
5745}
5746
5747/* additional initialization for auto-configuration model */
5748static void alc880_auto_init(struct hda_codec *codec)
5749{
5750	struct alc_spec *spec = codec->spec;
5751	alc880_auto_init_multi_out(codec);
5752	alc880_auto_init_extra_out(codec);
5753	alc880_auto_init_analog_input(codec);
5754	alc880_auto_init_input_src(codec);
5755	alc_auto_init_digital(codec);
5756	if (spec->unsol_event)
5757		alc_inithook(codec);
5758}
5759
5760/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5761 * one of two digital mic pins, e.g. on ALC272
5762 */
5763static void fixup_automic_adc(struct hda_codec *codec)
5764{
5765	struct alc_spec *spec = codec->spec;
5766	int i;
5767
5768	for (i = 0; i < spec->num_adc_nids; i++) {
5769		hda_nid_t cap = spec->capsrc_nids ?
5770			spec->capsrc_nids[i] : spec->adc_nids[i];
5771		int iidx, eidx;
5772
5773		iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5774		if (iidx < 0)
5775			continue;
5776		eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5777		if (eidx < 0)
5778			continue;
5779		spec->int_mic.mux_idx = iidx;
5780		spec->ext_mic.mux_idx = eidx;
5781		if (spec->capsrc_nids)
5782			spec->capsrc_nids += i;
5783		spec->adc_nids += i;
5784		spec->num_adc_nids = 1;
5785		/* optional dock-mic */
5786		eidx = get_connection_index(codec, cap, spec->dock_mic.pin);
5787		if (eidx < 0)
5788			spec->dock_mic.pin = 0;
5789		else
5790			spec->dock_mic.mux_idx = eidx;
5791		return;
5792	}
5793	snd_printd(KERN_INFO "hda_codec: %s: "
5794		   "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5795		   codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5796	spec->auto_mic = 0; /* disable auto-mic to be sure */
5797}
5798
5799/* select or unmute the given capsrc route */
5800static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5801				    int idx)
5802{
5803	if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5804		snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5805					 HDA_AMP_MUTE, 0);
5806	} else {
5807		snd_hda_codec_write_cache(codec, cap, 0,
5808					  AC_VERB_SET_CONNECT_SEL, idx);
5809	}
5810}
5811
5812/* set the default connection to that pin */
5813static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
5814{
5815	struct alc_spec *spec = codec->spec;
5816	int i;
5817
5818	if (!pin)
5819		return 0;
5820	for (i = 0; i < spec->num_adc_nids; i++) {
5821		hda_nid_t cap = spec->capsrc_nids ?
5822			spec->capsrc_nids[i] : spec->adc_nids[i];
5823		int idx;
5824
5825		idx = get_connection_index(codec, cap, pin);
5826		if (idx < 0)
5827			continue;
5828		select_or_unmute_capsrc(codec, cap, idx);
5829		return i; /* return the found index */
5830	}
5831	return -1; /* not found */
5832}
5833
5834/* choose the ADC/MUX containing the input pin and initialize the setup */
5835static void fixup_single_adc(struct hda_codec *codec)
5836{
5837	struct alc_spec *spec = codec->spec;
5838	struct auto_pin_cfg *cfg = &spec->autocfg;
5839	int i;
5840
5841	/* search for the input pin; there must be only one */
5842	if (cfg->num_inputs != 1)
5843		return;
5844	i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
5845	if (i >= 0) {
5846		/* use only this ADC */
5847		if (spec->capsrc_nids)
5848			spec->capsrc_nids += i;
5849		spec->adc_nids += i;
5850		spec->num_adc_nids = 1;
5851		spec->single_input_src = 1;
5852	}
5853}
5854
5855/* initialize dual adcs */
5856static void fixup_dual_adc_switch(struct hda_codec *codec)
5857{
5858	struct alc_spec *spec = codec->spec;
5859	init_capsrc_for_pin(codec, spec->ext_mic.pin);
5860	init_capsrc_for_pin(codec, spec->dock_mic.pin);
5861	init_capsrc_for_pin(codec, spec->int_mic.pin);
5862}
5863
5864/* initialize some special cases for input sources */
5865static void alc_init_special_input_src(struct hda_codec *codec)
5866{
5867	struct alc_spec *spec = codec->spec;
5868	if (spec->dual_adc_switch)
5869		fixup_dual_adc_switch(codec);
5870	else if (spec->single_input_src)
5871		init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin);
5872}
5873
5874static void set_capture_mixer(struct hda_codec *codec)
5875{
5876	struct alc_spec *spec = codec->spec;
5877	static const struct snd_kcontrol_new *caps[2][3] = {
5878		{ alc_capture_mixer_nosrc1,
5879		  alc_capture_mixer_nosrc2,
5880		  alc_capture_mixer_nosrc3 },
5881		{ alc_capture_mixer1,
5882		  alc_capture_mixer2,
5883		  alc_capture_mixer3 },
5884	};
5885	if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
5886		int mux = 0;
5887		int num_adcs = spec->num_adc_nids;
5888		if (spec->dual_adc_switch)
5889			num_adcs = 1;
5890		else if (spec->auto_mic)
5891			fixup_automic_adc(codec);
5892		else if (spec->input_mux) {
5893			if (spec->input_mux->num_items > 1)
5894				mux = 1;
5895			else if (spec->input_mux->num_items == 1)
5896				fixup_single_adc(codec);
5897		}
5898		spec->cap_mixer = caps[mux][num_adcs - 1];
5899	}
5900}
5901
5902/* fill adc_nids (and capsrc_nids) containing all active input pins */
5903static void fillup_priv_adc_nids(struct hda_codec *codec, const hda_nid_t *nids,
5904				 int num_nids)
5905{
5906	struct alc_spec *spec = codec->spec;
5907	struct auto_pin_cfg *cfg = &spec->autocfg;
5908	int n;
5909	hda_nid_t fallback_adc = 0, fallback_cap = 0;
5910
5911	for (n = 0; n < num_nids; n++) {
5912		hda_nid_t adc, cap;
5913		hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5914		int nconns, i, j;
5915
5916		adc = nids[n];
5917		if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5918			continue;
5919		cap = adc;
5920		nconns = snd_hda_get_connections(codec, cap, conn,
5921						 ARRAY_SIZE(conn));
5922		if (nconns == 1) {
5923			cap = conn[0];
5924			nconns = snd_hda_get_connections(codec, cap, conn,
5925							 ARRAY_SIZE(conn));
5926		}
5927		if (nconns <= 0)
5928			continue;
5929		if (!fallback_adc) {
5930			fallback_adc = adc;
5931			fallback_cap = cap;
5932		}
5933		for (i = 0; i < cfg->num_inputs; i++) {
5934			hda_nid_t nid = cfg->inputs[i].pin;
5935			for (j = 0; j < nconns; j++) {
5936				if (conn[j] == nid)
5937					break;
5938			}
5939			if (j >= nconns)
5940				break;
5941		}
5942		if (i >= cfg->num_inputs) {
5943			int num_adcs = spec->num_adc_nids;
5944			spec->private_adc_nids[num_adcs] = adc;
5945			spec->private_capsrc_nids[num_adcs] = cap;
5946			spec->num_adc_nids++;
5947			spec->adc_nids = spec->private_adc_nids;
5948			if (adc != cap)
5949				spec->capsrc_nids = spec->private_capsrc_nids;
5950		}
5951	}
5952	if (!spec->num_adc_nids) {
5953		printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
5954		       " using fallback 0x%x\n",
5955		       codec->chip_name, fallback_adc);
5956		spec->private_adc_nids[0] = fallback_adc;
5957		spec->adc_nids = spec->private_adc_nids;
5958		if (fallback_adc != fallback_cap) {
5959			spec->private_capsrc_nids[0] = fallback_cap;
5960			spec->capsrc_nids = spec->private_adc_nids;
5961		}
5962	}
5963}
5964
5965#ifdef CONFIG_SND_HDA_INPUT_BEEP
5966#define set_beep_amp(spec, nid, idx, dir) \
5967	((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
5968
5969static const struct snd_pci_quirk beep_white_list[] = {
5970	SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
5971	SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
5972	SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
5973	SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
5974	SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
5975	{}
5976};
5977
5978static inline int has_cdefine_beep(struct hda_codec *codec)
5979{
5980	struct alc_spec *spec = codec->spec;
5981	const struct snd_pci_quirk *q;
5982	q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5983	if (q)
5984		return q->value;
5985	return spec->cdefine.enable_pcbeep;
5986}
5987#else
5988#define set_beep_amp(spec, nid, idx, dir) /* NOP */
5989#define has_cdefine_beep(codec)		0
5990#endif
5991
5992/*
5993 * OK, here we have finally the patch for ALC880
5994 */
5995
5996static int patch_alc880(struct hda_codec *codec)
5997{
5998	struct alc_spec *spec;
5999	int board_config;
6000	int err;
6001
6002	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6003	if (spec == NULL)
6004		return -ENOMEM;
6005
6006	codec->spec = spec;
6007
6008	board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
6009						  alc880_models,
6010						  alc880_cfg_tbl);
6011	if (board_config < 0) {
6012		printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6013		       codec->chip_name);
6014		board_config = ALC880_AUTO;
6015	}
6016
6017	if (board_config == ALC880_AUTO) {
6018		/* automatic parse from the BIOS config */
6019		err = alc880_parse_auto_config(codec);
6020		if (err < 0) {
6021			alc_free(codec);
6022			return err;
6023		} else if (!err) {
6024			printk(KERN_INFO
6025			       "hda_codec: Cannot set up configuration "
6026			       "from BIOS.  Using 3-stack mode...\n");
6027			board_config = ALC880_3ST;
6028		}
6029	}
6030
6031	err = snd_hda_attach_beep_device(codec, 0x1);
6032	if (err < 0) {
6033		alc_free(codec);
6034		return err;
6035	}
6036
6037	if (board_config != ALC880_AUTO)
6038		setup_preset(codec, &alc880_presets[board_config]);
6039
6040	spec->stream_analog_playback = &alc880_pcm_analog_playback;
6041	spec->stream_analog_capture = &alc880_pcm_analog_capture;
6042	spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
6043
6044	spec->stream_digital_playback = &alc880_pcm_digital_playback;
6045	spec->stream_digital_capture = &alc880_pcm_digital_capture;
6046
6047	if (!spec->adc_nids && spec->input_mux) {
6048		/* check whether NID 0x07 is valid */
6049		unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
6050		/* get type */
6051		wcap = get_wcaps_type(wcap);
6052		if (wcap != AC_WID_AUD_IN) {
6053			spec->adc_nids = alc880_adc_nids_alt;
6054			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
6055		} else {
6056			spec->adc_nids = alc880_adc_nids;
6057			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
6058		}
6059	}
6060	set_capture_mixer(codec);
6061	set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
6062
6063	spec->vmaster_nid = 0x0c;
6064
6065	codec->patch_ops = alc_patch_ops;
6066	if (board_config == ALC880_AUTO)
6067		spec->init_hook = alc880_auto_init;
6068#ifdef CONFIG_SND_HDA_POWER_SAVE
6069	if (!spec->loopback.amplist)
6070		spec->loopback.amplist = alc880_loopbacks;
6071#endif
6072
6073	return 0;
6074}
6075
6076
6077/*
6078 * ALC260 support
6079 */
6080
6081static const hda_nid_t alc260_dac_nids[1] = {
6082	/* front */
6083	0x02,
6084};
6085
6086static const hda_nid_t alc260_adc_nids[1] = {
6087	/* ADC0 */
6088	0x04,
6089};
6090
6091static const hda_nid_t alc260_adc_nids_alt[1] = {
6092	/* ADC1 */
6093	0x05,
6094};
6095
6096/* NIDs used when simultaneous access to both ADCs makes sense.  Note that
6097 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
6098 */
6099static const hda_nid_t alc260_dual_adc_nids[2] = {
6100	/* ADC0, ADC1 */
6101	0x04, 0x05
6102};
6103
6104#define ALC260_DIGOUT_NID	0x03
6105#define ALC260_DIGIN_NID	0x06
6106
6107static const struct hda_input_mux alc260_capture_source = {
6108	.num_items = 4,
6109	.items = {
6110		{ "Mic", 0x0 },
6111		{ "Front Mic", 0x1 },
6112		{ "Line", 0x2 },
6113		{ "CD", 0x4 },
6114	},
6115};
6116
6117/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
6118 * headphone jack and the internal CD lines since these are the only pins at
6119 * which audio can appear.  For flexibility, also allow the option of
6120 * recording the mixer output on the second ADC (ADC0 doesn't have a
6121 * connection to the mixer output).
6122 */
6123static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
6124	{
6125		.num_items = 3,
6126		.items = {
6127			{ "Mic/Line", 0x0 },
6128			{ "CD", 0x4 },
6129			{ "Headphone", 0x2 },
6130		},
6131	},
6132	{
6133		.num_items = 4,
6134		.items = {
6135			{ "Mic/Line", 0x0 },
6136			{ "CD", 0x4 },
6137			{ "Headphone", 0x2 },
6138			{ "Mixer", 0x5 },
6139		},
6140	},
6141
6142};
6143
6144/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
6145 * the Fujitsu S702x, but jacks are marked differently.
6146 */
6147static const struct hda_input_mux alc260_acer_capture_sources[2] = {
6148	{
6149		.num_items = 4,
6150		.items = {
6151			{ "Mic", 0x0 },
6152			{ "Line", 0x2 },
6153			{ "CD", 0x4 },
6154			{ "Headphone", 0x5 },
6155		},
6156	},
6157	{
6158		.num_items = 5,
6159		.items = {
6160			{ "Mic", 0x0 },
6161			{ "Line", 0x2 },
6162			{ "CD", 0x4 },
6163			{ "Headphone", 0x6 },
6164			{ "Mixer", 0x5 },
6165		},
6166	},
6167};
6168
6169/* Maxdata Favorit 100XS */
6170static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
6171	{
6172		.num_items = 2,
6173		.items = {
6174			{ "Line/Mic", 0x0 },
6175			{ "CD", 0x4 },
6176		},
6177	},
6178	{
6179		.num_items = 3,
6180		.items = {
6181			{ "Line/Mic", 0x0 },
6182			{ "CD", 0x4 },
6183			{ "Mixer", 0x5 },
6184		},
6185	},
6186};
6187
6188/*
6189 * This is just place-holder, so there's something for alc_build_pcms to look
6190 * at when it calculates the maximum number of channels. ALC260 has no mixer
6191 * element which allows changing the channel mode, so the verb list is
6192 * never used.
6193 */
6194static const struct hda_channel_mode alc260_modes[1] = {
6195	{ 2, NULL },
6196};
6197
6198
6199/* Mixer combinations
6200 *
6201 * basic: base_output + input + pc_beep + capture
6202 * HP: base_output + input + capture_alt
6203 * HP_3013: hp_3013 + input + capture
6204 * fujitsu: fujitsu + capture
6205 * acer: acer + capture
6206 */
6207
6208static const struct snd_kcontrol_new alc260_base_output_mixer[] = {
6209	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6210	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6211	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6212	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6213	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6214	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6215	{ } /* end */
6216};
6217
6218static const struct snd_kcontrol_new alc260_input_mixer[] = {
6219	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6220	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6221	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6222	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6223	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6224	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6225	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
6226	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
6227	{ } /* end */
6228};
6229
6230/* update HP, line and mono out pins according to the master switch */
6231static void alc260_hp_master_update(struct hda_codec *codec)
6232{
6233	update_speakers(codec);
6234}
6235
6236static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
6237				   struct snd_ctl_elem_value *ucontrol)
6238{
6239	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6240	struct alc_spec *spec = codec->spec;
6241	*ucontrol->value.integer.value = !spec->master_mute;
6242	return 0;
6243}
6244
6245static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
6246				   struct snd_ctl_elem_value *ucontrol)
6247{
6248	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6249	struct alc_spec *spec = codec->spec;
6250	int val = !*ucontrol->value.integer.value;
6251
6252	if (val == spec->master_mute)
6253		return 0;
6254	spec->master_mute = val;
6255	alc260_hp_master_update(codec);
6256	return 1;
6257}
6258
6259static const struct snd_kcontrol_new alc260_hp_output_mixer[] = {
6260	{
6261		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6262		.name = "Master Playback Switch",
6263		.subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
6264		.info = snd_ctl_boolean_mono_info,
6265		.get = alc260_hp_master_sw_get,
6266		.put = alc260_hp_master_sw_put,
6267	},
6268	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6269	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6270	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6271	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6272	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6273			      HDA_OUTPUT),
6274	HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6275	{ } /* end */
6276};
6277
6278static const struct hda_verb alc260_hp_unsol_verbs[] = {
6279	{0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6280	{},
6281};
6282
6283static void alc260_hp_setup(struct hda_codec *codec)
6284{
6285	struct alc_spec *spec = codec->spec;
6286
6287	spec->autocfg.hp_pins[0] = 0x0f;
6288	spec->autocfg.speaker_pins[0] = 0x10;
6289	spec->autocfg.speaker_pins[1] = 0x11;
6290	spec->automute = 1;
6291	spec->automute_mode = ALC_AUTOMUTE_PIN;
6292}
6293
6294static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
6295	{
6296		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6297		.name = "Master Playback Switch",
6298		.subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
6299		.info = snd_ctl_boolean_mono_info,
6300		.get = alc260_hp_master_sw_get,
6301		.put = alc260_hp_master_sw_put,
6302	},
6303	HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6304	HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6305	HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
6306	HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
6307	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6308	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6309	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6310	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
6311	{ } /* end */
6312};
6313
6314static void alc260_hp_3013_setup(struct hda_codec *codec)
6315{
6316	struct alc_spec *spec = codec->spec;
6317
6318	spec->autocfg.hp_pins[0] = 0x15;
6319	spec->autocfg.speaker_pins[0] = 0x10;
6320	spec->autocfg.speaker_pins[1] = 0x11;
6321	spec->automute = 1;
6322	spec->automute_mode = ALC_AUTOMUTE_PIN;
6323}
6324
6325static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
6326	.ops = &snd_hda_bind_vol,
6327	.values = {
6328		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
6329		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
6330		HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6331		0
6332	},
6333};
6334
6335static const struct hda_bind_ctls alc260_dc7600_bind_switch = {
6336	.ops = &snd_hda_bind_sw,
6337	.values = {
6338		HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6339		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6340		0
6341	},
6342};
6343
6344static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
6345	HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6346	HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6347	HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6348	HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6349	{ } /* end */
6350};
6351
6352static const struct hda_verb alc260_hp_3013_unsol_verbs[] = {
6353	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6354	{},
6355};
6356
6357static void alc260_hp_3012_setup(struct hda_codec *codec)
6358{
6359	struct alc_spec *spec = codec->spec;
6360
6361	spec->autocfg.hp_pins[0] = 0x10;
6362	spec->autocfg.speaker_pins[0] = 0x0f;
6363	spec->autocfg.speaker_pins[1] = 0x11;
6364	spec->autocfg.speaker_pins[2] = 0x15;
6365	spec->automute = 1;
6366	spec->automute_mode = ALC_AUTOMUTE_PIN;
6367}
6368
6369/* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12,
6370 * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
6371 */
6372static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
6373	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6374	HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
6375	ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6376	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6377	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6378	HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6379	HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
6380	ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
6381	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6382	HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
6383	{ } /* end */
6384};
6385
6386/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
6387 * versions of the ALC260 don't act on requests to enable mic bias from NID
6388 * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
6389 * datasheet doesn't mention this restriction.  At this stage it's not clear
6390 * whether this behaviour is intentional or is a hardware bug in chip
6391 * revisions available in early 2006.  Therefore for now allow the
6392 * "Headphone Jack Mode" control to span all choices, but if it turns out
6393 * that the lack of mic bias for this NID is intentional we could change the
6394 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6395 *
6396 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6397 * don't appear to make the mic bias available from the "line" jack, even
6398 * though the NID used for this jack (0x14) can supply it.  The theory is
6399 * that perhaps Acer have included blocking capacitors between the ALC260
6400 * and the output jack.  If this turns out to be the case for all such
6401 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6402 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
6403 *
6404 * The C20x Tablet series have a mono internal speaker which is controlled
6405 * via the chip's Mono sum widget and pin complex, so include the necessary
6406 * controls for such models.  On models without a "mono speaker" the control
6407 * won't do anything.
6408 */
6409static const struct snd_kcontrol_new alc260_acer_mixer[] = {
6410	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6411	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6412	ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6413	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6414			      HDA_OUTPUT),
6415	HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
6416			   HDA_INPUT),
6417	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6418	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6419	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6420	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6421	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6422	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6423	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6424	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6425	{ } /* end */
6426};
6427
6428/* Maxdata Favorit 100XS: one output and one input (0x12) jack
6429 */
6430static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
6431	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6432	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6433	ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6434	HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6435	HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6436	ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6437	{ } /* end */
6438};
6439
6440/* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6441 * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
6442 */
6443static const struct snd_kcontrol_new alc260_will_mixer[] = {
6444	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6445	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6446	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6447	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6448	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6449	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6450	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6451	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6452	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6453	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6454	{ } /* end */
6455};
6456
6457/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6458 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6459 */
6460static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6461	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6462	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6463	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6464	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6465	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6466	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6467	HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6468	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6469	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6470	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6471	{ } /* end */
6472};
6473
6474/*
6475 * initialization verbs
6476 */
6477static const struct hda_verb alc260_init_verbs[] = {
6478	/* Line In pin widget for input */
6479	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6480	/* CD pin widget for input */
6481	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6482	/* Mic1 (rear panel) pin widget for input and vref at 80% */
6483	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6484	/* Mic2 (front panel) pin widget for input and vref at 80% */
6485	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6486	/* LINE-2 is used for line-out in rear */
6487	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6488	/* select line-out */
6489	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
6490	/* LINE-OUT pin */
6491	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6492	/* enable HP */
6493	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6494	/* enable Mono */
6495	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6496	/* mute capture amp left and right */
6497	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6498	/* set connection select to line in (default select for this ADC) */
6499	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6500	/* mute capture amp left and right */
6501	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6502	/* set connection select to line in (default select for this ADC) */
6503	{0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
6504	/* set vol=0 Line-Out mixer amp left and right */
6505	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6506	/* unmute pin widget amp left and right (no gain on this amp) */
6507	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6508	/* set vol=0 HP mixer amp left and right */
6509	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6510	/* unmute pin widget amp left and right (no gain on this amp) */
6511	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6512	/* set vol=0 Mono mixer amp left and right */
6513	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6514	/* unmute pin widget amp left and right (no gain on this amp) */
6515	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6516	/* unmute LINE-2 out pin */
6517	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6518	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6519	 * Line In 2 = 0x03
6520	 */
6521	/* mute analog inputs */
6522	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6523	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6524	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6525	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6526	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6527	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6528	/* mute Front out path */
6529	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6530	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6531	/* mute Headphone out path */
6532	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6533	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6534	/* mute Mono out path */
6535	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6536	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6537	{ }
6538};
6539
6540#if 0 /* should be identical with alc260_init_verbs? */
6541static const struct hda_verb alc260_hp_init_verbs[] = {
6542	/* Headphone and output */
6543	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6544	/* mono output */
6545	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6546	/* Mic1 (rear panel) pin widget for input and vref at 80% */
6547	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6548	/* Mic2 (front panel) pin widget for input and vref at 80% */
6549	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6550	/* Line In pin widget for input */
6551	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6552	/* Line-2 pin widget for output */
6553	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6554	/* CD pin widget for input */
6555	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6556	/* unmute amp left and right */
6557	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6558	/* set connection select to line in (default select for this ADC) */
6559	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6560	/* unmute Line-Out mixer amp left and right (volume = 0) */
6561	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6562	/* mute pin widget amp left and right (no gain on this amp) */
6563	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6564	/* unmute HP mixer amp left and right (volume = 0) */
6565	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6566	/* mute pin widget amp left and right (no gain on this amp) */
6567	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6568	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6569	 * Line In 2 = 0x03
6570	 */
6571	/* mute analog inputs */
6572	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6573	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6574	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6575	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6576	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6577	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6578	/* Unmute Front out path */
6579	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6580	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6581	/* Unmute Headphone out path */
6582	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6583	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6584	/* Unmute Mono out path */
6585	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6586	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6587	{ }
6588};
6589#endif
6590
6591static const struct hda_verb alc260_hp_3013_init_verbs[] = {
6592	/* Line out and output */
6593	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6594	/* mono output */
6595	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6596	/* Mic1 (rear panel) pin widget for input and vref at 80% */
6597	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6598	/* Mic2 (front panel) pin widget for input and vref at 80% */
6599	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6600	/* Line In pin widget for input */
6601	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6602	/* Headphone pin widget for output */
6603	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6604	/* CD pin widget for input */
6605	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6606	/* unmute amp left and right */
6607	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6608	/* set connection select to line in (default select for this ADC) */
6609	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6610	/* unmute Line-Out mixer amp left and right (volume = 0) */
6611	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6612	/* mute pin widget amp left and right (no gain on this amp) */
6613	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6614	/* unmute HP mixer amp left and right (volume = 0) */
6615	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6616	/* mute pin widget amp left and right (no gain on this amp) */
6617	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6618	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6619	 * Line In 2 = 0x03
6620	 */
6621	/* mute analog inputs */
6622	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6623	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6624	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6625	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6626	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6627	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6628	/* Unmute Front out path */
6629	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6630	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6631	/* Unmute Headphone out path */
6632	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6633	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6634	/* Unmute Mono out path */
6635	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6636	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6637	{ }
6638};
6639
6640/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
6641 * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6642 * audio = 0x16, internal speaker = 0x10.
6643 */
6644static const struct hda_verb alc260_fujitsu_init_verbs[] = {
6645	/* Disable all GPIOs */
6646	{0x01, AC_VERB_SET_GPIO_MASK, 0},
6647	/* Internal speaker is connected to headphone pin */
6648	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6649	/* Headphone/Line-out jack connects to Line1 pin; make it an output */
6650	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6651	/* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6652	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6653	/* Ensure all other unused pins are disabled and muted. */
6654	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6655	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6656	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6657	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6658	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6659	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6660	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6661	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6662
6663	/* Disable digital (SPDIF) pins */
6664	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6665	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6666
6667	/* Ensure Line1 pin widget takes its input from the OUT1 sum bus
6668	 * when acting as an output.
6669	 */
6670	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6671
6672	/* Start with output sum widgets muted and their output gains at min */
6673	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6674	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6675	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6676	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6677	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6678	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6679	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6680	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6681	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6682
6683	/* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6684	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6685	/* Unmute Line1 pin widget output buffer since it starts as an output.
6686	 * If the pin mode is changed by the user the pin mode control will
6687	 * take care of enabling the pin's input/output buffers as needed.
6688	 * Therefore there's no need to enable the input buffer at this
6689	 * stage.
6690	 */
6691	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6692	/* Unmute input buffer of pin widget used for Line-in (no equiv
6693	 * mixer ctrl)
6694	 */
6695	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6696
6697	/* Mute capture amp left and right */
6698	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6699	/* Set ADC connection select to match default mixer setting - line
6700	 * in (on mic1 pin)
6701	 */
6702	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6703
6704	/* Do the same for the second ADC: mute capture input amp and
6705	 * set ADC connection to line in (on mic1 pin)
6706	 */
6707	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6708	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6709
6710	/* Mute all inputs to mixer widget (even unconnected ones) */
6711	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6712	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6713	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6714	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6715	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6716	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6717	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6718	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6719
6720	{ }
6721};
6722
6723/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6724 * similar laptops (adapted from Fujitsu init verbs).
6725 */
6726static const struct hda_verb alc260_acer_init_verbs[] = {
6727	/* On TravelMate laptops, GPIO 0 enables the internal speaker and
6728	 * the headphone jack.  Turn this on and rely on the standard mute
6729	 * methods whenever the user wants to turn these outputs off.
6730	 */
6731	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6732	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6733	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6734	/* Internal speaker/Headphone jack is connected to Line-out pin */
6735	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6736	/* Internal microphone/Mic jack is connected to Mic1 pin */
6737	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6738	/* Line In jack is connected to Line1 pin */
6739	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6740	/* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6741	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6742	/* Ensure all other unused pins are disabled and muted. */
6743	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6744	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6745	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6746	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6747	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6748	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6749	/* Disable digital (SPDIF) pins */
6750	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6751	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6752
6753	/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6754	 * bus when acting as outputs.
6755	 */
6756	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6757	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6758
6759	/* Start with output sum widgets muted and their output gains at min */
6760	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6761	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6762	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6763	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6764	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6765	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6766	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6767	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6768	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6769
6770	/* Unmute Line-out pin widget amp left and right
6771	 * (no equiv mixer ctrl)
6772	 */
6773	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6774	/* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6775	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6776	/* Unmute Mic1 and Line1 pin widget input buffers since they start as
6777	 * inputs. If the pin mode is changed by the user the pin mode control
6778	 * will take care of enabling the pin's input/output buffers as needed.
6779	 * Therefore there's no need to enable the input buffer at this
6780	 * stage.
6781	 */
6782	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6783	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6784
6785	/* Mute capture amp left and right */
6786	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6787	/* Set ADC connection select to match default mixer setting - mic
6788	 * (on mic1 pin)
6789	 */
6790	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6791
6792	/* Do similar with the second ADC: mute capture input amp and
6793	 * set ADC connection to mic to match ALSA's default state.
6794	 */
6795	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6796	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6797
6798	/* Mute all inputs to mixer widget (even unconnected ones) */
6799	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6800	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6801	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6802	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6803	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6804	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6805	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6806	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6807
6808	{ }
6809};
6810
6811/* Initialisation sequence for Maxdata Favorit 100XS
6812 * (adapted from Acer init verbs).
6813 */
6814static const struct hda_verb alc260_favorit100_init_verbs[] = {
6815	/* GPIO 0 enables the output jack.
6816	 * Turn this on and rely on the standard mute
6817	 * methods whenever the user wants to turn these outputs off.
6818	 */
6819	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6820	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6821	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6822	/* Line/Mic input jack is connected to Mic1 pin */
6823	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6824	/* Ensure all other unused pins are disabled and muted. */
6825	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6826	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6827	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6828	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6829	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6830	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6831	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6832	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6833	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6834	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6835	/* Disable digital (SPDIF) pins */
6836	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6837	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6838
6839	/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6840	 * bus when acting as outputs.
6841	 */
6842	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6843	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6844
6845	/* Start with output sum widgets muted and their output gains at min */
6846	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6847	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6848	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6849	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6850	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6851	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6852	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6853	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6854	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6855
6856	/* Unmute Line-out pin widget amp left and right
6857	 * (no equiv mixer ctrl)
6858	 */
6859	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6860	/* Unmute Mic1 and Line1 pin widget input buffers since they start as
6861	 * inputs. If the pin mode is changed by the user the pin mode control
6862	 * will take care of enabling the pin's input/output buffers as needed.
6863	 * Therefore there's no need to enable the input buffer at this
6864	 * stage.
6865	 */
6866	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6867
6868	/* Mute capture amp left and right */
6869	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6870	/* Set ADC connection select to match default mixer setting - mic
6871	 * (on mic1 pin)
6872	 */
6873	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6874
6875	/* Do similar with the second ADC: mute capture input amp and
6876	 * set ADC connection to mic to match ALSA's default state.
6877	 */
6878	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6879	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6880
6881	/* Mute all inputs to mixer widget (even unconnected ones) */
6882	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6883	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6884	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6885	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6886	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6887	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6888	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6889	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6890
6891	{ }
6892};
6893
6894static const struct hda_verb alc260_will_verbs[] = {
6895	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6896	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6897	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6898	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6899	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6900	{0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6901	{}
6902};
6903
6904static const struct hda_verb alc260_replacer_672v_verbs[] = {
6905	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6906	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6907	{0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6908
6909	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6910	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6911	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6912
6913	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6914	{}
6915};
6916
6917/* toggle speaker-output according to the hp-jack state */
6918static void alc260_replacer_672v_automute(struct hda_codec *codec)
6919{
6920        unsigned int present;
6921
6922	/* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
6923	present = snd_hda_jack_detect(codec, 0x0f);
6924	if (present) {
6925		snd_hda_codec_write_cache(codec, 0x01, 0,
6926					  AC_VERB_SET_GPIO_DATA, 1);
6927		snd_hda_codec_write_cache(codec, 0x0f, 0,
6928					  AC_VERB_SET_PIN_WIDGET_CONTROL,
6929					  PIN_HP);
6930	} else {
6931		snd_hda_codec_write_cache(codec, 0x01, 0,
6932					  AC_VERB_SET_GPIO_DATA, 0);
6933		snd_hda_codec_write_cache(codec, 0x0f, 0,
6934					  AC_VERB_SET_PIN_WIDGET_CONTROL,
6935					  PIN_OUT);
6936	}
6937}
6938
6939static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6940                                       unsigned int res)
6941{
6942        if ((res >> 26) == ALC880_HP_EVENT)
6943                alc260_replacer_672v_automute(codec);
6944}
6945
6946static const struct hda_verb alc260_hp_dc7600_verbs[] = {
6947	{0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6948	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6949	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6950	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6951	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6952	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6953	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6954	{0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6955	{0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6956	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6957	{}
6958};
6959
6960/* Test configuration for debugging, modelled after the ALC880 test
6961 * configuration.
6962 */
6963#ifdef CONFIG_SND_DEBUG
6964static const hda_nid_t alc260_test_dac_nids[1] = {
6965	0x02,
6966};
6967static const hda_nid_t alc260_test_adc_nids[2] = {
6968	0x04, 0x05,
6969};
6970/* For testing the ALC260, each input MUX needs its own definition since
6971 * the signal assignments are different.  This assumes that the first ADC
6972 * is NID 0x04.
6973 */
6974static const struct hda_input_mux alc260_test_capture_sources[2] = {
6975	{
6976		.num_items = 7,
6977		.items = {
6978			{ "MIC1 pin", 0x0 },
6979			{ "MIC2 pin", 0x1 },
6980			{ "LINE1 pin", 0x2 },
6981			{ "LINE2 pin", 0x3 },
6982			{ "CD pin", 0x4 },
6983			{ "LINE-OUT pin", 0x5 },
6984			{ "HP-OUT pin", 0x6 },
6985		},
6986        },
6987	{
6988		.num_items = 8,
6989		.items = {
6990			{ "MIC1 pin", 0x0 },
6991			{ "MIC2 pin", 0x1 },
6992			{ "LINE1 pin", 0x2 },
6993			{ "LINE2 pin", 0x3 },
6994			{ "CD pin", 0x4 },
6995			{ "Mixer", 0x5 },
6996			{ "LINE-OUT pin", 0x6 },
6997			{ "HP-OUT pin", 0x7 },
6998		},
6999        },
7000};
7001static const struct snd_kcontrol_new alc260_test_mixer[] = {
7002	/* Output driver widgets */
7003	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
7004	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
7005	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
7006	HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
7007	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
7008	HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
7009
7010	/* Modes for retasking pin widgets
7011	 * Note: the ALC260 doesn't seem to act on requests to enable mic
7012         * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
7013         * mention this restriction.  At this stage it's not clear whether
7014         * this behaviour is intentional or is a hardware bug in chip
7015         * revisions available at least up until early 2006.  Therefore for
7016         * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
7017         * choices, but if it turns out that the lack of mic bias for these
7018         * NIDs is intentional we could change their modes from
7019         * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
7020	 */
7021	ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
7022	ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
7023	ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
7024	ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
7025	ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
7026	ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
7027
7028	/* Loopback mixer controls */
7029	HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
7030	HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
7031	HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
7032	HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
7033	HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
7034	HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
7035	HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
7036	HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
7037	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
7038	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7039	HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
7040	HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
7041	HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
7042	HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
7043
7044	/* Controls for GPIO pins, assuming they are configured as outputs */
7045	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
7046	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
7047	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
7048	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
7049
7050	/* Switches to allow the digital IO pins to be enabled.  The datasheet
7051	 * is ambigious as to which NID is which; testing on laptops which
7052	 * make this output available should provide clarification.
7053	 */
7054	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
7055	ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
7056
7057	/* A switch allowing EAPD to be enabled.  Some laptops seem to use
7058	 * this output to turn on an external amplifier.
7059	 */
7060	ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
7061	ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
7062
7063	{ } /* end */
7064};
7065static const struct hda_verb alc260_test_init_verbs[] = {
7066	/* Enable all GPIOs as outputs with an initial value of 0 */
7067	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
7068	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
7069	{0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
7070
7071	/* Enable retasking pins as output, initially without power amp */
7072	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7073	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7074	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7075	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7076	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7077	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7078
7079	/* Disable digital (SPDIF) pins initially, but users can enable
7080	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
7081	 * payload also sets the generation to 0, output to be in "consumer"
7082	 * PCM format, copyright asserted, no pre-emphasis and no validity
7083	 * control.
7084	 */
7085	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
7086	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
7087
7088	/* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7089	 * OUT1 sum bus when acting as an output.
7090	 */
7091	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
7092	{0x0c, AC_VERB_SET_CONNECT_SEL, 0},
7093	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
7094	{0x0e, AC_VERB_SET_CONNECT_SEL, 0},
7095
7096	/* Start with output sum widgets muted and their output gains at min */
7097	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7098	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7099	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7100	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7101	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7102	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7103	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7104	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7105	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7106
7107	/* Unmute retasking pin widget output buffers since the default
7108	 * state appears to be output.  As the pin mode is changed by the
7109	 * user the pin mode control will take care of enabling the pin's
7110	 * input/output buffers as needed.
7111	 */
7112	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7113	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7114	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7115	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7116	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7117	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7118	/* Also unmute the mono-out pin widget */
7119	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7120
7121	/* Mute capture amp left and right */
7122	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7123	/* Set ADC connection select to match default mixer setting (mic1
7124	 * pin)
7125	 */
7126	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7127
7128	/* Do the same for the second ADC: mute capture input amp and
7129	 * set ADC connection to mic1 pin
7130	 */
7131	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7132	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7133
7134	/* Mute all inputs to mixer widget (even unconnected ones) */
7135	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
7136	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
7137	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
7138	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
7139	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
7140	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
7141	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
7142	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
7143
7144	{ }
7145};
7146#endif
7147
7148#define alc260_pcm_analog_playback	alc880_pcm_analog_alt_playback
7149#define alc260_pcm_analog_capture	alc880_pcm_analog_capture
7150
7151#define alc260_pcm_digital_playback	alc880_pcm_digital_playback
7152#define alc260_pcm_digital_capture	alc880_pcm_digital_capture
7153
7154/*
7155 * for BIOS auto-configuration
7156 */
7157
7158static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
7159					const char *pfx, int *vol_bits)
7160{
7161	hda_nid_t nid_vol;
7162	unsigned long vol_val, sw_val;
7163	int err;
7164
7165	if (nid >= 0x0f && nid < 0x11) {
7166		nid_vol = nid - 0x7;
7167		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
7168		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
7169	} else if (nid == 0x11) {
7170		nid_vol = nid - 0x7;
7171		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
7172		sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
7173	} else if (nid >= 0x12 && nid <= 0x15) {
7174		nid_vol = 0x08;
7175		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
7176		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
7177	} else
7178		return 0; /* N/A */
7179
7180	if (!(*vol_bits & (1 << nid_vol))) {
7181		/* first control for the volume widget */
7182		err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
7183		if (err < 0)
7184			return err;
7185		*vol_bits |= (1 << nid_vol);
7186	}
7187	err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
7188	if (err < 0)
7189		return err;
7190	return 1;
7191}
7192
7193/* add playback controls from the parsed DAC table */
7194static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
7195					     const struct auto_pin_cfg *cfg)
7196{
7197	hda_nid_t nid;
7198	int err;
7199	int vols = 0;
7200
7201	spec->multiout.num_dacs = 1;
7202	spec->multiout.dac_nids = spec->private_dac_nids;
7203	spec->private_dac_nids[0] = 0x02;
7204
7205	nid = cfg->line_out_pins[0];
7206	if (nid) {
7207		const char *pfx;
7208		if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
7209			pfx = "Master";
7210		else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
7211			pfx = "Speaker";
7212		else
7213			pfx = "Front";
7214		err = alc260_add_playback_controls(spec, nid, pfx, &vols);
7215		if (err < 0)
7216			return err;
7217	}
7218
7219	nid = cfg->speaker_pins[0];
7220	if (nid) {
7221		err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
7222		if (err < 0)
7223			return err;
7224	}
7225
7226	nid = cfg->hp_pins[0];
7227	if (nid) {
7228		err = alc260_add_playback_controls(spec, nid, "Headphone",
7229						   &vols);
7230		if (err < 0)
7231			return err;
7232	}
7233	return 0;
7234}
7235
7236/* create playback/capture controls for input pins */
7237static int alc260_auto_create_input_ctls(struct hda_codec *codec,
7238						const struct auto_pin_cfg *cfg)
7239{
7240	return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
7241}
7242
7243static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
7244					      hda_nid_t nid, int pin_type,
7245					      int sel_idx)
7246{
7247	alc_set_pin_output(codec, nid, pin_type);
7248	/* need the manual connection? */
7249	if (nid >= 0x12) {
7250		int idx = nid - 0x12;
7251		snd_hda_codec_write(codec, idx + 0x0b, 0,
7252				    AC_VERB_SET_CONNECT_SEL, sel_idx);
7253	}
7254}
7255
7256static void alc260_auto_init_multi_out(struct hda_codec *codec)
7257{
7258	struct alc_spec *spec = codec->spec;
7259	hda_nid_t nid;
7260
7261	nid = spec->autocfg.line_out_pins[0];
7262	if (nid) {
7263		int pin_type = get_pin_type(spec->autocfg.line_out_type);
7264		alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
7265	}
7266
7267	nid = spec->autocfg.speaker_pins[0];
7268	if (nid)
7269		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
7270
7271	nid = spec->autocfg.hp_pins[0];
7272	if (nid)
7273		alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
7274}
7275
7276#define ALC260_PIN_CD_NID		0x16
7277static void alc260_auto_init_analog_input(struct hda_codec *codec)
7278{
7279	struct alc_spec *spec = codec->spec;
7280	struct auto_pin_cfg *cfg = &spec->autocfg;
7281	int i;
7282
7283	for (i = 0; i < cfg->num_inputs; i++) {
7284		hda_nid_t nid = cfg->inputs[i].pin;
7285		if (nid >= 0x12) {
7286			alc_set_input_pin(codec, nid, cfg->inputs[i].type);
7287			if (nid != ALC260_PIN_CD_NID &&
7288			    (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
7289				snd_hda_codec_write(codec, nid, 0,
7290						    AC_VERB_SET_AMP_GAIN_MUTE,
7291						    AMP_OUT_MUTE);
7292		}
7293	}
7294}
7295
7296#define alc260_auto_init_input_src	alc880_auto_init_input_src
7297
7298/*
7299 * generic initialization of ADC, input mixers and output mixers
7300 */
7301static const struct hda_verb alc260_volume_init_verbs[] = {
7302	/*
7303	 * Unmute ADC0-1 and set the default input to mic-in
7304	 */
7305	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7306	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7307	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7308	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7309
7310	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7311	 * mixer widget
7312	 * Note: PASD motherboards uses the Line In 2 as the input for
7313	 * front panel mic (mic 2)
7314	 */
7315	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7316	/* mute analog inputs */
7317	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7318	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7319	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7320	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7321	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7322
7323	/*
7324	 * Set up output mixers (0x08 - 0x0a)
7325	 */
7326	/* set vol=0 to output mixers */
7327	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7328	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7329	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7330	/* set up input amps for analog loopback */
7331	/* Amp Indices: DAC = 0, mixer = 1 */
7332	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7333	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7334	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7335	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7336	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7337	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7338
7339	{ }
7340};
7341
7342static int alc260_parse_auto_config(struct hda_codec *codec)
7343{
7344	struct alc_spec *spec = codec->spec;
7345	int err;
7346	static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
7347
7348	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7349					   alc260_ignore);
7350	if (err < 0)
7351		return err;
7352	err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7353	if (err < 0)
7354		return err;
7355	if (!spec->kctls.list)
7356		return 0; /* can't find valid BIOS pin config */
7357	err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
7358	if (err < 0)
7359		return err;
7360
7361	spec->multiout.max_channels = 2;
7362
7363	if (spec->autocfg.dig_outs)
7364		spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
7365	if (spec->kctls.list)
7366		add_mixer(spec, spec->kctls.list);
7367
7368	add_verb(spec, alc260_volume_init_verbs);
7369
7370	spec->num_mux_defs = 1;
7371	spec->input_mux = &spec->private_imux[0];
7372
7373	alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
7374
7375	return 1;
7376}
7377
7378/* additional initialization for auto-configuration model */
7379static void alc260_auto_init(struct hda_codec *codec)
7380{
7381	struct alc_spec *spec = codec->spec;
7382	alc260_auto_init_multi_out(codec);
7383	alc260_auto_init_analog_input(codec);
7384	alc260_auto_init_input_src(codec);
7385	alc_auto_init_digital(codec);
7386	if (spec->unsol_event)
7387		alc_inithook(codec);
7388}
7389
7390#ifdef CONFIG_SND_HDA_POWER_SAVE
7391static const struct hda_amp_list alc260_loopbacks[] = {
7392	{ 0x07, HDA_INPUT, 0 },
7393	{ 0x07, HDA_INPUT, 1 },
7394	{ 0x07, HDA_INPUT, 2 },
7395	{ 0x07, HDA_INPUT, 3 },
7396	{ 0x07, HDA_INPUT, 4 },
7397	{ } /* end */
7398};
7399#endif
7400
7401/*
7402 * Pin config fixes
7403 */
7404enum {
7405	PINFIX_HP_DC5750,
7406};
7407
7408static const struct alc_fixup alc260_fixups[] = {
7409	[PINFIX_HP_DC5750] = {
7410		.type = ALC_FIXUP_PINS,
7411		.v.pins = (const struct alc_pincfg[]) {
7412			{ 0x11, 0x90130110 }, /* speaker */
7413			{ }
7414		}
7415	},
7416};
7417
7418static const struct snd_pci_quirk alc260_fixup_tbl[] = {
7419	SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7420	{}
7421};
7422
7423/*
7424 * ALC260 configurations
7425 */
7426static const char * const alc260_models[ALC260_MODEL_LAST] = {
7427	[ALC260_BASIC]		= "basic",
7428	[ALC260_HP]		= "hp",
7429	[ALC260_HP_3013]	= "hp-3013",
7430	[ALC260_HP_DC7600]	= "hp-dc7600",
7431	[ALC260_FUJITSU_S702X]	= "fujitsu",
7432	[ALC260_ACER]		= "acer",
7433	[ALC260_WILL]		= "will",
7434	[ALC260_REPLACER_672V]	= "replacer",
7435	[ALC260_FAVORIT100]	= "favorit100",
7436#ifdef CONFIG_SND_DEBUG
7437	[ALC260_TEST]		= "test",
7438#endif
7439	[ALC260_AUTO]		= "auto",
7440};
7441
7442static const struct snd_pci_quirk alc260_cfg_tbl[] = {
7443	SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
7444	SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
7445	SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
7446	SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
7447	SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
7448	SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
7449	SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
7450	SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
7451	SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
7452	SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7453	SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7454	SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7455	SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7456	SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7457	SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7458	SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7459	SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7460	SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
7461	SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
7462	SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
7463	{}
7464};
7465
7466static const struct alc_config_preset alc260_presets[] = {
7467	[ALC260_BASIC] = {
7468		.mixers = { alc260_base_output_mixer,
7469			    alc260_input_mixer },
7470		.init_verbs = { alc260_init_verbs },
7471		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
7472		.dac_nids = alc260_dac_nids,
7473		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7474		.adc_nids = alc260_dual_adc_nids,
7475		.num_channel_mode = ARRAY_SIZE(alc260_modes),
7476		.channel_mode = alc260_modes,
7477		.input_mux = &alc260_capture_source,
7478	},
7479	[ALC260_HP] = {
7480		.mixers = { alc260_hp_output_mixer,
7481			    alc260_input_mixer },
7482		.init_verbs = { alc260_init_verbs,
7483				alc260_hp_unsol_verbs },
7484		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
7485		.dac_nids = alc260_dac_nids,
7486		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7487		.adc_nids = alc260_adc_nids_alt,
7488		.num_channel_mode = ARRAY_SIZE(alc260_modes),
7489		.channel_mode = alc260_modes,
7490		.input_mux = &alc260_capture_source,
7491		.unsol_event = alc_sku_unsol_event,
7492		.setup = alc260_hp_setup,
7493		.init_hook = alc_inithook,
7494	},
7495	[ALC260_HP_DC7600] = {
7496		.mixers = { alc260_hp_dc7600_mixer,
7497			    alc260_input_mixer },
7498		.init_verbs = { alc260_init_verbs,
7499				alc260_hp_dc7600_verbs },
7500		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
7501		.dac_nids = alc260_dac_nids,
7502		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7503		.adc_nids = alc260_adc_nids_alt,
7504		.num_channel_mode = ARRAY_SIZE(alc260_modes),
7505		.channel_mode = alc260_modes,
7506		.input_mux = &alc260_capture_source,
7507		.unsol_event = alc_sku_unsol_event,
7508		.setup = alc260_hp_3012_setup,
7509		.init_hook = alc_inithook,
7510	},
7511	[ALC260_HP_3013] = {
7512		.mixers = { alc260_hp_3013_mixer,
7513			    alc260_input_mixer },
7514		.init_verbs = { alc260_hp_3013_init_verbs,
7515				alc260_hp_3013_unsol_verbs },
7516		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
7517		.dac_nids = alc260_dac_nids,
7518		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7519		.adc_nids = alc260_adc_nids_alt,
7520		.num_channel_mode = ARRAY_SIZE(alc260_modes),
7521		.channel_mode = alc260_modes,
7522		.input_mux = &alc260_capture_source,
7523		.unsol_event = alc_sku_unsol_event,
7524		.setup = alc260_hp_3013_setup,
7525		.init_hook = alc_inithook,
7526	},
7527	[ALC260_FUJITSU_S702X] = {
7528		.mixers = { alc260_fujitsu_mixer },
7529		.init_verbs = { alc260_fujitsu_init_verbs },
7530		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
7531		.dac_nids = alc260_dac_nids,
7532		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7533		.adc_nids = alc260_dual_adc_nids,
7534		.num_channel_mode = ARRAY_SIZE(alc260_modes),
7535		.channel_mode = alc260_modes,
7536		.num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7537		.input_mux = alc260_fujitsu_capture_sources,
7538	},
7539	[ALC260_ACER] = {
7540		.mixers = { alc260_acer_mixer },
7541		.init_verbs = { alc260_acer_init_verbs },
7542		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
7543		.dac_nids = alc260_dac_nids,
7544		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7545		.adc_nids = alc260_dual_adc_nids,
7546		.num_channel_mode = ARRAY_SIZE(alc260_modes),
7547		.channel_mode = alc260_modes,
7548		.num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7549		.input_mux = alc260_acer_capture_sources,
7550	},
7551	[ALC260_FAVORIT100] = {
7552		.mixers = { alc260_favorit100_mixer },
7553		.init_verbs = { alc260_favorit100_init_verbs },
7554		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
7555		.dac_nids = alc260_dac_nids,
7556		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7557		.adc_nids = alc260_dual_adc_nids,
7558		.num_channel_mode = ARRAY_SIZE(alc260_modes),
7559		.channel_mode = alc260_modes,
7560		.num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7561		.input_mux = alc260_favorit100_capture_sources,
7562	},
7563	[ALC260_WILL] = {
7564		.mixers = { alc260_will_mixer },
7565		.init_verbs = { alc260_init_verbs, alc260_will_verbs },
7566		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
7567		.dac_nids = alc260_dac_nids,
7568		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7569		.adc_nids = alc260_adc_nids,
7570		.dig_out_nid = ALC260_DIGOUT_NID,
7571		.num_channel_mode = ARRAY_SIZE(alc260_modes),
7572		.channel_mode = alc260_modes,
7573		.input_mux = &alc260_capture_source,
7574	},
7575	[ALC260_REPLACER_672V] = {
7576		.mixers = { alc260_replacer_672v_mixer },
7577		.init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7578		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
7579		.dac_nids = alc260_dac_nids,
7580		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7581		.adc_nids = alc260_adc_nids,
7582		.dig_out_nid = ALC260_DIGOUT_NID,
7583		.num_channel_mode = ARRAY_SIZE(alc260_modes),
7584		.channel_mode = alc260_modes,
7585		.input_mux = &alc260_capture_source,
7586		.unsol_event = alc260_replacer_672v_unsol_event,
7587		.init_hook = alc260_replacer_672v_automute,
7588	},
7589#ifdef CONFIG_SND_DEBUG
7590	[ALC260_TEST] = {
7591		.mixers = { alc260_test_mixer },
7592		.init_verbs = { alc260_test_init_verbs },
7593		.num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7594		.dac_nids = alc260_test_dac_nids,
7595		.num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7596		.adc_nids = alc260_test_adc_nids,
7597		.num_channel_mode = ARRAY_SIZE(alc260_modes),
7598		.channel_mode = alc260_modes,
7599		.num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7600		.input_mux = alc260_test_capture_sources,
7601	},
7602#endif
7603};
7604
7605static int patch_alc260(struct hda_codec *codec)
7606{
7607	struct alc_spec *spec;
7608	int err, board_config;
7609
7610	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7611	if (spec == NULL)
7612		return -ENOMEM;
7613
7614	codec->spec = spec;
7615
7616	board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7617						  alc260_models,
7618						  alc260_cfg_tbl);
7619	if (board_config < 0) {
7620		snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
7621			   codec->chip_name);
7622		board_config = ALC260_AUTO;
7623	}
7624
7625	if (board_config == ALC260_AUTO) {
7626		alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7627		alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7628	}
7629
7630	if (board_config == ALC260_AUTO) {
7631		/* automatic parse from the BIOS config */
7632		err = alc260_parse_auto_config(codec);
7633		if (err < 0) {
7634			alc_free(codec);
7635			return err;
7636		} else if (!err) {
7637			printk(KERN_INFO
7638			       "hda_codec: Cannot set up configuration "
7639			       "from BIOS.  Using base mode...\n");
7640			board_config = ALC260_BASIC;
7641		}
7642	}
7643
7644	err = snd_hda_attach_beep_device(codec, 0x1);
7645	if (err < 0) {
7646		alc_free(codec);
7647		return err;
7648	}
7649
7650	if (board_config != ALC260_AUTO)
7651		setup_preset(codec, &alc260_presets[board_config]);
7652
7653	spec->stream_analog_playback = &alc260_pcm_analog_playback;
7654	spec->stream_analog_capture = &alc260_pcm_analog_capture;
7655	spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
7656
7657	spec->stream_digital_playback = &alc260_pcm_digital_playback;
7658	spec->stream_digital_capture = &alc260_pcm_digital_capture;
7659
7660	if (!spec->adc_nids && spec->input_mux) {
7661		/* check whether NID 0x04 is valid */
7662		unsigned int wcap = get_wcaps(codec, 0x04);
7663		wcap = get_wcaps_type(wcap);
7664		/* get type */
7665		if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7666			spec->adc_nids = alc260_adc_nids_alt;
7667			spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7668		} else {
7669			spec->adc_nids = alc260_adc_nids;
7670			spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7671		}
7672	}
7673	set_capture_mixer(codec);
7674	set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
7675
7676	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7677
7678	spec->vmaster_nid = 0x08;
7679
7680	codec->patch_ops = alc_patch_ops;
7681	if (board_config == ALC260_AUTO)
7682		spec->init_hook = alc260_auto_init;
7683	spec->shutup = alc_eapd_shutup;
7684#ifdef CONFIG_SND_HDA_POWER_SAVE
7685	if (!spec->loopback.amplist)
7686		spec->loopback.amplist = alc260_loopbacks;
7687#endif
7688
7689	return 0;
7690}
7691
7692
7693/*
7694 * ALC882/883/885/888/889 support
7695 *
7696 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7697 * configuration.  Each pin widget can choose any input DACs and a mixer.
7698 * Each ADC is connected from a mixer of all inputs.  This makes possible
7699 * 6-channel independent captures.
7700 *
7701 * In addition, an independent DAC for the multi-playback (not used in this
7702 * driver yet).
7703 */
7704#define ALC882_DIGOUT_NID	0x06
7705#define ALC882_DIGIN_NID	0x0a
7706#define ALC883_DIGOUT_NID	ALC882_DIGOUT_NID
7707#define ALC883_DIGIN_NID	ALC882_DIGIN_NID
7708#define ALC1200_DIGOUT_NID	0x10
7709
7710
7711static const struct hda_channel_mode alc882_ch_modes[1] = {
7712	{ 8, NULL }
7713};
7714
7715/* DACs */
7716static const hda_nid_t alc882_dac_nids[4] = {
7717	/* front, rear, clfe, rear_surr */
7718	0x02, 0x03, 0x04, 0x05
7719};
7720#define alc883_dac_nids		alc882_dac_nids
7721
7722/* ADCs */
7723#define alc882_adc_nids		alc880_adc_nids
7724#define alc882_adc_nids_alt	alc880_adc_nids_alt
7725#define alc883_adc_nids		alc882_adc_nids_alt
7726static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7727static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7728#define alc889_adc_nids		alc880_adc_nids
7729
7730static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7731static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
7732#define alc883_capsrc_nids	alc882_capsrc_nids_alt
7733static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7734#define alc889_capsrc_nids	alc882_capsrc_nids
7735
7736/* input MUX */
7737/* FIXME: should be a matrix-type input source selection */
7738
7739static const struct hda_input_mux alc882_capture_source = {
7740	.num_items = 4,
7741	.items = {
7742		{ "Mic", 0x0 },
7743		{ "Front Mic", 0x1 },
7744		{ "Line", 0x2 },
7745		{ "CD", 0x4 },
7746	},
7747};
7748
7749#define alc883_capture_source	alc882_capture_source
7750
7751static const struct hda_input_mux alc889_capture_source = {
7752	.num_items = 3,
7753	.items = {
7754		{ "Front Mic", 0x0 },
7755		{ "Mic", 0x3 },
7756		{ "Line", 0x2 },
7757	},
7758};
7759
7760static const struct hda_input_mux mb5_capture_source = {
7761	.num_items = 3,
7762	.items = {
7763		{ "Mic", 0x1 },
7764		{ "Line", 0x7 },
7765		{ "CD", 0x4 },
7766	},
7767};
7768
7769static const struct hda_input_mux macmini3_capture_source = {
7770	.num_items = 2,
7771	.items = {
7772		{ "Line", 0x2 },
7773		{ "CD", 0x4 },
7774	},
7775};
7776
7777static const struct hda_input_mux alc883_3stack_6ch_intel = {
7778	.num_items = 4,
7779	.items = {
7780		{ "Mic", 0x1 },
7781		{ "Front Mic", 0x0 },
7782		{ "Line", 0x2 },
7783		{ "CD", 0x4 },
7784	},
7785};
7786
7787static const struct hda_input_mux alc883_lenovo_101e_capture_source = {
7788	.num_items = 2,
7789	.items = {
7790		{ "Mic", 0x1 },
7791		{ "Line", 0x2 },
7792	},
7793};
7794
7795static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7796	.num_items = 4,
7797	.items = {
7798		{ "Mic", 0x0 },
7799		{ "Internal Mic", 0x1 },
7800		{ "Line", 0x2 },
7801		{ "CD", 0x4 },
7802	},
7803};
7804
7805static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7806	.num_items = 2,
7807	.items = {
7808		{ "Mic", 0x0 },
7809		{ "Internal Mic", 0x1 },
7810	},
7811};
7812
7813static const struct hda_input_mux alc883_lenovo_sky_capture_source = {
7814	.num_items = 3,
7815	.items = {
7816		{ "Mic", 0x0 },
7817		{ "Front Mic", 0x1 },
7818		{ "Line", 0x4 },
7819	},
7820};
7821
7822static const struct hda_input_mux alc883_asus_eee1601_capture_source = {
7823	.num_items = 2,
7824	.items = {
7825		{ "Mic", 0x0 },
7826		{ "Line", 0x2 },
7827	},
7828};
7829
7830static const struct hda_input_mux alc889A_mb31_capture_source = {
7831	.num_items = 2,
7832	.items = {
7833		{ "Mic", 0x0 },
7834		/* Front Mic (0x01) unused */
7835		{ "Line", 0x2 },
7836		/* Line 2 (0x03) unused */
7837		/* CD (0x04) unused? */
7838	},
7839};
7840
7841static const struct hda_input_mux alc889A_imac91_capture_source = {
7842	.num_items = 2,
7843	.items = {
7844		{ "Mic", 0x01 },
7845		{ "Line", 0x2 }, /* Not sure! */
7846	},
7847};
7848
7849/*
7850 * 2ch mode
7851 */
7852static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7853	{ 2, NULL }
7854};
7855
7856/*
7857 * 2ch mode
7858 */
7859static const struct hda_verb alc882_3ST_ch2_init[] = {
7860	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7861	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7862	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7863	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7864	{ } /* end */
7865};
7866
7867/*
7868 * 4ch mode
7869 */
7870static const struct hda_verb alc882_3ST_ch4_init[] = {
7871	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7872	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7873	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7874	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7875	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7876	{ } /* end */
7877};
7878
7879/*
7880 * 6ch mode
7881 */
7882static const struct hda_verb alc882_3ST_ch6_init[] = {
7883	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7884	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7885	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7886	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7887	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7888	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7889	{ } /* end */
7890};
7891
7892static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
7893	{ 2, alc882_3ST_ch2_init },
7894	{ 4, alc882_3ST_ch4_init },
7895	{ 6, alc882_3ST_ch6_init },
7896};
7897
7898#define alc883_3ST_6ch_modes	alc882_3ST_6ch_modes
7899
7900/*
7901 * 2ch mode
7902 */
7903static const struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7904	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7905	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7906	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7907	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7908	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7909	{ } /* end */
7910};
7911
7912/*
7913 * 4ch mode
7914 */
7915static const struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7916	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7917	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7918	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7919	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7920	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7921	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7922	{ } /* end */
7923};
7924
7925/*
7926 * 6ch mode
7927 */
7928static const struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7929	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7930	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7931	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7932	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7933	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7934	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7935	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7936	{ } /* end */
7937};
7938
7939static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7940	{ 2, alc883_3ST_ch2_clevo_init },
7941	{ 4, alc883_3ST_ch4_clevo_init },
7942	{ 6, alc883_3ST_ch6_clevo_init },
7943};
7944
7945
7946/*
7947 * 6ch mode
7948 */
7949static const struct hda_verb alc882_sixstack_ch6_init[] = {
7950	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7951	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7952	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7953	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7954	{ } /* end */
7955};
7956
7957/*
7958 * 8ch mode
7959 */
7960static const struct hda_verb alc882_sixstack_ch8_init[] = {
7961	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7962	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7963	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7964	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7965	{ } /* end */
7966};
7967
7968static const struct hda_channel_mode alc882_sixstack_modes[2] = {
7969	{ 6, alc882_sixstack_ch6_init },
7970	{ 8, alc882_sixstack_ch8_init },
7971};
7972
7973
7974/* Macbook Air 2,1 */
7975
7976static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7977      { 2, NULL },
7978};
7979
7980/*
7981 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
7982 */
7983
7984/*
7985 * 2ch mode
7986 */
7987static const struct hda_verb alc885_mbp_ch2_init[] = {
7988	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7989	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7990	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7991	{ } /* end */
7992};
7993
7994/*
7995 * 4ch mode
7996 */
7997static const struct hda_verb alc885_mbp_ch4_init[] = {
7998	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7999	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8000	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8001	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8002	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8003	{ } /* end */
8004};
8005
8006static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
8007	{ 2, alc885_mbp_ch2_init },
8008	{ 4, alc885_mbp_ch4_init },
8009};
8010
8011/*
8012 * 2ch
8013 * Speakers/Woofer/HP = Front
8014 * LineIn = Input
8015 */
8016static const struct hda_verb alc885_mb5_ch2_init[] = {
8017	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8018	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8019	{ } /* end */
8020};
8021
8022/*
8023 * 6ch mode
8024 * Speakers/HP = Front
8025 * Woofer = LFE
8026 * LineIn = Surround
8027 */
8028static const struct hda_verb alc885_mb5_ch6_init[] = {
8029	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8030	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8031	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8032	{ } /* end */
8033};
8034
8035static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
8036	{ 2, alc885_mb5_ch2_init },
8037	{ 6, alc885_mb5_ch6_init },
8038};
8039
8040#define alc885_macmini3_6ch_modes	alc885_mb5_6ch_modes
8041
8042/*
8043 * 2ch mode
8044 */
8045static const struct hda_verb alc883_4ST_ch2_init[] = {
8046	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8047	{ 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8048	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8049	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8050	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8051	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8052	{ } /* end */
8053};
8054
8055/*
8056 * 4ch mode
8057 */
8058static const struct hda_verb alc883_4ST_ch4_init[] = {
8059	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8060	{ 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8061	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8062	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8063	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8064	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8065	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8066	{ } /* end */
8067};
8068
8069/*
8070 * 6ch mode
8071 */
8072static const struct hda_verb alc883_4ST_ch6_init[] = {
8073	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8074	{ 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8075	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8076	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8077	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8078	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8079	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8080	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8081	{ } /* end */
8082};
8083
8084/*
8085 * 8ch mode
8086 */
8087static const struct hda_verb alc883_4ST_ch8_init[] = {
8088	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8089	{ 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8090	{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8091	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8092	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8093	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8094	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8095	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8096	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8097	{ } /* end */
8098};
8099
8100static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
8101	{ 2, alc883_4ST_ch2_init },
8102	{ 4, alc883_4ST_ch4_init },
8103	{ 6, alc883_4ST_ch6_init },
8104	{ 8, alc883_4ST_ch8_init },
8105};
8106
8107
8108/*
8109 * 2ch mode
8110 */
8111static const struct hda_verb alc883_3ST_ch2_intel_init[] = {
8112	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8113	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8114	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8115	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8116	{ } /* end */
8117};
8118
8119/*
8120 * 4ch mode
8121 */
8122static const struct hda_verb alc883_3ST_ch4_intel_init[] = {
8123	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8124	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8125	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8126	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8127	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8128	{ } /* end */
8129};
8130
8131/*
8132 * 6ch mode
8133 */
8134static const struct hda_verb alc883_3ST_ch6_intel_init[] = {
8135	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8136	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8137	{ 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
8138	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8139	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8140	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8141	{ } /* end */
8142};
8143
8144static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
8145	{ 2, alc883_3ST_ch2_intel_init },
8146	{ 4, alc883_3ST_ch4_intel_init },
8147	{ 6, alc883_3ST_ch6_intel_init },
8148};
8149
8150/*
8151 * 2ch mode
8152 */
8153static const struct hda_verb alc889_ch2_intel_init[] = {
8154	{ 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8155	{ 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
8156	{ 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
8157	{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
8158	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8159	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8160	{ } /* end */
8161};
8162
8163/*
8164 * 6ch mode
8165 */
8166static const struct hda_verb alc889_ch6_intel_init[] = {
8167	{ 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8168	{ 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8169	{ 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8170	{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8171	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8172	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8173	{ } /* end */
8174};
8175
8176/*
8177 * 8ch mode
8178 */
8179static const struct hda_verb alc889_ch8_intel_init[] = {
8180	{ 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8181	{ 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8182	{ 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8183	{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8184	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
8185	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8186	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8187	{ } /* end */
8188};
8189
8190static const struct hda_channel_mode alc889_8ch_intel_modes[3] = {
8191	{ 2, alc889_ch2_intel_init },
8192	{ 6, alc889_ch6_intel_init },
8193	{ 8, alc889_ch8_intel_init },
8194};
8195
8196/*
8197 * 6ch mode
8198 */
8199static const struct hda_verb alc883_sixstack_ch6_init[] = {
8200	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8201	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8202	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8203	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8204	{ } /* end */
8205};
8206
8207/*
8208 * 8ch mode
8209 */
8210static const struct hda_verb alc883_sixstack_ch8_init[] = {
8211	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8212	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8213	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8214	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8215	{ } /* end */
8216};
8217
8218static const struct hda_channel_mode alc883_sixstack_modes[2] = {
8219	{ 6, alc883_sixstack_ch6_init },
8220	{ 8, alc883_sixstack_ch8_init },
8221};
8222
8223
8224/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
8225 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
8226 */
8227static const struct snd_kcontrol_new alc882_base_mixer[] = {
8228	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8229	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8230	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8231	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8232	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8233	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8234	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8235	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8236	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8237	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8238	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8239	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8240	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8241	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8242	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8243	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8244	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8245	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8246	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8247	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8248	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8249	{ } /* end */
8250};
8251
8252/* Macbook Air 2,1 same control for HP and internal Speaker */
8253
8254static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
8255      HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8256      HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
8257     { }
8258};
8259
8260
8261static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
8262	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8263	HDA_BIND_MUTE   ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8264	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8265	HDA_BIND_MUTE   ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
8266	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8267	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8268	HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8269	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8270	HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8271	HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
8272	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
8273	{ } /* end */
8274};
8275
8276static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
8277	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8278	HDA_BIND_MUTE   ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8279	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8280	HDA_BIND_MUTE   ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8281	HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8282	HDA_BIND_MUTE   ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8283	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8284	HDA_BIND_MUTE   ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8285	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8286	HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8287	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8288	HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8289	HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8290	HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
8291	{ } /* end */
8292};
8293
8294static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
8295	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8296	HDA_BIND_MUTE   ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8297	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8298	HDA_BIND_MUTE   ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8299	HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8300	HDA_BIND_MUTE   ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8301	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8302	HDA_BIND_MUTE   ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8303	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8304	HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8305	HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8306	{ } /* end */
8307};
8308
8309static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
8310	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8311	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8312	{ } /* end */
8313};
8314
8315
8316static const struct snd_kcontrol_new alc882_w2jc_mixer[] = {
8317	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8318	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8319	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8320	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8321	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8322	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8323	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8324	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8325	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8326	{ } /* end */
8327};
8328
8329static const struct snd_kcontrol_new alc882_targa_mixer[] = {
8330	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8331	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8332	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8333	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8334	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8335	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8336	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8337	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8338	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8339	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8340	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8341	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8342	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8343	{ } /* end */
8344};
8345
8346/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8347 *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8348 */
8349static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
8350	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8351	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8352	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8353	HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8354	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8355	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8356	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8357	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8358	HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8359	HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8360	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8361	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8362	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8363	{ } /* end */
8364};
8365
8366static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
8367	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8368	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8369	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8370	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8371	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8372	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8373	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8374	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8375	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8376	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8377	{ } /* end */
8378};
8379
8380static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
8381	{
8382		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8383		.name = "Channel Mode",
8384		.info = alc_ch_mode_info,
8385		.get = alc_ch_mode_get,
8386		.put = alc_ch_mode_put,
8387	},
8388	{ } /* end */
8389};
8390
8391static const struct hda_verb alc882_base_init_verbs[] = {
8392	/* Front mixer: unmute input/output amp left and right (volume = 0) */
8393	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8394	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8395	/* Rear mixer */
8396	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8397	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8398	/* CLFE mixer */
8399	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8400	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8401	/* Side mixer */
8402	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8403	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8404
8405	/* Front Pin: output 0 (0x0c) */
8406	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8407	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8408	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8409	/* Rear Pin: output 1 (0x0d) */
8410	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8411	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8412	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8413	/* CLFE Pin: output 2 (0x0e) */
8414	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8415	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8416	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8417	/* Side Pin: output 3 (0x0f) */
8418	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8419	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8420	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8421	/* Mic (rear) pin: input vref at 80% */
8422	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8423	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8424	/* Front Mic pin: input vref at 80% */
8425	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8426	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8427	/* Line In pin: input */
8428	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8429	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8430	/* Line-2 In: Headphone output (output 0 - 0x0c) */
8431	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8432	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8433	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8434	/* CD pin widget for input */
8435	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8436
8437	/* FIXME: use matrix-type input source selection */
8438	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8439	/* Input mixer2 */
8440	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8441	/* Input mixer3 */
8442	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8443	/* ADC2: mute amp left and right */
8444	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8445	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8446	/* ADC3: mute amp left and right */
8447	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8448	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8449
8450	{ }
8451};
8452
8453static const struct hda_verb alc882_adc1_init_verbs[] = {
8454	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8455	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8456	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8457	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8458	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8459	/* ADC1: mute amp left and right */
8460	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8461	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8462	{ }
8463};
8464
8465static const struct hda_verb alc882_eapd_verbs[] = {
8466	/* change to EAPD mode */
8467	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8468	{0x20, AC_VERB_SET_PROC_COEF, 0x3060},
8469	{ }
8470};
8471
8472static const struct hda_verb alc889_eapd_verbs[] = {
8473	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8474	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8475	{ }
8476};
8477
8478static const struct hda_verb alc_hp15_unsol_verbs[] = {
8479	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8480	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8481	{}
8482};
8483
8484static const struct hda_verb alc885_init_verbs[] = {
8485	/* Front mixer: unmute input/output amp left and right (volume = 0) */
8486	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8487	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8488	/* Rear mixer */
8489	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8490	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8491	/* CLFE mixer */
8492	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8493	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8494	/* Side mixer */
8495	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8496	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8497
8498	/* Front HP Pin: output 0 (0x0c) */
8499	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8500	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8501	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8502	/* Front Pin: output 0 (0x0c) */
8503	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8504	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8505	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8506	/* Rear Pin: output 1 (0x0d) */
8507	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8508	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8509	{0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8510	/* CLFE Pin: output 2 (0x0e) */
8511	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8512	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8513	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8514	/* Side Pin: output 3 (0x0f) */
8515	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8516	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8517	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8518	/* Mic (rear) pin: input vref at 80% */
8519	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8520	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8521	/* Front Mic pin: input vref at 80% */
8522	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8523	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8524	/* Line In pin: input */
8525	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8526	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8527
8528	/* Mixer elements: 0x18, , 0x1a, 0x1b */
8529	/* Input mixer1 */
8530	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8531	/* Input mixer2 */
8532	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8533	/* Input mixer3 */
8534	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8535	/* ADC2: mute amp left and right */
8536	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8537	/* ADC3: mute amp left and right */
8538	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8539
8540	{ }
8541};
8542
8543static const struct hda_verb alc885_init_input_verbs[] = {
8544	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8545	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8546	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8547	{ }
8548};
8549
8550
8551/* Unmute Selector 24h and set the default input to front mic */
8552static const struct hda_verb alc889_init_input_verbs[] = {
8553	{0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8554	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8555	{ }
8556};
8557
8558
8559#define alc883_init_verbs	alc882_base_init_verbs
8560
8561/* Mac Pro test */
8562static const struct snd_kcontrol_new alc882_macpro_mixer[] = {
8563	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8564	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8565	HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8566	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8567	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8568	/* FIXME: this looks suspicious...
8569	HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8570	HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
8571	*/
8572	{ } /* end */
8573};
8574
8575static const struct hda_verb alc882_macpro_init_verbs[] = {
8576	/* Front mixer: unmute input/output amp left and right (volume = 0) */
8577	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8578	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8579	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8580	/* Front Pin: output 0 (0x0c) */
8581	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8582	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8583	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8584	/* Front Mic pin: input vref at 80% */
8585	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8586	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8587	/* Speaker:  output */
8588	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8589	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8590	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8591	/* Headphone output (output 0 - 0x0c) */
8592	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8593	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8594	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8595
8596	/* FIXME: use matrix-type input source selection */
8597	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8598	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8599	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8600	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8601	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8602	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8603	/* Input mixer2 */
8604	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8605	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8606	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8607	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8608	/* Input mixer3 */
8609	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8610	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8611	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8612	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8613	/* ADC1: mute amp left and right */
8614	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8615	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8616	/* ADC2: mute amp left and right */
8617	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8618	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8619	/* ADC3: mute amp left and right */
8620	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8621	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8622
8623	{ }
8624};
8625
8626/* Macbook 5,1 */
8627static const struct hda_verb alc885_mb5_init_verbs[] = {
8628	/* DACs */
8629	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8630	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8631	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8632	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8633	/* Front mixer */
8634	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8635	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8636	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8637	/* Surround mixer */
8638	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8639	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8640	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8641	/* LFE mixer */
8642	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8643	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8644	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8645	/* HP mixer */
8646	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8647	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8648	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8649	/* Front Pin (0x0c) */
8650	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8651	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8652	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8653	/* LFE Pin (0x0e) */
8654	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8655	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8656	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8657	/* HP Pin (0x0f) */
8658	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8659	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8660	{0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8661	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8662	/* Front Mic pin: input vref at 80% */
8663	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8664	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8665	/* Line In pin */
8666	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8667	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8668
8669	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8670	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8671	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
8672	{ }
8673};
8674
8675/* Macmini 3,1 */
8676static const struct hda_verb alc885_macmini3_init_verbs[] = {
8677	/* DACs */
8678	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8679	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8680	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8681	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8682	/* Front mixer */
8683	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8684	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8685	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8686	/* Surround mixer */
8687	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8688	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8689	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8690	/* LFE mixer */
8691	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8692	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8693	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8694	/* HP mixer */
8695	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8696	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8697	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8698	/* Front Pin (0x0c) */
8699	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8700	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8701	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8702	/* LFE Pin (0x0e) */
8703	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8704	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8705	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8706	/* HP Pin (0x0f) */
8707	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8708	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8709	{0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8710	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8711	/* Line In pin */
8712	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8713	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8714
8715	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8716	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8717	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8718	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8719	{ }
8720};
8721
8722
8723static const struct hda_verb alc885_mba21_init_verbs[] = {
8724	/*Internal and HP Speaker Mixer*/
8725	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8726	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8727	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8728	/*Internal Speaker Pin (0x0c)*/
8729	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8730	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8731	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8732	/* HP Pin: output 0 (0x0e) */
8733	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8734	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8735	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8736	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8737	/* Line in (is hp when jack connected)*/
8738	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8739	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8740
8741	{ }
8742 };
8743
8744
8745/* Macbook Pro rev3 */
8746static const struct hda_verb alc885_mbp3_init_verbs[] = {
8747	/* Front mixer: unmute input/output amp left and right (volume = 0) */
8748	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8749	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8750	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8751	/* Rear mixer */
8752	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8753	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8754	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8755	/* HP mixer */
8756	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8757	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8758	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8759	/* Front Pin: output 0 (0x0c) */
8760	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8761	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8762	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8763	/* HP Pin: output 0 (0x0e) */
8764	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8765	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8766	{0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
8767	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8768	/* Mic (rear) pin: input vref at 80% */
8769	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8770	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8771	/* Front Mic pin: input vref at 80% */
8772	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8773	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8774	/* Line In pin: use output 1 when in LineOut mode */
8775	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8776	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8777	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8778
8779	/* FIXME: use matrix-type input source selection */
8780	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8781	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8782	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8783	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8784	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8785	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8786	/* Input mixer2 */
8787	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8788	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8789	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8790	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8791	/* Input mixer3 */
8792	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8793	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8794	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8795	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8796	/* ADC1: mute amp left and right */
8797	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8798	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8799	/* ADC2: mute amp left and right */
8800	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8801	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8802	/* ADC3: mute amp left and right */
8803	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8804	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8805
8806	{ }
8807};
8808
8809/* iMac 9,1 */
8810static const struct hda_verb alc885_imac91_init_verbs[] = {
8811	/* Internal Speaker Pin (0x0c) */
8812	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8813	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8814	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8815	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8816	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8817	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8818	/* HP Pin: Rear */
8819	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8820	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8821	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8822	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8823	/* Line in Rear */
8824	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8825	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8826	/* Front Mic pin: input vref at 80% */
8827	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8828	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8829	/* Rear mixer */
8830	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8831	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8832	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8833	/* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8834	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8835	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8836	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8837	/* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8838	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8839	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8840	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8841	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8842	/* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8843	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8844	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8845	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8846	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8847	/* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8848	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8849	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8850	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8851	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8852	/* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8853	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8854	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8855	/* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8856	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8857	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8858	/* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8859	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8860	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8861	{ }
8862};
8863
8864/* iMac 24 mixer. */
8865static const struct snd_kcontrol_new alc885_imac24_mixer[] = {
8866	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8867	HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8868	{ } /* end */
8869};
8870
8871/* iMac 24 init verbs. */
8872static const struct hda_verb alc885_imac24_init_verbs[] = {
8873	/* Internal speakers: output 0 (0x0c) */
8874	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8875	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8876	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8877	/* Internal speakers: output 0 (0x0c) */
8878	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8879	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8880	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8881	/* Headphone: output 0 (0x0c) */
8882	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8883	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8884	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8885	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8886	/* Front Mic: input vref at 80% */
8887	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8888	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8889	{ }
8890};
8891
8892/* Toggle speaker-output according to the hp-jack state */
8893static void alc885_imac24_setup(struct hda_codec *codec)
8894{
8895	struct alc_spec *spec = codec->spec;
8896
8897	spec->autocfg.hp_pins[0] = 0x14;
8898	spec->autocfg.speaker_pins[0] = 0x18;
8899	spec->autocfg.speaker_pins[1] = 0x1a;
8900	spec->automute = 1;
8901	spec->automute_mode = ALC_AUTOMUTE_AMP;
8902}
8903
8904#define alc885_mb5_setup	alc885_imac24_setup
8905#define alc885_macmini3_setup	alc885_imac24_setup
8906
8907/* Macbook Air 2,1 */
8908static void alc885_mba21_setup(struct hda_codec *codec)
8909{
8910       struct alc_spec *spec = codec->spec;
8911
8912       spec->autocfg.hp_pins[0] = 0x14;
8913       spec->autocfg.speaker_pins[0] = 0x18;
8914	spec->automute = 1;
8915	spec->automute_mode = ALC_AUTOMUTE_AMP;
8916}
8917
8918
8919
8920static void alc885_mbp3_setup(struct hda_codec *codec)
8921{
8922	struct alc_spec *spec = codec->spec;
8923
8924	spec->autocfg.hp_pins[0] = 0x15;
8925	spec->autocfg.speaker_pins[0] = 0x14;
8926	spec->automute = 1;
8927	spec->automute_mode = ALC_AUTOMUTE_AMP;
8928}
8929
8930static void alc885_imac91_setup(struct hda_codec *codec)
8931{
8932	struct alc_spec *spec = codec->spec;
8933
8934	spec->autocfg.hp_pins[0] = 0x14;
8935	spec->autocfg.speaker_pins[0] = 0x18;
8936	spec->autocfg.speaker_pins[1] = 0x1a;
8937	spec->automute = 1;
8938	spec->automute_mode = ALC_AUTOMUTE_AMP;
8939}
8940
8941static const struct hda_verb alc882_targa_verbs[] = {
8942	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8943	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8944
8945	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8946	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8947
8948	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8949	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8950	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8951
8952	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8953	{ } /* end */
8954};
8955
8956/* toggle speaker-output according to the hp-jack state */
8957static void alc882_targa_automute(struct hda_codec *codec)
8958{
8959	struct alc_spec *spec = codec->spec;
8960	alc_hp_automute(codec);
8961	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8962				  spec->jack_present ? 1 : 3);
8963}
8964
8965static void alc882_targa_setup(struct hda_codec *codec)
8966{
8967	struct alc_spec *spec = codec->spec;
8968
8969	spec->autocfg.hp_pins[0] = 0x14;
8970	spec->autocfg.speaker_pins[0] = 0x1b;
8971	spec->automute = 1;
8972	spec->automute_mode = ALC_AUTOMUTE_AMP;
8973}
8974
8975static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8976{
8977	if ((res >> 26) == ALC880_HP_EVENT)
8978		alc882_targa_automute(codec);
8979}
8980
8981static const struct hda_verb alc882_asus_a7j_verbs[] = {
8982	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8983	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8984
8985	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8986	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8987	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8988
8989	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8990	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8991	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8992
8993	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8994	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8995	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8996	{ } /* end */
8997};
8998
8999static const struct hda_verb alc882_asus_a7m_verbs[] = {
9000	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9001	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9002
9003	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9004	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9005	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9006
9007	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
9008	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
9009	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
9010
9011	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
9012	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
9013	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
9014 	{ } /* end */
9015};
9016
9017static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
9018{
9019	unsigned int gpiostate, gpiomask, gpiodir;
9020
9021	gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
9022				       AC_VERB_GET_GPIO_DATA, 0);
9023
9024	if (!muted)
9025		gpiostate |= (1 << pin);
9026	else
9027		gpiostate &= ~(1 << pin);
9028
9029	gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
9030				      AC_VERB_GET_GPIO_MASK, 0);
9031	gpiomask |= (1 << pin);
9032
9033	gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
9034				     AC_VERB_GET_GPIO_DIRECTION, 0);
9035	gpiodir |= (1 << pin);
9036
9037
9038	snd_hda_codec_write(codec, codec->afg, 0,
9039			    AC_VERB_SET_GPIO_MASK, gpiomask);
9040	snd_hda_codec_write(codec, codec->afg, 0,
9041			    AC_VERB_SET_GPIO_DIRECTION, gpiodir);
9042
9043	msleep(1);
9044
9045	snd_hda_codec_write(codec, codec->afg, 0,
9046			    AC_VERB_SET_GPIO_DATA, gpiostate);
9047}
9048
9049/* set up GPIO at initialization */
9050static void alc885_macpro_init_hook(struct hda_codec *codec)
9051{
9052	alc882_gpio_mute(codec, 0, 0);
9053	alc882_gpio_mute(codec, 1, 0);
9054}
9055
9056/* set up GPIO and update auto-muting at initialization */
9057static void alc885_imac24_init_hook(struct hda_codec *codec)
9058{
9059	alc885_macpro_init_hook(codec);
9060	alc_hp_automute(codec);
9061}
9062
9063/*
9064 * generic initialization of ADC, input mixers and output mixers
9065 */
9066static const struct hda_verb alc883_auto_init_verbs[] = {
9067	/*
9068	 * Unmute ADC0-2 and set the default input to mic-in
9069	 */
9070	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9071	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9072	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9073	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9074
9075	/*
9076	 * Set up output mixers (0x0c - 0x0f)
9077	 */
9078	/* set vol=0 to output mixers */
9079	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9080	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9081	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9082	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9083	/* set up input amps for analog loopback */
9084	/* Amp Indices: DAC = 0, mixer = 1 */
9085	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9086	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9087	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9088	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9089	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9090	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9091	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9092	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9093	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9094	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9095
9096	/* FIXME: use matrix-type input source selection */
9097	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9098	/* Input mixer2 */
9099	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9100	/* Input mixer3 */
9101	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9102	{ }
9103};
9104
9105/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
9106static const struct hda_verb alc889A_mb31_ch2_init[] = {
9107	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},             /* HP as front */
9108	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9109	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},    /* Line as input */
9110	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},   /* Line off */
9111	{ } /* end */
9112};
9113
9114/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
9115static const struct hda_verb alc889A_mb31_ch4_init[] = {
9116	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},             /* HP as front */
9117	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9118	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},   /* Line as output */
9119	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9120	{ } /* end */
9121};
9122
9123/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
9124static const struct hda_verb alc889A_mb31_ch5_init[] = {
9125	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},             /* HP as rear */
9126	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9127	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},    /* Line as input */
9128	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},   /* Line off */
9129	{ } /* end */
9130};
9131
9132/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
9133static const struct hda_verb alc889A_mb31_ch6_init[] = {
9134	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},             /* HP as front */
9135	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},   /* Subwoofer off */
9136	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},   /* Line as output */
9137	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9138	{ } /* end */
9139};
9140
9141static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
9142	{ 2, alc889A_mb31_ch2_init },
9143	{ 4, alc889A_mb31_ch4_init },
9144	{ 5, alc889A_mb31_ch5_init },
9145	{ 6, alc889A_mb31_ch6_init },
9146};
9147
9148static const struct hda_verb alc883_medion_eapd_verbs[] = {
9149        /* eanable EAPD on medion laptop */
9150	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9151	{0x20, AC_VERB_SET_PROC_COEF, 0x3070},
9152	{ }
9153};
9154
9155#define alc883_base_mixer	alc882_base_mixer
9156
9157static const struct snd_kcontrol_new alc883_mitac_mixer[] = {
9158	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9159	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9160	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9161	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9162	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9163	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9164	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9165	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9166	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9167	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9168	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9169	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9170	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9171	{ } /* end */
9172};
9173
9174static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
9175	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9176	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9177	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9178	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9179	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9180	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9181	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9182	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9183	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9184	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9185	{ } /* end */
9186};
9187
9188static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
9189	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9190	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9191	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9192	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9193	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9194	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9195	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9196	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9197	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9198	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9199	{ } /* end */
9200};
9201
9202static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
9203	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9204	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9205	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9206	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9207	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9208	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9209	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9210	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9211	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9212	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9213	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9214	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9215	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9216	{ } /* end */
9217};
9218
9219static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
9220	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9221	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9222	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9223	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9224	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9225	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9226	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9227	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9228	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9229	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9230	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9231	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9232	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9233	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9234	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9235	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9236	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9237	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9238	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9239	{ } /* end */
9240};
9241
9242static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
9243	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9244	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9245	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9246	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9247	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9248			      HDA_OUTPUT),
9249	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9250	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9251	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9252	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9253	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9254	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9255	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9256	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9257	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9258	HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
9259	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9260	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9261	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
9262	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9263	{ } /* end */
9264};
9265
9266static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
9267	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9268	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9269	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9270	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9271	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9272			      HDA_OUTPUT),
9273	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9274	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9275	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9276	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9277	HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
9278	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9279	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9280	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9281	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
9282	HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
9283	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
9284	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9285	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
9286	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9287	{ } /* end */
9288};
9289
9290static const struct snd_kcontrol_new alc883_fivestack_mixer[] = {
9291	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9292	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9293	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9294	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9295	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9296	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9297	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9298	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9299	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9300	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9301	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9302	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9303	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9304	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9305	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9306	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9307	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9308	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9309	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9310	{ } /* end */
9311};
9312
9313static const struct snd_kcontrol_new alc883_targa_mixer[] = {
9314	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9315	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9316	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9317	HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9318	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9319	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9320	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9321	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9322	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9323	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9324	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9325	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9326	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9327	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9328	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9329	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9330	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9331	{ } /* end */
9332};
9333
9334static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
9335	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9336	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9337	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9338	HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9339	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9340	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9341	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9342	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9343	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9344	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9345	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9346	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9347	{ } /* end */
9348};
9349
9350static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
9351	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9352	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9353	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9354	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9355	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9356	{ } /* end */
9357};
9358
9359static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
9360	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9361	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9362	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9363	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9364	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9365	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9366	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9367	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9368	{ } /* end */
9369};
9370
9371static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
9372	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9373	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9374	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9375	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9376	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9377	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9378	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9379	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9380	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9381	{ } /* end */
9382};
9383
9384static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
9385	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9386	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9387	HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9388	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9389	HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9390	HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9391	{ } /* end */
9392};
9393
9394static const struct hda_verb alc883_medion_wim2160_verbs[] = {
9395	/* Unmute front mixer */
9396	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9397	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9398
9399	/* Set speaker pin to front mixer */
9400	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9401
9402	/* Init headphone pin */
9403	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9404	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9405	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9406	{0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9407
9408	{ } /* end */
9409};
9410
9411/* toggle speaker-output according to the hp-jack state */
9412static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9413{
9414	struct alc_spec *spec = codec->spec;
9415
9416	spec->autocfg.hp_pins[0] = 0x1a;
9417	spec->autocfg.speaker_pins[0] = 0x15;
9418	spec->automute = 1;
9419	spec->automute_mode = ALC_AUTOMUTE_AMP;
9420}
9421
9422static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
9423	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9424	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9425	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9426	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9427	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9428	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9429	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9430	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9431	{ } /* end */
9432};
9433
9434static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9435	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9436	HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9437	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9438	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9439	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9440	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9441	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9442	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9443	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9444	{ } /* end */
9445};
9446
9447static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9448	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9449	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9450	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9451	HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9452	HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9453						0x0d, 1, 0x0, HDA_OUTPUT),
9454	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9455	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9456	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9457	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9458	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9459	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9460	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9461	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9462	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9463	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9464	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9465	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9466	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9467	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9468	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9469	{ } /* end */
9470};
9471
9472static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9473	/* Output mixers */
9474	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9475	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9476	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9477	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9478	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9479		HDA_OUTPUT),
9480	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9481	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9482	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9483	/* Output switches */
9484	HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9485	HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9486	HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9487	/* Boost mixers */
9488	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9489	HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
9490	/* Input mixers */
9491	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9492	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9493	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9494	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9495	{ } /* end */
9496};
9497
9498static const struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9499	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9500	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9501	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9502	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9503	HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
9504	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9505	{ } /* end */
9506};
9507
9508static const struct hda_bind_ctls alc883_bind_cap_vol = {
9509	.ops = &snd_hda_bind_vol,
9510	.values = {
9511		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9512		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9513		0
9514	},
9515};
9516
9517static const struct hda_bind_ctls alc883_bind_cap_switch = {
9518	.ops = &snd_hda_bind_sw,
9519	.values = {
9520		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9521		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9522		0
9523	},
9524};
9525
9526static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9527	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9528	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9529	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9530	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9531	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9532	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9533	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9534	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9535	{ } /* end */
9536};
9537
9538static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9539	HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9540	HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9541	{
9542		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9543		/* .name = "Capture Source", */
9544		.name = "Input Source",
9545		.count = 1,
9546		.info = alc_mux_enum_info,
9547		.get = alc_mux_enum_get,
9548		.put = alc_mux_enum_put,
9549	},
9550	{ } /* end */
9551};
9552
9553static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
9554	{
9555		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9556		.name = "Channel Mode",
9557		.info = alc_ch_mode_info,
9558		.get = alc_ch_mode_get,
9559		.put = alc_ch_mode_put,
9560	},
9561	{ } /* end */
9562};
9563
9564/* toggle speaker-output according to the hp-jack state */
9565static void alc883_mitac_setup(struct hda_codec *codec)
9566{
9567	struct alc_spec *spec = codec->spec;
9568
9569	spec->autocfg.hp_pins[0] = 0x15;
9570	spec->autocfg.speaker_pins[0] = 0x14;
9571	spec->autocfg.speaker_pins[1] = 0x17;
9572	spec->automute = 1;
9573	spec->automute_mode = ALC_AUTOMUTE_AMP;
9574}
9575
9576static const struct hda_verb alc883_mitac_verbs[] = {
9577	/* HP */
9578	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9579	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9580	/* Subwoofer */
9581	{0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9582	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9583
9584	/* enable unsolicited event */
9585	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9586	/* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9587
9588	{ } /* end */
9589};
9590
9591static const struct hda_verb alc883_clevo_m540r_verbs[] = {
9592	/* HP */
9593	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9594	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9595	/* Int speaker */
9596	/*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9597
9598	/* enable unsolicited event */
9599	/*
9600	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9601	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9602	*/
9603
9604	{ } /* end */
9605};
9606
9607static const struct hda_verb alc883_clevo_m720_verbs[] = {
9608	/* HP */
9609	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9610	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9611	/* Int speaker */
9612	{0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9613	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9614
9615	/* enable unsolicited event */
9616	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9617	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9618
9619	{ } /* end */
9620};
9621
9622static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9623	/* HP */
9624	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9625	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9626	/* Subwoofer */
9627	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9628	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9629
9630	/* enable unsolicited event */
9631	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9632
9633	{ } /* end */
9634};
9635
9636static const struct hda_verb alc883_targa_verbs[] = {
9637	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9638	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9639
9640	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9641	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9642
9643/* Connect Line-Out side jack (SPDIF) to Side */
9644	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9645	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9646	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9647/* Connect Mic jack to CLFE */
9648	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9649	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9650	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9651/* Connect Line-in jack to Surround */
9652	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9653	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9654	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9655/* Connect HP out jack to Front */
9656	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9657	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9658	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9659
9660	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9661
9662	{ } /* end */
9663};
9664
9665static const struct hda_verb alc883_lenovo_101e_verbs[] = {
9666	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9667	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9668        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9669	{ } /* end */
9670};
9671
9672static const struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9673        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9674	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9675        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9676        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9677	{ } /* end */
9678};
9679
9680static const struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9681	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9682	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9683	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9684	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9685	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
9686	{ } /* end */
9687};
9688
9689static const struct hda_verb alc883_haier_w66_verbs[] = {
9690	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9691	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9692
9693	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9694
9695	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9696	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9697	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9698	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9699	{ } /* end */
9700};
9701
9702static const struct hda_verb alc888_lenovo_sky_verbs[] = {
9703	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9704	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9705	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9706	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9707	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9708	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9709	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9710	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9711	{ } /* end */
9712};
9713
9714static const struct hda_verb alc888_6st_dell_verbs[] = {
9715	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9716	{ }
9717};
9718
9719static const struct hda_verb alc883_vaiott_verbs[] = {
9720	/* HP */
9721	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9722	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9723
9724	/* enable unsolicited event */
9725	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9726
9727	{ } /* end */
9728};
9729
9730static void alc888_3st_hp_setup(struct hda_codec *codec)
9731{
9732	struct alc_spec *spec = codec->spec;
9733
9734	spec->autocfg.hp_pins[0] = 0x1b;
9735	spec->autocfg.speaker_pins[0] = 0x14;
9736	spec->autocfg.speaker_pins[1] = 0x16;
9737	spec->autocfg.speaker_pins[2] = 0x18;
9738	spec->automute = 1;
9739	spec->automute_mode = ALC_AUTOMUTE_AMP;
9740}
9741
9742static const struct hda_verb alc888_3st_hp_verbs[] = {
9743	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Front: output 0 (0x0c) */
9744	{0x16, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Rear : output 1 (0x0d) */
9745	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02},	/* CLFE : output 2 (0x0e) */
9746	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9747	{ } /* end */
9748};
9749
9750/*
9751 * 2ch mode
9752 */
9753static const struct hda_verb alc888_3st_hp_2ch_init[] = {
9754	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9755	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9756	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9757	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9758	{ } /* end */
9759};
9760
9761/*
9762 * 4ch mode
9763 */
9764static const struct hda_verb alc888_3st_hp_4ch_init[] = {
9765	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9766	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9767	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9768	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9769	{ 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9770	{ } /* end */
9771};
9772
9773/*
9774 * 6ch mode
9775 */
9776static const struct hda_verb alc888_3st_hp_6ch_init[] = {
9777	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9778	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9779	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
9780	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9781	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9782	{ 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9783	{ } /* end */
9784};
9785
9786static const struct hda_channel_mode alc888_3st_hp_modes[3] = {
9787	{ 2, alc888_3st_hp_2ch_init },
9788	{ 4, alc888_3st_hp_4ch_init },
9789	{ 6, alc888_3st_hp_6ch_init },
9790};
9791
9792static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)
9793{
9794	struct alc_spec *spec = codec->spec;
9795
9796	spec->autocfg.hp_pins[0] = 0x1b;
9797	spec->autocfg.line_out_pins[0] = 0x14;
9798	spec->autocfg.speaker_pins[0] = 0x15;
9799	spec->automute = 1;
9800	spec->automute_mode = ALC_AUTOMUTE_AMP;
9801}
9802
9803/* toggle speaker-output according to the hp-jack state */
9804static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
9805{
9806	struct alc_spec *spec = codec->spec;
9807
9808	spec->autocfg.hp_pins[0] = 0x14;
9809	spec->autocfg.speaker_pins[0] = 0x15;
9810	spec->automute = 1;
9811	spec->automute_mode = ALC_AUTOMUTE_AMP;
9812}
9813
9814/* toggle speaker-output according to the hp-jack state */
9815#define alc883_targa_init_hook		alc882_targa_init_hook
9816#define alc883_targa_unsol_event	alc882_targa_unsol_event
9817
9818static void alc883_clevo_m720_setup(struct hda_codec *codec)
9819{
9820	struct alc_spec *spec = codec->spec;
9821
9822	spec->autocfg.hp_pins[0] = 0x15;
9823	spec->autocfg.speaker_pins[0] = 0x14;
9824	spec->automute = 1;
9825	spec->automute_mode = ALC_AUTOMUTE_AMP;
9826}
9827
9828static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9829{
9830	alc_hp_automute(codec);
9831	alc88x_simple_mic_automute(codec);
9832}
9833
9834static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
9835					   unsigned int res)
9836{
9837	switch (res >> 26) {
9838	case ALC880_MIC_EVENT:
9839		alc88x_simple_mic_automute(codec);
9840		break;
9841	default:
9842		alc_sku_unsol_event(codec, res);
9843		break;
9844	}
9845}
9846
9847/* toggle speaker-output according to the hp-jack state */
9848static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
9849{
9850	struct alc_spec *spec = codec->spec;
9851
9852	spec->autocfg.hp_pins[0] = 0x14;
9853	spec->autocfg.speaker_pins[0] = 0x15;
9854	spec->automute = 1;
9855	spec->automute_mode = ALC_AUTOMUTE_AMP;
9856}
9857
9858static void alc883_haier_w66_setup(struct hda_codec *codec)
9859{
9860	struct alc_spec *spec = codec->spec;
9861
9862	spec->autocfg.hp_pins[0] = 0x1b;
9863	spec->autocfg.speaker_pins[0] = 0x14;
9864	spec->automute = 1;
9865	spec->automute_mode = ALC_AUTOMUTE_AMP;
9866}
9867
9868static void alc883_lenovo_101e_setup(struct hda_codec *codec)
9869{
9870	struct alc_spec *spec = codec->spec;
9871
9872	spec->autocfg.hp_pins[0] = 0x1b;
9873	spec->autocfg.line_out_pins[0] = 0x14;
9874	spec->autocfg.speaker_pins[0] = 0x15;
9875	spec->automute = 1;
9876	spec->detect_line = 1;
9877	spec->automute_lines = 1;
9878	spec->automute_mode = ALC_AUTOMUTE_AMP;
9879}
9880
9881/* toggle speaker-output according to the hp-jack state */
9882static void alc883_acer_aspire_setup(struct hda_codec *codec)
9883{
9884	struct alc_spec *spec = codec->spec;
9885
9886	spec->autocfg.hp_pins[0] = 0x14;
9887	spec->autocfg.speaker_pins[0] = 0x15;
9888	spec->autocfg.speaker_pins[1] = 0x16;
9889	spec->automute = 1;
9890	spec->automute_mode = ALC_AUTOMUTE_AMP;
9891}
9892
9893static const struct hda_verb alc883_acer_eapd_verbs[] = {
9894	/* HP Pin: output 0 (0x0c) */
9895	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9896	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9897	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9898	/* Front Pin: output 0 (0x0c) */
9899	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9900	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9901	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9902	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9903        /* eanable EAPD on medion laptop */
9904	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9905	{0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9906	/* enable unsolicited event */
9907	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9908	{ }
9909};
9910
9911static void alc888_6st_dell_setup(struct hda_codec *codec)
9912{
9913	struct alc_spec *spec = codec->spec;
9914
9915	spec->autocfg.hp_pins[0] = 0x1b;
9916	spec->autocfg.speaker_pins[0] = 0x14;
9917	spec->autocfg.speaker_pins[1] = 0x15;
9918	spec->autocfg.speaker_pins[2] = 0x16;
9919	spec->autocfg.speaker_pins[3] = 0x17;
9920	spec->automute = 1;
9921	spec->automute_mode = ALC_AUTOMUTE_AMP;
9922}
9923
9924static void alc888_lenovo_sky_setup(struct hda_codec *codec)
9925{
9926	struct alc_spec *spec = codec->spec;
9927
9928	spec->autocfg.hp_pins[0] = 0x1b;
9929	spec->autocfg.speaker_pins[0] = 0x14;
9930	spec->autocfg.speaker_pins[1] = 0x15;
9931	spec->autocfg.speaker_pins[2] = 0x16;
9932	spec->autocfg.speaker_pins[3] = 0x17;
9933	spec->autocfg.speaker_pins[4] = 0x1a;
9934	spec->automute = 1;
9935	spec->automute_mode = ALC_AUTOMUTE_AMP;
9936}
9937
9938static void alc883_vaiott_setup(struct hda_codec *codec)
9939{
9940	struct alc_spec *spec = codec->spec;
9941
9942	spec->autocfg.hp_pins[0] = 0x15;
9943	spec->autocfg.speaker_pins[0] = 0x14;
9944	spec->autocfg.speaker_pins[1] = 0x17;
9945	spec->automute = 1;
9946	spec->automute_mode = ALC_AUTOMUTE_AMP;
9947}
9948
9949static const struct hda_verb alc888_asus_m90v_verbs[] = {
9950	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9951	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9952	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9953	/* enable unsolicited event */
9954	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9955	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9956	{ } /* end */
9957};
9958
9959static void alc883_mode2_setup(struct hda_codec *codec)
9960{
9961	struct alc_spec *spec = codec->spec;
9962
9963	spec->autocfg.hp_pins[0] = 0x1b;
9964	spec->autocfg.speaker_pins[0] = 0x14;
9965	spec->autocfg.speaker_pins[1] = 0x15;
9966	spec->autocfg.speaker_pins[2] = 0x16;
9967	spec->ext_mic.pin = 0x18;
9968	spec->int_mic.pin = 0x19;
9969	spec->ext_mic.mux_idx = 0;
9970	spec->int_mic.mux_idx = 1;
9971	spec->auto_mic = 1;
9972	spec->automute = 1;
9973	spec->automute_mode = ALC_AUTOMUTE_AMP;
9974}
9975
9976static const struct hda_verb alc888_asus_eee1601_verbs[] = {
9977	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9978	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9979	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9980	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9981	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9982	{0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9983	{0x20, AC_VERB_SET_PROC_COEF,  0x0838},
9984	/* enable unsolicited event */
9985	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9986	{ } /* end */
9987};
9988
9989static void alc883_eee1601_inithook(struct hda_codec *codec)
9990{
9991	struct alc_spec *spec = codec->spec;
9992
9993	spec->autocfg.hp_pins[0] = 0x14;
9994	spec->autocfg.speaker_pins[0] = 0x1b;
9995	alc_hp_automute(codec);
9996}
9997
9998static const struct hda_verb alc889A_mb31_verbs[] = {
9999	/* Init rear pin (used as headphone output) */
10000	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},    /* Apple Headphones */
10001	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},           /* Connect to front */
10002	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10003	/* Init line pin (used as output in 4ch and 6ch mode) */
10004	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},           /* Connect to CLFE */
10005	/* Init line 2 pin (used as headphone out by default) */
10006	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},  /* Use as input */
10007	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
10008	{ } /* end */
10009};
10010
10011/* Mute speakers according to the headphone jack state */
10012static void alc889A_mb31_automute(struct hda_codec *codec)
10013{
10014	unsigned int present;
10015
10016	/* Mute only in 2ch or 4ch mode */
10017	if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
10018	    == 0x00) {
10019		present = snd_hda_jack_detect(codec, 0x15);
10020		snd_hda_codec_amp_stereo(codec, 0x14,  HDA_OUTPUT, 0,
10021			HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
10022		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10023			HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
10024	}
10025}
10026
10027static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
10028{
10029	if ((res >> 26) == ALC880_HP_EVENT)
10030		alc889A_mb31_automute(codec);
10031}
10032
10033
10034#ifdef CONFIG_SND_HDA_POWER_SAVE
10035#define alc882_loopbacks	alc880_loopbacks
10036#endif
10037
10038/* pcm configuration: identical with ALC880 */
10039#define alc882_pcm_analog_playback	alc880_pcm_analog_playback
10040#define alc882_pcm_analog_capture	alc880_pcm_analog_capture
10041#define alc882_pcm_digital_playback	alc880_pcm_digital_playback
10042#define alc882_pcm_digital_capture	alc880_pcm_digital_capture
10043
10044static const hda_nid_t alc883_slave_dig_outs[] = {
10045	ALC1200_DIGOUT_NID, 0,
10046};
10047
10048static const hda_nid_t alc1200_slave_dig_outs[] = {
10049	ALC883_DIGOUT_NID, 0,
10050};
10051
10052/*
10053 * configuration and preset
10054 */
10055static const char * const alc882_models[ALC882_MODEL_LAST] = {
10056	[ALC882_3ST_DIG]	= "3stack-dig",
10057	[ALC882_6ST_DIG]	= "6stack-dig",
10058	[ALC882_ARIMA]		= "arima",
10059	[ALC882_W2JC]		= "w2jc",
10060	[ALC882_TARGA]		= "targa",
10061	[ALC882_ASUS_A7J]	= "asus-a7j",
10062	[ALC882_ASUS_A7M]	= "asus-a7m",
10063	[ALC885_MACPRO]		= "macpro",
10064	[ALC885_MB5]		= "mb5",
10065	[ALC885_MACMINI3]	= "macmini3",
10066	[ALC885_MBA21]		= "mba21",
10067	[ALC885_MBP3]		= "mbp3",
10068	[ALC885_IMAC24]		= "imac24",
10069	[ALC885_IMAC91]		= "imac91",
10070	[ALC883_3ST_2ch_DIG]	= "3stack-2ch-dig",
10071	[ALC883_3ST_6ch_DIG]	= "3stack-6ch-dig",
10072	[ALC883_3ST_6ch]	= "3stack-6ch",
10073	[ALC883_6ST_DIG]	= "alc883-6stack-dig",
10074	[ALC883_TARGA_DIG]	= "targa-dig",
10075	[ALC883_TARGA_2ch_DIG]	= "targa-2ch-dig",
10076	[ALC883_TARGA_8ch_DIG]	= "targa-8ch-dig",
10077	[ALC883_ACER]		= "acer",
10078	[ALC883_ACER_ASPIRE]	= "acer-aspire",
10079	[ALC888_ACER_ASPIRE_4930G]	= "acer-aspire-4930g",
10080	[ALC888_ACER_ASPIRE_6530G]	= "acer-aspire-6530g",
10081	[ALC888_ACER_ASPIRE_8930G]	= "acer-aspire-8930g",
10082	[ALC888_ACER_ASPIRE_7730G]	= "acer-aspire-7730g",
10083	[ALC883_MEDION]		= "medion",
10084	[ALC883_MEDION_WIM2160]	= "medion-wim2160",
10085	[ALC883_LAPTOP_EAPD]	= "laptop-eapd",
10086	[ALC883_LENOVO_101E_2ch] = "lenovo-101e",
10087	[ALC883_LENOVO_NB0763]	= "lenovo-nb0763",
10088	[ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
10089	[ALC888_LENOVO_SKY] = "lenovo-sky",
10090	[ALC883_HAIER_W66] 	= "haier-w66",
10091	[ALC888_3ST_HP]		= "3stack-hp",
10092	[ALC888_6ST_DELL]	= "6stack-dell",
10093	[ALC883_MITAC]		= "mitac",
10094	[ALC883_CLEVO_M540R]	= "clevo-m540r",
10095	[ALC883_CLEVO_M720]	= "clevo-m720",
10096	[ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
10097	[ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
10098	[ALC883_3ST_6ch_INTEL]	= "3stack-6ch-intel",
10099	[ALC889A_INTEL]		= "intel-alc889a",
10100	[ALC889_INTEL]		= "intel-x58",
10101	[ALC1200_ASUS_P5Q]	= "asus-p5q",
10102	[ALC889A_MB31]		= "mb31",
10103	[ALC883_SONY_VAIO_TT]	= "sony-vaio-tt",
10104	[ALC882_AUTO]		= "auto",
10105};
10106
10107static const struct snd_pci_quirk alc882_cfg_tbl[] = {
10108	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
10109
10110	SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
10111	SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
10112	SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
10113	SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
10114	SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
10115	SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
10116	SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
10117		ALC888_ACER_ASPIRE_4930G),
10118	SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
10119		ALC888_ACER_ASPIRE_4930G),
10120	SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
10121		ALC888_ACER_ASPIRE_8930G),
10122	SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
10123		ALC888_ACER_ASPIRE_8930G),
10124	SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
10125	SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
10126	SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
10127		ALC888_ACER_ASPIRE_6530G),
10128	SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
10129		ALC888_ACER_ASPIRE_6530G),
10130	SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
10131		ALC888_ACER_ASPIRE_7730G),
10132	/* default Acer -- disabled as it causes more problems.
10133	 *    model=auto should work fine now
10134	 */
10135	/* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
10136
10137	SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
10138
10139	SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG),
10140	SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
10141	SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
10142	SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
10143	SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
10144	SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
10145
10146	SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
10147	SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
10148	SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
10149	SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
10150	SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
10151	SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
10152	SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
10153	SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
10154	SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
10155	SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
10156	SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
10157
10158	SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
10159	SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
10160	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
10161	SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
10162	SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
10163	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
10164	SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
10165	SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
10166	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
10167
10168	SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
10169	SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
10170	SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
10171	SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
10172	SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
10173	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
10174	SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
10175	SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
10176	SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
10177	SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
10178	SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
10179	SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
10180	SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
10181	SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
10182	SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
10183	SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
10184	SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
10185	SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
10186	SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
10187	SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
10188	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
10189	SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
10190	SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
10191	SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
10192	SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
10193	SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
10194	SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
10195	SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
10196	SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
10197	SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
10198	SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
10199
10200	SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
10201	SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
10202	SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
10203	SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
10204	SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
10205	SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
10206	SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
10207	/* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
10208	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
10209	SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
10210		      ALC883_FUJITSU_PI2515),
10211	SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
10212		ALC888_FUJITSU_XA3530),
10213	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
10214	SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10215	SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10216	SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10217	SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
10218	SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
10219	SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
10220	SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
10221
10222	SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
10223	SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
10224	SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
10225	SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
10226	SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
10227	SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
10228	SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
10229
10230	{}
10231};
10232
10233/* codec SSID table for Intel Mac */
10234static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
10235	SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
10236	SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
10237	SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
10238	SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
10239	SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
10240	SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
10241	SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
10242	SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
10243	SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
10244	SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
10245	SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
10246	SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
10247	SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
10248	SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
10249	SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
10250	SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
10251	SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
10252	/* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
10253	 * so apparently no perfect solution yet
10254	 */
10255	SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
10256	SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
10257	SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
10258	{} /* terminator */
10259};
10260
10261static const struct alc_config_preset alc882_presets[] = {
10262	[ALC882_3ST_DIG] = {
10263		.mixers = { alc882_base_mixer },
10264		.init_verbs = { alc882_base_init_verbs,
10265				alc882_adc1_init_verbs },
10266		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10267		.dac_nids = alc882_dac_nids,
10268		.dig_out_nid = ALC882_DIGOUT_NID,
10269		.dig_in_nid = ALC882_DIGIN_NID,
10270		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10271		.channel_mode = alc882_ch_modes,
10272		.need_dac_fix = 1,
10273		.input_mux = &alc882_capture_source,
10274	},
10275	[ALC882_6ST_DIG] = {
10276		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
10277		.init_verbs = { alc882_base_init_verbs,
10278				alc882_adc1_init_verbs },
10279		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10280		.dac_nids = alc882_dac_nids,
10281		.dig_out_nid = ALC882_DIGOUT_NID,
10282		.dig_in_nid = ALC882_DIGIN_NID,
10283		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10284		.channel_mode = alc882_sixstack_modes,
10285		.input_mux = &alc882_capture_source,
10286	},
10287	[ALC882_ARIMA] = {
10288		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
10289		.init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10290				alc882_eapd_verbs },
10291		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10292		.dac_nids = alc882_dac_nids,
10293		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10294		.channel_mode = alc882_sixstack_modes,
10295		.input_mux = &alc882_capture_source,
10296	},
10297	[ALC882_W2JC] = {
10298		.mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
10299		.init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10300				alc882_eapd_verbs, alc880_gpio1_init_verbs },
10301		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10302		.dac_nids = alc882_dac_nids,
10303		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10304		.channel_mode = alc880_threestack_modes,
10305		.need_dac_fix = 1,
10306		.input_mux = &alc882_capture_source,
10307		.dig_out_nid = ALC882_DIGOUT_NID,
10308	},
10309	   [ALC885_MBA21] = {
10310			.mixers = { alc885_mba21_mixer },
10311			.init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
10312			.num_dacs = 2,
10313			.dac_nids = alc882_dac_nids,
10314			.channel_mode = alc885_mba21_ch_modes,
10315			.num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10316			.input_mux = &alc882_capture_source,
10317			.unsol_event = alc_sku_unsol_event,
10318			.setup = alc885_mba21_setup,
10319			.init_hook = alc_hp_automute,
10320       },
10321	[ALC885_MBP3] = {
10322		.mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10323		.init_verbs = { alc885_mbp3_init_verbs,
10324				alc880_gpio1_init_verbs },
10325		.num_dacs = 2,
10326		.dac_nids = alc882_dac_nids,
10327		.hp_nid = 0x04,
10328		.channel_mode = alc885_mbp_4ch_modes,
10329		.num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
10330		.input_mux = &alc882_capture_source,
10331		.dig_out_nid = ALC882_DIGOUT_NID,
10332		.dig_in_nid = ALC882_DIGIN_NID,
10333		.unsol_event = alc_sku_unsol_event,
10334		.setup = alc885_mbp3_setup,
10335		.init_hook = alc_hp_automute,
10336	},
10337	[ALC885_MB5] = {
10338		.mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10339		.init_verbs = { alc885_mb5_init_verbs,
10340				alc880_gpio1_init_verbs },
10341		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10342		.dac_nids = alc882_dac_nids,
10343		.channel_mode = alc885_mb5_6ch_modes,
10344		.num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10345		.input_mux = &mb5_capture_source,
10346		.dig_out_nid = ALC882_DIGOUT_NID,
10347		.dig_in_nid = ALC882_DIGIN_NID,
10348		.unsol_event = alc_sku_unsol_event,
10349		.setup = alc885_mb5_setup,
10350		.init_hook = alc_hp_automute,
10351	},
10352	[ALC885_MACMINI3] = {
10353		.mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10354		.init_verbs = { alc885_macmini3_init_verbs,
10355				alc880_gpio1_init_verbs },
10356		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10357		.dac_nids = alc882_dac_nids,
10358		.channel_mode = alc885_macmini3_6ch_modes,
10359		.num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10360		.input_mux = &macmini3_capture_source,
10361		.dig_out_nid = ALC882_DIGOUT_NID,
10362		.dig_in_nid = ALC882_DIGIN_NID,
10363		.unsol_event = alc_sku_unsol_event,
10364		.setup = alc885_macmini3_setup,
10365		.init_hook = alc_hp_automute,
10366	},
10367	[ALC885_MACPRO] = {
10368		.mixers = { alc882_macpro_mixer },
10369		.init_verbs = { alc882_macpro_init_verbs },
10370		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10371		.dac_nids = alc882_dac_nids,
10372		.dig_out_nid = ALC882_DIGOUT_NID,
10373		.dig_in_nid = ALC882_DIGIN_NID,
10374		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10375		.channel_mode = alc882_ch_modes,
10376		.input_mux = &alc882_capture_source,
10377		.init_hook = alc885_macpro_init_hook,
10378	},
10379	[ALC885_IMAC24] = {
10380		.mixers = { alc885_imac24_mixer },
10381		.init_verbs = { alc885_imac24_init_verbs },
10382		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10383		.dac_nids = alc882_dac_nids,
10384		.dig_out_nid = ALC882_DIGOUT_NID,
10385		.dig_in_nid = ALC882_DIGIN_NID,
10386		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10387		.channel_mode = alc882_ch_modes,
10388		.input_mux = &alc882_capture_source,
10389		.unsol_event = alc_sku_unsol_event,
10390		.setup = alc885_imac24_setup,
10391		.init_hook = alc885_imac24_init_hook,
10392	},
10393	[ALC885_IMAC91] = {
10394		.mixers = {alc885_imac91_mixer},
10395		.init_verbs = { alc885_imac91_init_verbs,
10396				alc880_gpio1_init_verbs },
10397		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10398		.dac_nids = alc882_dac_nids,
10399		.channel_mode = alc885_mba21_ch_modes,
10400		.num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10401		.input_mux = &alc889A_imac91_capture_source,
10402		.dig_out_nid = ALC882_DIGOUT_NID,
10403		.dig_in_nid = ALC882_DIGIN_NID,
10404		.unsol_event = alc_sku_unsol_event,
10405		.setup = alc885_imac91_setup,
10406		.init_hook = alc_hp_automute,
10407	},
10408	[ALC882_TARGA] = {
10409		.mixers = { alc882_targa_mixer, alc882_chmode_mixer },
10410		.init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10411				alc880_gpio3_init_verbs, alc882_targa_verbs},
10412		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10413		.dac_nids = alc882_dac_nids,
10414		.dig_out_nid = ALC882_DIGOUT_NID,
10415		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10416		.adc_nids = alc882_adc_nids,
10417		.capsrc_nids = alc882_capsrc_nids,
10418		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10419		.channel_mode = alc882_3ST_6ch_modes,
10420		.need_dac_fix = 1,
10421		.input_mux = &alc882_capture_source,
10422		.unsol_event = alc_sku_unsol_event,
10423		.setup = alc882_targa_setup,
10424		.init_hook = alc882_targa_automute,
10425	},
10426	[ALC882_ASUS_A7J] = {
10427		.mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
10428		.init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10429				alc882_asus_a7j_verbs},
10430		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10431		.dac_nids = alc882_dac_nids,
10432		.dig_out_nid = ALC882_DIGOUT_NID,
10433		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10434		.adc_nids = alc882_adc_nids,
10435		.capsrc_nids = alc882_capsrc_nids,
10436		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10437		.channel_mode = alc882_3ST_6ch_modes,
10438		.need_dac_fix = 1,
10439		.input_mux = &alc882_capture_source,
10440	},
10441	[ALC882_ASUS_A7M] = {
10442		.mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
10443		.init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10444				alc882_eapd_verbs, alc880_gpio1_init_verbs,
10445				alc882_asus_a7m_verbs },
10446		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10447		.dac_nids = alc882_dac_nids,
10448		.dig_out_nid = ALC882_DIGOUT_NID,
10449		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10450		.channel_mode = alc880_threestack_modes,
10451		.need_dac_fix = 1,
10452		.input_mux = &alc882_capture_source,
10453	},
10454	[ALC883_3ST_2ch_DIG] = {
10455		.mixers = { alc883_3ST_2ch_mixer },
10456		.init_verbs = { alc883_init_verbs },
10457		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10458		.dac_nids = alc883_dac_nids,
10459		.dig_out_nid = ALC883_DIGOUT_NID,
10460		.dig_in_nid = ALC883_DIGIN_NID,
10461		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10462		.channel_mode = alc883_3ST_2ch_modes,
10463		.input_mux = &alc883_capture_source,
10464	},
10465	[ALC883_3ST_6ch_DIG] = {
10466		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10467		.init_verbs = { alc883_init_verbs },
10468		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10469		.dac_nids = alc883_dac_nids,
10470		.dig_out_nid = ALC883_DIGOUT_NID,
10471		.dig_in_nid = ALC883_DIGIN_NID,
10472		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10473		.channel_mode = alc883_3ST_6ch_modes,
10474		.need_dac_fix = 1,
10475		.input_mux = &alc883_capture_source,
10476	},
10477	[ALC883_3ST_6ch] = {
10478		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10479		.init_verbs = { alc883_init_verbs },
10480		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10481		.dac_nids = alc883_dac_nids,
10482		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10483		.channel_mode = alc883_3ST_6ch_modes,
10484		.need_dac_fix = 1,
10485		.input_mux = &alc883_capture_source,
10486	},
10487	[ALC883_3ST_6ch_INTEL] = {
10488		.mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10489		.init_verbs = { alc883_init_verbs },
10490		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10491		.dac_nids = alc883_dac_nids,
10492		.dig_out_nid = ALC883_DIGOUT_NID,
10493		.dig_in_nid = ALC883_DIGIN_NID,
10494		.slave_dig_outs = alc883_slave_dig_outs,
10495		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10496		.channel_mode = alc883_3ST_6ch_intel_modes,
10497		.need_dac_fix = 1,
10498		.input_mux = &alc883_3stack_6ch_intel,
10499	},
10500	[ALC889A_INTEL] = {
10501		.mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10502		.init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10503				alc_hp15_unsol_verbs },
10504		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10505		.dac_nids = alc883_dac_nids,
10506		.num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10507		.adc_nids = alc889_adc_nids,
10508		.dig_out_nid = ALC883_DIGOUT_NID,
10509		.dig_in_nid = ALC883_DIGIN_NID,
10510		.slave_dig_outs = alc883_slave_dig_outs,
10511		.num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10512		.channel_mode = alc889_8ch_intel_modes,
10513		.capsrc_nids = alc889_capsrc_nids,
10514		.input_mux = &alc889_capture_source,
10515		.setup = alc889_automute_setup,
10516		.init_hook = alc_hp_automute,
10517		.unsol_event = alc_sku_unsol_event,
10518		.need_dac_fix = 1,
10519	},
10520	[ALC889_INTEL] = {
10521		.mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10522		.init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
10523				alc889_eapd_verbs, alc_hp15_unsol_verbs},
10524		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10525		.dac_nids = alc883_dac_nids,
10526		.num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10527		.adc_nids = alc889_adc_nids,
10528		.dig_out_nid = ALC883_DIGOUT_NID,
10529		.dig_in_nid = ALC883_DIGIN_NID,
10530		.slave_dig_outs = alc883_slave_dig_outs,
10531		.num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10532		.channel_mode = alc889_8ch_intel_modes,
10533		.capsrc_nids = alc889_capsrc_nids,
10534		.input_mux = &alc889_capture_source,
10535		.setup = alc889_automute_setup,
10536		.init_hook = alc889_intel_init_hook,
10537		.unsol_event = alc_sku_unsol_event,
10538		.need_dac_fix = 1,
10539	},
10540	[ALC883_6ST_DIG] = {
10541		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
10542		.init_verbs = { alc883_init_verbs },
10543		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10544		.dac_nids = alc883_dac_nids,
10545		.dig_out_nid = ALC883_DIGOUT_NID,
10546		.dig_in_nid = ALC883_DIGIN_NID,
10547		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10548		.channel_mode = alc883_sixstack_modes,
10549		.input_mux = &alc883_capture_source,
10550	},
10551	[ALC883_TARGA_DIG] = {
10552		.mixers = { alc883_targa_mixer, alc883_chmode_mixer },
10553		.init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10554				alc883_targa_verbs},
10555		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10556		.dac_nids = alc883_dac_nids,
10557		.dig_out_nid = ALC883_DIGOUT_NID,
10558		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10559		.channel_mode = alc883_3ST_6ch_modes,
10560		.need_dac_fix = 1,
10561		.input_mux = &alc883_capture_source,
10562		.unsol_event = alc883_targa_unsol_event,
10563		.setup = alc882_targa_setup,
10564		.init_hook = alc882_targa_automute,
10565	},
10566	[ALC883_TARGA_2ch_DIG] = {
10567		.mixers = { alc883_targa_2ch_mixer},
10568		.init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10569				alc883_targa_verbs},
10570		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10571		.dac_nids = alc883_dac_nids,
10572		.adc_nids = alc883_adc_nids_alt,
10573		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10574		.capsrc_nids = alc883_capsrc_nids,
10575		.dig_out_nid = ALC883_DIGOUT_NID,
10576		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10577		.channel_mode = alc883_3ST_2ch_modes,
10578		.input_mux = &alc883_capture_source,
10579		.unsol_event = alc883_targa_unsol_event,
10580		.setup = alc882_targa_setup,
10581		.init_hook = alc882_targa_automute,
10582	},
10583	[ALC883_TARGA_8ch_DIG] = {
10584		.mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10585			    alc883_chmode_mixer },
10586		.init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10587				alc883_targa_verbs },
10588		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10589		.dac_nids = alc883_dac_nids,
10590		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10591		.adc_nids = alc883_adc_nids_rev,
10592		.capsrc_nids = alc883_capsrc_nids_rev,
10593		.dig_out_nid = ALC883_DIGOUT_NID,
10594		.dig_in_nid = ALC883_DIGIN_NID,
10595		.num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10596		.channel_mode = alc883_4ST_8ch_modes,
10597		.need_dac_fix = 1,
10598		.input_mux = &alc883_capture_source,
10599		.unsol_event = alc883_targa_unsol_event,
10600		.setup = alc882_targa_setup,
10601		.init_hook = alc882_targa_automute,
10602	},
10603	[ALC883_ACER] = {
10604		.mixers = { alc883_base_mixer },
10605		/* On TravelMate laptops, GPIO 0 enables the internal speaker
10606		 * and the headphone jack.  Turn this on and rely on the
10607		 * standard mute methods whenever the user wants to turn
10608		 * these outputs off.
10609		 */
10610		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10611		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10612		.dac_nids = alc883_dac_nids,
10613		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10614		.channel_mode = alc883_3ST_2ch_modes,
10615		.input_mux = &alc883_capture_source,
10616	},
10617	[ALC883_ACER_ASPIRE] = {
10618		.mixers = { alc883_acer_aspire_mixer },
10619		.init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
10620		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10621		.dac_nids = alc883_dac_nids,
10622		.dig_out_nid = ALC883_DIGOUT_NID,
10623		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10624		.channel_mode = alc883_3ST_2ch_modes,
10625		.input_mux = &alc883_capture_source,
10626		.unsol_event = alc_sku_unsol_event,
10627		.setup = alc883_acer_aspire_setup,
10628		.init_hook = alc_hp_automute,
10629	},
10630	[ALC888_ACER_ASPIRE_4930G] = {
10631		.mixers = { alc888_acer_aspire_4930g_mixer,
10632				alc883_chmode_mixer },
10633		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10634				alc888_acer_aspire_4930g_verbs },
10635		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10636		.dac_nids = alc883_dac_nids,
10637		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10638		.adc_nids = alc883_adc_nids_rev,
10639		.capsrc_nids = alc883_capsrc_nids_rev,
10640		.dig_out_nid = ALC883_DIGOUT_NID,
10641		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10642		.channel_mode = alc883_3ST_6ch_modes,
10643		.need_dac_fix = 1,
10644		.const_channel_count = 6,
10645		.num_mux_defs =
10646			ARRAY_SIZE(alc888_2_capture_sources),
10647		.input_mux = alc888_2_capture_sources,
10648		.unsol_event = alc_sku_unsol_event,
10649		.setup = alc888_acer_aspire_4930g_setup,
10650		.init_hook = alc_hp_automute,
10651	},
10652	[ALC888_ACER_ASPIRE_6530G] = {
10653		.mixers = { alc888_acer_aspire_6530_mixer },
10654		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10655				alc888_acer_aspire_6530g_verbs },
10656		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10657		.dac_nids = alc883_dac_nids,
10658		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10659		.adc_nids = alc883_adc_nids_rev,
10660		.capsrc_nids = alc883_capsrc_nids_rev,
10661		.dig_out_nid = ALC883_DIGOUT_NID,
10662		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10663		.channel_mode = alc883_3ST_2ch_modes,
10664		.num_mux_defs =
10665			ARRAY_SIZE(alc888_2_capture_sources),
10666		.input_mux = alc888_acer_aspire_6530_sources,
10667		.unsol_event = alc_sku_unsol_event,
10668		.setup = alc888_acer_aspire_6530g_setup,
10669		.init_hook = alc_hp_automute,
10670	},
10671	[ALC888_ACER_ASPIRE_8930G] = {
10672		.mixers = { alc889_acer_aspire_8930g_mixer,
10673				alc883_chmode_mixer },
10674		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10675				alc889_acer_aspire_8930g_verbs,
10676				alc889_eapd_verbs},
10677		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10678		.dac_nids = alc883_dac_nids,
10679		.num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10680		.adc_nids = alc889_adc_nids,
10681		.capsrc_nids = alc889_capsrc_nids,
10682		.dig_out_nid = ALC883_DIGOUT_NID,
10683		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10684		.channel_mode = alc883_3ST_6ch_modes,
10685		.need_dac_fix = 1,
10686		.const_channel_count = 6,
10687		.num_mux_defs =
10688			ARRAY_SIZE(alc889_capture_sources),
10689		.input_mux = alc889_capture_sources,
10690		.unsol_event = alc_sku_unsol_event,
10691		.setup = alc889_acer_aspire_8930g_setup,
10692		.init_hook = alc_hp_automute,
10693#ifdef CONFIG_SND_HDA_POWER_SAVE
10694		.power_hook = alc_power_eapd,
10695#endif
10696	},
10697	[ALC888_ACER_ASPIRE_7730G] = {
10698		.mixers = { alc883_3ST_6ch_mixer,
10699				alc883_chmode_mixer },
10700		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10701				alc888_acer_aspire_7730G_verbs },
10702		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10703		.dac_nids = alc883_dac_nids,
10704		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10705		.adc_nids = alc883_adc_nids_rev,
10706		.capsrc_nids = alc883_capsrc_nids_rev,
10707		.dig_out_nid = ALC883_DIGOUT_NID,
10708		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10709		.channel_mode = alc883_3ST_6ch_modes,
10710		.need_dac_fix = 1,
10711		.const_channel_count = 6,
10712		.input_mux = &alc883_capture_source,
10713		.unsol_event = alc_sku_unsol_event,
10714		.setup = alc888_acer_aspire_7730g_setup,
10715		.init_hook = alc_hp_automute,
10716	},
10717	[ALC883_MEDION] = {
10718		.mixers = { alc883_fivestack_mixer,
10719			    alc883_chmode_mixer },
10720		.init_verbs = { alc883_init_verbs,
10721				alc883_medion_eapd_verbs },
10722		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10723		.dac_nids = alc883_dac_nids,
10724		.adc_nids = alc883_adc_nids_alt,
10725		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10726		.capsrc_nids = alc883_capsrc_nids,
10727		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10728		.channel_mode = alc883_sixstack_modes,
10729		.input_mux = &alc883_capture_source,
10730	},
10731	[ALC883_MEDION_WIM2160] = {
10732		.mixers = { alc883_medion_wim2160_mixer },
10733		.init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10734		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10735		.dac_nids = alc883_dac_nids,
10736		.dig_out_nid = ALC883_DIGOUT_NID,
10737		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10738		.adc_nids = alc883_adc_nids,
10739		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10740		.channel_mode = alc883_3ST_2ch_modes,
10741		.input_mux = &alc883_capture_source,
10742		.unsol_event = alc_sku_unsol_event,
10743		.setup = alc883_medion_wim2160_setup,
10744		.init_hook = alc_hp_automute,
10745	},
10746	[ALC883_LAPTOP_EAPD] = {
10747		.mixers = { alc883_base_mixer },
10748		.init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10749		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10750		.dac_nids = alc883_dac_nids,
10751		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10752		.channel_mode = alc883_3ST_2ch_modes,
10753		.input_mux = &alc883_capture_source,
10754	},
10755	[ALC883_CLEVO_M540R] = {
10756		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10757		.init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10758		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10759		.dac_nids = alc883_dac_nids,
10760		.dig_out_nid = ALC883_DIGOUT_NID,
10761		.dig_in_nid = ALC883_DIGIN_NID,
10762		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10763		.channel_mode = alc883_3ST_6ch_clevo_modes,
10764		.need_dac_fix = 1,
10765		.input_mux = &alc883_capture_source,
10766		/* This machine has the hardware HP auto-muting, thus
10767		 * we need no software mute via unsol event
10768		 */
10769	},
10770	[ALC883_CLEVO_M720] = {
10771		.mixers = { alc883_clevo_m720_mixer },
10772		.init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
10773		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10774		.dac_nids = alc883_dac_nids,
10775		.dig_out_nid = ALC883_DIGOUT_NID,
10776		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10777		.channel_mode = alc883_3ST_2ch_modes,
10778		.input_mux = &alc883_capture_source,
10779		.unsol_event = alc883_clevo_m720_unsol_event,
10780		.setup = alc883_clevo_m720_setup,
10781		.init_hook = alc883_clevo_m720_init_hook,
10782	},
10783	[ALC883_LENOVO_101E_2ch] = {
10784		.mixers = { alc883_lenovo_101e_2ch_mixer},
10785		.init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10786		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10787		.dac_nids = alc883_dac_nids,
10788		.adc_nids = alc883_adc_nids_alt,
10789		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10790		.capsrc_nids = alc883_capsrc_nids,
10791		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10792		.channel_mode = alc883_3ST_2ch_modes,
10793		.input_mux = &alc883_lenovo_101e_capture_source,
10794		.setup = alc883_lenovo_101e_setup,
10795		.unsol_event = alc_sku_unsol_event,
10796		.init_hook = alc_inithook,
10797	},
10798	[ALC883_LENOVO_NB0763] = {
10799		.mixers = { alc883_lenovo_nb0763_mixer },
10800		.init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10801		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10802		.dac_nids = alc883_dac_nids,
10803		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10804		.channel_mode = alc883_3ST_2ch_modes,
10805		.need_dac_fix = 1,
10806		.input_mux = &alc883_lenovo_nb0763_capture_source,
10807		.unsol_event = alc_sku_unsol_event,
10808		.setup = alc883_lenovo_nb0763_setup,
10809		.init_hook = alc_hp_automute,
10810	},
10811	[ALC888_LENOVO_MS7195_DIG] = {
10812		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10813		.init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10814		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10815		.dac_nids = alc883_dac_nids,
10816		.dig_out_nid = ALC883_DIGOUT_NID,
10817		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10818		.channel_mode = alc883_3ST_6ch_modes,
10819		.need_dac_fix = 1,
10820		.input_mux = &alc883_capture_source,
10821		.unsol_event = alc_sku_unsol_event,
10822		.setup = alc888_lenovo_ms7195_setup,
10823		.init_hook = alc_inithook,
10824	},
10825	[ALC883_HAIER_W66] = {
10826		.mixers = { alc883_targa_2ch_mixer},
10827		.init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10828		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10829		.dac_nids = alc883_dac_nids,
10830		.dig_out_nid = ALC883_DIGOUT_NID,
10831		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10832		.channel_mode = alc883_3ST_2ch_modes,
10833		.input_mux = &alc883_capture_source,
10834		.unsol_event = alc_sku_unsol_event,
10835		.setup = alc883_haier_w66_setup,
10836		.init_hook = alc_hp_automute,
10837	},
10838	[ALC888_3ST_HP] = {
10839		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10840		.init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
10841		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10842		.dac_nids = alc883_dac_nids,
10843		.num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10844		.channel_mode = alc888_3st_hp_modes,
10845		.need_dac_fix = 1,
10846		.input_mux = &alc883_capture_source,
10847		.unsol_event = alc_sku_unsol_event,
10848		.setup = alc888_3st_hp_setup,
10849		.init_hook = alc_hp_automute,
10850	},
10851	[ALC888_6ST_DELL] = {
10852		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
10853		.init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10854		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10855		.dac_nids = alc883_dac_nids,
10856		.dig_out_nid = ALC883_DIGOUT_NID,
10857		.dig_in_nid = ALC883_DIGIN_NID,
10858		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10859		.channel_mode = alc883_sixstack_modes,
10860		.input_mux = &alc883_capture_source,
10861		.unsol_event = alc_sku_unsol_event,
10862		.setup = alc888_6st_dell_setup,
10863		.init_hook = alc_hp_automute,
10864	},
10865	[ALC883_MITAC] = {
10866		.mixers = { alc883_mitac_mixer },
10867		.init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10868		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10869		.dac_nids = alc883_dac_nids,
10870		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10871		.channel_mode = alc883_3ST_2ch_modes,
10872		.input_mux = &alc883_capture_source,
10873		.unsol_event = alc_sku_unsol_event,
10874		.setup = alc883_mitac_setup,
10875		.init_hook = alc_hp_automute,
10876	},
10877	[ALC883_FUJITSU_PI2515] = {
10878		.mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10879		.init_verbs = { alc883_init_verbs,
10880				alc883_2ch_fujitsu_pi2515_verbs},
10881		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10882		.dac_nids = alc883_dac_nids,
10883		.dig_out_nid = ALC883_DIGOUT_NID,
10884		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10885		.channel_mode = alc883_3ST_2ch_modes,
10886		.input_mux = &alc883_fujitsu_pi2515_capture_source,
10887		.unsol_event = alc_sku_unsol_event,
10888		.setup = alc883_2ch_fujitsu_pi2515_setup,
10889		.init_hook = alc_hp_automute,
10890	},
10891	[ALC888_FUJITSU_XA3530] = {
10892		.mixers = { alc888_base_mixer, alc883_chmode_mixer },
10893		.init_verbs = { alc883_init_verbs,
10894			alc888_fujitsu_xa3530_verbs },
10895		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10896		.dac_nids = alc883_dac_nids,
10897		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10898		.adc_nids = alc883_adc_nids_rev,
10899		.capsrc_nids = alc883_capsrc_nids_rev,
10900		.dig_out_nid = ALC883_DIGOUT_NID,
10901		.num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10902		.channel_mode = alc888_4ST_8ch_intel_modes,
10903		.num_mux_defs =
10904			ARRAY_SIZE(alc888_2_capture_sources),
10905		.input_mux = alc888_2_capture_sources,
10906		.unsol_event = alc_sku_unsol_event,
10907		.setup = alc888_fujitsu_xa3530_setup,
10908		.init_hook = alc_hp_automute,
10909	},
10910	[ALC888_LENOVO_SKY] = {
10911		.mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10912		.init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10913		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10914		.dac_nids = alc883_dac_nids,
10915		.dig_out_nid = ALC883_DIGOUT_NID,
10916		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10917		.channel_mode = alc883_sixstack_modes,
10918		.need_dac_fix = 1,
10919		.input_mux = &alc883_lenovo_sky_capture_source,
10920		.unsol_event = alc_sku_unsol_event,
10921		.setup = alc888_lenovo_sky_setup,
10922		.init_hook = alc_hp_automute,
10923	},
10924	[ALC888_ASUS_M90V] = {
10925		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10926		.init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10927		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10928		.dac_nids = alc883_dac_nids,
10929		.dig_out_nid = ALC883_DIGOUT_NID,
10930		.dig_in_nid = ALC883_DIGIN_NID,
10931		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10932		.channel_mode = alc883_3ST_6ch_modes,
10933		.need_dac_fix = 1,
10934		.input_mux = &alc883_fujitsu_pi2515_capture_source,
10935		.unsol_event = alc_sku_unsol_event,
10936		.setup = alc883_mode2_setup,
10937		.init_hook = alc_inithook,
10938	},
10939	[ALC888_ASUS_EEE1601] = {
10940		.mixers = { alc883_asus_eee1601_mixer },
10941		.cap_mixer = alc883_asus_eee1601_cap_mixer,
10942		.init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10943		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10944		.dac_nids = alc883_dac_nids,
10945		.dig_out_nid = ALC883_DIGOUT_NID,
10946		.dig_in_nid = ALC883_DIGIN_NID,
10947		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10948		.channel_mode = alc883_3ST_2ch_modes,
10949		.need_dac_fix = 1,
10950		.input_mux = &alc883_asus_eee1601_capture_source,
10951		.unsol_event = alc_sku_unsol_event,
10952		.init_hook = alc883_eee1601_inithook,
10953	},
10954	[ALC1200_ASUS_P5Q] = {
10955		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
10956		.init_verbs = { alc883_init_verbs },
10957		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10958		.dac_nids = alc883_dac_nids,
10959		.dig_out_nid = ALC1200_DIGOUT_NID,
10960		.dig_in_nid = ALC883_DIGIN_NID,
10961		.slave_dig_outs = alc1200_slave_dig_outs,
10962		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10963		.channel_mode = alc883_sixstack_modes,
10964		.input_mux = &alc883_capture_source,
10965	},
10966	[ALC889A_MB31] = {
10967		.mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10968		.init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10969			alc880_gpio1_init_verbs },
10970		.adc_nids = alc883_adc_nids,
10971		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10972		.capsrc_nids = alc883_capsrc_nids,
10973		.dac_nids = alc883_dac_nids,
10974		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10975		.channel_mode = alc889A_mb31_6ch_modes,
10976		.num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10977		.input_mux = &alc889A_mb31_capture_source,
10978		.dig_out_nid = ALC883_DIGOUT_NID,
10979		.unsol_event = alc889A_mb31_unsol_event,
10980		.init_hook = alc889A_mb31_automute,
10981	},
10982	[ALC883_SONY_VAIO_TT] = {
10983		.mixers = { alc883_vaiott_mixer },
10984		.init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10985		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10986		.dac_nids = alc883_dac_nids,
10987		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10988		.channel_mode = alc883_3ST_2ch_modes,
10989		.input_mux = &alc883_capture_source,
10990		.unsol_event = alc_sku_unsol_event,
10991		.setup = alc883_vaiott_setup,
10992		.init_hook = alc_hp_automute,
10993	},
10994};
10995
10996
10997/*
10998 * Pin config fixes
10999 */
11000enum {
11001	PINFIX_ABIT_AW9D_MAX,
11002	PINFIX_LENOVO_Y530,
11003	PINFIX_PB_M5210,
11004	PINFIX_ACER_ASPIRE_7736,
11005};
11006
11007static const struct alc_fixup alc882_fixups[] = {
11008	[PINFIX_ABIT_AW9D_MAX] = {
11009		.type = ALC_FIXUP_PINS,
11010		.v.pins = (const struct alc_pincfg[]) {
11011			{ 0x15, 0x01080104 }, /* side */
11012			{ 0x16, 0x01011012 }, /* rear */
11013			{ 0x17, 0x01016011 }, /* clfe */
11014			{ }
11015		}
11016	},
11017	[PINFIX_LENOVO_Y530] = {
11018		.type = ALC_FIXUP_PINS,
11019		.v.pins = (const struct alc_pincfg[]) {
11020			{ 0x15, 0x99130112 }, /* rear int speakers */
11021			{ 0x16, 0x99130111 }, /* subwoofer */
11022			{ }
11023		}
11024	},
11025	[PINFIX_PB_M5210] = {
11026		.type = ALC_FIXUP_VERBS,
11027		.v.verbs = (const struct hda_verb[]) {
11028			{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
11029			{}
11030		}
11031	},
11032	[PINFIX_ACER_ASPIRE_7736] = {
11033		.type = ALC_FIXUP_SKU,
11034		.v.sku = ALC_FIXUP_SKU_IGNORE,
11035	},
11036};
11037
11038static const struct snd_pci_quirk alc882_fixup_tbl[] = {
11039	SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
11040	SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
11041	SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
11042	SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
11043	{}
11044};
11045
11046/*
11047 * BIOS auto configuration
11048 */
11049static int alc882_auto_create_input_ctls(struct hda_codec *codec,
11050						const struct auto_pin_cfg *cfg)
11051{
11052	return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
11053}
11054
11055static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
11056					      hda_nid_t nid, int pin_type,
11057					      hda_nid_t dac)
11058{
11059	int idx;
11060
11061	/* set as output */
11062	alc_set_pin_output(codec, nid, pin_type);
11063
11064	if (dac == 0x25)
11065		idx = 4;
11066	else if (dac >= 0x02 && dac <= 0x05)
11067		idx = dac - 2;
11068	else
11069		return;
11070	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
11071}
11072
11073static void alc882_auto_init_multi_out(struct hda_codec *codec)
11074{
11075	struct alc_spec *spec = codec->spec;
11076	int i;
11077
11078	for (i = 0; i <= HDA_SIDE; i++) {
11079		hda_nid_t nid = spec->autocfg.line_out_pins[i];
11080		int pin_type = get_pin_type(spec->autocfg.line_out_type);
11081		if (nid)
11082			alc882_auto_set_output_and_unmute(codec, nid, pin_type,
11083					spec->multiout.dac_nids[i]);
11084	}
11085}
11086
11087static void alc882_auto_init_hp_out(struct hda_codec *codec)
11088{
11089	struct alc_spec *spec = codec->spec;
11090	hda_nid_t pin, dac;
11091	int i;
11092
11093	if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) {
11094		for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
11095			pin = spec->autocfg.hp_pins[i];
11096			if (!pin)
11097				break;
11098			dac = spec->multiout.hp_nid;
11099			if (!dac)
11100				dac = spec->multiout.dac_nids[0]; /* to front */
11101			alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
11102		}
11103	}
11104
11105	if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) {
11106		for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
11107			pin = spec->autocfg.speaker_pins[i];
11108			if (!pin)
11109				break;
11110			dac = spec->multiout.extra_out_nid[0];
11111			if (!dac)
11112				dac = spec->multiout.dac_nids[0]; /* to front */
11113			alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
11114		}
11115	}
11116}
11117
11118static void alc882_auto_init_analog_input(struct hda_codec *codec)
11119{
11120	struct alc_spec *spec = codec->spec;
11121	struct auto_pin_cfg *cfg = &spec->autocfg;
11122	int i;
11123
11124	for (i = 0; i < cfg->num_inputs; i++) {
11125		hda_nid_t nid = cfg->inputs[i].pin;
11126		alc_set_input_pin(codec, nid, cfg->inputs[i].type);
11127		if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
11128			snd_hda_codec_write(codec, nid, 0,
11129					    AC_VERB_SET_AMP_GAIN_MUTE,
11130					    AMP_OUT_MUTE);
11131	}
11132}
11133
11134static void alc882_auto_init_input_src(struct hda_codec *codec)
11135{
11136	struct alc_spec *spec = codec->spec;
11137	int c;
11138
11139	for (c = 0; c < spec->num_adc_nids; c++) {
11140		hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
11141		hda_nid_t nid = spec->capsrc_nids[c];
11142		unsigned int mux_idx;
11143		const struct hda_input_mux *imux;
11144		int conns, mute, idx, item;
11145
11146		/* mute ADC */
11147		snd_hda_codec_write(codec, spec->adc_nids[c], 0,
11148				    AC_VERB_SET_AMP_GAIN_MUTE,
11149				    AMP_IN_MUTE(0));
11150
11151		conns = snd_hda_get_connections(codec, nid, conn_list,
11152						ARRAY_SIZE(conn_list));
11153		if (conns < 0)
11154			continue;
11155		mux_idx = c >= spec->num_mux_defs ? 0 : c;
11156		imux = &spec->input_mux[mux_idx];
11157		if (!imux->num_items && mux_idx > 0)
11158			imux = &spec->input_mux[0];
11159		for (idx = 0; idx < conns; idx++) {
11160			/* if the current connection is the selected one,
11161			 * unmute it as default - otherwise mute it
11162			 */
11163			mute = AMP_IN_MUTE(idx);
11164			for (item = 0; item < imux->num_items; item++) {
11165				if (imux->items[item].index == idx) {
11166					if (spec->cur_mux[c] == item)
11167						mute = AMP_IN_UNMUTE(idx);
11168					break;
11169				}
11170			}
11171			/* check if we have a selector or mixer
11172			 * we could check for the widget type instead, but
11173			 * just check for Amp-In presence (in case of mixer
11174			 * without amp-in there is something wrong, this
11175			 * function shouldn't be used or capsrc nid is wrong)
11176			 */
11177			if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
11178				snd_hda_codec_write(codec, nid, 0,
11179						    AC_VERB_SET_AMP_GAIN_MUTE,
11180						    mute);
11181			else if (mute != AMP_IN_MUTE(idx))
11182				snd_hda_codec_write(codec, nid, 0,
11183						    AC_VERB_SET_CONNECT_SEL,
11184						    idx);
11185		}
11186	}
11187}
11188
11189/* add mic boosts if needed */
11190static int alc_auto_add_mic_boost(struct hda_codec *codec)
11191{
11192	struct alc_spec *spec = codec->spec;
11193	struct auto_pin_cfg *cfg = &spec->autocfg;
11194	int i, err;
11195	int type_idx = 0;
11196	hda_nid_t nid;
11197	const char *prev_label = NULL;
11198
11199	for (i = 0; i < cfg->num_inputs; i++) {
11200		if (cfg->inputs[i].type > AUTO_PIN_MIC)
11201			break;
11202		nid = cfg->inputs[i].pin;
11203		if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
11204			const char *label;
11205			char boost_label[32];
11206
11207			label = hda_get_autocfg_input_label(codec, cfg, i);
11208			if (prev_label && !strcmp(label, prev_label))
11209				type_idx++;
11210			else
11211				type_idx = 0;
11212			prev_label = label;
11213
11214			snprintf(boost_label, sizeof(boost_label),
11215				 "%s Boost Volume", label);
11216			err = add_control(spec, ALC_CTL_WIDGET_VOL,
11217					  boost_label, type_idx,
11218				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11219			if (err < 0)
11220				return err;
11221		}
11222	}
11223	return 0;
11224}
11225
11226/* almost identical with ALC880 parser... */
11227static int alc882_parse_auto_config(struct hda_codec *codec)
11228{
11229	struct alc_spec *spec = codec->spec;
11230	static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
11231	int err;
11232
11233	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11234					   alc882_ignore);
11235	if (err < 0)
11236		return err;
11237	if (!spec->autocfg.line_outs)
11238		return 0; /* can't find valid BIOS pin config */
11239
11240	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
11241	if (err < 0)
11242		return err;
11243	err = alc_auto_add_multi_channel_mode(codec);
11244	if (err < 0)
11245		return err;
11246	err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
11247	if (err < 0)
11248		return err;
11249	err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
11250					   "Headphone");
11251	if (err < 0)
11252		return err;
11253	err = alc880_auto_create_extra_out(spec,
11254					   spec->autocfg.speaker_pins[0],
11255					   "Speaker");
11256	if (err < 0)
11257		return err;
11258	err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
11259	if (err < 0)
11260		return err;
11261
11262	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11263
11264	alc_auto_parse_digital(codec);
11265
11266	if (spec->kctls.list)
11267		add_mixer(spec, spec->kctls.list);
11268
11269	add_verb(spec, alc883_auto_init_verbs);
11270	/* if ADC 0x07 is available, initialize it, too */
11271	if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
11272		add_verb(spec, alc882_adc1_init_verbs);
11273
11274	spec->num_mux_defs = 1;
11275	spec->input_mux = &spec->private_imux[0];
11276
11277	alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
11278
11279	err = alc_auto_add_mic_boost(codec);
11280	if (err < 0)
11281		return err;
11282
11283	return 1; /* config found */
11284}
11285
11286/* additional initialization for auto-configuration model */
11287static void alc882_auto_init(struct hda_codec *codec)
11288{
11289	struct alc_spec *spec = codec->spec;
11290	alc882_auto_init_multi_out(codec);
11291	alc882_auto_init_hp_out(codec);
11292	alc882_auto_init_analog_input(codec);
11293	alc882_auto_init_input_src(codec);
11294	alc_auto_init_digital(codec);
11295	if (spec->unsol_event)
11296		alc_inithook(codec);
11297}
11298
11299static int patch_alc882(struct hda_codec *codec)
11300{
11301	struct alc_spec *spec;
11302	int err, board_config;
11303
11304	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11305	if (spec == NULL)
11306		return -ENOMEM;
11307
11308	codec->spec = spec;
11309
11310	switch (codec->vendor_id) {
11311	case 0x10ec0882:
11312	case 0x10ec0885:
11313		break;
11314	default:
11315		/* ALC883 and variants */
11316		alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11317		break;
11318	}
11319
11320	board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
11321						  alc882_models,
11322						  alc882_cfg_tbl);
11323
11324	if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
11325		board_config = snd_hda_check_board_codec_sid_config(codec,
11326			ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
11327
11328	if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
11329		printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
11330		       codec->chip_name);
11331		board_config = ALC882_AUTO;
11332	}
11333
11334	if (board_config == ALC882_AUTO) {
11335		alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11336		alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11337	}
11338
11339	alc_auto_parse_customize_define(codec);
11340
11341	if (board_config == ALC882_AUTO) {
11342		/* automatic parse from the BIOS config */
11343		err = alc882_parse_auto_config(codec);
11344		if (err < 0) {
11345			alc_free(codec);
11346			return err;
11347		} else if (!err) {
11348			printk(KERN_INFO
11349			       "hda_codec: Cannot set up configuration "
11350			       "from BIOS.  Using base mode...\n");
11351			board_config = ALC882_3ST_DIG;
11352		}
11353	}
11354
11355	if (has_cdefine_beep(codec)) {
11356		err = snd_hda_attach_beep_device(codec, 0x1);
11357		if (err < 0) {
11358			alc_free(codec);
11359			return err;
11360		}
11361	}
11362
11363	if (board_config != ALC882_AUTO)
11364		setup_preset(codec, &alc882_presets[board_config]);
11365
11366	spec->stream_analog_playback = &alc882_pcm_analog_playback;
11367	spec->stream_analog_capture = &alc882_pcm_analog_capture;
11368	/* FIXME: setup DAC5 */
11369	/*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
11370	spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11371
11372	spec->stream_digital_playback = &alc882_pcm_digital_playback;
11373	spec->stream_digital_capture = &alc882_pcm_digital_capture;
11374
11375	if (!spec->adc_nids && spec->input_mux) {
11376		int i, j;
11377		spec->num_adc_nids = 0;
11378		for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
11379			const struct hda_input_mux *imux = spec->input_mux;
11380			hda_nid_t cap;
11381			hda_nid_t items[16];
11382			hda_nid_t nid = alc882_adc_nids[i];
11383			unsigned int wcap = get_wcaps(codec, nid);
11384			/* get type */
11385			wcap = get_wcaps_type(wcap);
11386			if (wcap != AC_WID_AUD_IN)
11387				continue;
11388			spec->private_adc_nids[spec->num_adc_nids] = nid;
11389			err = snd_hda_get_connections(codec, nid, &cap, 1);
11390			if (err < 0)
11391				continue;
11392			err = snd_hda_get_connections(codec, cap, items,
11393						      ARRAY_SIZE(items));
11394			if (err < 0)
11395				continue;
11396			for (j = 0; j < imux->num_items; j++)
11397				if (imux->items[j].index >= err)
11398					break;
11399			if (j < imux->num_items)
11400				continue;
11401			spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11402			spec->num_adc_nids++;
11403		}
11404		spec->adc_nids = spec->private_adc_nids;
11405		spec->capsrc_nids = spec->private_capsrc_nids;
11406	}
11407
11408	set_capture_mixer(codec);
11409
11410	if (has_cdefine_beep(codec))
11411		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11412
11413	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
11414
11415	spec->vmaster_nid = 0x0c;
11416
11417	codec->patch_ops = alc_patch_ops;
11418	if (board_config == ALC882_AUTO)
11419		spec->init_hook = alc882_auto_init;
11420
11421	alc_init_jacks(codec);
11422#ifdef CONFIG_SND_HDA_POWER_SAVE
11423	if (!spec->loopback.amplist)
11424		spec->loopback.amplist = alc882_loopbacks;
11425#endif
11426
11427	return 0;
11428}
11429
11430
11431/*
11432 * ALC262 support
11433 */
11434
11435#define ALC262_DIGOUT_NID	ALC880_DIGOUT_NID
11436#define ALC262_DIGIN_NID	ALC880_DIGIN_NID
11437
11438#define alc262_dac_nids		alc260_dac_nids
11439#define alc262_adc_nids		alc882_adc_nids
11440#define alc262_adc_nids_alt	alc882_adc_nids_alt
11441#define alc262_capsrc_nids	alc882_capsrc_nids
11442#define alc262_capsrc_nids_alt	alc882_capsrc_nids_alt
11443
11444#define alc262_modes		alc260_modes
11445#define alc262_capture_source	alc882_capture_source
11446
11447static const hda_nid_t alc262_dmic_adc_nids[1] = {
11448	/* ADC0 */
11449	0x09
11450};
11451
11452static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11453
11454static const struct snd_kcontrol_new alc262_base_mixer[] = {
11455	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11456	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11457	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11458	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11459	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11460	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11461	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11462	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11463	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11464	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11465	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11466	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11467	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11468	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11469	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11470	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11471	{ } /* end */
11472};
11473
11474/* update HP, line and mono-out pins according to the master switch */
11475#define alc262_hp_master_update		alc260_hp_master_update
11476
11477static void alc262_hp_bpc_setup(struct hda_codec *codec)
11478{
11479	struct alc_spec *spec = codec->spec;
11480
11481	spec->autocfg.hp_pins[0] = 0x1b;
11482	spec->autocfg.speaker_pins[0] = 0x16;
11483	spec->automute = 1;
11484	spec->automute_mode = ALC_AUTOMUTE_PIN;
11485}
11486
11487static void alc262_hp_wildwest_setup(struct hda_codec *codec)
11488{
11489	struct alc_spec *spec = codec->spec;
11490
11491	spec->autocfg.hp_pins[0] = 0x15;
11492	spec->autocfg.speaker_pins[0] = 0x16;
11493	spec->automute = 1;
11494	spec->automute_mode = ALC_AUTOMUTE_PIN;
11495}
11496
11497#define alc262_hp_master_sw_get		alc260_hp_master_sw_get
11498#define alc262_hp_master_sw_put		alc260_hp_master_sw_put
11499
11500#define ALC262_HP_MASTER_SWITCH					\
11501	{							\
11502		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,		\
11503		.name = "Master Playback Switch",		\
11504		.info = snd_ctl_boolean_mono_info,		\
11505		.get = alc262_hp_master_sw_get,			\
11506		.put = alc262_hp_master_sw_put,			\
11507	}, \
11508	{							\
11509		.iface = NID_MAPPING,				\
11510		.name = "Master Playback Switch",		\
11511		.private_value = 0x15 | (0x16 << 8) | (0x1b << 16),	\
11512	}
11513
11514
11515static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
11516	ALC262_HP_MASTER_SWITCH,
11517	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11518	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11519	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11520	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11521			      HDA_OUTPUT),
11522	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11523			    HDA_OUTPUT),
11524	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11525	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11526	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11527	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11528	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11529	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11530	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11531	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11532	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11533	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11534	HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11535	HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11536	{ } /* end */
11537};
11538
11539static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
11540	ALC262_HP_MASTER_SWITCH,
11541	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11542	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11543	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11544	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11545	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11546			      HDA_OUTPUT),
11547	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11548			    HDA_OUTPUT),
11549	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11550	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
11551	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
11552	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11553	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11554	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11555	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11556	{ } /* end */
11557};
11558
11559static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11560	HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11561	HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11562	HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
11563	{ } /* end */
11564};
11565
11566/* mute/unmute internal speaker according to the hp jack and mute state */
11567static void alc262_hp_t5735_setup(struct hda_codec *codec)
11568{
11569	struct alc_spec *spec = codec->spec;
11570
11571	spec->autocfg.hp_pins[0] = 0x15;
11572	spec->autocfg.speaker_pins[0] = 0x14;
11573	spec->automute = 1;
11574	spec->automute_mode = ALC_AUTOMUTE_PIN;
11575}
11576
11577static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
11578	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11579	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11580	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11581	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11582	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11583	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11584	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11585	{ } /* end */
11586};
11587
11588static const struct hda_verb alc262_hp_t5735_verbs[] = {
11589	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11590	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11591
11592	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11593	{ }
11594};
11595
11596static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
11597	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11598	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11599	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11600	HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
11601	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11602	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11603	{ } /* end */
11604};
11605
11606static const struct hda_verb alc262_hp_rp5700_verbs[] = {
11607	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11608	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11609	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11610	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11611	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11612	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11613	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11614	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11615	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11616	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11617	{}
11618};
11619
11620static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
11621	.num_items = 1,
11622	.items = {
11623		{ "Line", 0x1 },
11624	},
11625};
11626
11627/* bind hp and internal speaker mute (with plug check) as master switch */
11628#define alc262_hippo_master_update	alc262_hp_master_update
11629#define alc262_hippo_master_sw_get	alc262_hp_master_sw_get
11630#define alc262_hippo_master_sw_put	alc262_hp_master_sw_put
11631
11632#define ALC262_HIPPO_MASTER_SWITCH				\
11633	{							\
11634		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,		\
11635		.name = "Master Playback Switch",		\
11636		.info = snd_ctl_boolean_mono_info,		\
11637		.get = alc262_hippo_master_sw_get,		\
11638		.put = alc262_hippo_master_sw_put,		\
11639	},							\
11640	{							\
11641		.iface = NID_MAPPING,				\
11642		.name = "Master Playback Switch",		\
11643		.subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11644			     (SUBDEV_SPEAKER(0) << 16), \
11645	}
11646
11647static const struct snd_kcontrol_new alc262_hippo_mixer[] = {
11648	ALC262_HIPPO_MASTER_SWITCH,
11649	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11650	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11651	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11652	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11653	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11654	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11655	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11656	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11657	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11658	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11659	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11660	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11661	{ } /* end */
11662};
11663
11664static const struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11665	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11666	ALC262_HIPPO_MASTER_SWITCH,
11667	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11668	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11669	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11670	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11671	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11672	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11673	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11674	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11675	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11676	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11677	{ } /* end */
11678};
11679
11680/* mute/unmute internal speaker according to the hp jack and mute state */
11681static void alc262_hippo_setup(struct hda_codec *codec)
11682{
11683	struct alc_spec *spec = codec->spec;
11684
11685	spec->autocfg.hp_pins[0] = 0x15;
11686	spec->autocfg.speaker_pins[0] = 0x14;
11687	spec->automute = 1;
11688	spec->automute_mode = ALC_AUTOMUTE_AMP;
11689}
11690
11691static void alc262_hippo1_setup(struct hda_codec *codec)
11692{
11693	struct alc_spec *spec = codec->spec;
11694
11695	spec->autocfg.hp_pins[0] = 0x1b;
11696	spec->autocfg.speaker_pins[0] = 0x14;
11697	spec->automute = 1;
11698	spec->automute_mode = ALC_AUTOMUTE_AMP;
11699}
11700
11701
11702static const struct snd_kcontrol_new alc262_sony_mixer[] = {
11703	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11704	ALC262_HIPPO_MASTER_SWITCH,
11705	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11706	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11707	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11708	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11709	{ } /* end */
11710};
11711
11712static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
11713	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11714	ALC262_HIPPO_MASTER_SWITCH,
11715	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11716	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11717	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11718	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11719	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11720	{ } /* end */
11721};
11722
11723static const struct snd_kcontrol_new alc262_tyan_mixer[] = {
11724	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11725	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11726	HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11727	HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11728	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11729	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11730	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11731	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11732	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11733	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11734	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11735	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11736	{ } /* end */
11737};
11738
11739static const struct hda_verb alc262_tyan_verbs[] = {
11740	/* Headphone automute */
11741	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11742	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11743	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11744
11745	/* P11 AUX_IN, white 4-pin connector */
11746	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11747	{0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11748	{0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11749	{0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11750
11751	{}
11752};
11753
11754/* unsolicited event for HP jack sensing */
11755static void alc262_tyan_setup(struct hda_codec *codec)
11756{
11757	struct alc_spec *spec = codec->spec;
11758
11759	spec->autocfg.hp_pins[0] = 0x1b;
11760	spec->autocfg.speaker_pins[0] = 0x15;
11761	spec->automute = 1;
11762	spec->automute_mode = ALC_AUTOMUTE_AMP;
11763}
11764
11765
11766#define alc262_capture_mixer		alc882_capture_mixer
11767#define alc262_capture_alt_mixer	alc882_capture_alt_mixer
11768
11769/*
11770 * generic initialization of ADC, input mixers and output mixers
11771 */
11772static const struct hda_verb alc262_init_verbs[] = {
11773	/*
11774	 * Unmute ADC0-2 and set the default input to mic-in
11775	 */
11776	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11777	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11778	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11779	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11780	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11781	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11782
11783	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11784	 * mixer widget
11785	 * Note: PASD motherboards uses the Line In 2 as the input for
11786	 * front panel mic (mic 2)
11787	 */
11788	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11789	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11790	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11791	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11792	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11793	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11794
11795	/*
11796	 * Set up output mixers (0x0c - 0x0e)
11797	 */
11798	/* set vol=0 to output mixers */
11799	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11800	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11801	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11802	/* set up input amps for analog loopback */
11803	/* Amp Indices: DAC = 0, mixer = 1 */
11804	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11805	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11806	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11807	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11808	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11809	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11810
11811	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11812	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11813	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11814	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11815	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11816	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11817
11818	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11819	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11820	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11821	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11822	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11823
11824	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11825	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11826
11827	/* FIXME: use matrix-type input source selection */
11828	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11829	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11830	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11831	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11832	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11833	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11834	/* Input mixer2 */
11835	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11836	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11837	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11838	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11839	/* Input mixer3 */
11840	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11841	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11842	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11843	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11844
11845	{ }
11846};
11847
11848static const struct hda_verb alc262_eapd_verbs[] = {
11849	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11850	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11851	{ }
11852};
11853
11854static const struct hda_verb alc262_hippo1_unsol_verbs[] = {
11855	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11856	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11857	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11858
11859	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11860	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11861	{}
11862};
11863
11864static const struct hda_verb alc262_sony_unsol_verbs[] = {
11865	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11866	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11867	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},	// Front Mic
11868
11869	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11870	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11871	{}
11872};
11873
11874static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11875	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11876	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11877	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11878	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11879	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11880	{ } /* end */
11881};
11882
11883static const struct hda_verb alc262_toshiba_s06_verbs[] = {
11884	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11885	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11886	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11887	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11888	{0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11889	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11890	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11891	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11892	{}
11893};
11894
11895static void alc262_toshiba_s06_setup(struct hda_codec *codec)
11896{
11897	struct alc_spec *spec = codec->spec;
11898
11899	spec->autocfg.hp_pins[0] = 0x15;
11900	spec->autocfg.speaker_pins[0] = 0x14;
11901	spec->ext_mic.pin = 0x18;
11902	spec->ext_mic.mux_idx = 0;
11903	spec->int_mic.pin = 0x12;
11904	spec->int_mic.mux_idx = 9;
11905	spec->auto_mic = 1;
11906	spec->automute = 1;
11907	spec->automute_mode = ALC_AUTOMUTE_PIN;
11908}
11909
11910/*
11911 * nec model
11912 *  0x15 = headphone
11913 *  0x16 = internal speaker
11914 *  0x18 = external mic
11915 */
11916
11917static const struct snd_kcontrol_new alc262_nec_mixer[] = {
11918	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11919	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11920
11921	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11922	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11923	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11924
11925	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11926	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11927	{ } /* end */
11928};
11929
11930static const struct hda_verb alc262_nec_verbs[] = {
11931	/* Unmute Speaker */
11932	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11933
11934	/* Headphone */
11935	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11936	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11937
11938	/* External mic to headphone */
11939	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11940	/* External mic to speaker */
11941	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11942	{}
11943};
11944
11945/*
11946 * fujitsu model
11947 *  0x14 = headphone/spdif-out, 0x15 = internal speaker,
11948 *  0x1b = port replicator headphone out
11949 */
11950
11951#define ALC_HP_EVENT	ALC880_HP_EVENT
11952
11953static const struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11954	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11955	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11956	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11957	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11958	{}
11959};
11960
11961static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11962	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11963	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11964	{}
11965};
11966
11967static const struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11968	/* Front Mic pin: input vref at 50% */
11969	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11970	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11971	{}
11972};
11973
11974static const struct hda_input_mux alc262_fujitsu_capture_source = {
11975	.num_items = 3,
11976	.items = {
11977		{ "Mic", 0x0 },
11978		{ "Internal Mic", 0x1 },
11979		{ "CD", 0x4 },
11980	},
11981};
11982
11983static const struct hda_input_mux alc262_HP_capture_source = {
11984	.num_items = 5,
11985	.items = {
11986		{ "Mic", 0x0 },
11987		{ "Front Mic", 0x1 },
11988		{ "Line", 0x2 },
11989		{ "CD", 0x4 },
11990		{ "AUX IN", 0x6 },
11991	},
11992};
11993
11994static const struct hda_input_mux alc262_HP_D7000_capture_source = {
11995	.num_items = 4,
11996	.items = {
11997		{ "Mic", 0x0 },
11998		{ "Front Mic", 0x2 },
11999		{ "Line", 0x1 },
12000		{ "CD", 0x4 },
12001	},
12002};
12003
12004static void alc262_fujitsu_setup(struct hda_codec *codec)
12005{
12006	struct alc_spec *spec = codec->spec;
12007
12008	spec->autocfg.hp_pins[0] = 0x14;
12009	spec->autocfg.hp_pins[1] = 0x1b;
12010	spec->autocfg.speaker_pins[0] = 0x15;
12011	spec->automute = 1;
12012	spec->automute_mode = ALC_AUTOMUTE_AMP;
12013}
12014
12015/* bind volumes of both NID 0x0c and 0x0d */
12016static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
12017	.ops = &snd_hda_bind_vol,
12018	.values = {
12019		HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
12020		HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
12021		0
12022	},
12023};
12024
12025static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
12026	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
12027	{
12028		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12029		.name = "Master Playback Switch",
12030		.subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
12031		.info = snd_ctl_boolean_mono_info,
12032		.get = alc262_hp_master_sw_get,
12033		.put = alc262_hp_master_sw_put,
12034	},
12035	{
12036		.iface = NID_MAPPING,
12037		.name = "Master Playback Switch",
12038		.private_value = 0x1b,
12039	},
12040	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12041	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12042	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12043	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12044	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12045	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12046	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12047	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12048	{ } /* end */
12049};
12050
12051static void alc262_lenovo_3000_setup(struct hda_codec *codec)
12052{
12053	struct alc_spec *spec = codec->spec;
12054
12055	spec->autocfg.hp_pins[0] = 0x1b;
12056	spec->autocfg.speaker_pins[0] = 0x14;
12057	spec->autocfg.speaker_pins[1] = 0x16;
12058	spec->automute = 1;
12059	spec->automute_mode = ALC_AUTOMUTE_AMP;
12060}
12061
12062static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
12063	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
12064	{
12065		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12066		.name = "Master Playback Switch",
12067		.subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
12068		.info = snd_ctl_boolean_mono_info,
12069		.get = alc262_hp_master_sw_get,
12070		.put = alc262_hp_master_sw_put,
12071	},
12072	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12073	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12074	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12075	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12076	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12077	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12078	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12079	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12080	{ } /* end */
12081};
12082
12083static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
12084	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
12085	ALC262_HIPPO_MASTER_SWITCH,
12086	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12087	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12088	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12089	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12090	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12091	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
12092	{ } /* end */
12093};
12094
12095/* additional init verbs for Benq laptops */
12096static const struct hda_verb alc262_EAPD_verbs[] = {
12097	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12098	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
12099	{}
12100};
12101
12102static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
12103	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12104	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12105
12106	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12107	{0x20, AC_VERB_SET_PROC_COEF,  0x3050},
12108	{}
12109};
12110
12111/* Samsung Q1 Ultra Vista model setup */
12112static const struct snd_kcontrol_new alc262_ultra_mixer[] = {
12113	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
12114	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
12115	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12116	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12117	HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
12118	HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
12119	{ } /* end */
12120};
12121
12122static const struct hda_verb alc262_ultra_verbs[] = {
12123	/* output mixer */
12124	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12125	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12126	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12127	/* speaker */
12128	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12129	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12130	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12131	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12132	/* HP */
12133	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12134	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12135	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12136	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12137	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12138	/* internal mic */
12139	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12140	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12141	/* ADC, choose mic */
12142	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12143	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12144	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12145	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12146	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12147	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12148	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12149	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12150	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12151	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
12152	{}
12153};
12154
12155/* mute/unmute internal speaker according to the hp jack and mute state */
12156static void alc262_ultra_automute(struct hda_codec *codec)
12157{
12158	struct alc_spec *spec = codec->spec;
12159	unsigned int mute;
12160
12161	mute = 0;
12162	/* auto-mute only when HP is used as HP */
12163	if (!spec->cur_mux[0]) {
12164		spec->jack_present = snd_hda_jack_detect(codec, 0x15);
12165		if (spec->jack_present)
12166			mute = HDA_AMP_MUTE;
12167	}
12168	/* mute/unmute internal speaker */
12169	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12170				 HDA_AMP_MUTE, mute);
12171	/* mute/unmute HP */
12172	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12173				 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
12174}
12175
12176/* unsolicited event for HP jack sensing */
12177static void alc262_ultra_unsol_event(struct hda_codec *codec,
12178				       unsigned int res)
12179{
12180	if ((res >> 26) != ALC880_HP_EVENT)
12181		return;
12182	alc262_ultra_automute(codec);
12183}
12184
12185static const struct hda_input_mux alc262_ultra_capture_source = {
12186	.num_items = 2,
12187	.items = {
12188		{ "Mic", 0x1 },
12189		{ "Headphone", 0x7 },
12190	},
12191};
12192
12193static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12194				     struct snd_ctl_elem_value *ucontrol)
12195{
12196	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12197	struct alc_spec *spec = codec->spec;
12198	int ret;
12199
12200	ret = alc_mux_enum_put(kcontrol, ucontrol);
12201	if (!ret)
12202		return 0;
12203	/* reprogram the HP pin as mic or HP according to the input source */
12204	snd_hda_codec_write_cache(codec, 0x15, 0,
12205				  AC_VERB_SET_PIN_WIDGET_CONTROL,
12206				  spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12207	alc262_ultra_automute(codec); /* mute/unmute HP */
12208	return ret;
12209}
12210
12211static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
12212	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12213	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12214	{
12215		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12216		.name = "Capture Source",
12217		.info = alc_mux_enum_info,
12218		.get = alc_mux_enum_get,
12219		.put = alc262_ultra_mux_enum_put,
12220	},
12221	{
12222		.iface = NID_MAPPING,
12223		.name = "Capture Source",
12224		.private_value = 0x15,
12225	},
12226	{ } /* end */
12227};
12228
12229/* We use two mixers depending on the output pin; 0x16 is a mono output
12230 * and thus it's bound with a different mixer.
12231 * This function returns which mixer amp should be used.
12232 */
12233static int alc262_check_volbit(hda_nid_t nid)
12234{
12235	if (!nid)
12236		return 0;
12237	else if (nid == 0x16)
12238		return 2;
12239	else
12240		return 1;
12241}
12242
12243static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
12244				  const char *pfx, int *vbits, int idx)
12245{
12246	unsigned long val;
12247	int vbit;
12248
12249	vbit = alc262_check_volbit(nid);
12250	if (!vbit)
12251		return 0;
12252	if (*vbits & vbit) /* a volume control for this mixer already there */
12253		return 0;
12254	*vbits |= vbit;
12255	if (vbit == 2)
12256		val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12257	else
12258		val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
12259	return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
12260}
12261
12262static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
12263				 const char *pfx, int idx)
12264{
12265	unsigned long val;
12266
12267	if (!nid)
12268		return 0;
12269	if (nid == 0x16)
12270		val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12271	else
12272		val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
12273	return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
12274}
12275
12276/* add playback controls from the parsed DAC table */
12277static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12278					     const struct auto_pin_cfg *cfg)
12279{
12280	const char *pfx;
12281	int vbits;
12282	int i, err;
12283
12284	spec->multiout.num_dacs = 1;	/* only use one dac */
12285	spec->multiout.dac_nids = spec->private_dac_nids;
12286	spec->private_dac_nids[0] = 2;
12287
12288	pfx = alc_get_line_out_pfx(spec, true);
12289	if (!pfx)
12290		pfx = "Front";
12291	for (i = 0; i < 2; i++) {
12292		err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12293		if (err < 0)
12294			return err;
12295		if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12296			err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12297						    "Speaker", i);
12298			if (err < 0)
12299				return err;
12300		}
12301		if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12302			err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12303						    "Headphone", i);
12304			if (err < 0)
12305				return err;
12306		}
12307	}
12308
12309	vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12310		alc262_check_volbit(cfg->speaker_pins[0]) |
12311		alc262_check_volbit(cfg->hp_pins[0]);
12312	if (vbits == 1 || vbits == 2)
12313		pfx = "Master"; /* only one mixer is used */
12314	vbits = 0;
12315	for (i = 0; i < 2; i++) {
12316		err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12317					     &vbits, i);
12318		if (err < 0)
12319			return err;
12320		if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12321			err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12322						     "Speaker", &vbits, i);
12323			if (err < 0)
12324				return err;
12325		}
12326		if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12327			err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12328						     "Headphone", &vbits, i);
12329			if (err < 0)
12330				return err;
12331		}
12332	}
12333	return 0;
12334}
12335
12336#define alc262_auto_create_input_ctls \
12337	alc882_auto_create_input_ctls
12338
12339/*
12340 * generic initialization of ADC, input mixers and output mixers
12341 */
12342static const struct hda_verb alc262_volume_init_verbs[] = {
12343	/*
12344	 * Unmute ADC0-2 and set the default input to mic-in
12345	 */
12346	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12347	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12348	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12349	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12350	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12351	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12352
12353	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12354	 * mixer widget
12355	 * Note: PASD motherboards uses the Line In 2 as the input for
12356	 * front panel mic (mic 2)
12357	 */
12358	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12359	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12360	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12361	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12362	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12363	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12364
12365	/*
12366	 * Set up output mixers (0x0c - 0x0f)
12367	 */
12368	/* set vol=0 to output mixers */
12369	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12370	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12371	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12372
12373	/* set up input amps for analog loopback */
12374	/* Amp Indices: DAC = 0, mixer = 1 */
12375	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12376	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12377	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12378	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12379	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12380	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12381
12382	/* FIXME: use matrix-type input source selection */
12383	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12384	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12385	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12386	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12387	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12388	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12389	/* Input mixer2 */
12390	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12391	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12392	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12393	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12394	/* Input mixer3 */
12395	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12396	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12397	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12398	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12399
12400	{ }
12401};
12402
12403static const struct hda_verb alc262_HP_BPC_init_verbs[] = {
12404	/*
12405	 * Unmute ADC0-2 and set the default input to mic-in
12406	 */
12407	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12408	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12409	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12410	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12411	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12412	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12413
12414	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12415	 * mixer widget
12416	 * Note: PASD motherboards uses the Line In 2 as the input for
12417	 * front panel mic (mic 2)
12418	 */
12419	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12420	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12421	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12422	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12423	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12424	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12425	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12426        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12427
12428	/*
12429	 * Set up output mixers (0x0c - 0x0e)
12430	 */
12431	/* set vol=0 to output mixers */
12432	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12433	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12434	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12435
12436	/* set up input amps for analog loopback */
12437	/* Amp Indices: DAC = 0, mixer = 1 */
12438	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12439	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12440	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12441	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12442	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12443	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12444
12445	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12446	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12447	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12448
12449	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12450	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12451
12452	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12453	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12454
12455	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12456	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12457        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12458	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12459	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12460
12461	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12462	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12463        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12464	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12465	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12466	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12467
12468
12469	/* FIXME: use matrix-type input source selection */
12470	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12471	/* Input mixer1: only unmute Mic */
12472	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12473	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12474	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12475	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12476	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12477	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12478	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12479	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12480	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12481	/* Input mixer2 */
12482	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12483	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12484	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12485	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12486	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12487	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12488	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12489	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12490	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12491	/* Input mixer3 */
12492	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12493	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12494	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12495	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12496	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12497	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12498	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12499	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12500	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12501
12502	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12503
12504	{ }
12505};
12506
12507static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12508	/*
12509	 * Unmute ADC0-2 and set the default input to mic-in
12510	 */
12511	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12512	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12513	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12514	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12515	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12516	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12517
12518	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12519	 * mixer widget
12520	 * Note: PASD motherboards uses the Line In 2 as the input for front
12521	 * panel mic (mic 2)
12522	 */
12523	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12524	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12525	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12526	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12527	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12528	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12529	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12530	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12531	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12532	/*
12533	 * Set up output mixers (0x0c - 0x0e)
12534	 */
12535	/* set vol=0 to output mixers */
12536	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12537	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12538	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12539
12540	/* set up input amps for analog loopback */
12541	/* Amp Indices: DAC = 0, mixer = 1 */
12542	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12543	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12544	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12545	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12546	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12547	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12548
12549
12550	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },	/* HP */
12551	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Mono */
12552	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* rear MIC */
12553	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* Line in */
12554	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* Front MIC */
12555	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Line out */
12556	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* CD in */
12557
12558	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12559	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12560
12561	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12562	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12563
12564	/* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12565	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12566	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12567	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12568	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12569	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12570
12571	/* FIXME: use matrix-type input source selection */
12572	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12573	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12574	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12575	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12576	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12577	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12578	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12579        /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
12580	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12581	/* Input mixer2 */
12582	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12583	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12584	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12585	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12586	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12587        /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12588	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12589	/* Input mixer3 */
12590	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12591	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12592	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12593	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12594	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12595        /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12596	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12597
12598	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12599
12600	{ }
12601};
12602
12603static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12604
12605	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Front Speaker */
12606	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12607	{0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12608
12609	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* MIC jack */
12610	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* Front MIC */
12611	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12612	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12613
12614	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },	/* HP  jack */
12615	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12616	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12617	{}
12618};
12619
12620/*
12621 * Pin config fixes
12622 */
12623enum {
12624	PINFIX_FSC_H270,
12625	PINFIX_HP_Z200,
12626};
12627
12628static const struct alc_fixup alc262_fixups[] = {
12629	[PINFIX_FSC_H270] = {
12630		.type = ALC_FIXUP_PINS,
12631		.v.pins = (const struct alc_pincfg[]) {
12632			{ 0x14, 0x99130110 }, /* speaker */
12633			{ 0x15, 0x0221142f }, /* front HP */
12634			{ 0x1b, 0x0121141f }, /* rear HP */
12635			{ }
12636		}
12637	},
12638	[PINFIX_HP_Z200] = {
12639		.type = ALC_FIXUP_PINS,
12640		.v.pins = (const struct alc_pincfg[]) {
12641			{ 0x16, 0x99130120 }, /* internal speaker */
12642			{ }
12643		}
12644	},
12645};
12646
12647static const struct snd_pci_quirk alc262_fixup_tbl[] = {
12648	SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", PINFIX_HP_Z200),
12649	SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12650	{}
12651};
12652
12653
12654#ifdef CONFIG_SND_HDA_POWER_SAVE
12655#define alc262_loopbacks	alc880_loopbacks
12656#endif
12657
12658/* pcm configuration: identical with ALC880 */
12659#define alc262_pcm_analog_playback	alc880_pcm_analog_playback
12660#define alc262_pcm_analog_capture	alc880_pcm_analog_capture
12661#define alc262_pcm_digital_playback	alc880_pcm_digital_playback
12662#define alc262_pcm_digital_capture	alc880_pcm_digital_capture
12663
12664/*
12665 * BIOS auto configuration
12666 */
12667static int alc262_parse_auto_config(struct hda_codec *codec)
12668{
12669	struct alc_spec *spec = codec->spec;
12670	int err;
12671	static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12672
12673	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12674					   alc262_ignore);
12675	if (err < 0)
12676		return err;
12677	if (!spec->autocfg.line_outs) {
12678		if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12679			spec->multiout.max_channels = 2;
12680			spec->no_analog = 1;
12681			goto dig_only;
12682		}
12683		return 0; /* can't find valid BIOS pin config */
12684	}
12685	err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12686	if (err < 0)
12687		return err;
12688	err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
12689	if (err < 0)
12690		return err;
12691
12692	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12693
12694 dig_only:
12695	alc_auto_parse_digital(codec);
12696
12697	if (spec->kctls.list)
12698		add_mixer(spec, spec->kctls.list);
12699
12700	add_verb(spec, alc262_volume_init_verbs);
12701	spec->num_mux_defs = 1;
12702	spec->input_mux = &spec->private_imux[0];
12703
12704	err = alc_auto_add_mic_boost(codec);
12705	if (err < 0)
12706		return err;
12707
12708	alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
12709
12710	return 1;
12711}
12712
12713#define alc262_auto_init_multi_out	alc882_auto_init_multi_out
12714#define alc262_auto_init_hp_out		alc882_auto_init_hp_out
12715#define alc262_auto_init_analog_input	alc882_auto_init_analog_input
12716#define alc262_auto_init_input_src	alc882_auto_init_input_src
12717
12718
12719/* init callback for auto-configuration model -- overriding the default init */
12720static void alc262_auto_init(struct hda_codec *codec)
12721{
12722	struct alc_spec *spec = codec->spec;
12723	alc262_auto_init_multi_out(codec);
12724	alc262_auto_init_hp_out(codec);
12725	alc262_auto_init_analog_input(codec);
12726	alc262_auto_init_input_src(codec);
12727	alc_auto_init_digital(codec);
12728	if (spec->unsol_event)
12729		alc_inithook(codec);
12730}
12731
12732/*
12733 * configuration and preset
12734 */
12735static const char * const alc262_models[ALC262_MODEL_LAST] = {
12736	[ALC262_BASIC]		= "basic",
12737	[ALC262_HIPPO]		= "hippo",
12738	[ALC262_HIPPO_1]	= "hippo_1",
12739	[ALC262_FUJITSU]	= "fujitsu",
12740	[ALC262_HP_BPC]		= "hp-bpc",
12741	[ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
12742	[ALC262_HP_TC_T5735]	= "hp-tc-t5735",
12743	[ALC262_HP_RP5700]	= "hp-rp5700",
12744	[ALC262_BENQ_ED8]	= "benq",
12745	[ALC262_BENQ_T31]	= "benq-t31",
12746	[ALC262_SONY_ASSAMD]	= "sony-assamd",
12747	[ALC262_TOSHIBA_S06]	= "toshiba-s06",
12748	[ALC262_TOSHIBA_RX1]	= "toshiba-rx1",
12749	[ALC262_ULTRA]		= "ultra",
12750	[ALC262_LENOVO_3000]	= "lenovo-3000",
12751	[ALC262_NEC]		= "nec",
12752	[ALC262_TYAN]		= "tyan",
12753	[ALC262_AUTO]		= "auto",
12754};
12755
12756static const struct snd_pci_quirk alc262_cfg_tbl[] = {
12757	SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
12758	SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
12759	SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12760			   ALC262_HP_BPC),
12761	SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12762			   ALC262_HP_BPC),
12763	SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12764			   ALC262_HP_BPC),
12765	SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200",
12766			   ALC262_AUTO),
12767	SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12768			   ALC262_HP_BPC),
12769	SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
12770	SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
12771	SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
12772	SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
12773	SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
12774	SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
12775	SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
12776	SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
12777	SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12778	SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12779	SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
12780	SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12781		      ALC262_HP_TC_T5735),
12782	SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
12783	SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12784	SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
12785	SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12786	SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
12787	SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
12788	SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12789	SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
12790#if 0 /* disable the quirk since model=auto works better in recent versions */
12791	SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12792			   ALC262_SONY_ASSAMD),
12793#endif
12794	SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
12795		      ALC262_TOSHIBA_RX1),
12796	SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
12797	SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
12798	SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
12799	SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
12800	SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12801			   ALC262_ULTRA),
12802	SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
12803	SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
12804	SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12805	SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12806	SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
12807	{}
12808};
12809
12810static const struct alc_config_preset alc262_presets[] = {
12811	[ALC262_BASIC] = {
12812		.mixers = { alc262_base_mixer },
12813		.init_verbs = { alc262_init_verbs },
12814		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12815		.dac_nids = alc262_dac_nids,
12816		.hp_nid = 0x03,
12817		.num_channel_mode = ARRAY_SIZE(alc262_modes),
12818		.channel_mode = alc262_modes,
12819		.input_mux = &alc262_capture_source,
12820	},
12821	[ALC262_HIPPO] = {
12822		.mixers = { alc262_hippo_mixer },
12823		.init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
12824		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12825		.dac_nids = alc262_dac_nids,
12826		.hp_nid = 0x03,
12827		.dig_out_nid = ALC262_DIGOUT_NID,
12828		.num_channel_mode = ARRAY_SIZE(alc262_modes),
12829		.channel_mode = alc262_modes,
12830		.input_mux = &alc262_capture_source,
12831		.unsol_event = alc_sku_unsol_event,
12832		.setup = alc262_hippo_setup,
12833		.init_hook = alc_inithook,
12834	},
12835	[ALC262_HIPPO_1] = {
12836		.mixers = { alc262_hippo1_mixer },
12837		.init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12838		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12839		.dac_nids = alc262_dac_nids,
12840		.hp_nid = 0x02,
12841		.dig_out_nid = ALC262_DIGOUT_NID,
12842		.num_channel_mode = ARRAY_SIZE(alc262_modes),
12843		.channel_mode = alc262_modes,
12844		.input_mux = &alc262_capture_source,
12845		.unsol_event = alc_sku_unsol_event,
12846		.setup = alc262_hippo1_setup,
12847		.init_hook = alc_inithook,
12848	},
12849	[ALC262_FUJITSU] = {
12850		.mixers = { alc262_fujitsu_mixer },
12851		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12852				alc262_fujitsu_unsol_verbs },
12853		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12854		.dac_nids = alc262_dac_nids,
12855		.hp_nid = 0x03,
12856		.dig_out_nid = ALC262_DIGOUT_NID,
12857		.num_channel_mode = ARRAY_SIZE(alc262_modes),
12858		.channel_mode = alc262_modes,
12859		.input_mux = &alc262_fujitsu_capture_source,
12860		.unsol_event = alc_sku_unsol_event,
12861		.setup = alc262_fujitsu_setup,
12862		.init_hook = alc_inithook,
12863	},
12864	[ALC262_HP_BPC] = {
12865		.mixers = { alc262_HP_BPC_mixer },
12866		.init_verbs = { alc262_HP_BPC_init_verbs },
12867		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12868		.dac_nids = alc262_dac_nids,
12869		.hp_nid = 0x03,
12870		.num_channel_mode = ARRAY_SIZE(alc262_modes),
12871		.channel_mode = alc262_modes,
12872		.input_mux = &alc262_HP_capture_source,
12873		.unsol_event = alc_sku_unsol_event,
12874		.setup = alc262_hp_bpc_setup,
12875		.init_hook = alc_inithook,
12876	},
12877	[ALC262_HP_BPC_D7000_WF] = {
12878		.mixers = { alc262_HP_BPC_WildWest_mixer },
12879		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12880		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12881		.dac_nids = alc262_dac_nids,
12882		.hp_nid = 0x03,
12883		.num_channel_mode = ARRAY_SIZE(alc262_modes),
12884		.channel_mode = alc262_modes,
12885		.input_mux = &alc262_HP_D7000_capture_source,
12886		.unsol_event = alc_sku_unsol_event,
12887		.setup = alc262_hp_wildwest_setup,
12888		.init_hook = alc_inithook,
12889	},
12890	[ALC262_HP_BPC_D7000_WL] = {
12891		.mixers = { alc262_HP_BPC_WildWest_mixer,
12892			    alc262_HP_BPC_WildWest_option_mixer },
12893		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12894		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12895		.dac_nids = alc262_dac_nids,
12896		.hp_nid = 0x03,
12897		.num_channel_mode = ARRAY_SIZE(alc262_modes),
12898		.channel_mode = alc262_modes,
12899		.input_mux = &alc262_HP_D7000_capture_source,
12900		.unsol_event = alc_sku_unsol_event,
12901		.setup = alc262_hp_wildwest_setup,
12902		.init_hook = alc_inithook,
12903	},
12904	[ALC262_HP_TC_T5735] = {
12905		.mixers = { alc262_hp_t5735_mixer },
12906		.init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12907		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12908		.dac_nids = alc262_dac_nids,
12909		.hp_nid = 0x03,
12910		.num_channel_mode = ARRAY_SIZE(alc262_modes),
12911		.channel_mode = alc262_modes,
12912		.input_mux = &alc262_capture_source,
12913		.unsol_event = alc_sku_unsol_event,
12914		.setup = alc262_hp_t5735_setup,
12915		.init_hook = alc_inithook,
12916	},
12917	[ALC262_HP_RP5700] = {
12918		.mixers = { alc262_hp_rp5700_mixer },
12919		.init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12920		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12921		.dac_nids = alc262_dac_nids,
12922		.num_channel_mode = ARRAY_SIZE(alc262_modes),
12923		.channel_mode = alc262_modes,
12924		.input_mux = &alc262_hp_rp5700_capture_source,
12925        },
12926	[ALC262_BENQ_ED8] = {
12927		.mixers = { alc262_base_mixer },
12928		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12929		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12930		.dac_nids = alc262_dac_nids,
12931		.hp_nid = 0x03,
12932		.num_channel_mode = ARRAY_SIZE(alc262_modes),
12933		.channel_mode = alc262_modes,
12934		.input_mux = &alc262_capture_source,
12935	},
12936	[ALC262_SONY_ASSAMD] = {
12937		.mixers = { alc262_sony_mixer },
12938		.init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12939		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12940		.dac_nids = alc262_dac_nids,
12941		.hp_nid = 0x02,
12942		.num_channel_mode = ARRAY_SIZE(alc262_modes),
12943		.channel_mode = alc262_modes,
12944		.input_mux = &alc262_capture_source,
12945		.unsol_event = alc_sku_unsol_event,
12946		.setup = alc262_hippo_setup,
12947		.init_hook = alc_inithook,
12948	},
12949	[ALC262_BENQ_T31] = {
12950		.mixers = { alc262_benq_t31_mixer },
12951		.init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12952				alc_hp15_unsol_verbs },
12953		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12954		.dac_nids = alc262_dac_nids,
12955		.hp_nid = 0x03,
12956		.num_channel_mode = ARRAY_SIZE(alc262_modes),
12957		.channel_mode = alc262_modes,
12958		.input_mux = &alc262_capture_source,
12959		.unsol_event = alc_sku_unsol_event,
12960		.setup = alc262_hippo_setup,
12961		.init_hook = alc_inithook,
12962	},
12963	[ALC262_ULTRA] = {
12964		.mixers = { alc262_ultra_mixer },
12965		.cap_mixer = alc262_ultra_capture_mixer,
12966		.init_verbs = { alc262_ultra_verbs },
12967		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12968		.dac_nids = alc262_dac_nids,
12969		.num_channel_mode = ARRAY_SIZE(alc262_modes),
12970		.channel_mode = alc262_modes,
12971		.input_mux = &alc262_ultra_capture_source,
12972		.adc_nids = alc262_adc_nids, /* ADC0 */
12973		.capsrc_nids = alc262_capsrc_nids,
12974		.num_adc_nids = 1, /* single ADC */
12975		.unsol_event = alc262_ultra_unsol_event,
12976		.init_hook = alc262_ultra_automute,
12977	},
12978	[ALC262_LENOVO_3000] = {
12979		.mixers = { alc262_lenovo_3000_mixer },
12980		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12981				alc262_lenovo_3000_unsol_verbs,
12982				alc262_lenovo_3000_init_verbs },
12983		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12984		.dac_nids = alc262_dac_nids,
12985		.hp_nid = 0x03,
12986		.dig_out_nid = ALC262_DIGOUT_NID,
12987		.num_channel_mode = ARRAY_SIZE(alc262_modes),
12988		.channel_mode = alc262_modes,
12989		.input_mux = &alc262_fujitsu_capture_source,
12990		.unsol_event = alc_sku_unsol_event,
12991		.setup = alc262_lenovo_3000_setup,
12992		.init_hook = alc_inithook,
12993	},
12994	[ALC262_NEC] = {
12995		.mixers = { alc262_nec_mixer },
12996		.init_verbs = { alc262_nec_verbs },
12997		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12998		.dac_nids = alc262_dac_nids,
12999		.hp_nid = 0x03,
13000		.num_channel_mode = ARRAY_SIZE(alc262_modes),
13001		.channel_mode = alc262_modes,
13002		.input_mux = &alc262_capture_source,
13003	},
13004	[ALC262_TOSHIBA_S06] = {
13005		.mixers = { alc262_toshiba_s06_mixer },
13006		.init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
13007							alc262_eapd_verbs },
13008		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
13009		.capsrc_nids = alc262_dmic_capsrc_nids,
13010		.dac_nids = alc262_dac_nids,
13011		.adc_nids = alc262_dmic_adc_nids, /* ADC0 */
13012		.num_adc_nids = 1, /* single ADC */
13013		.dig_out_nid = ALC262_DIGOUT_NID,
13014		.num_channel_mode = ARRAY_SIZE(alc262_modes),
13015		.channel_mode = alc262_modes,
13016		.unsol_event = alc_sku_unsol_event,
13017		.setup = alc262_toshiba_s06_setup,
13018		.init_hook = alc_inithook,
13019	},
13020	[ALC262_TOSHIBA_RX1] = {
13021		.mixers = { alc262_toshiba_rx1_mixer },
13022		.init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
13023		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
13024		.dac_nids = alc262_dac_nids,
13025		.hp_nid = 0x03,
13026		.num_channel_mode = ARRAY_SIZE(alc262_modes),
13027		.channel_mode = alc262_modes,
13028		.input_mux = &alc262_capture_source,
13029		.unsol_event = alc_sku_unsol_event,
13030		.setup = alc262_hippo_setup,
13031		.init_hook = alc_inithook,
13032	},
13033	[ALC262_TYAN] = {
13034		.mixers = { alc262_tyan_mixer },
13035		.init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
13036		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
13037		.dac_nids = alc262_dac_nids,
13038		.hp_nid = 0x02,
13039		.dig_out_nid = ALC262_DIGOUT_NID,
13040		.num_channel_mode = ARRAY_SIZE(alc262_modes),
13041		.channel_mode = alc262_modes,
13042		.input_mux = &alc262_capture_source,
13043		.unsol_event = alc_sku_unsol_event,
13044		.setup = alc262_tyan_setup,
13045		.init_hook = alc_hp_automute,
13046	},
13047};
13048
13049static int patch_alc262(struct hda_codec *codec)
13050{
13051	struct alc_spec *spec;
13052	int board_config;
13053	int err;
13054
13055	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13056	if (spec == NULL)
13057		return -ENOMEM;
13058
13059	codec->spec = spec;
13060#if 0
13061	/* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
13062	 * under-run
13063	 */
13064	{
13065	int tmp;
13066	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
13067	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
13068	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
13069	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
13070	}
13071#endif
13072	alc_auto_parse_customize_define(codec);
13073
13074	alc_fix_pll_init(codec, 0x20, 0x0a, 10);
13075
13076	board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
13077						  alc262_models,
13078						  alc262_cfg_tbl);
13079
13080	if (board_config < 0) {
13081		printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13082		       codec->chip_name);
13083		board_config = ALC262_AUTO;
13084	}
13085
13086	if (board_config == ALC262_AUTO) {
13087		alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
13088		alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
13089	}
13090
13091	if (board_config == ALC262_AUTO) {
13092		/* automatic parse from the BIOS config */
13093		err = alc262_parse_auto_config(codec);
13094		if (err < 0) {
13095			alc_free(codec);
13096			return err;
13097		} else if (!err) {
13098			printk(KERN_INFO
13099			       "hda_codec: Cannot set up configuration "
13100			       "from BIOS.  Using base mode...\n");
13101			board_config = ALC262_BASIC;
13102		}
13103	}
13104
13105	if (!spec->no_analog && has_cdefine_beep(codec)) {
13106		err = snd_hda_attach_beep_device(codec, 0x1);
13107		if (err < 0) {
13108			alc_free(codec);
13109			return err;
13110		}
13111	}
13112
13113	if (board_config != ALC262_AUTO)
13114		setup_preset(codec, &alc262_presets[board_config]);
13115
13116	spec->stream_analog_playback = &alc262_pcm_analog_playback;
13117	spec->stream_analog_capture = &alc262_pcm_analog_capture;
13118
13119	spec->stream_digital_playback = &alc262_pcm_digital_playback;
13120	spec->stream_digital_capture = &alc262_pcm_digital_capture;
13121
13122	if (!spec->adc_nids && spec->input_mux) {
13123		int i;
13124		/* check whether the digital-mic has to be supported */
13125		for (i = 0; i < spec->input_mux->num_items; i++) {
13126			if (spec->input_mux->items[i].index >= 9)
13127				break;
13128		}
13129		if (i < spec->input_mux->num_items) {
13130			/* use only ADC0 */
13131			spec->adc_nids = alc262_dmic_adc_nids;
13132			spec->num_adc_nids = 1;
13133			spec->capsrc_nids = alc262_dmic_capsrc_nids;
13134		} else {
13135			/* all analog inputs */
13136			/* check whether NID 0x07 is valid */
13137			unsigned int wcap = get_wcaps(codec, 0x07);
13138
13139			/* get type */
13140			wcap = get_wcaps_type(wcap);
13141			if (wcap != AC_WID_AUD_IN) {
13142				spec->adc_nids = alc262_adc_nids_alt;
13143				spec->num_adc_nids =
13144					ARRAY_SIZE(alc262_adc_nids_alt);
13145				spec->capsrc_nids = alc262_capsrc_nids_alt;
13146			} else {
13147				spec->adc_nids = alc262_adc_nids;
13148				spec->num_adc_nids =
13149					ARRAY_SIZE(alc262_adc_nids);
13150				spec->capsrc_nids = alc262_capsrc_nids;
13151			}
13152		}
13153	}
13154	if (!spec->cap_mixer && !spec->no_analog)
13155		set_capture_mixer(codec);
13156	if (!spec->no_analog && has_cdefine_beep(codec))
13157		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
13158
13159	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
13160
13161	spec->vmaster_nid = 0x0c;
13162
13163	codec->patch_ops = alc_patch_ops;
13164	if (board_config == ALC262_AUTO)
13165		spec->init_hook = alc262_auto_init;
13166	spec->shutup = alc_eapd_shutup;
13167
13168	alc_init_jacks(codec);
13169#ifdef CONFIG_SND_HDA_POWER_SAVE
13170	if (!spec->loopback.amplist)
13171		spec->loopback.amplist = alc262_loopbacks;
13172#endif
13173
13174	return 0;
13175}
13176
13177/*
13178 *  ALC268 channel source setting (2 channel)
13179 */
13180#define ALC268_DIGOUT_NID	ALC880_DIGOUT_NID
13181#define alc268_modes		alc260_modes
13182
13183static const hda_nid_t alc268_dac_nids[2] = {
13184	/* front, hp */
13185	0x02, 0x03
13186};
13187
13188static const hda_nid_t alc268_adc_nids[2] = {
13189	/* ADC0-1 */
13190	0x08, 0x07
13191};
13192
13193static const hda_nid_t alc268_adc_nids_alt[1] = {
13194	/* ADC0 */
13195	0x08
13196};
13197
13198static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
13199
13200static const struct snd_kcontrol_new alc268_base_mixer[] = {
13201	/* output mixer control */
13202	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13203	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13204	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13205	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13206	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13207	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13208	HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13209	{ }
13210};
13211
13212static const struct snd_kcontrol_new alc268_toshiba_mixer[] = {
13213	/* output mixer control */
13214	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13215	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13216	ALC262_HIPPO_MASTER_SWITCH,
13217	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13218	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13219	HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13220	{ }
13221};
13222
13223/* bind Beep switches of both NID 0x0f and 0x10 */
13224static const struct hda_bind_ctls alc268_bind_beep_sw = {
13225	.ops = &snd_hda_bind_sw,
13226	.values = {
13227		HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
13228		HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
13229		0
13230	},
13231};
13232
13233static const struct snd_kcontrol_new alc268_beep_mixer[] = {
13234	HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
13235	HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
13236	{ }
13237};
13238
13239static const struct hda_verb alc268_eapd_verbs[] = {
13240	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13241	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13242	{ }
13243};
13244
13245/* Toshiba specific */
13246static const struct hda_verb alc268_toshiba_verbs[] = {
13247	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13248	{ } /* end */
13249};
13250
13251/* Acer specific */
13252/* bind volumes of both NID 0x02 and 0x03 */
13253static const struct hda_bind_ctls alc268_acer_bind_master_vol = {
13254	.ops = &snd_hda_bind_vol,
13255	.values = {
13256		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13257		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13258		0
13259	},
13260};
13261
13262static void alc268_acer_setup(struct hda_codec *codec)
13263{
13264	struct alc_spec *spec = codec->spec;
13265
13266	spec->autocfg.hp_pins[0] = 0x14;
13267	spec->autocfg.speaker_pins[0] = 0x15;
13268	spec->automute = 1;
13269	spec->automute_mode = ALC_AUTOMUTE_AMP;
13270}
13271
13272#define alc268_acer_master_sw_get	alc262_hp_master_sw_get
13273#define alc268_acer_master_sw_put	alc262_hp_master_sw_put
13274
13275static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13276	/* output mixer control */
13277	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13278	{
13279		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13280		.name = "Master Playback Switch",
13281		.subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
13282		.info = snd_ctl_boolean_mono_info,
13283		.get = alc268_acer_master_sw_get,
13284		.put = alc268_acer_master_sw_put,
13285	},
13286	HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13287	{ }
13288};
13289
13290static const struct snd_kcontrol_new alc268_acer_mixer[] = {
13291	/* output mixer control */
13292	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13293	{
13294		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13295		.name = "Master Playback Switch",
13296		.subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13297		.info = snd_ctl_boolean_mono_info,
13298		.get = alc268_acer_master_sw_get,
13299		.put = alc268_acer_master_sw_put,
13300	},
13301	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13302	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13303	HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13304	{ }
13305};
13306
13307static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13308	/* output mixer control */
13309	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13310	{
13311		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13312		.name = "Master Playback Switch",
13313		.subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13314		.info = snd_ctl_boolean_mono_info,
13315		.get = alc268_acer_master_sw_get,
13316		.put = alc268_acer_master_sw_put,
13317	},
13318	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13319	HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13320	{ }
13321};
13322
13323static const struct hda_verb alc268_acer_aspire_one_verbs[] = {
13324	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13325	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13326	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13327	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13328	{0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13329	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13330	{ }
13331};
13332
13333static const struct hda_verb alc268_acer_verbs[] = {
13334	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13335	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13336	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13337	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13338	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13339	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13340	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13341	{ }
13342};
13343
13344/* unsolicited event for HP jack sensing */
13345#define alc268_toshiba_setup		alc262_hippo_setup
13346
13347static void alc268_acer_lc_setup(struct hda_codec *codec)
13348{
13349	struct alc_spec *spec = codec->spec;
13350	spec->autocfg.hp_pins[0] = 0x15;
13351	spec->autocfg.speaker_pins[0] = 0x14;
13352	spec->automute = 1;
13353	spec->automute_mode = ALC_AUTOMUTE_AMP;
13354	spec->ext_mic.pin = 0x18;
13355	spec->ext_mic.mux_idx = 0;
13356	spec->int_mic.pin = 0x12;
13357	spec->int_mic.mux_idx = 6;
13358	spec->auto_mic = 1;
13359}
13360
13361static const struct snd_kcontrol_new alc268_dell_mixer[] = {
13362	/* output mixer control */
13363	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13364	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13365	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13366	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13367	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13368	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13369	{ }
13370};
13371
13372static const struct hda_verb alc268_dell_verbs[] = {
13373	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13374	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13375	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13376	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13377	{ }
13378};
13379
13380/* mute/unmute internal speaker according to the hp jack and mute state */
13381static void alc268_dell_setup(struct hda_codec *codec)
13382{
13383	struct alc_spec *spec = codec->spec;
13384
13385	spec->autocfg.hp_pins[0] = 0x15;
13386	spec->autocfg.speaker_pins[0] = 0x14;
13387	spec->ext_mic.pin = 0x18;
13388	spec->ext_mic.mux_idx = 0;
13389	spec->int_mic.pin = 0x19;
13390	spec->int_mic.mux_idx = 1;
13391	spec->auto_mic = 1;
13392	spec->automute = 1;
13393	spec->automute_mode = ALC_AUTOMUTE_PIN;
13394}
13395
13396static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13397	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13398	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13399	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13400	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13401	HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13402	HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
13403	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13404	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13405	{ }
13406};
13407
13408static const struct hda_verb alc267_quanta_il1_verbs[] = {
13409	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13410	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13411	{ }
13412};
13413
13414static void alc267_quanta_il1_setup(struct hda_codec *codec)
13415{
13416	struct alc_spec *spec = codec->spec;
13417	spec->autocfg.hp_pins[0] = 0x15;
13418	spec->autocfg.speaker_pins[0] = 0x14;
13419	spec->ext_mic.pin = 0x18;
13420	spec->ext_mic.mux_idx = 0;
13421	spec->int_mic.pin = 0x19;
13422	spec->int_mic.mux_idx = 1;
13423	spec->auto_mic = 1;
13424	spec->automute = 1;
13425	spec->automute_mode = ALC_AUTOMUTE_PIN;
13426}
13427
13428/*
13429 * generic initialization of ADC, input mixers and output mixers
13430 */
13431static const struct hda_verb alc268_base_init_verbs[] = {
13432	/* Unmute DAC0-1 and set vol = 0 */
13433	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13434	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13435
13436	/*
13437	 * Set up output mixers (0x0c - 0x0e)
13438	 */
13439	/* set vol=0 to output mixers */
13440	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13441        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13442
13443	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13444	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13445
13446	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13447	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13448	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13449	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13450	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13451	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13452	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13453	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13454
13455	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13456	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13457	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13458	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13459	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13460
13461	/* set PCBEEP vol = 0, mute connections */
13462	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13463	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13464	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13465
13466	/* Unmute Selector 23h,24h and set the default input to mic-in */
13467
13468	{0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13469	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13470	{0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13471	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13472
13473	{ }
13474};
13475
13476/*
13477 * generic initialization of ADC, input mixers and output mixers
13478 */
13479static const struct hda_verb alc268_volume_init_verbs[] = {
13480	/* set output DAC */
13481	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13482	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13483
13484	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13485	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13486	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13487	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13488	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13489
13490	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13491	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13492	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13493
13494	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13495	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13496
13497	/* set PCBEEP vol = 0, mute connections */
13498	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13499	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13500	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13501
13502	{ }
13503};
13504
13505static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13506	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13507	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13508	{ } /* end */
13509};
13510
13511static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13512	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13513	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13514	_DEFINE_CAPSRC(1),
13515	{ } /* end */
13516};
13517
13518static const struct snd_kcontrol_new alc268_capture_mixer[] = {
13519	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13520	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13521	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13522	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
13523	_DEFINE_CAPSRC(2),
13524	{ } /* end */
13525};
13526
13527static const struct hda_input_mux alc268_capture_source = {
13528	.num_items = 4,
13529	.items = {
13530		{ "Mic", 0x0 },
13531		{ "Front Mic", 0x1 },
13532		{ "Line", 0x2 },
13533		{ "CD", 0x3 },
13534	},
13535};
13536
13537static const struct hda_input_mux alc268_acer_capture_source = {
13538	.num_items = 3,
13539	.items = {
13540		{ "Mic", 0x0 },
13541		{ "Internal Mic", 0x1 },
13542		{ "Line", 0x2 },
13543	},
13544};
13545
13546static const struct hda_input_mux alc268_acer_dmic_capture_source = {
13547	.num_items = 3,
13548	.items = {
13549		{ "Mic", 0x0 },
13550		{ "Internal Mic", 0x6 },
13551		{ "Line", 0x2 },
13552	},
13553};
13554
13555#ifdef CONFIG_SND_DEBUG
13556static const struct snd_kcontrol_new alc268_test_mixer[] = {
13557	/* Volume widgets */
13558	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13559	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13560	HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13561	HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13562	HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13563	HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13564	HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13565	HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13566	HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13567	HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13568	HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13569	HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13570	HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
13571	/* The below appears problematic on some hardwares */
13572	/*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
13573	HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13574	HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13575	HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13576	HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13577
13578	/* Modes for retasking pin widgets */
13579	ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13580	ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13581	ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13582	ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13583
13584	/* Controls for GPIO pins, assuming they are configured as outputs */
13585	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13586	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13587	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13588	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13589
13590	/* Switches to allow the digital SPDIF output pin to be enabled.
13591	 * The ALC268 does not have an SPDIF input.
13592	 */
13593	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13594
13595	/* A switch allowing EAPD to be enabled.  Some laptops seem to use
13596	 * this output to turn on an external amplifier.
13597	 */
13598	ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13599	ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13600
13601	{ } /* end */
13602};
13603#endif
13604
13605/* create input playback/capture controls for the given pin */
13606static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13607				    const char *ctlname, int idx)
13608{
13609	hda_nid_t dac;
13610	int err;
13611
13612	switch (nid) {
13613	case 0x14:
13614	case 0x16:
13615		dac = 0x02;
13616		break;
13617	case 0x15:
13618	case 0x1a: /* ALC259/269 only */
13619	case 0x1b: /* ALC259/269 only */
13620	case 0x21: /* ALC269vb has this pin, too */
13621		dac = 0x03;
13622		break;
13623	default:
13624		snd_printd(KERN_WARNING "hda_codec: "
13625			   "ignoring pin 0x%x as unknown\n", nid);
13626		return 0;
13627	}
13628	if (spec->multiout.dac_nids[0] != dac &&
13629	    spec->multiout.dac_nids[1] != dac) {
13630		err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
13631				  HDA_COMPOSE_AMP_VAL(dac, 3, idx,
13632						      HDA_OUTPUT));
13633		if (err < 0)
13634			return err;
13635		spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
13636	}
13637
13638	if (nid != 0x16)
13639		err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13640			  HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
13641	else /* mono */
13642		err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13643			  HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
13644	if (err < 0)
13645		return err;
13646	return 0;
13647}
13648
13649/* add playback controls from the parsed DAC table */
13650static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13651					     const struct auto_pin_cfg *cfg)
13652{
13653	hda_nid_t nid;
13654	int err;
13655
13656	spec->multiout.dac_nids = spec->private_dac_nids;
13657
13658	nid = cfg->line_out_pins[0];
13659	if (nid) {
13660		const char *name;
13661		if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13662			name = "Speaker";
13663		else
13664			name = "Front";
13665		err = alc268_new_analog_output(spec, nid, name, 0);
13666		if (err < 0)
13667			return err;
13668	}
13669
13670	nid = cfg->speaker_pins[0];
13671	if (nid == 0x1d) {
13672		err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
13673				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13674		if (err < 0)
13675			return err;
13676	} else if (nid) {
13677		err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13678		if (err < 0)
13679			return err;
13680	}
13681	nid = cfg->hp_pins[0];
13682	if (nid) {
13683		err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13684		if (err < 0)
13685			return err;
13686	}
13687
13688	nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13689	if (nid == 0x16) {
13690		err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
13691				  HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
13692		if (err < 0)
13693			return err;
13694	}
13695	return 0;
13696}
13697
13698/* create playback/capture controls for input pins */
13699static int alc268_auto_create_input_ctls(struct hda_codec *codec,
13700						const struct auto_pin_cfg *cfg)
13701{
13702	return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
13703}
13704
13705static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13706					      hda_nid_t nid, int pin_type)
13707{
13708	int idx;
13709
13710	alc_set_pin_output(codec, nid, pin_type);
13711	if (nid == 0x14 || nid == 0x16)
13712		idx = 0;
13713	else
13714		idx = 1;
13715	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13716}
13717
13718static void alc268_auto_init_multi_out(struct hda_codec *codec)
13719{
13720	struct alc_spec *spec = codec->spec;
13721	int i;
13722
13723	for (i = 0; i < spec->autocfg.line_outs; i++) {
13724		hda_nid_t nid = spec->autocfg.line_out_pins[i];
13725		int pin_type = get_pin_type(spec->autocfg.line_out_type);
13726		alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13727	}
13728}
13729
13730static void alc268_auto_init_hp_out(struct hda_codec *codec)
13731{
13732	struct alc_spec *spec = codec->spec;
13733	hda_nid_t pin;
13734	int i;
13735
13736	for (i = 0; i < spec->autocfg.hp_outs; i++) {
13737		pin = spec->autocfg.hp_pins[i];
13738		alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
13739	}
13740	for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13741		pin = spec->autocfg.speaker_pins[i];
13742		alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
13743	}
13744	if (spec->autocfg.mono_out_pin)
13745		snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13746				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13747}
13748
13749static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13750{
13751	struct alc_spec *spec = codec->spec;
13752	hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13753	hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13754	hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13755	unsigned int	dac_vol1, dac_vol2;
13756
13757	if (line_nid == 0x1d || speaker_nid == 0x1d) {
13758		snd_hda_codec_write(codec, speaker_nid, 0,
13759				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13760		/* mute mixer inputs from 0x1d */
13761		snd_hda_codec_write(codec, 0x0f, 0,
13762				    AC_VERB_SET_AMP_GAIN_MUTE,
13763				    AMP_IN_UNMUTE(1));
13764		snd_hda_codec_write(codec, 0x10, 0,
13765				    AC_VERB_SET_AMP_GAIN_MUTE,
13766				    AMP_IN_UNMUTE(1));
13767	} else {
13768		/* unmute mixer inputs from 0x1d */
13769		snd_hda_codec_write(codec, 0x0f, 0,
13770				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13771		snd_hda_codec_write(codec, 0x10, 0,
13772				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13773	}
13774
13775	dac_vol1 = dac_vol2 = 0xb000 | 0x40;	/* set max volume  */
13776	if (line_nid == 0x14)
13777		dac_vol2 = AMP_OUT_ZERO;
13778	else if (line_nid == 0x15)
13779		dac_vol1 = AMP_OUT_ZERO;
13780	if (hp_nid == 0x14)
13781		dac_vol2 = AMP_OUT_ZERO;
13782	else if (hp_nid == 0x15)
13783		dac_vol1 = AMP_OUT_ZERO;
13784	if (line_nid != 0x16 || hp_nid != 0x16 ||
13785	    spec->autocfg.line_out_pins[1] != 0x16 ||
13786	    spec->autocfg.line_out_pins[2] != 0x16)
13787		dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13788
13789	snd_hda_codec_write(codec, 0x02, 0,
13790			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13791	snd_hda_codec_write(codec, 0x03, 0,
13792			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13793}
13794
13795/* pcm configuration: identical with ALC880 */
13796#define alc268_pcm_analog_playback	alc880_pcm_analog_playback
13797#define alc268_pcm_analog_capture	alc880_pcm_analog_capture
13798#define alc268_pcm_analog_alt_capture	alc880_pcm_analog_alt_capture
13799#define alc268_pcm_digital_playback	alc880_pcm_digital_playback
13800
13801/*
13802 * BIOS auto configuration
13803 */
13804static int alc268_parse_auto_config(struct hda_codec *codec)
13805{
13806	struct alc_spec *spec = codec->spec;
13807	int err;
13808	static const hda_nid_t alc268_ignore[] = { 0 };
13809
13810	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13811					   alc268_ignore);
13812	if (err < 0)
13813		return err;
13814	if (!spec->autocfg.line_outs) {
13815		if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13816			spec->multiout.max_channels = 2;
13817			spec->no_analog = 1;
13818			goto dig_only;
13819		}
13820		return 0; /* can't find valid BIOS pin config */
13821	}
13822	err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13823	if (err < 0)
13824		return err;
13825	err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
13826	if (err < 0)
13827		return err;
13828
13829	spec->multiout.max_channels = 2;
13830
13831 dig_only:
13832	/* digital only support output */
13833	alc_auto_parse_digital(codec);
13834	if (spec->kctls.list)
13835		add_mixer(spec, spec->kctls.list);
13836
13837	if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
13838		add_mixer(spec, alc268_beep_mixer);
13839
13840	add_verb(spec, alc268_volume_init_verbs);
13841	spec->num_mux_defs = 2;
13842	spec->input_mux = &spec->private_imux[0];
13843
13844	err = alc_auto_add_mic_boost(codec);
13845	if (err < 0)
13846		return err;
13847
13848	alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
13849
13850	return 1;
13851}
13852
13853#define alc268_auto_init_analog_input	alc882_auto_init_analog_input
13854#define alc268_auto_init_input_src	alc882_auto_init_input_src
13855
13856/* init callback for auto-configuration model -- overriding the default init */
13857static void alc268_auto_init(struct hda_codec *codec)
13858{
13859	struct alc_spec *spec = codec->spec;
13860	alc268_auto_init_multi_out(codec);
13861	alc268_auto_init_hp_out(codec);
13862	alc268_auto_init_mono_speaker_out(codec);
13863	alc268_auto_init_analog_input(codec);
13864	alc268_auto_init_input_src(codec);
13865	alc_auto_init_digital(codec);
13866	if (spec->unsol_event)
13867		alc_inithook(codec);
13868}
13869
13870/*
13871 * configuration and preset
13872 */
13873static const char * const alc268_models[ALC268_MODEL_LAST] = {
13874	[ALC267_QUANTA_IL1]	= "quanta-il1",
13875	[ALC268_3ST]		= "3stack",
13876	[ALC268_TOSHIBA]	= "toshiba",
13877	[ALC268_ACER]		= "acer",
13878	[ALC268_ACER_DMIC]	= "acer-dmic",
13879	[ALC268_ACER_ASPIRE_ONE]	= "acer-aspire",
13880	[ALC268_DELL]		= "dell",
13881	[ALC268_ZEPTO]		= "zepto",
13882#ifdef CONFIG_SND_DEBUG
13883	[ALC268_TEST]		= "test",
13884#endif
13885	[ALC268_AUTO]		= "auto",
13886};
13887
13888static const struct snd_pci_quirk alc268_cfg_tbl[] = {
13889	SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
13890	SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
13891	SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
13892	SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
13893	SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
13894	SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13895						ALC268_ACER_ASPIRE_ONE),
13896	SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
13897	SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron 910", ALC268_AUTO),
13898	SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13899			"Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
13900	/* almost compatible with toshiba but with optional digital outs;
13901	 * auto-probing seems working fine
13902	 */
13903	SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
13904			   ALC268_AUTO),
13905	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
13906	SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
13907	SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
13908	SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
13909	{}
13910};
13911
13912/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13913static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13914	SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13915	SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13916	SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13917			   ALC268_TOSHIBA),
13918	{}
13919};
13920
13921static const struct alc_config_preset alc268_presets[] = {
13922	[ALC267_QUANTA_IL1] = {
13923		.mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13924			    alc268_capture_nosrc_mixer },
13925		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13926				alc267_quanta_il1_verbs },
13927		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
13928		.dac_nids = alc268_dac_nids,
13929		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13930		.adc_nids = alc268_adc_nids_alt,
13931		.hp_nid = 0x03,
13932		.num_channel_mode = ARRAY_SIZE(alc268_modes),
13933		.channel_mode = alc268_modes,
13934		.unsol_event = alc_sku_unsol_event,
13935		.setup = alc267_quanta_il1_setup,
13936		.init_hook = alc_inithook,
13937	},
13938	[ALC268_3ST] = {
13939		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13940			    alc268_beep_mixer },
13941		.init_verbs = { alc268_base_init_verbs },
13942		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
13943		.dac_nids = alc268_dac_nids,
13944                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13945                .adc_nids = alc268_adc_nids_alt,
13946		.capsrc_nids = alc268_capsrc_nids,
13947		.hp_nid = 0x03,
13948		.dig_out_nid = ALC268_DIGOUT_NID,
13949		.num_channel_mode = ARRAY_SIZE(alc268_modes),
13950		.channel_mode = alc268_modes,
13951		.input_mux = &alc268_capture_source,
13952	},
13953	[ALC268_TOSHIBA] = {
13954		.mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
13955			    alc268_beep_mixer },
13956		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13957				alc268_toshiba_verbs },
13958		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
13959		.dac_nids = alc268_dac_nids,
13960		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13961		.adc_nids = alc268_adc_nids_alt,
13962		.capsrc_nids = alc268_capsrc_nids,
13963		.hp_nid = 0x03,
13964		.num_channel_mode = ARRAY_SIZE(alc268_modes),
13965		.channel_mode = alc268_modes,
13966		.input_mux = &alc268_capture_source,
13967		.unsol_event = alc_sku_unsol_event,
13968		.setup = alc268_toshiba_setup,
13969		.init_hook = alc_inithook,
13970	},
13971	[ALC268_ACER] = {
13972		.mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
13973			    alc268_beep_mixer },
13974		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13975				alc268_acer_verbs },
13976		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
13977		.dac_nids = alc268_dac_nids,
13978		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13979		.adc_nids = alc268_adc_nids_alt,
13980		.capsrc_nids = alc268_capsrc_nids,
13981		.hp_nid = 0x02,
13982		.num_channel_mode = ARRAY_SIZE(alc268_modes),
13983		.channel_mode = alc268_modes,
13984		.input_mux = &alc268_acer_capture_source,
13985		.unsol_event = alc_sku_unsol_event,
13986		.setup = alc268_acer_setup,
13987		.init_hook = alc_inithook,
13988	},
13989	[ALC268_ACER_DMIC] = {
13990		.mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13991			    alc268_beep_mixer },
13992		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13993				alc268_acer_verbs },
13994		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
13995		.dac_nids = alc268_dac_nids,
13996		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13997		.adc_nids = alc268_adc_nids_alt,
13998		.capsrc_nids = alc268_capsrc_nids,
13999		.hp_nid = 0x02,
14000		.num_channel_mode = ARRAY_SIZE(alc268_modes),
14001		.channel_mode = alc268_modes,
14002		.input_mux = &alc268_acer_dmic_capture_source,
14003		.unsol_event = alc_sku_unsol_event,
14004		.setup = alc268_acer_setup,
14005		.init_hook = alc_inithook,
14006	},
14007	[ALC268_ACER_ASPIRE_ONE] = {
14008		.mixers = { alc268_acer_aspire_one_mixer,
14009			    alc268_beep_mixer,
14010			    alc268_capture_nosrc_mixer },
14011		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
14012				alc268_acer_aspire_one_verbs },
14013		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
14014		.dac_nids = alc268_dac_nids,
14015		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
14016		.adc_nids = alc268_adc_nids_alt,
14017		.capsrc_nids = alc268_capsrc_nids,
14018		.hp_nid = 0x03,
14019		.num_channel_mode = ARRAY_SIZE(alc268_modes),
14020		.channel_mode = alc268_modes,
14021		.unsol_event = alc_sku_unsol_event,
14022		.setup = alc268_acer_lc_setup,
14023		.init_hook = alc_inithook,
14024	},
14025	[ALC268_DELL] = {
14026		.mixers = { alc268_dell_mixer, alc268_beep_mixer,
14027			    alc268_capture_nosrc_mixer },
14028		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
14029				alc268_dell_verbs },
14030		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
14031		.dac_nids = alc268_dac_nids,
14032		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
14033		.adc_nids = alc268_adc_nids_alt,
14034		.capsrc_nids = alc268_capsrc_nids,
14035		.hp_nid = 0x02,
14036		.num_channel_mode = ARRAY_SIZE(alc268_modes),
14037		.channel_mode = alc268_modes,
14038		.unsol_event = alc_sku_unsol_event,
14039		.setup = alc268_dell_setup,
14040		.init_hook = alc_inithook,
14041	},
14042	[ALC268_ZEPTO] = {
14043		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
14044			    alc268_beep_mixer },
14045		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
14046				alc268_toshiba_verbs },
14047		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
14048		.dac_nids = alc268_dac_nids,
14049		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
14050		.adc_nids = alc268_adc_nids_alt,
14051		.capsrc_nids = alc268_capsrc_nids,
14052		.hp_nid = 0x03,
14053		.dig_out_nid = ALC268_DIGOUT_NID,
14054		.num_channel_mode = ARRAY_SIZE(alc268_modes),
14055		.channel_mode = alc268_modes,
14056		.input_mux = &alc268_capture_source,
14057		.unsol_event = alc_sku_unsol_event,
14058		.setup = alc268_toshiba_setup,
14059		.init_hook = alc_inithook,
14060	},
14061#ifdef CONFIG_SND_DEBUG
14062	[ALC268_TEST] = {
14063		.mixers = { alc268_test_mixer, alc268_capture_mixer },
14064		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
14065				alc268_volume_init_verbs },
14066		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
14067		.dac_nids = alc268_dac_nids,
14068		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
14069		.adc_nids = alc268_adc_nids_alt,
14070		.capsrc_nids = alc268_capsrc_nids,
14071		.hp_nid = 0x03,
14072		.dig_out_nid = ALC268_DIGOUT_NID,
14073		.num_channel_mode = ARRAY_SIZE(alc268_modes),
14074		.channel_mode = alc268_modes,
14075		.input_mux = &alc268_capture_source,
14076	},
14077#endif
14078};
14079
14080static int patch_alc268(struct hda_codec *codec)
14081{
14082	struct alc_spec *spec;
14083	int board_config;
14084	int i, has_beep, err;
14085
14086	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14087	if (spec == NULL)
14088		return -ENOMEM;
14089
14090	codec->spec = spec;
14091
14092	board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
14093						  alc268_models,
14094						  alc268_cfg_tbl);
14095
14096	if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
14097		board_config = snd_hda_check_board_codec_sid_config(codec,
14098			ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
14099
14100	if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
14101		printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14102		       codec->chip_name);
14103		board_config = ALC268_AUTO;
14104	}
14105
14106	if (board_config == ALC268_AUTO) {
14107		/* automatic parse from the BIOS config */
14108		err = alc268_parse_auto_config(codec);
14109		if (err < 0) {
14110			alc_free(codec);
14111			return err;
14112		} else if (!err) {
14113			printk(KERN_INFO
14114			       "hda_codec: Cannot set up configuration "
14115			       "from BIOS.  Using base mode...\n");
14116			board_config = ALC268_3ST;
14117		}
14118	}
14119
14120	if (board_config != ALC268_AUTO)
14121		setup_preset(codec, &alc268_presets[board_config]);
14122
14123	spec->stream_analog_playback = &alc268_pcm_analog_playback;
14124	spec->stream_analog_capture = &alc268_pcm_analog_capture;
14125	spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
14126
14127	spec->stream_digital_playback = &alc268_pcm_digital_playback;
14128
14129	has_beep = 0;
14130	for (i = 0; i < spec->num_mixers; i++) {
14131		if (spec->mixers[i] == alc268_beep_mixer) {
14132			has_beep = 1;
14133			break;
14134		}
14135	}
14136
14137	if (has_beep) {
14138		err = snd_hda_attach_beep_device(codec, 0x1);
14139		if (err < 0) {
14140			alc_free(codec);
14141			return err;
14142		}
14143		if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
14144			/* override the amp caps for beep generator */
14145			snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
14146					  (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
14147					  (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
14148					  (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
14149					  (0 << AC_AMPCAP_MUTE_SHIFT));
14150	}
14151
14152	if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
14153		/* check whether NID 0x07 is valid */
14154		unsigned int wcap = get_wcaps(codec, 0x07);
14155
14156		spec->capsrc_nids = alc268_capsrc_nids;
14157		/* get type */
14158		wcap = get_wcaps_type(wcap);
14159		if (spec->auto_mic ||
14160		    wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
14161			spec->adc_nids = alc268_adc_nids_alt;
14162			spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
14163			if (spec->auto_mic)
14164				fixup_automic_adc(codec);
14165			if (spec->auto_mic || spec->input_mux->num_items == 1)
14166				add_mixer(spec, alc268_capture_nosrc_mixer);
14167			else
14168				add_mixer(spec, alc268_capture_alt_mixer);
14169		} else {
14170			spec->adc_nids = alc268_adc_nids;
14171			spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
14172			add_mixer(spec, alc268_capture_mixer);
14173		}
14174	}
14175
14176	spec->vmaster_nid = 0x02;
14177
14178	codec->patch_ops = alc_patch_ops;
14179	if (board_config == ALC268_AUTO)
14180		spec->init_hook = alc268_auto_init;
14181	spec->shutup = alc_eapd_shutup;
14182
14183	alc_init_jacks(codec);
14184
14185	return 0;
14186}
14187
14188/*
14189 *  ALC269 channel source setting (2 channel)
14190 */
14191#define ALC269_DIGOUT_NID	ALC880_DIGOUT_NID
14192
14193#define alc269_dac_nids		alc260_dac_nids
14194
14195static const hda_nid_t alc269_adc_nids[1] = {
14196	/* ADC1 */
14197	0x08,
14198};
14199
14200static const hda_nid_t alc269_capsrc_nids[1] = {
14201	0x23,
14202};
14203
14204static const hda_nid_t alc269vb_adc_nids[1] = {
14205	/* ADC1 */
14206	0x09,
14207};
14208
14209static const hda_nid_t alc269vb_capsrc_nids[1] = {
14210	0x22,
14211};
14212
14213static const hda_nid_t alc269_adc_candidates[] = {
14214	0x08, 0x09, 0x07, 0x11,
14215};
14216
14217#define alc269_modes		alc260_modes
14218#define alc269_capture_source	alc880_lg_lw_capture_source
14219
14220static const struct snd_kcontrol_new alc269_base_mixer[] = {
14221	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14222	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14223	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14224	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14225	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14226	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14227	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14228	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14229	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14230	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
14231	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14232	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14233	{ } /* end */
14234};
14235
14236static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14237	/* output mixer control */
14238	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14239	{
14240		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14241		.name = "Master Playback Switch",
14242		.subdevice = HDA_SUBDEV_AMP_FLAG,
14243		.info = snd_hda_mixer_amp_switch_info,
14244		.get = snd_hda_mixer_amp_switch_get,
14245		.put = alc268_acer_master_sw_put,
14246		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14247	},
14248	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14249	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14250	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14251	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14252	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14253	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14254	{ }
14255};
14256
14257static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14258	/* output mixer control */
14259	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14260	{
14261		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14262		.name = "Master Playback Switch",
14263		.subdevice = HDA_SUBDEV_AMP_FLAG,
14264		.info = snd_hda_mixer_amp_switch_info,
14265		.get = snd_hda_mixer_amp_switch_get,
14266		.put = alc268_acer_master_sw_put,
14267		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14268	},
14269	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14270	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14271	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14272	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14273	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14274	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14275	HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14276	HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
14277	HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
14278	{ }
14279};
14280
14281static const struct snd_kcontrol_new alc269_laptop_mixer[] = {
14282	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14283	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14284	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14285	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14286	{ } /* end */
14287};
14288
14289static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
14290	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14291	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14292	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14293	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14294	{ } /* end */
14295};
14296
14297static const struct snd_kcontrol_new alc269_asus_mixer[] = {
14298	HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14299	HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14300	{ } /* end */
14301};
14302
14303/* capture mixer elements */
14304static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14305	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14306	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14307	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14308	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14309	{ } /* end */
14310};
14311
14312static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
14313	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14314	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14315	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14316	{ } /* end */
14317};
14318
14319static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14320	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14321	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14322	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14323	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14324	{ } /* end */
14325};
14326
14327static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14328	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14329	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14330	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14331	{ } /* end */
14332};
14333
14334/* FSC amilo */
14335#define alc269_fujitsu_mixer	alc269_laptop_mixer
14336
14337static const struct hda_verb alc269_quanta_fl1_verbs[] = {
14338	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14339	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14340	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14341	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14342	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14343	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14344	{ }
14345};
14346
14347static const struct hda_verb alc269_lifebook_verbs[] = {
14348	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14349	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14350	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14351	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14352	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14353	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14354	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14355	{0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14356	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14357	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14358	{ }
14359};
14360
14361/* toggle speaker-output according to the hp-jack state */
14362static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14363{
14364	alc_hp_automute(codec);
14365
14366	snd_hda_codec_write(codec, 0x20, 0,
14367			AC_VERB_SET_COEF_INDEX, 0x0c);
14368	snd_hda_codec_write(codec, 0x20, 0,
14369			AC_VERB_SET_PROC_COEF, 0x680);
14370
14371	snd_hda_codec_write(codec, 0x20, 0,
14372			AC_VERB_SET_COEF_INDEX, 0x0c);
14373	snd_hda_codec_write(codec, 0x20, 0,
14374			AC_VERB_SET_PROC_COEF, 0x480);
14375}
14376
14377#define alc269_lifebook_speaker_automute \
14378	alc269_quanta_fl1_speaker_automute
14379
14380static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14381{
14382	unsigned int present_laptop;
14383	unsigned int present_dock;
14384
14385	present_laptop	= snd_hda_jack_detect(codec, 0x18);
14386	present_dock	= snd_hda_jack_detect(codec, 0x1b);
14387
14388	/* Laptop mic port overrides dock mic port, design decision */
14389	if (present_dock)
14390		snd_hda_codec_write(codec, 0x23, 0,
14391				AC_VERB_SET_CONNECT_SEL, 0x3);
14392	if (present_laptop)
14393		snd_hda_codec_write(codec, 0x23, 0,
14394				AC_VERB_SET_CONNECT_SEL, 0x0);
14395	if (!present_dock && !present_laptop)
14396		snd_hda_codec_write(codec, 0x23, 0,
14397				AC_VERB_SET_CONNECT_SEL, 0x1);
14398}
14399
14400static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14401				    unsigned int res)
14402{
14403	switch (res >> 26) {
14404	case ALC880_HP_EVENT:
14405		alc269_quanta_fl1_speaker_automute(codec);
14406		break;
14407	case ALC880_MIC_EVENT:
14408		alc_mic_automute(codec);
14409		break;
14410	}
14411}
14412
14413static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14414					unsigned int res)
14415{
14416	if ((res >> 26) == ALC880_HP_EVENT)
14417		alc269_lifebook_speaker_automute(codec);
14418	if ((res >> 26) == ALC880_MIC_EVENT)
14419		alc269_lifebook_mic_autoswitch(codec);
14420}
14421
14422static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14423{
14424	struct alc_spec *spec = codec->spec;
14425	spec->autocfg.hp_pins[0] = 0x15;
14426	spec->autocfg.speaker_pins[0] = 0x14;
14427	spec->automute_mixer_nid[0] = 0x0c;
14428	spec->automute = 1;
14429	spec->automute_mode = ALC_AUTOMUTE_MIXER;
14430	spec->ext_mic.pin = 0x18;
14431	spec->ext_mic.mux_idx = 0;
14432	spec->int_mic.pin = 0x19;
14433	spec->int_mic.mux_idx = 1;
14434	spec->auto_mic = 1;
14435}
14436
14437static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14438{
14439	alc269_quanta_fl1_speaker_automute(codec);
14440	alc_mic_automute(codec);
14441}
14442
14443static void alc269_lifebook_setup(struct hda_codec *codec)
14444{
14445	struct alc_spec *spec = codec->spec;
14446	spec->autocfg.hp_pins[0] = 0x15;
14447	spec->autocfg.hp_pins[1] = 0x1a;
14448	spec->autocfg.speaker_pins[0] = 0x14;
14449	spec->automute_mixer_nid[0] = 0x0c;
14450	spec->automute = 1;
14451	spec->automute_mode = ALC_AUTOMUTE_MIXER;
14452}
14453
14454static void alc269_lifebook_init_hook(struct hda_codec *codec)
14455{
14456	alc269_lifebook_speaker_automute(codec);
14457	alc269_lifebook_mic_autoswitch(codec);
14458}
14459
14460static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {
14461	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14462	{0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14463	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14464	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14465	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14466	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14467	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14468	{}
14469};
14470
14471static const struct hda_verb alc269_laptop_amic_init_verbs[] = {
14472	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14473	{0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14474	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14475	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14476	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14477	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14478	{}
14479};
14480
14481static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14482	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14483	{0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14484	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14485	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14486	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14487	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14488	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14489	{}
14490};
14491
14492static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14493	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14494	{0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14495	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14496	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14497	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14498	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14499	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14500	{}
14501};
14502
14503static const struct hda_verb alc271_acer_dmic_verbs[] = {
14504	{0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14505	{0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14506	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14507	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14508	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14509	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14510	{0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14511	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14512	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14513	{0x22, AC_VERB_SET_CONNECT_SEL, 6},
14514	{ }
14515};
14516
14517static void alc269_laptop_amic_setup(struct hda_codec *codec)
14518{
14519	struct alc_spec *spec = codec->spec;
14520	spec->autocfg.hp_pins[0] = 0x15;
14521	spec->autocfg.speaker_pins[0] = 0x14;
14522	spec->automute_mixer_nid[0] = 0x0c;
14523	spec->automute = 1;
14524	spec->automute_mode = ALC_AUTOMUTE_MIXER;
14525	spec->ext_mic.pin = 0x18;
14526	spec->ext_mic.mux_idx = 0;
14527	spec->int_mic.pin = 0x19;
14528	spec->int_mic.mux_idx = 1;
14529	spec->auto_mic = 1;
14530}
14531
14532static void alc269_laptop_dmic_setup(struct hda_codec *codec)
14533{
14534	struct alc_spec *spec = codec->spec;
14535	spec->autocfg.hp_pins[0] = 0x15;
14536	spec->autocfg.speaker_pins[0] = 0x14;
14537	spec->automute_mixer_nid[0] = 0x0c;
14538	spec->automute = 1;
14539	spec->automute_mode = ALC_AUTOMUTE_MIXER;
14540	spec->ext_mic.pin = 0x18;
14541	spec->ext_mic.mux_idx = 0;
14542	spec->int_mic.pin = 0x12;
14543	spec->int_mic.mux_idx = 5;
14544	spec->auto_mic = 1;
14545}
14546
14547static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
14548{
14549	struct alc_spec *spec = codec->spec;
14550	spec->autocfg.hp_pins[0] = 0x21;
14551	spec->autocfg.speaker_pins[0] = 0x14;
14552	spec->automute_mixer_nid[0] = 0x0c;
14553	spec->automute = 1;
14554	spec->automute_mode = ALC_AUTOMUTE_MIXER;
14555	spec->ext_mic.pin = 0x18;
14556	spec->ext_mic.mux_idx = 0;
14557	spec->int_mic.pin = 0x19;
14558	spec->int_mic.mux_idx = 1;
14559	spec->auto_mic = 1;
14560}
14561
14562static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14563{
14564	struct alc_spec *spec = codec->spec;
14565	spec->autocfg.hp_pins[0] = 0x21;
14566	spec->autocfg.speaker_pins[0] = 0x14;
14567	spec->automute_mixer_nid[0] = 0x0c;
14568	spec->automute = 1;
14569	spec->automute_mode = ALC_AUTOMUTE_MIXER;
14570	spec->ext_mic.pin = 0x18;
14571	spec->ext_mic.mux_idx = 0;
14572	spec->int_mic.pin = 0x12;
14573	spec->int_mic.mux_idx = 6;
14574	spec->auto_mic = 1;
14575}
14576
14577/*
14578 * generic initialization of ADC, input mixers and output mixers
14579 */
14580static const struct hda_verb alc269_init_verbs[] = {
14581	/*
14582	 * Unmute ADC0 and set the default input to mic-in
14583	 */
14584	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14585
14586	/*
14587	 * Set up output mixers (0x02 - 0x03)
14588	 */
14589	/* set vol=0 to output mixers */
14590	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14591	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14592
14593	/* set up input amps for analog loopback */
14594	/* Amp Indices: DAC = 0, mixer = 1 */
14595	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14596	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14597	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14598	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14599	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14600	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14601
14602	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14603	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14604	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14605	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14606	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14607	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14608	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14609
14610	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14611	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14612
14613	/* FIXME: use Mux-type input source selection */
14614	/* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14615	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14616	{0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
14617
14618	/* set EAPD */
14619	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14620	{ }
14621};
14622
14623static const struct hda_verb alc269vb_init_verbs[] = {
14624	/*
14625	 * Unmute ADC0 and set the default input to mic-in
14626	 */
14627	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14628
14629	/*
14630	 * Set up output mixers (0x02 - 0x03)
14631	 */
14632	/* set vol=0 to output mixers */
14633	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14634	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14635
14636	/* set up input amps for analog loopback */
14637	/* Amp Indices: DAC = 0, mixer = 1 */
14638	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14639	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14640	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14641	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14642	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14643	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14644
14645	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14646	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14647	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14648	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14649	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14650	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14651	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14652
14653	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14654	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14655
14656	/* FIXME: use Mux-type input source selection */
14657	/* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14658	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14659	{0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
14660
14661	/* set EAPD */
14662	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14663	{ }
14664};
14665
14666#define alc269_auto_create_multi_out_ctls \
14667	alc268_auto_create_multi_out_ctls
14668#define alc269_auto_create_input_ctls \
14669	alc268_auto_create_input_ctls
14670
14671#ifdef CONFIG_SND_HDA_POWER_SAVE
14672#define alc269_loopbacks	alc880_loopbacks
14673#endif
14674
14675/* pcm configuration: identical with ALC880 */
14676#define alc269_pcm_analog_playback	alc880_pcm_analog_playback
14677#define alc269_pcm_analog_capture	alc880_pcm_analog_capture
14678#define alc269_pcm_digital_playback	alc880_pcm_digital_playback
14679#define alc269_pcm_digital_capture	alc880_pcm_digital_capture
14680
14681static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14682	.substreams = 1,
14683	.channels_min = 2,
14684	.channels_max = 8,
14685	.rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14686	/* NID is set in alc_build_pcms */
14687	.ops = {
14688		.open = alc880_playback_pcm_open,
14689		.prepare = alc880_playback_pcm_prepare,
14690		.cleanup = alc880_playback_pcm_cleanup
14691	},
14692};
14693
14694static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14695	.substreams = 1,
14696	.channels_min = 2,
14697	.channels_max = 2,
14698	.rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14699	/* NID is set in alc_build_pcms */
14700};
14701
14702#ifdef CONFIG_SND_HDA_POWER_SAVE
14703static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14704{
14705	switch (codec->subsystem_id) {
14706	case 0x103c1586:
14707		return 1;
14708	}
14709	return 0;
14710}
14711
14712static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14713{
14714	/* update mute-LED according to the speaker mute state */
14715	if (nid == 0x01 || nid == 0x14) {
14716		int pinval;
14717		if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14718		    HDA_AMP_MUTE)
14719			pinval = 0x24;
14720		else
14721			pinval = 0x20;
14722		/* mic2 vref pin is used for mute LED control */
14723		snd_hda_codec_update_cache(codec, 0x19, 0,
14724					   AC_VERB_SET_PIN_WIDGET_CONTROL,
14725					   pinval);
14726	}
14727	return alc_check_power_status(codec, nid);
14728}
14729#endif /* CONFIG_SND_HDA_POWER_SAVE */
14730
14731static int alc275_setup_dual_adc(struct hda_codec *codec)
14732{
14733	struct alc_spec *spec = codec->spec;
14734
14735	if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14736		return 0;
14737	if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14738	    (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14739		if (spec->ext_mic.pin <= 0x12) {
14740			spec->private_adc_nids[0] = 0x08;
14741			spec->private_adc_nids[1] = 0x11;
14742			spec->private_capsrc_nids[0] = 0x23;
14743			spec->private_capsrc_nids[1] = 0x22;
14744		} else {
14745			spec->private_adc_nids[0] = 0x11;
14746			spec->private_adc_nids[1] = 0x08;
14747			spec->private_capsrc_nids[0] = 0x22;
14748			spec->private_capsrc_nids[1] = 0x23;
14749		}
14750		spec->adc_nids = spec->private_adc_nids;
14751		spec->capsrc_nids = spec->private_capsrc_nids;
14752		spec->num_adc_nids = 2;
14753		spec->dual_adc_switch = 1;
14754		snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14755			    spec->adc_nids[0], spec->adc_nids[1]);
14756		return 1;
14757	}
14758	return 0;
14759}
14760
14761/* different alc269-variants */
14762enum {
14763	ALC269_TYPE_NORMAL,
14764	ALC269_TYPE_ALC258,
14765	ALC269_TYPE_ALC259,
14766	ALC269_TYPE_ALC269VB,
14767	ALC269_TYPE_ALC270,
14768	ALC269_TYPE_ALC271X,
14769};
14770
14771/*
14772 * BIOS auto configuration
14773 */
14774static int alc269_parse_auto_config(struct hda_codec *codec)
14775{
14776	struct alc_spec *spec = codec->spec;
14777	int err;
14778	static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14779
14780	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14781					   alc269_ignore);
14782	if (err < 0)
14783		return err;
14784
14785	err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14786	if (err < 0)
14787		return err;
14788	if (spec->codec_variant == ALC269_TYPE_NORMAL)
14789		err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14790	else
14791		err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14792						 0x22, 0);
14793	if (err < 0)
14794		return err;
14795
14796	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14797
14798	alc_auto_parse_digital(codec);
14799
14800	if (spec->kctls.list)
14801		add_mixer(spec, spec->kctls.list);
14802
14803	if (spec->codec_variant != ALC269_TYPE_NORMAL) {
14804		add_verb(spec, alc269vb_init_verbs);
14805		alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
14806	} else {
14807		add_verb(spec, alc269_init_verbs);
14808		alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
14809	}
14810
14811	spec->num_mux_defs = 1;
14812	spec->input_mux = &spec->private_imux[0];
14813
14814	if (!alc275_setup_dual_adc(codec))
14815		fillup_priv_adc_nids(codec, alc269_adc_candidates,
14816				     sizeof(alc269_adc_candidates));
14817
14818	err = alc_auto_add_mic_boost(codec);
14819	if (err < 0)
14820		return err;
14821
14822	if (!spec->cap_mixer && !spec->no_analog)
14823		set_capture_mixer(codec);
14824
14825	return 1;
14826}
14827
14828#define alc269_auto_init_multi_out	alc268_auto_init_multi_out
14829#define alc269_auto_init_hp_out		alc268_auto_init_hp_out
14830#define alc269_auto_init_analog_input	alc882_auto_init_analog_input
14831#define alc269_auto_init_input_src	alc882_auto_init_input_src
14832
14833
14834/* init callback for auto-configuration model -- overriding the default init */
14835static void alc269_auto_init(struct hda_codec *codec)
14836{
14837	struct alc_spec *spec = codec->spec;
14838	alc269_auto_init_multi_out(codec);
14839	alc269_auto_init_hp_out(codec);
14840	alc269_auto_init_analog_input(codec);
14841	if (!spec->dual_adc_switch)
14842		alc269_auto_init_input_src(codec);
14843	alc_auto_init_digital(codec);
14844	if (spec->unsol_event)
14845		alc_inithook(codec);
14846}
14847
14848static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14849{
14850	int val = alc_read_coef_idx(codec, 0x04);
14851	if (power_up)
14852		val |= 1 << 11;
14853	else
14854		val &= ~(1 << 11);
14855	alc_write_coef_idx(codec, 0x04, val);
14856}
14857
14858static void alc269_shutup(struct hda_codec *codec)
14859{
14860	if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14861		alc269_toggle_power_output(codec, 0);
14862	if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14863		alc269_toggle_power_output(codec, 0);
14864		msleep(150);
14865	}
14866}
14867
14868#ifdef SND_HDA_NEEDS_RESUME
14869static int alc269_resume(struct hda_codec *codec)
14870{
14871	if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14872		alc269_toggle_power_output(codec, 0);
14873		msleep(150);
14874	}
14875
14876	codec->patch_ops.init(codec);
14877
14878	if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
14879		alc269_toggle_power_output(codec, 1);
14880		msleep(200);
14881	}
14882
14883	if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14884		alc269_toggle_power_output(codec, 1);
14885
14886	snd_hda_codec_resume_amp(codec);
14887	snd_hda_codec_resume_cache(codec);
14888	hda_call_check_power_status(codec, 0x01);
14889	return 0;
14890}
14891#endif /* SND_HDA_NEEDS_RESUME */
14892
14893static void alc269_fixup_hweq(struct hda_codec *codec,
14894			       const struct alc_fixup *fix, int action)
14895{
14896	int coef;
14897
14898	if (action != ALC_FIXUP_ACT_INIT)
14899		return;
14900	coef = alc_read_coef_idx(codec, 0x1e);
14901	alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14902}
14903
14904static void alc271_fixup_dmic(struct hda_codec *codec,
14905			      const struct alc_fixup *fix, int action)
14906{
14907	static const struct hda_verb verbs[] = {
14908		{0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14909		{0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14910		{}
14911	};
14912	unsigned int cfg;
14913
14914	if (strcmp(codec->chip_name, "ALC271X"))
14915		return;
14916	cfg = snd_hda_codec_get_pincfg(codec, 0x12);
14917	if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
14918		snd_hda_sequence_write(codec, verbs);
14919}
14920
14921enum {
14922	ALC269_FIXUP_SONY_VAIO,
14923	ALC275_FIXUP_SONY_VAIO_GPIO2,
14924	ALC269_FIXUP_DELL_M101Z,
14925	ALC269_FIXUP_SKU_IGNORE,
14926	ALC269_FIXUP_ASUS_G73JW,
14927	ALC269_FIXUP_LENOVO_EAPD,
14928	ALC275_FIXUP_SONY_HWEQ,
14929	ALC271_FIXUP_DMIC,
14930};
14931
14932static const struct alc_fixup alc269_fixups[] = {
14933	[ALC269_FIXUP_SONY_VAIO] = {
14934		.type = ALC_FIXUP_VERBS,
14935		.v.verbs = (const struct hda_verb[]) {
14936			{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14937			{}
14938		}
14939	},
14940	[ALC275_FIXUP_SONY_VAIO_GPIO2] = {
14941		.type = ALC_FIXUP_VERBS,
14942		.v.verbs = (const struct hda_verb[]) {
14943			{0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14944			{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14945			{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14946			{ }
14947		},
14948		.chained = true,
14949		.chain_id = ALC269_FIXUP_SONY_VAIO
14950	},
14951	[ALC269_FIXUP_DELL_M101Z] = {
14952		.type = ALC_FIXUP_VERBS,
14953		.v.verbs = (const struct hda_verb[]) {
14954			/* Enables internal speaker */
14955			{0x20, AC_VERB_SET_COEF_INDEX, 13},
14956			{0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14957			{}
14958		}
14959	},
14960	[ALC269_FIXUP_SKU_IGNORE] = {
14961		.type = ALC_FIXUP_SKU,
14962		.v.sku = ALC_FIXUP_SKU_IGNORE,
14963	},
14964	[ALC269_FIXUP_ASUS_G73JW] = {
14965		.type = ALC_FIXUP_PINS,
14966		.v.pins = (const struct alc_pincfg[]) {
14967			{ 0x17, 0x99130111 }, /* subwoofer */
14968			{ }
14969		}
14970	},
14971	[ALC269_FIXUP_LENOVO_EAPD] = {
14972		.type = ALC_FIXUP_VERBS,
14973		.v.verbs = (const struct hda_verb[]) {
14974			{0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14975			{}
14976		}
14977	},
14978	[ALC275_FIXUP_SONY_HWEQ] = {
14979		.type = ALC_FIXUP_FUNC,
14980		.v.func = alc269_fixup_hweq,
14981		.chained = true,
14982		.chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
14983	},
14984	[ALC271_FIXUP_DMIC] = {
14985		.type = ALC_FIXUP_FUNC,
14986		.v.func = alc271_fixup_dmic,
14987	},
14988};
14989
14990static const struct snd_pci_quirk alc269_fixup_tbl[] = {
14991	SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
14992	SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14993	SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14994	SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14995	SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
14996	SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
14997	SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
14998	SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
14999	SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
15000	SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
15001	SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
15002	SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
15003	SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
15004	{}
15005};
15006
15007
15008/*
15009 * configuration and preset
15010 */
15011static const char * const alc269_models[ALC269_MODEL_LAST] = {
15012	[ALC269_BASIC]			= "basic",
15013	[ALC269_QUANTA_FL1]		= "quanta",
15014	[ALC269_AMIC]			= "laptop-amic",
15015	[ALC269_DMIC]			= "laptop-dmic",
15016	[ALC269_FUJITSU]		= "fujitsu",
15017	[ALC269_LIFEBOOK]		= "lifebook",
15018	[ALC269_AUTO]			= "auto",
15019};
15020
15021static const struct snd_pci_quirk alc269_cfg_tbl[] = {
15022	SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
15023	SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
15024	SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
15025		      ALC269_AMIC),
15026	SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
15027	SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
15028	SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
15029	SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
15030	SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
15031	SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
15032	SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
15033	SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
15034	SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
15035	SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
15036	SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
15037	SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
15038	SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
15039	SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
15040	SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
15041	SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
15042	SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
15043	SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
15044	SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
15045	SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
15046	SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
15047	SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
15048	SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
15049	SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
15050	SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
15051	SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
15052	SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
15053	SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
15054	SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
15055	SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
15056	SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
15057	SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
15058	SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
15059	SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
15060	SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
15061	SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
15062	SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
15063		      ALC269_DMIC),
15064	SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
15065		      ALC269_DMIC),
15066	SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
15067	SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
15068	SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
15069	SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
15070	SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
15071	SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
15072	SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
15073	SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
15074	SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
15075	SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
15076	{}
15077};
15078
15079static const struct alc_config_preset alc269_presets[] = {
15080	[ALC269_BASIC] = {
15081		.mixers = { alc269_base_mixer },
15082		.init_verbs = { alc269_init_verbs },
15083		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
15084		.dac_nids = alc269_dac_nids,
15085		.hp_nid = 0x03,
15086		.num_channel_mode = ARRAY_SIZE(alc269_modes),
15087		.channel_mode = alc269_modes,
15088		.input_mux = &alc269_capture_source,
15089	},
15090	[ALC269_QUANTA_FL1] = {
15091		.mixers = { alc269_quanta_fl1_mixer },
15092		.init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
15093		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
15094		.dac_nids = alc269_dac_nids,
15095		.hp_nid = 0x03,
15096		.num_channel_mode = ARRAY_SIZE(alc269_modes),
15097		.channel_mode = alc269_modes,
15098		.input_mux = &alc269_capture_source,
15099		.unsol_event = alc269_quanta_fl1_unsol_event,
15100		.setup = alc269_quanta_fl1_setup,
15101		.init_hook = alc269_quanta_fl1_init_hook,
15102	},
15103	[ALC269_AMIC] = {
15104		.mixers = { alc269_laptop_mixer },
15105		.cap_mixer = alc269_laptop_analog_capture_mixer,
15106		.init_verbs = { alc269_init_verbs,
15107				alc269_laptop_amic_init_verbs },
15108		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
15109		.dac_nids = alc269_dac_nids,
15110		.hp_nid = 0x03,
15111		.num_channel_mode = ARRAY_SIZE(alc269_modes),
15112		.channel_mode = alc269_modes,
15113		.unsol_event = alc_sku_unsol_event,
15114		.setup = alc269_laptop_amic_setup,
15115		.init_hook = alc_inithook,
15116	},
15117	[ALC269_DMIC] = {
15118		.mixers = { alc269_laptop_mixer },
15119		.cap_mixer = alc269_laptop_digital_capture_mixer,
15120		.init_verbs = { alc269_init_verbs,
15121				alc269_laptop_dmic_init_verbs },
15122		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
15123		.dac_nids = alc269_dac_nids,
15124		.hp_nid = 0x03,
15125		.num_channel_mode = ARRAY_SIZE(alc269_modes),
15126		.channel_mode = alc269_modes,
15127		.unsol_event = alc_sku_unsol_event,
15128		.setup = alc269_laptop_dmic_setup,
15129		.init_hook = alc_inithook,
15130	},
15131	[ALC269VB_AMIC] = {
15132		.mixers = { alc269vb_laptop_mixer },
15133		.cap_mixer = alc269vb_laptop_analog_capture_mixer,
15134		.init_verbs = { alc269vb_init_verbs,
15135				alc269vb_laptop_amic_init_verbs },
15136		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
15137		.dac_nids = alc269_dac_nids,
15138		.hp_nid = 0x03,
15139		.num_channel_mode = ARRAY_SIZE(alc269_modes),
15140		.channel_mode = alc269_modes,
15141		.unsol_event = alc_sku_unsol_event,
15142		.setup = alc269vb_laptop_amic_setup,
15143		.init_hook = alc_inithook,
15144	},
15145	[ALC269VB_DMIC] = {
15146		.mixers = { alc269vb_laptop_mixer },
15147		.cap_mixer = alc269vb_laptop_digital_capture_mixer,
15148		.init_verbs = { alc269vb_init_verbs,
15149				alc269vb_laptop_dmic_init_verbs },
15150		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
15151		.dac_nids = alc269_dac_nids,
15152		.hp_nid = 0x03,
15153		.num_channel_mode = ARRAY_SIZE(alc269_modes),
15154		.channel_mode = alc269_modes,
15155		.unsol_event = alc_sku_unsol_event,
15156		.setup = alc269vb_laptop_dmic_setup,
15157		.init_hook = alc_inithook,
15158	},
15159	[ALC269_FUJITSU] = {
15160		.mixers = { alc269_fujitsu_mixer },
15161		.cap_mixer = alc269_laptop_digital_capture_mixer,
15162		.init_verbs = { alc269_init_verbs,
15163				alc269_laptop_dmic_init_verbs },
15164		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
15165		.dac_nids = alc269_dac_nids,
15166		.hp_nid = 0x03,
15167		.num_channel_mode = ARRAY_SIZE(alc269_modes),
15168		.channel_mode = alc269_modes,
15169		.unsol_event = alc_sku_unsol_event,
15170		.setup = alc269_laptop_dmic_setup,
15171		.init_hook = alc_inithook,
15172	},
15173	[ALC269_LIFEBOOK] = {
15174		.mixers = { alc269_lifebook_mixer },
15175		.init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15176		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
15177		.dac_nids = alc269_dac_nids,
15178		.hp_nid = 0x03,
15179		.num_channel_mode = ARRAY_SIZE(alc269_modes),
15180		.channel_mode = alc269_modes,
15181		.input_mux = &alc269_capture_source,
15182		.unsol_event = alc269_lifebook_unsol_event,
15183		.setup = alc269_lifebook_setup,
15184		.init_hook = alc269_lifebook_init_hook,
15185	},
15186	[ALC271_ACER] = {
15187		.mixers = { alc269_asus_mixer },
15188		.cap_mixer = alc269vb_laptop_digital_capture_mixer,
15189		.init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15190		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
15191		.dac_nids = alc269_dac_nids,
15192		.adc_nids = alc262_dmic_adc_nids,
15193		.num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15194		.capsrc_nids = alc262_dmic_capsrc_nids,
15195		.num_channel_mode = ARRAY_SIZE(alc269_modes),
15196		.channel_mode = alc269_modes,
15197		.input_mux = &alc269_capture_source,
15198		.dig_out_nid = ALC880_DIGOUT_NID,
15199		.unsol_event = alc_sku_unsol_event,
15200		.setup = alc269vb_laptop_dmic_setup,
15201		.init_hook = alc_inithook,
15202	},
15203};
15204
15205static int alc269_fill_coef(struct hda_codec *codec)
15206{
15207	int val;
15208
15209	if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
15210		alc_write_coef_idx(codec, 0xf, 0x960b);
15211		alc_write_coef_idx(codec, 0xe, 0x8817);
15212	}
15213
15214	if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
15215		alc_write_coef_idx(codec, 0xf, 0x960b);
15216		alc_write_coef_idx(codec, 0xe, 0x8814);
15217	}
15218
15219	if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
15220		val = alc_read_coef_idx(codec, 0x04);
15221		/* Power up output pin */
15222		alc_write_coef_idx(codec, 0x04, val | (1<<11));
15223	}
15224
15225	if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
15226		val = alc_read_coef_idx(codec, 0xd);
15227		if ((val & 0x0c00) >> 10 != 0x1) {
15228			/* Capless ramp up clock control */
15229			alc_write_coef_idx(codec, 0xd, val | (1<<10));
15230		}
15231		val = alc_read_coef_idx(codec, 0x17);
15232		if ((val & 0x01c0) >> 6 != 0x4) {
15233			/* Class D power on reset */
15234			alc_write_coef_idx(codec, 0x17, val | (1<<7));
15235		}
15236	}
15237
15238	val = alc_read_coef_idx(codec, 0xd); /* Class D */
15239	alc_write_coef_idx(codec, 0xd, val | (1<<14));
15240
15241	val = alc_read_coef_idx(codec, 0x4); /* HP */
15242	alc_write_coef_idx(codec, 0x4, val | (1<<11));
15243
15244	return 0;
15245}
15246
15247static int patch_alc269(struct hda_codec *codec)
15248{
15249	struct alc_spec *spec;
15250	int board_config, coef;
15251	int err;
15252
15253	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15254	if (spec == NULL)
15255		return -ENOMEM;
15256
15257	codec->spec = spec;
15258
15259	alc_auto_parse_customize_define(codec);
15260
15261	if (codec->vendor_id == 0x10ec0269) {
15262		coef = alc_read_coef_idx(codec, 0);
15263		if ((coef & 0x00f0) == 0x0010) {
15264			if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15265			    spec->cdefine.platform_type == 1) {
15266				alc_codec_rename(codec, "ALC271X");
15267				spec->codec_variant = ALC269_TYPE_ALC271X;
15268			} else if ((coef & 0xf000) == 0x1000) {
15269				spec->codec_variant = ALC269_TYPE_ALC270;
15270			} else if ((coef & 0xf000) == 0x2000) {
15271				alc_codec_rename(codec, "ALC259");
15272				spec->codec_variant = ALC269_TYPE_ALC259;
15273			} else if ((coef & 0xf000) == 0x3000) {
15274				alc_codec_rename(codec, "ALC258");
15275				spec->codec_variant = ALC269_TYPE_ALC258;
15276			} else {
15277				alc_codec_rename(codec, "ALC269VB");
15278				spec->codec_variant = ALC269_TYPE_ALC269VB;
15279			}
15280		} else
15281			alc_fix_pll_init(codec, 0x20, 0x04, 15);
15282		alc269_fill_coef(codec);
15283	}
15284
15285	board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15286						  alc269_models,
15287						  alc269_cfg_tbl);
15288
15289	if (board_config < 0) {
15290		printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15291		       codec->chip_name);
15292		board_config = ALC269_AUTO;
15293	}
15294
15295	if (board_config == ALC269_AUTO) {
15296		alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15297		alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15298	}
15299
15300	if (board_config == ALC269_AUTO) {
15301		/* automatic parse from the BIOS config */
15302		err = alc269_parse_auto_config(codec);
15303		if (err < 0) {
15304			alc_free(codec);
15305			return err;
15306		} else if (!err) {
15307			printk(KERN_INFO
15308			       "hda_codec: Cannot set up configuration "
15309			       "from BIOS.  Using base mode...\n");
15310			board_config = ALC269_BASIC;
15311		}
15312	}
15313
15314	if (has_cdefine_beep(codec)) {
15315		err = snd_hda_attach_beep_device(codec, 0x1);
15316		if (err < 0) {
15317			alc_free(codec);
15318			return err;
15319		}
15320	}
15321
15322	if (board_config != ALC269_AUTO)
15323		setup_preset(codec, &alc269_presets[board_config]);
15324
15325	if (board_config == ALC269_QUANTA_FL1) {
15326		/* Due to a hardware problem on Lenovo Ideadpad, we need to
15327		 * fix the sample rate of analog I/O to 44.1kHz
15328		 */
15329		spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15330		spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
15331	} else if (spec->dual_adc_switch) {
15332		spec->stream_analog_playback = &alc269_pcm_analog_playback;
15333		/* switch ADC dynamically */
15334		spec->stream_analog_capture = &dualmic_pcm_analog_capture;
15335	} else {
15336		spec->stream_analog_playback = &alc269_pcm_analog_playback;
15337		spec->stream_analog_capture = &alc269_pcm_analog_capture;
15338	}
15339	spec->stream_digital_playback = &alc269_pcm_digital_playback;
15340	spec->stream_digital_capture = &alc269_pcm_digital_capture;
15341
15342	if (!spec->adc_nids) { /* wasn't filled automatically? use default */
15343		if (spec->codec_variant == ALC269_TYPE_NORMAL) {
15344			spec->adc_nids = alc269_adc_nids;
15345			spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15346			spec->capsrc_nids = alc269_capsrc_nids;
15347		} else {
15348			spec->adc_nids = alc269vb_adc_nids;
15349			spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15350			spec->capsrc_nids = alc269vb_capsrc_nids;
15351		}
15352	}
15353
15354	if (!spec->cap_mixer)
15355		set_capture_mixer(codec);
15356	if (has_cdefine_beep(codec))
15357		set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
15358
15359	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
15360
15361	spec->vmaster_nid = 0x02;
15362
15363	codec->patch_ops = alc_patch_ops;
15364#ifdef SND_HDA_NEEDS_RESUME
15365	codec->patch_ops.resume = alc269_resume;
15366#endif
15367	if (board_config == ALC269_AUTO)
15368		spec->init_hook = alc269_auto_init;
15369	spec->shutup = alc269_shutup;
15370
15371	alc_init_jacks(codec);
15372#ifdef CONFIG_SND_HDA_POWER_SAVE
15373	if (!spec->loopback.amplist)
15374		spec->loopback.amplist = alc269_loopbacks;
15375	if (alc269_mic2_for_mute_led(codec))
15376		codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
15377#endif
15378
15379	return 0;
15380}
15381
15382/*
15383 *  ALC861 channel source setting (2/6 channel selection for 3-stack)
15384 */
15385
15386/*
15387 * set the path ways for 2 channel output
15388 * need to set the codec line out and mic 1 pin widgets to inputs
15389 */
15390static const struct hda_verb alc861_threestack_ch2_init[] = {
15391	/* set pin widget 1Ah (line in) for input */
15392	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15393	/* set pin widget 18h (mic1/2) for input, for mic also enable
15394	 * the vref
15395	 */
15396	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15397
15398	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15399#if 0
15400	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15401	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15402#endif
15403	{ } /* end */
15404};
15405/*
15406 * 6ch mode
15407 * need to set the codec line out and mic 1 pin widgets to outputs
15408 */
15409static const struct hda_verb alc861_threestack_ch6_init[] = {
15410	/* set pin widget 1Ah (line in) for output (Back Surround)*/
15411	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15412	/* set pin widget 18h (mic1) for output (CLFE)*/
15413	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15414
15415	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15416	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15417
15418	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15419#if 0
15420	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15421	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15422#endif
15423	{ } /* end */
15424};
15425
15426static const struct hda_channel_mode alc861_threestack_modes[2] = {
15427	{ 2, alc861_threestack_ch2_init },
15428	{ 6, alc861_threestack_ch6_init },
15429};
15430/* Set mic1 as input and unmute the mixer */
15431static const struct hda_verb alc861_uniwill_m31_ch2_init[] = {
15432	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15433	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15434	{ } /* end */
15435};
15436/* Set mic1 as output and mute mixer */
15437static const struct hda_verb alc861_uniwill_m31_ch4_init[] = {
15438	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15439	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15440	{ } /* end */
15441};
15442
15443static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
15444	{ 2, alc861_uniwill_m31_ch2_init },
15445	{ 4, alc861_uniwill_m31_ch4_init },
15446};
15447
15448/* Set mic1 and line-in as input and unmute the mixer */
15449static const struct hda_verb alc861_asus_ch2_init[] = {
15450	/* set pin widget 1Ah (line in) for input */
15451	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15452	/* set pin widget 18h (mic1/2) for input, for mic also enable
15453	 * the vref
15454	 */
15455	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15456
15457	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15458#if 0
15459	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15460	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15461#endif
15462	{ } /* end */
15463};
15464/* Set mic1 nad line-in as output and mute mixer */
15465static const struct hda_verb alc861_asus_ch6_init[] = {
15466	/* set pin widget 1Ah (line in) for output (Back Surround)*/
15467	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15468	/* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15469	/* set pin widget 18h (mic1) for output (CLFE)*/
15470	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15471	/* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15472	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15473	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15474
15475	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15476#if 0
15477	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15478	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15479#endif
15480	{ } /* end */
15481};
15482
15483static const struct hda_channel_mode alc861_asus_modes[2] = {
15484	{ 2, alc861_asus_ch2_init },
15485	{ 6, alc861_asus_ch6_init },
15486};
15487
15488/* patch-ALC861 */
15489
15490static const struct snd_kcontrol_new alc861_base_mixer[] = {
15491        /* output mixer control */
15492	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15493	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15494	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15495	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15496	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15497
15498        /*Input mixer control */
15499	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15500	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15501	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15502	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15503	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15504	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15505	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15506	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15507	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15508	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15509
15510	{ } /* end */
15511};
15512
15513static const struct snd_kcontrol_new alc861_3ST_mixer[] = {
15514        /* output mixer control */
15515	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15516	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15517	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15518	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15519	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15520
15521	/* Input mixer control */
15522	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15523	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15524	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15525	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15526	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15527	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15528	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15529	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15530	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15531	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15532
15533	{
15534		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15535		.name = "Channel Mode",
15536		.info = alc_ch_mode_info,
15537		.get = alc_ch_mode_get,
15538		.put = alc_ch_mode_put,
15539                .private_value = ARRAY_SIZE(alc861_threestack_modes),
15540	},
15541	{ } /* end */
15542};
15543
15544static const struct snd_kcontrol_new alc861_toshiba_mixer[] = {
15545        /* output mixer control */
15546	HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15547	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15548	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15549
15550	{ } /* end */
15551};
15552
15553static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15554        /* output mixer control */
15555	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15556	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15557	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15558	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15559	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15560
15561	/* Input mixer control */
15562	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15563	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15564	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15565	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15566	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15567	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15568	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15569	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15570	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15571	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15572
15573	{
15574		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15575		.name = "Channel Mode",
15576		.info = alc_ch_mode_info,
15577		.get = alc_ch_mode_get,
15578		.put = alc_ch_mode_put,
15579                .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15580	},
15581	{ } /* end */
15582};
15583
15584static const struct snd_kcontrol_new alc861_asus_mixer[] = {
15585        /* output mixer control */
15586	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15587	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15588	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15589	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15590	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15591
15592	/* Input mixer control */
15593	HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15594	HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15595	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15596	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15597	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15598	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15599	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15600	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15601	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15602	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15603
15604	{
15605		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15606		.name = "Channel Mode",
15607		.info = alc_ch_mode_info,
15608		.get = alc_ch_mode_get,
15609		.put = alc_ch_mode_put,
15610                .private_value = ARRAY_SIZE(alc861_asus_modes),
15611	},
15612	{ }
15613};
15614
15615/* additional mixer */
15616static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
15617	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15618	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15619	{ }
15620};
15621
15622/*
15623 * generic initialization of ADC, input mixers and output mixers
15624 */
15625static const struct hda_verb alc861_base_init_verbs[] = {
15626	/*
15627	 * Unmute ADC0 and set the default input to mic-in
15628	 */
15629	/* port-A for surround (rear panel) */
15630	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15631	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15632	/* port-B for mic-in (rear panel) with vref */
15633	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15634	/* port-C for line-in (rear panel) */
15635	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15636	/* port-D for Front */
15637	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15638	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15639	/* port-E for HP out (front panel) */
15640	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15641	/* route front PCM to HP */
15642	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15643	/* port-F for mic-in (front panel) with vref */
15644	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15645	/* port-G for CLFE (rear panel) */
15646	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15647	{ 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15648	/* port-H for side (rear panel) */
15649	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15650	{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15651	/* CD-in */
15652	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15653	/* route front mic to ADC1*/
15654	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15655	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15656
15657	/* Unmute DAC0~3 & spdif out*/
15658	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15659	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15660	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15661	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15662	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15663
15664	/* Unmute Mixer 14 (mic) 1c (Line in)*/
15665	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15666        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15667	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15668        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15669
15670	/* Unmute Stereo Mixer 15 */
15671	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15672	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15673	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15674	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15675
15676	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15677	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15678	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15679	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15680	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15681	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15682	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15683	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15684	/* hp used DAC 3 (Front) */
15685	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15686        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15687
15688	{ }
15689};
15690
15691static const struct hda_verb alc861_threestack_init_verbs[] = {
15692	/*
15693	 * Unmute ADC0 and set the default input to mic-in
15694	 */
15695	/* port-A for surround (rear panel) */
15696	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15697	/* port-B for mic-in (rear panel) with vref */
15698	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15699	/* port-C for line-in (rear panel) */
15700	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15701	/* port-D for Front */
15702	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15703	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15704	/* port-E for HP out (front panel) */
15705	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15706	/* route front PCM to HP */
15707	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15708	/* port-F for mic-in (front panel) with vref */
15709	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15710	/* port-G for CLFE (rear panel) */
15711	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15712	/* port-H for side (rear panel) */
15713	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15714	/* CD-in */
15715	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15716	/* route front mic to ADC1*/
15717	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15718	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15719	/* Unmute DAC0~3 & spdif out*/
15720	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15721	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15722	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15723	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15724	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15725
15726	/* Unmute Mixer 14 (mic) 1c (Line in)*/
15727	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15728        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15729	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15730        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15731
15732	/* Unmute Stereo Mixer 15 */
15733	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15734	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15735	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15736	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15737
15738	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15739	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15740	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15741	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15742	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15743	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15744	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15745	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15746	/* hp used DAC 3 (Front) */
15747	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15748        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15749	{ }
15750};
15751
15752static const struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15753	/*
15754	 * Unmute ADC0 and set the default input to mic-in
15755	 */
15756	/* port-A for surround (rear panel) */
15757	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15758	/* port-B for mic-in (rear panel) with vref */
15759	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15760	/* port-C for line-in (rear panel) */
15761	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15762	/* port-D for Front */
15763	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15764	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15765	/* port-E for HP out (front panel) */
15766	/* this has to be set to VREF80 */
15767	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15768	/* route front PCM to HP */
15769	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15770	/* port-F for mic-in (front panel) with vref */
15771	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15772	/* port-G for CLFE (rear panel) */
15773	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15774	/* port-H for side (rear panel) */
15775	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15776	/* CD-in */
15777	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15778	/* route front mic to ADC1*/
15779	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15780	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15781	/* Unmute DAC0~3 & spdif out*/
15782	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15783	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15784	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15785	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15786	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15787
15788	/* Unmute Mixer 14 (mic) 1c (Line in)*/
15789	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15790        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15791	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15792        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15793
15794	/* Unmute Stereo Mixer 15 */
15795	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15796	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15797	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15798	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15799
15800	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15801	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15802	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15803	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15804	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15805	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15806	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15807	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15808	/* hp used DAC 3 (Front) */
15809	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15810        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15811	{ }
15812};
15813
15814static const struct hda_verb alc861_asus_init_verbs[] = {
15815	/*
15816	 * Unmute ADC0 and set the default input to mic-in
15817	 */
15818	/* port-A for surround (rear panel)
15819	 * according to codec#0 this is the HP jack
15820	 */
15821	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15822	/* route front PCM to HP */
15823	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15824	/* port-B for mic-in (rear panel) with vref */
15825	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15826	/* port-C for line-in (rear panel) */
15827	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15828	/* port-D for Front */
15829	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15830	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15831	/* port-E for HP out (front panel) */
15832	/* this has to be set to VREF80 */
15833	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15834	/* route front PCM to HP */
15835	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15836	/* port-F for mic-in (front panel) with vref */
15837	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15838	/* port-G for CLFE (rear panel) */
15839	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15840	/* port-H for side (rear panel) */
15841	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15842	/* CD-in */
15843	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15844	/* route front mic to ADC1*/
15845	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15846	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15847	/* Unmute DAC0~3 & spdif out*/
15848	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15849	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15850	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15851	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15852	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15853	/* Unmute Mixer 14 (mic) 1c (Line in)*/
15854	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15855        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15856	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15857        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15858
15859	/* Unmute Stereo Mixer 15 */
15860	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15861	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15862	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15863	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15864
15865	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15866	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15867	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15868	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15869	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15870	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15871	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15872	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15873	/* hp used DAC 3 (Front) */
15874	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15875	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15876	{ }
15877};
15878
15879/* additional init verbs for ASUS laptops */
15880static const struct hda_verb alc861_asus_laptop_init_verbs[] = {
15881	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15882	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15883	{ }
15884};
15885
15886/*
15887 * generic initialization of ADC, input mixers and output mixers
15888 */
15889static const struct hda_verb alc861_auto_init_verbs[] = {
15890	/*
15891	 * Unmute ADC0 and set the default input to mic-in
15892	 */
15893	/* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
15894	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15895
15896	/* Unmute DAC0~3 & spdif out*/
15897	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15898	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15899	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15900	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15901	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15902
15903	/* Unmute Mixer 14 (mic) 1c (Line in)*/
15904	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15905	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15906	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15907	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15908
15909	/* Unmute Stereo Mixer 15 */
15910	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15911	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15912	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15913	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15914
15915	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15916	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15917	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15918	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15919	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15920	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15921	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15922	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15923
15924	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15925	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15926	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15927	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15928	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15929	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15930	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15931	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15932
15933	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},	/* set Mic 1 */
15934
15935	{ }
15936};
15937
15938static const struct hda_verb alc861_toshiba_init_verbs[] = {
15939	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15940
15941	{ }
15942};
15943
15944/* toggle speaker-output according to the hp-jack state */
15945static void alc861_toshiba_automute(struct hda_codec *codec)
15946{
15947	unsigned int present = snd_hda_jack_detect(codec, 0x0f);
15948
15949	snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15950				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15951	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15952				 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
15953}
15954
15955static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15956				       unsigned int res)
15957{
15958	if ((res >> 26) == ALC880_HP_EVENT)
15959		alc861_toshiba_automute(codec);
15960}
15961
15962/* pcm configuration: identical with ALC880 */
15963#define alc861_pcm_analog_playback	alc880_pcm_analog_playback
15964#define alc861_pcm_analog_capture	alc880_pcm_analog_capture
15965#define alc861_pcm_digital_playback	alc880_pcm_digital_playback
15966#define alc861_pcm_digital_capture	alc880_pcm_digital_capture
15967
15968
15969#define ALC861_DIGOUT_NID	0x07
15970
15971static const struct hda_channel_mode alc861_8ch_modes[1] = {
15972	{ 8, NULL }
15973};
15974
15975static const hda_nid_t alc861_dac_nids[4] = {
15976	/* front, surround, clfe, side */
15977	0x03, 0x06, 0x05, 0x04
15978};
15979
15980static const hda_nid_t alc660_dac_nids[3] = {
15981	/* front, clfe, surround */
15982	0x03, 0x05, 0x06
15983};
15984
15985static const hda_nid_t alc861_adc_nids[1] = {
15986	/* ADC0-2 */
15987	0x08,
15988};
15989
15990static const struct hda_input_mux alc861_capture_source = {
15991	.num_items = 5,
15992	.items = {
15993		{ "Mic", 0x0 },
15994		{ "Front Mic", 0x3 },
15995		{ "Line", 0x1 },
15996		{ "CD", 0x4 },
15997		{ "Mixer", 0x5 },
15998	},
15999};
16000
16001static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
16002{
16003	struct alc_spec *spec = codec->spec;
16004	hda_nid_t mix, srcs[5];
16005	int i, j, num;
16006
16007	if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
16008		return 0;
16009	num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
16010	if (num < 0)
16011		return 0;
16012	for (i = 0; i < num; i++) {
16013		unsigned int type;
16014		type = get_wcaps_type(get_wcaps(codec, srcs[i]));
16015		if (type != AC_WID_AUD_OUT)
16016			continue;
16017		for (j = 0; j < spec->multiout.num_dacs; j++)
16018			if (spec->multiout.dac_nids[j] == srcs[i])
16019				break;
16020		if (j >= spec->multiout.num_dacs)
16021			return srcs[i];
16022	}
16023	return 0;
16024}
16025
16026/* fill in the dac_nids table from the parsed pin configuration */
16027static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
16028				     const struct auto_pin_cfg *cfg)
16029{
16030	struct alc_spec *spec = codec->spec;
16031	int i;
16032	hda_nid_t nid, dac;
16033
16034	spec->multiout.dac_nids = spec->private_dac_nids;
16035	for (i = 0; i < cfg->line_outs; i++) {
16036		nid = cfg->line_out_pins[i];
16037		dac = alc861_look_for_dac(codec, nid);
16038		if (!dac)
16039			continue;
16040		spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
16041	}
16042	return 0;
16043}
16044
16045static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
16046				  hda_nid_t nid, int idx, unsigned int chs)
16047{
16048	return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
16049			   HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
16050}
16051
16052#define alc861_create_out_sw(codec, pfx, nid, chs) \
16053	__alc861_create_out_sw(codec, pfx, nid, 0, chs)
16054
16055/* add playback controls from the parsed DAC table */
16056static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
16057					     const struct auto_pin_cfg *cfg)
16058{
16059	struct alc_spec *spec = codec->spec;
16060	static const char * const chname[4] = {
16061		"Front", "Surround", NULL /*CLFE*/, "Side"
16062	};
16063	const char *pfx = alc_get_line_out_pfx(spec, true);
16064	hda_nid_t nid;
16065	int i, err, noutputs;
16066
16067	noutputs = cfg->line_outs;
16068	if (spec->multi_ios > 0)
16069		noutputs += spec->multi_ios;
16070
16071	for (i = 0; i < noutputs; i++) {
16072		nid = spec->multiout.dac_nids[i];
16073		if (!nid)
16074			continue;
16075		if (!pfx && i == 2) {
16076			/* Center/LFE */
16077			err = alc861_create_out_sw(codec, "Center", nid, 1);
16078			if (err < 0)
16079				return err;
16080			err = alc861_create_out_sw(codec, "LFE", nid, 2);
16081			if (err < 0)
16082				return err;
16083		} else {
16084			const char *name = pfx;
16085			int index = i;
16086			if (!name) {
16087				name = chname[i];
16088				index = 0;
16089			}
16090			err = __alc861_create_out_sw(codec, name, nid, index, 3);
16091			if (err < 0)
16092				return err;
16093		}
16094	}
16095	return 0;
16096}
16097
16098static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
16099{
16100	struct alc_spec *spec = codec->spec;
16101	int err;
16102	hda_nid_t nid;
16103
16104	if (!pin)
16105		return 0;
16106
16107	if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
16108		nid = alc861_look_for_dac(codec, pin);
16109		if (nid) {
16110			err = alc861_create_out_sw(codec, "Headphone", nid, 3);
16111			if (err < 0)
16112				return err;
16113			spec->multiout.hp_nid = nid;
16114		}
16115	}
16116	return 0;
16117}
16118
16119/* create playback/capture controls for input pins */
16120static int alc861_auto_create_input_ctls(struct hda_codec *codec,
16121						const struct auto_pin_cfg *cfg)
16122{
16123	return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
16124}
16125
16126static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
16127					      hda_nid_t nid,
16128					      int pin_type, hda_nid_t dac)
16129{
16130	hda_nid_t mix, srcs[5];
16131	int i, num;
16132
16133	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
16134			    pin_type);
16135	snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16136			    AMP_OUT_UNMUTE);
16137	if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
16138		return;
16139	num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
16140	if (num < 0)
16141		return;
16142	for (i = 0; i < num; i++) {
16143		unsigned int mute;
16144		if (srcs[i] == dac || srcs[i] == 0x15)
16145			mute = AMP_IN_UNMUTE(i);
16146		else
16147			mute = AMP_IN_MUTE(i);
16148		snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16149				    mute);
16150	}
16151}
16152
16153static void alc861_auto_init_multi_out(struct hda_codec *codec)
16154{
16155	struct alc_spec *spec = codec->spec;
16156	int i;
16157
16158	for (i = 0; i < spec->autocfg.line_outs; i++) {
16159		hda_nid_t nid = spec->autocfg.line_out_pins[i];
16160		int pin_type = get_pin_type(spec->autocfg.line_out_type);
16161		if (nid)
16162			alc861_auto_set_output_and_unmute(codec, nid, pin_type,
16163							  spec->multiout.dac_nids[i]);
16164	}
16165}
16166
16167static void alc861_auto_init_hp_out(struct hda_codec *codec)
16168{
16169	struct alc_spec *spec = codec->spec;
16170
16171	if (spec->autocfg.hp_outs)
16172		alc861_auto_set_output_and_unmute(codec,
16173						  spec->autocfg.hp_pins[0],
16174						  PIN_HP,
16175						  spec->multiout.hp_nid);
16176	if (spec->autocfg.speaker_outs)
16177		alc861_auto_set_output_and_unmute(codec,
16178						  spec->autocfg.speaker_pins[0],
16179						  PIN_OUT,
16180						  spec->multiout.dac_nids[0]);
16181}
16182
16183static void alc861_auto_init_analog_input(struct hda_codec *codec)
16184{
16185	struct alc_spec *spec = codec->spec;
16186	struct auto_pin_cfg *cfg = &spec->autocfg;
16187	int i;
16188
16189	for (i = 0; i < cfg->num_inputs; i++) {
16190		hda_nid_t nid = cfg->inputs[i].pin;
16191		if (nid >= 0x0c && nid <= 0x11)
16192			alc_set_input_pin(codec, nid, cfg->inputs[i].type);
16193	}
16194}
16195
16196/* parse the BIOS configuration and set up the alc_spec */
16197/* return 1 if successful, 0 if the proper config is not found,
16198 * or a negative error code
16199 */
16200static int alc861_parse_auto_config(struct hda_codec *codec)
16201{
16202	struct alc_spec *spec = codec->spec;
16203	int err;
16204	static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
16205
16206	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16207					   alc861_ignore);
16208	if (err < 0)
16209		return err;
16210	if (!spec->autocfg.line_outs)
16211		return 0; /* can't find valid BIOS pin config */
16212
16213	err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
16214	if (err < 0)
16215		return err;
16216	err = alc_auto_add_multi_channel_mode(codec);
16217	if (err < 0)
16218		return err;
16219	err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
16220	if (err < 0)
16221		return err;
16222	err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
16223	if (err < 0)
16224		return err;
16225	err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
16226	if (err < 0)
16227		return err;
16228
16229	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16230
16231	alc_auto_parse_digital(codec);
16232
16233	if (spec->kctls.list)
16234		add_mixer(spec, spec->kctls.list);
16235
16236	add_verb(spec, alc861_auto_init_verbs);
16237
16238	spec->num_mux_defs = 1;
16239	spec->input_mux = &spec->private_imux[0];
16240
16241	spec->adc_nids = alc861_adc_nids;
16242	spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
16243	set_capture_mixer(codec);
16244
16245	alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
16246
16247	return 1;
16248}
16249
16250/* additional initialization for auto-configuration model */
16251static void alc861_auto_init(struct hda_codec *codec)
16252{
16253	struct alc_spec *spec = codec->spec;
16254	alc861_auto_init_multi_out(codec);
16255	alc861_auto_init_hp_out(codec);
16256	alc861_auto_init_analog_input(codec);
16257	alc_auto_init_digital(codec);
16258	if (spec->unsol_event)
16259		alc_inithook(codec);
16260}
16261
16262#ifdef CONFIG_SND_HDA_POWER_SAVE
16263static const struct hda_amp_list alc861_loopbacks[] = {
16264	{ 0x15, HDA_INPUT, 0 },
16265	{ 0x15, HDA_INPUT, 1 },
16266	{ 0x15, HDA_INPUT, 2 },
16267	{ 0x15, HDA_INPUT, 3 },
16268	{ } /* end */
16269};
16270#endif
16271
16272
16273/*
16274 * configuration and preset
16275 */
16276static const char * const alc861_models[ALC861_MODEL_LAST] = {
16277	[ALC861_3ST]		= "3stack",
16278	[ALC660_3ST]		= "3stack-660",
16279	[ALC861_3ST_DIG]	= "3stack-dig",
16280	[ALC861_6ST_DIG]	= "6stack-dig",
16281	[ALC861_UNIWILL_M31]	= "uniwill-m31",
16282	[ALC861_TOSHIBA]	= "toshiba",
16283	[ALC861_ASUS]		= "asus",
16284	[ALC861_ASUS_LAPTOP]	= "asus-laptop",
16285	[ALC861_AUTO]		= "auto",
16286};
16287
16288static const struct snd_pci_quirk alc861_cfg_tbl[] = {
16289	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
16290	SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16291	SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16292	SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
16293	SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
16294	SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
16295	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
16296	/* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16297	 *        Any other models that need this preset?
16298	 */
16299	/* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
16300	SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16301	SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
16302	SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
16303	SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16304	SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16305	/* FIXME: the below seems conflict */
16306	/* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
16307	SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
16308	SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
16309	{}
16310};
16311
16312static const struct alc_config_preset alc861_presets[] = {
16313	[ALC861_3ST] = {
16314		.mixers = { alc861_3ST_mixer },
16315		.init_verbs = { alc861_threestack_init_verbs },
16316		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
16317		.dac_nids = alc861_dac_nids,
16318		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16319		.channel_mode = alc861_threestack_modes,
16320		.need_dac_fix = 1,
16321		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16322		.adc_nids = alc861_adc_nids,
16323		.input_mux = &alc861_capture_source,
16324	},
16325	[ALC861_3ST_DIG] = {
16326		.mixers = { alc861_base_mixer },
16327		.init_verbs = { alc861_threestack_init_verbs },
16328		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
16329		.dac_nids = alc861_dac_nids,
16330		.dig_out_nid = ALC861_DIGOUT_NID,
16331		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16332		.channel_mode = alc861_threestack_modes,
16333		.need_dac_fix = 1,
16334		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16335		.adc_nids = alc861_adc_nids,
16336		.input_mux = &alc861_capture_source,
16337	},
16338	[ALC861_6ST_DIG] = {
16339		.mixers = { alc861_base_mixer },
16340		.init_verbs = { alc861_base_init_verbs },
16341		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
16342		.dac_nids = alc861_dac_nids,
16343		.dig_out_nid = ALC861_DIGOUT_NID,
16344		.num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16345		.channel_mode = alc861_8ch_modes,
16346		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16347		.adc_nids = alc861_adc_nids,
16348		.input_mux = &alc861_capture_source,
16349	},
16350	[ALC660_3ST] = {
16351		.mixers = { alc861_3ST_mixer },
16352		.init_verbs = { alc861_threestack_init_verbs },
16353		.num_dacs = ARRAY_SIZE(alc660_dac_nids),
16354		.dac_nids = alc660_dac_nids,
16355		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16356		.channel_mode = alc861_threestack_modes,
16357		.need_dac_fix = 1,
16358		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16359		.adc_nids = alc861_adc_nids,
16360		.input_mux = &alc861_capture_source,
16361	},
16362	[ALC861_UNIWILL_M31] = {
16363		.mixers = { alc861_uniwill_m31_mixer },
16364		.init_verbs = { alc861_uniwill_m31_init_verbs },
16365		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
16366		.dac_nids = alc861_dac_nids,
16367		.dig_out_nid = ALC861_DIGOUT_NID,
16368		.num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16369		.channel_mode = alc861_uniwill_m31_modes,
16370		.need_dac_fix = 1,
16371		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16372		.adc_nids = alc861_adc_nids,
16373		.input_mux = &alc861_capture_source,
16374	},
16375	[ALC861_TOSHIBA] = {
16376		.mixers = { alc861_toshiba_mixer },
16377		.init_verbs = { alc861_base_init_verbs,
16378				alc861_toshiba_init_verbs },
16379		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
16380		.dac_nids = alc861_dac_nids,
16381		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16382		.channel_mode = alc883_3ST_2ch_modes,
16383		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16384		.adc_nids = alc861_adc_nids,
16385		.input_mux = &alc861_capture_source,
16386		.unsol_event = alc861_toshiba_unsol_event,
16387		.init_hook = alc861_toshiba_automute,
16388	},
16389	[ALC861_ASUS] = {
16390		.mixers = { alc861_asus_mixer },
16391		.init_verbs = { alc861_asus_init_verbs },
16392		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
16393		.dac_nids = alc861_dac_nids,
16394		.dig_out_nid = ALC861_DIGOUT_NID,
16395		.num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16396		.channel_mode = alc861_asus_modes,
16397		.need_dac_fix = 1,
16398		.hp_nid = 0x06,
16399		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16400		.adc_nids = alc861_adc_nids,
16401		.input_mux = &alc861_capture_source,
16402	},
16403	[ALC861_ASUS_LAPTOP] = {
16404		.mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16405		.init_verbs = { alc861_asus_init_verbs,
16406				alc861_asus_laptop_init_verbs },
16407		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
16408		.dac_nids = alc861_dac_nids,
16409		.dig_out_nid = ALC861_DIGOUT_NID,
16410		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16411		.channel_mode = alc883_3ST_2ch_modes,
16412		.need_dac_fix = 1,
16413		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16414		.adc_nids = alc861_adc_nids,
16415		.input_mux = &alc861_capture_source,
16416	},
16417};
16418
16419/* Pin config fixes */
16420enum {
16421	PINFIX_FSC_AMILO_PI1505,
16422	PINFIX_ASUS_A6RP,
16423};
16424
16425static const struct alc_fixup alc861_fixups[] = {
16426	[PINFIX_FSC_AMILO_PI1505] = {
16427		.type = ALC_FIXUP_PINS,
16428		.v.pins = (const struct alc_pincfg[]) {
16429			{ 0x0b, 0x0221101f }, /* HP */
16430			{ 0x0f, 0x90170310 }, /* speaker */
16431			{ }
16432		}
16433	},
16434	[PINFIX_ASUS_A6RP] = {
16435		.type = ALC_FIXUP_VERBS,
16436		.v.verbs = (const struct hda_verb[]) {
16437			/* node 0x0f VREF seems controlling the master output */
16438			{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
16439			{ }
16440		},
16441	},
16442};
16443
16444static const struct snd_pci_quirk alc861_fixup_tbl[] = {
16445	SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", PINFIX_ASUS_A6RP),
16446	SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", PINFIX_ASUS_A6RP),
16447	SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16448	{}
16449};
16450
16451static int patch_alc861(struct hda_codec *codec)
16452{
16453	struct alc_spec *spec;
16454	int board_config;
16455	int err;
16456
16457	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16458	if (spec == NULL)
16459		return -ENOMEM;
16460
16461	codec->spec = spec;
16462
16463        board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16464						  alc861_models,
16465						  alc861_cfg_tbl);
16466
16467	if (board_config < 0) {
16468		printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16469		       codec->chip_name);
16470		board_config = ALC861_AUTO;
16471	}
16472
16473	if (board_config == ALC861_AUTO) {
16474		alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16475		alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16476	}
16477
16478	if (board_config == ALC861_AUTO) {
16479		/* automatic parse from the BIOS config */
16480		err = alc861_parse_auto_config(codec);
16481		if (err < 0) {
16482			alc_free(codec);
16483			return err;
16484		} else if (!err) {
16485			printk(KERN_INFO
16486			       "hda_codec: Cannot set up configuration "
16487			       "from BIOS.  Using base mode...\n");
16488		   board_config = ALC861_3ST_DIG;
16489		}
16490	}
16491
16492	err = snd_hda_attach_beep_device(codec, 0x23);
16493	if (err < 0) {
16494		alc_free(codec);
16495		return err;
16496	}
16497
16498	if (board_config != ALC861_AUTO)
16499		setup_preset(codec, &alc861_presets[board_config]);
16500
16501	spec->stream_analog_playback = &alc861_pcm_analog_playback;
16502	spec->stream_analog_capture = &alc861_pcm_analog_capture;
16503
16504	spec->stream_digital_playback = &alc861_pcm_digital_playback;
16505	spec->stream_digital_capture = &alc861_pcm_digital_capture;
16506
16507	if (!spec->cap_mixer)
16508		set_capture_mixer(codec);
16509	set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16510
16511	spec->vmaster_nid = 0x03;
16512
16513	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
16514
16515	codec->patch_ops = alc_patch_ops;
16516	if (board_config == ALC861_AUTO) {
16517		spec->init_hook = alc861_auto_init;
16518#ifdef CONFIG_SND_HDA_POWER_SAVE
16519		spec->power_hook = alc_power_eapd;
16520#endif
16521	}
16522#ifdef CONFIG_SND_HDA_POWER_SAVE
16523	if (!spec->loopback.amplist)
16524		spec->loopback.amplist = alc861_loopbacks;
16525#endif
16526
16527	return 0;
16528}
16529
16530/*
16531 * ALC861-VD support
16532 *
16533 * Based on ALC882
16534 *
16535 * In addition, an independent DAC
16536 */
16537#define ALC861VD_DIGOUT_NID	0x06
16538
16539static const hda_nid_t alc861vd_dac_nids[4] = {
16540	/* front, surr, clfe, side surr */
16541	0x02, 0x03, 0x04, 0x05
16542};
16543
16544/* dac_nids for ALC660vd are in a different order - according to
16545 * Realtek's driver.
16546 * This should probably result in a different mixer for 6stack models
16547 * of ALC660vd codecs, but for now there is only 3stack mixer
16548 * - and it is the same as in 861vd.
16549 * adc_nids in ALC660vd are (is) the same as in 861vd
16550 */
16551static const hda_nid_t alc660vd_dac_nids[3] = {
16552	/* front, rear, clfe, rear_surr */
16553	0x02, 0x04, 0x03
16554};
16555
16556static const hda_nid_t alc861vd_adc_nids[1] = {
16557	/* ADC0 */
16558	0x09,
16559};
16560
16561static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
16562
16563/* input MUX */
16564/* FIXME: should be a matrix-type input source selection */
16565static const struct hda_input_mux alc861vd_capture_source = {
16566	.num_items = 4,
16567	.items = {
16568		{ "Mic", 0x0 },
16569		{ "Front Mic", 0x1 },
16570		{ "Line", 0x2 },
16571		{ "CD", 0x4 },
16572	},
16573};
16574
16575static const struct hda_input_mux alc861vd_dallas_capture_source = {
16576	.num_items = 2,
16577	.items = {
16578		{ "Mic", 0x0 },
16579		{ "Internal Mic", 0x1 },
16580	},
16581};
16582
16583static const struct hda_input_mux alc861vd_hp_capture_source = {
16584	.num_items = 2,
16585	.items = {
16586		{ "Front Mic", 0x0 },
16587		{ "ATAPI Mic", 0x1 },
16588	},
16589};
16590
16591/*
16592 * 2ch mode
16593 */
16594static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
16595	{ 2, NULL }
16596};
16597
16598/*
16599 * 6ch mode
16600 */
16601static const struct hda_verb alc861vd_6stack_ch6_init[] = {
16602	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16603	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16604	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16605	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16606	{ } /* end */
16607};
16608
16609/*
16610 * 8ch mode
16611 */
16612static const struct hda_verb alc861vd_6stack_ch8_init[] = {
16613	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16614	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16615	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16616	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16617	{ } /* end */
16618};
16619
16620static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
16621	{ 6, alc861vd_6stack_ch6_init },
16622	{ 8, alc861vd_6stack_ch8_init },
16623};
16624
16625static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16626	{
16627		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16628		.name = "Channel Mode",
16629		.info = alc_ch_mode_info,
16630		.get = alc_ch_mode_get,
16631		.put = alc_ch_mode_put,
16632	},
16633	{ } /* end */
16634};
16635
16636/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16637 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16638 */
16639static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16640	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16641	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16642
16643	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16644	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16645
16646	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16647				HDA_OUTPUT),
16648	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16649				HDA_OUTPUT),
16650	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16651	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16652
16653	HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16654	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16655
16656	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16657
16658	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16659	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16660	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16661
16662	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16663	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16664	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16665
16666	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16667	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16668
16669	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16670	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16671
16672	{ } /* end */
16673};
16674
16675static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16676	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16677	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16678
16679	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16680
16681	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16682	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16683	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16684
16685	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16686	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16687	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16688
16689	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16690	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16691
16692	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16693	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16694
16695	{ } /* end */
16696};
16697
16698static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16699	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16700	/*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16701	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16702
16703	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16704
16705	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16706	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16707	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16708
16709	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16710	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16711	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16712
16713	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16714	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16715
16716	{ } /* end */
16717};
16718
16719/* Pin assignment: Speaker=0x14, HP = 0x15,
16720 *                 Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
16721 */
16722static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
16723	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16724	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
16725	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16726	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16727	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16728	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16729	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16730	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
16731	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16732	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16733	{ } /* end */
16734};
16735
16736/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16737 *                 Front Mic=0x18, ATAPI Mic = 0x19,
16738 */
16739static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16740	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16741	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16742	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16743	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16744	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16745	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16746	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16747	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16748
16749	{ } /* end */
16750};
16751
16752/*
16753 * generic initialization of ADC, input mixers and output mixers
16754 */
16755static const struct hda_verb alc861vd_volume_init_verbs[] = {
16756	/*
16757	 * Unmute ADC0 and set the default input to mic-in
16758	 */
16759	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16760	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16761
16762	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16763	 * the analog-loopback mixer widget
16764	 */
16765	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16766	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16767	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16768	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16769	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16770	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16771
16772	/* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
16773	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16774	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16775	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
16776	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
16777
16778	/*
16779	 * Set up output mixers (0x02 - 0x05)
16780	 */
16781	/* set vol=0 to output mixers */
16782	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16783	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16784	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16785	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16786
16787	/* set up input amps for analog loopback */
16788	/* Amp Indices: DAC = 0, mixer = 1 */
16789	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16790	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16791	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16792	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16793	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16794	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16795	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16796	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16797
16798	{ }
16799};
16800
16801/*
16802 * 3-stack pin configuration:
16803 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16804 */
16805static const struct hda_verb alc861vd_3stack_init_verbs[] = {
16806	/*
16807	 * Set pin mode and muting
16808	 */
16809	/* set front pin widgets 0x14 for output */
16810	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16811	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16812	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16813
16814	/* Mic (rear) pin: input vref at 80% */
16815	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16816	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16817	/* Front Mic pin: input vref at 80% */
16818	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16819	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16820	/* Line In pin: input */
16821	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16822	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16823	/* Line-2 In: Headphone output (output 0 - 0x0c) */
16824	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16825	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16826	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16827	/* CD pin widget for input */
16828	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16829
16830	{ }
16831};
16832
16833/*
16834 * 6-stack pin configuration:
16835 */
16836static const struct hda_verb alc861vd_6stack_init_verbs[] = {
16837	/*
16838	 * Set pin mode and muting
16839	 */
16840	/* set front pin widgets 0x14 for output */
16841	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16842	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16843	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16844
16845	/* Rear Pin: output 1 (0x0d) */
16846	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16847	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16848	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16849	/* CLFE Pin: output 2 (0x0e) */
16850	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16851	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16852	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16853	/* Side Pin: output 3 (0x0f) */
16854	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16855	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16856	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16857
16858	/* Mic (rear) pin: input vref at 80% */
16859	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16860	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16861	/* Front Mic pin: input vref at 80% */
16862	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16863	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16864	/* Line In pin: input */
16865	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16866	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16867	/* Line-2 In: Headphone output (output 0 - 0x0c) */
16868	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16869	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16870	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16871	/* CD pin widget for input */
16872	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16873
16874	{ }
16875};
16876
16877static const struct hda_verb alc861vd_eapd_verbs[] = {
16878	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16879	{ }
16880};
16881
16882static const struct hda_verb alc660vd_eapd_verbs[] = {
16883	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16884	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16885	{ }
16886};
16887
16888static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16889	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16890	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16891	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16892	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16893	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16894	{}
16895};
16896
16897static void alc861vd_lenovo_setup(struct hda_codec *codec)
16898{
16899	struct alc_spec *spec = codec->spec;
16900	spec->autocfg.hp_pins[0] = 0x1b;
16901	spec->autocfg.speaker_pins[0] = 0x14;
16902	spec->automute = 1;
16903	spec->automute_mode = ALC_AUTOMUTE_AMP;
16904}
16905
16906static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16907{
16908	alc_hp_automute(codec);
16909	alc88x_simple_mic_automute(codec);
16910}
16911
16912static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16913					unsigned int res)
16914{
16915	switch (res >> 26) {
16916	case ALC880_MIC_EVENT:
16917		alc88x_simple_mic_automute(codec);
16918		break;
16919	default:
16920		alc_sku_unsol_event(codec, res);
16921		break;
16922	}
16923}
16924
16925static const struct hda_verb alc861vd_dallas_verbs[] = {
16926	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16927	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16928	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16929	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16930
16931	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16932	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16933	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16934	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16935	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16936	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16937	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16938	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16939
16940	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16941	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16942	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16943	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16944	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16945	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16946	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16947	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16948
16949	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16950	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16951	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16952	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16953	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16954	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16955	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16956	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16957
16958	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16959	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16960	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16961	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16962
16963	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16964	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16965	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16966
16967	{ } /* end */
16968};
16969
16970/* toggle speaker-output according to the hp-jack state */
16971static void alc861vd_dallas_setup(struct hda_codec *codec)
16972{
16973	struct alc_spec *spec = codec->spec;
16974
16975	spec->autocfg.hp_pins[0] = 0x15;
16976	spec->autocfg.speaker_pins[0] = 0x14;
16977	spec->automute = 1;
16978	spec->automute_mode = ALC_AUTOMUTE_AMP;
16979}
16980
16981#ifdef CONFIG_SND_HDA_POWER_SAVE
16982#define alc861vd_loopbacks	alc880_loopbacks
16983#endif
16984
16985/* pcm configuration: identical with ALC880 */
16986#define alc861vd_pcm_analog_playback	alc880_pcm_analog_playback
16987#define alc861vd_pcm_analog_capture	alc880_pcm_analog_capture
16988#define alc861vd_pcm_digital_playback	alc880_pcm_digital_playback
16989#define alc861vd_pcm_digital_capture	alc880_pcm_digital_capture
16990
16991/*
16992 * configuration and preset
16993 */
16994static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
16995	[ALC660VD_3ST]		= "3stack-660",
16996	[ALC660VD_3ST_DIG]	= "3stack-660-digout",
16997	[ALC660VD_ASUS_V1S]	= "asus-v1s",
16998	[ALC861VD_3ST]		= "3stack",
16999	[ALC861VD_3ST_DIG]	= "3stack-digout",
17000	[ALC861VD_6ST_DIG]	= "6stack-digout",
17001	[ALC861VD_LENOVO]	= "lenovo",
17002	[ALC861VD_DALLAS]	= "dallas",
17003	[ALC861VD_HP]		= "hp",
17004	[ALC861VD_AUTO]		= "auto",
17005};
17006
17007static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
17008	SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
17009	SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
17010	SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
17011	/*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
17012	SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
17013	SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
17014	SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
17015	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
17016	/*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
17017	SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
17018	SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
17019	SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
17020	SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
17021	SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
17022	SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
17023	{}
17024};
17025
17026static const struct alc_config_preset alc861vd_presets[] = {
17027	[ALC660VD_3ST] = {
17028		.mixers = { alc861vd_3st_mixer },
17029		.init_verbs = { alc861vd_volume_init_verbs,
17030				 alc861vd_3stack_init_verbs },
17031		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17032		.dac_nids = alc660vd_dac_nids,
17033		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17034		.channel_mode = alc861vd_3stack_2ch_modes,
17035		.input_mux = &alc861vd_capture_source,
17036	},
17037	[ALC660VD_3ST_DIG] = {
17038		.mixers = { alc861vd_3st_mixer },
17039		.init_verbs = { alc861vd_volume_init_verbs,
17040				 alc861vd_3stack_init_verbs },
17041		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17042		.dac_nids = alc660vd_dac_nids,
17043		.dig_out_nid = ALC861VD_DIGOUT_NID,
17044		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17045		.channel_mode = alc861vd_3stack_2ch_modes,
17046		.input_mux = &alc861vd_capture_source,
17047	},
17048	[ALC861VD_3ST] = {
17049		.mixers = { alc861vd_3st_mixer },
17050		.init_verbs = { alc861vd_volume_init_verbs,
17051				 alc861vd_3stack_init_verbs },
17052		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17053		.dac_nids = alc861vd_dac_nids,
17054		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17055		.channel_mode = alc861vd_3stack_2ch_modes,
17056		.input_mux = &alc861vd_capture_source,
17057	},
17058	[ALC861VD_3ST_DIG] = {
17059		.mixers = { alc861vd_3st_mixer },
17060		.init_verbs = { alc861vd_volume_init_verbs,
17061		 		 alc861vd_3stack_init_verbs },
17062		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17063		.dac_nids = alc861vd_dac_nids,
17064		.dig_out_nid = ALC861VD_DIGOUT_NID,
17065		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17066		.channel_mode = alc861vd_3stack_2ch_modes,
17067		.input_mux = &alc861vd_capture_source,
17068	},
17069	[ALC861VD_6ST_DIG] = {
17070		.mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
17071		.init_verbs = { alc861vd_volume_init_verbs,
17072				alc861vd_6stack_init_verbs },
17073		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17074		.dac_nids = alc861vd_dac_nids,
17075		.dig_out_nid = ALC861VD_DIGOUT_NID,
17076		.num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
17077		.channel_mode = alc861vd_6stack_modes,
17078		.input_mux = &alc861vd_capture_source,
17079	},
17080	[ALC861VD_LENOVO] = {
17081		.mixers = { alc861vd_lenovo_mixer },
17082		.init_verbs = { alc861vd_volume_init_verbs,
17083				alc861vd_3stack_init_verbs,
17084				alc861vd_eapd_verbs,
17085				alc861vd_lenovo_unsol_verbs },
17086		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17087		.dac_nids = alc660vd_dac_nids,
17088		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17089		.channel_mode = alc861vd_3stack_2ch_modes,
17090		.input_mux = &alc861vd_capture_source,
17091		.unsol_event = alc861vd_lenovo_unsol_event,
17092		.setup = alc861vd_lenovo_setup,
17093		.init_hook = alc861vd_lenovo_init_hook,
17094	},
17095	[ALC861VD_DALLAS] = {
17096		.mixers = { alc861vd_dallas_mixer },
17097		.init_verbs = { alc861vd_dallas_verbs },
17098		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17099		.dac_nids = alc861vd_dac_nids,
17100		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17101		.channel_mode = alc861vd_3stack_2ch_modes,
17102		.input_mux = &alc861vd_dallas_capture_source,
17103		.unsol_event = alc_sku_unsol_event,
17104		.setup = alc861vd_dallas_setup,
17105		.init_hook = alc_hp_automute,
17106	},
17107	[ALC861VD_HP] = {
17108		.mixers = { alc861vd_hp_mixer },
17109		.init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
17110		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17111		.dac_nids = alc861vd_dac_nids,
17112		.dig_out_nid = ALC861VD_DIGOUT_NID,
17113		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17114		.channel_mode = alc861vd_3stack_2ch_modes,
17115		.input_mux = &alc861vd_hp_capture_source,
17116		.unsol_event = alc_sku_unsol_event,
17117		.setup = alc861vd_dallas_setup,
17118		.init_hook = alc_hp_automute,
17119	},
17120	[ALC660VD_ASUS_V1S] = {
17121		.mixers = { alc861vd_lenovo_mixer },
17122		.init_verbs = { alc861vd_volume_init_verbs,
17123				alc861vd_3stack_init_verbs,
17124				alc861vd_eapd_verbs,
17125				alc861vd_lenovo_unsol_verbs },
17126		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17127		.dac_nids = alc660vd_dac_nids,
17128		.dig_out_nid = ALC861VD_DIGOUT_NID,
17129		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17130		.channel_mode = alc861vd_3stack_2ch_modes,
17131		.input_mux = &alc861vd_capture_source,
17132		.unsol_event = alc861vd_lenovo_unsol_event,
17133		.setup = alc861vd_lenovo_setup,
17134		.init_hook = alc861vd_lenovo_init_hook,
17135	},
17136};
17137
17138/*
17139 * BIOS auto configuration
17140 */
17141static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
17142						const struct auto_pin_cfg *cfg)
17143{
17144	return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
17145}
17146
17147
17148static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
17149				hda_nid_t nid, int pin_type, int dac_idx)
17150{
17151	alc_set_pin_output(codec, nid, pin_type);
17152}
17153
17154static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
17155{
17156	struct alc_spec *spec = codec->spec;
17157	int i;
17158
17159	for (i = 0; i <= HDA_SIDE; i++) {
17160		hda_nid_t nid = spec->autocfg.line_out_pins[i];
17161		int pin_type = get_pin_type(spec->autocfg.line_out_type);
17162		if (nid)
17163			alc861vd_auto_set_output_and_unmute(codec, nid,
17164							    pin_type, i);
17165	}
17166}
17167
17168
17169static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
17170{
17171	struct alc_spec *spec = codec->spec;
17172	hda_nid_t pin;
17173
17174	pin = spec->autocfg.hp_pins[0];
17175	if (pin) /* connect to front and use dac 0 */
17176		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
17177	pin = spec->autocfg.speaker_pins[0];
17178	if (pin)
17179		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
17180}
17181
17182#define ALC861VD_PIN_CD_NID		ALC880_PIN_CD_NID
17183
17184static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
17185{
17186	struct alc_spec *spec = codec->spec;
17187	struct auto_pin_cfg *cfg = &spec->autocfg;
17188	int i;
17189
17190	for (i = 0; i < cfg->num_inputs; i++) {
17191		hda_nid_t nid = cfg->inputs[i].pin;
17192		if (alc_is_input_pin(codec, nid)) {
17193			alc_set_input_pin(codec, nid, cfg->inputs[i].type);
17194			if (nid != ALC861VD_PIN_CD_NID &&
17195			    (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
17196				snd_hda_codec_write(codec, nid, 0,
17197						AC_VERB_SET_AMP_GAIN_MUTE,
17198						AMP_OUT_MUTE);
17199		}
17200	}
17201}
17202
17203#define alc861vd_auto_init_input_src	alc882_auto_init_input_src
17204
17205#define alc861vd_idx_to_mixer_vol(nid)		((nid) + 0x02)
17206#define alc861vd_idx_to_mixer_switch(nid)	((nid) + 0x0c)
17207
17208/* add playback controls from the parsed DAC table */
17209/* Based on ALC880 version. But ALC861VD has separate,
17210 * different NIDs for mute/unmute switch and volume control */
17211static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17212					     const struct auto_pin_cfg *cfg)
17213{
17214	static const char * const chname[4] = {
17215		"Front", "Surround", "CLFE", "Side"
17216	};
17217	const char *pfx = alc_get_line_out_pfx(spec, true);
17218	hda_nid_t nid_v, nid_s;
17219	int i, err, noutputs;
17220
17221	noutputs = cfg->line_outs;
17222	if (spec->multi_ios > 0)
17223		noutputs += spec->multi_ios;
17224
17225	for (i = 0; i < noutputs; i++) {
17226		if (!spec->multiout.dac_nids[i])
17227			continue;
17228		nid_v = alc861vd_idx_to_mixer_vol(
17229				alc880_dac_to_idx(
17230					spec->multiout.dac_nids[i]));
17231		nid_s = alc861vd_idx_to_mixer_switch(
17232				alc880_dac_to_idx(
17233					spec->multiout.dac_nids[i]));
17234
17235		if (!pfx && i == 2) {
17236			/* Center/LFE */
17237			err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17238					      "Center",
17239					  HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
17240							      HDA_OUTPUT));
17241			if (err < 0)
17242				return err;
17243			err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17244					      "LFE",
17245					  HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
17246							      HDA_OUTPUT));
17247			if (err < 0)
17248				return err;
17249			err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17250					     "Center",
17251					  HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17252							      HDA_INPUT));
17253			if (err < 0)
17254				return err;
17255			err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17256					     "LFE",
17257					  HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17258							      HDA_INPUT));
17259			if (err < 0)
17260				return err;
17261		} else {
17262			const char *name = pfx;
17263			int index = i;
17264			if (!name) {
17265				name = chname[i];
17266				index = 0;
17267			}
17268			err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17269						name, index,
17270					  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17271							      HDA_OUTPUT));
17272			if (err < 0)
17273				return err;
17274			err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17275					       name, index,
17276					  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
17277							      HDA_INPUT));
17278			if (err < 0)
17279				return err;
17280		}
17281	}
17282	return 0;
17283}
17284
17285/* add playback controls for speaker and HP outputs */
17286/* Based on ALC880 version. But ALC861VD has separate,
17287 * different NIDs for mute/unmute switch and volume control */
17288static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17289					hda_nid_t pin, const char *pfx)
17290{
17291	hda_nid_t nid_v, nid_s;
17292	int err;
17293
17294	if (!pin)
17295		return 0;
17296
17297	if (alc880_is_fixed_pin(pin)) {
17298		nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17299		/* specify the DAC as the extra output */
17300		if (!spec->multiout.hp_nid)
17301			spec->multiout.hp_nid = nid_v;
17302		else
17303			spec->multiout.extra_out_nid[0] = nid_v;
17304		/* control HP volume/switch on the output mixer amp */
17305		nid_v = alc861vd_idx_to_mixer_vol(
17306				alc880_fixed_pin_idx(pin));
17307		nid_s = alc861vd_idx_to_mixer_switch(
17308				alc880_fixed_pin_idx(pin));
17309
17310		err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
17311				  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17312		if (err < 0)
17313			return err;
17314		err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
17315				  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17316		if (err < 0)
17317			return err;
17318	} else if (alc880_is_multi_pin(pin)) {
17319		/* set manual connection */
17320		/* we have only a switch on HP-out PIN */
17321		err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
17322				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17323		if (err < 0)
17324			return err;
17325	}
17326	return 0;
17327}
17328
17329/* parse the BIOS configuration and set up the alc_spec
17330 * return 1 if successful, 0 if the proper config is not found,
17331 * or a negative error code
17332 * Based on ALC880 version - had to change it to override
17333 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17334static int alc861vd_parse_auto_config(struct hda_codec *codec)
17335{
17336	struct alc_spec *spec = codec->spec;
17337	int err;
17338	static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
17339
17340	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17341					   alc861vd_ignore);
17342	if (err < 0)
17343		return err;
17344	if (!spec->autocfg.line_outs)
17345		return 0; /* can't find valid BIOS pin config */
17346
17347	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17348	if (err < 0)
17349		return err;
17350	err = alc_auto_add_multi_channel_mode(codec);
17351	if (err < 0)
17352		return err;
17353	err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17354	if (err < 0)
17355		return err;
17356	err = alc861vd_auto_create_extra_out(spec,
17357					     spec->autocfg.speaker_pins[0],
17358					     "Speaker");
17359	if (err < 0)
17360		return err;
17361	err = alc861vd_auto_create_extra_out(spec,
17362					     spec->autocfg.hp_pins[0],
17363					     "Headphone");
17364	if (err < 0)
17365		return err;
17366	err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
17367	if (err < 0)
17368		return err;
17369
17370	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17371
17372	alc_auto_parse_digital(codec);
17373
17374	if (spec->kctls.list)
17375		add_mixer(spec, spec->kctls.list);
17376
17377	add_verb(spec, alc861vd_volume_init_verbs);
17378
17379	spec->num_mux_defs = 1;
17380	spec->input_mux = &spec->private_imux[0];
17381
17382	err = alc_auto_add_mic_boost(codec);
17383	if (err < 0)
17384		return err;
17385
17386	alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
17387
17388	return 1;
17389}
17390
17391/* additional initialization for auto-configuration model */
17392static void alc861vd_auto_init(struct hda_codec *codec)
17393{
17394	struct alc_spec *spec = codec->spec;
17395	alc861vd_auto_init_multi_out(codec);
17396	alc861vd_auto_init_hp_out(codec);
17397	alc861vd_auto_init_analog_input(codec);
17398	alc861vd_auto_init_input_src(codec);
17399	alc_auto_init_digital(codec);
17400	if (spec->unsol_event)
17401		alc_inithook(codec);
17402}
17403
17404enum {
17405	ALC660VD_FIX_ASUS_GPIO1
17406};
17407
17408/* reset GPIO1 */
17409static const struct alc_fixup alc861vd_fixups[] = {
17410	[ALC660VD_FIX_ASUS_GPIO1] = {
17411		.type = ALC_FIXUP_VERBS,
17412		.v.verbs = (const struct hda_verb[]) {
17413			{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17414			{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17415			{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17416			{ }
17417		}
17418	},
17419};
17420
17421static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
17422	SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17423	{}
17424};
17425
17426static int patch_alc861vd(struct hda_codec *codec)
17427{
17428	struct alc_spec *spec;
17429	int err, board_config;
17430
17431	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17432	if (spec == NULL)
17433		return -ENOMEM;
17434
17435	codec->spec = spec;
17436
17437	board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17438						  alc861vd_models,
17439						  alc861vd_cfg_tbl);
17440
17441	if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
17442		printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17443		       codec->chip_name);
17444		board_config = ALC861VD_AUTO;
17445	}
17446
17447	if (board_config == ALC861VD_AUTO) {
17448		alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17449		alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17450	}
17451
17452	if (board_config == ALC861VD_AUTO) {
17453		/* automatic parse from the BIOS config */
17454		err = alc861vd_parse_auto_config(codec);
17455		if (err < 0) {
17456			alc_free(codec);
17457			return err;
17458		} else if (!err) {
17459			printk(KERN_INFO
17460			       "hda_codec: Cannot set up configuration "
17461			       "from BIOS.  Using base mode...\n");
17462			board_config = ALC861VD_3ST;
17463		}
17464	}
17465
17466	err = snd_hda_attach_beep_device(codec, 0x23);
17467	if (err < 0) {
17468		alc_free(codec);
17469		return err;
17470	}
17471
17472	if (board_config != ALC861VD_AUTO)
17473		setup_preset(codec, &alc861vd_presets[board_config]);
17474
17475	if (codec->vendor_id == 0x10ec0660) {
17476		/* always turn on EAPD */
17477		add_verb(spec, alc660vd_eapd_verbs);
17478	}
17479
17480	spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17481	spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17482
17483	spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17484	spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17485
17486	if (!spec->adc_nids) {
17487		spec->adc_nids = alc861vd_adc_nids;
17488		spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17489	}
17490	if (!spec->capsrc_nids)
17491		spec->capsrc_nids = alc861vd_capsrc_nids;
17492
17493	set_capture_mixer(codec);
17494	set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17495
17496	spec->vmaster_nid = 0x02;
17497
17498	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
17499
17500	codec->patch_ops = alc_patch_ops;
17501
17502	if (board_config == ALC861VD_AUTO)
17503		spec->init_hook = alc861vd_auto_init;
17504	spec->shutup = alc_eapd_shutup;
17505#ifdef CONFIG_SND_HDA_POWER_SAVE
17506	if (!spec->loopback.amplist)
17507		spec->loopback.amplist = alc861vd_loopbacks;
17508#endif
17509
17510	return 0;
17511}
17512
17513/*
17514 * ALC662 support
17515 *
17516 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17517 * configuration.  Each pin widget can choose any input DACs and a mixer.
17518 * Each ADC is connected from a mixer of all inputs.  This makes possible
17519 * 6-channel independent captures.
17520 *
17521 * In addition, an independent DAC for the multi-playback (not used in this
17522 * driver yet).
17523 */
17524#define ALC662_DIGOUT_NID	0x06
17525#define ALC662_DIGIN_NID	0x0a
17526
17527static const hda_nid_t alc662_dac_nids[3] = {
17528	/* front, rear, clfe */
17529	0x02, 0x03, 0x04
17530};
17531
17532static const hda_nid_t alc272_dac_nids[2] = {
17533	0x02, 0x03
17534};
17535
17536static const hda_nid_t alc662_adc_nids[2] = {
17537	/* ADC1-2 */
17538	0x09, 0x08
17539};
17540
17541static const hda_nid_t alc272_adc_nids[1] = {
17542	/* ADC1-2 */
17543	0x08,
17544};
17545
17546static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
17547static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
17548
17549
17550/* input MUX */
17551/* FIXME: should be a matrix-type input source selection */
17552static const struct hda_input_mux alc662_capture_source = {
17553	.num_items = 4,
17554	.items = {
17555		{ "Mic", 0x0 },
17556		{ "Front Mic", 0x1 },
17557		{ "Line", 0x2 },
17558		{ "CD", 0x4 },
17559	},
17560};
17561
17562static const struct hda_input_mux alc662_lenovo_101e_capture_source = {
17563	.num_items = 2,
17564	.items = {
17565		{ "Mic", 0x1 },
17566		{ "Line", 0x2 },
17567	},
17568};
17569
17570static const struct hda_input_mux alc663_capture_source = {
17571	.num_items = 3,
17572	.items = {
17573		{ "Mic", 0x0 },
17574		{ "Front Mic", 0x1 },
17575		{ "Line", 0x2 },
17576	},
17577};
17578
17579#if 0 /* set to 1 for testing other input sources below */
17580static const struct hda_input_mux alc272_nc10_capture_source = {
17581	.num_items = 16,
17582	.items = {
17583		{ "Autoselect Mic", 0x0 },
17584		{ "Internal Mic", 0x1 },
17585		{ "In-0x02", 0x2 },
17586		{ "In-0x03", 0x3 },
17587		{ "In-0x04", 0x4 },
17588		{ "In-0x05", 0x5 },
17589		{ "In-0x06", 0x6 },
17590		{ "In-0x07", 0x7 },
17591		{ "In-0x08", 0x8 },
17592		{ "In-0x09", 0x9 },
17593		{ "In-0x0a", 0x0a },
17594		{ "In-0x0b", 0x0b },
17595		{ "In-0x0c", 0x0c },
17596		{ "In-0x0d", 0x0d },
17597		{ "In-0x0e", 0x0e },
17598		{ "In-0x0f", 0x0f },
17599	},
17600};
17601#endif
17602
17603/*
17604 * 2ch mode
17605 */
17606static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
17607	{ 2, NULL }
17608};
17609
17610/*
17611 * 2ch mode
17612 */
17613static const struct hda_verb alc662_3ST_ch2_init[] = {
17614	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17615	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17616	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17617	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17618	{ } /* end */
17619};
17620
17621/*
17622 * 6ch mode
17623 */
17624static const struct hda_verb alc662_3ST_ch6_init[] = {
17625	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17626	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17627	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17628	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17629	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17630	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17631	{ } /* end */
17632};
17633
17634static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17635	{ 2, alc662_3ST_ch2_init },
17636	{ 6, alc662_3ST_ch6_init },
17637};
17638
17639/*
17640 * 2ch mode
17641 */
17642static const struct hda_verb alc662_sixstack_ch6_init[] = {
17643	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17644	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17645	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17646	{ } /* end */
17647};
17648
17649/*
17650 * 6ch mode
17651 */
17652static const struct hda_verb alc662_sixstack_ch8_init[] = {
17653	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17654	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17655	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17656	{ } /* end */
17657};
17658
17659static const struct hda_channel_mode alc662_5stack_modes[2] = {
17660	{ 2, alc662_sixstack_ch6_init },
17661	{ 6, alc662_sixstack_ch8_init },
17662};
17663
17664/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17665 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17666 */
17667
17668static const struct snd_kcontrol_new alc662_base_mixer[] = {
17669	/* output mixer control */
17670	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
17671	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17672	HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
17673	HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
17674	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17675	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17676	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17677	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
17678	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17679
17680	/*Input mixer control */
17681	HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17682	HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17683	HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17684	HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17685	HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17686	HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17687	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17688	HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
17689	{ } /* end */
17690};
17691
17692static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17693	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17694	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17695	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17696	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17697	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17698	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17699	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17700	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17701	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17702	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17703	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17704	{ } /* end */
17705};
17706
17707static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17708	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17709	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17710	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17711	HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
17712	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17713	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17714	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17715	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
17716	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17717	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17718	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17719	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17720	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17721	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17722	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17723	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17724	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17725	{ } /* end */
17726};
17727
17728static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17729	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17730	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
17731	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17732	HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
17733	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17734	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17735	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17736	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17737	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17738	{ } /* end */
17739};
17740
17741static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
17742	HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17743	ALC262_HIPPO_MASTER_SWITCH,
17744
17745	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
17746	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17747	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17748
17749	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
17750	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17751	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17752	{ } /* end */
17753};
17754
17755static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
17756	ALC262_HIPPO_MASTER_SWITCH,
17757	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17758	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17759	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17760	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17761	HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17762	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17763	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17764	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17765	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17766	{ } /* end */
17767};
17768
17769static const struct hda_bind_ctls alc663_asus_bind_master_vol = {
17770	.ops = &snd_hda_bind_vol,
17771	.values = {
17772		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17773		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17774		0
17775	},
17776};
17777
17778static const struct hda_bind_ctls alc663_asus_one_bind_switch = {
17779	.ops = &snd_hda_bind_sw,
17780	.values = {
17781		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17782		HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17783		0
17784	},
17785};
17786
17787static const struct snd_kcontrol_new alc663_m51va_mixer[] = {
17788	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17789	HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17790	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17791	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17792	{ } /* end */
17793};
17794
17795static const struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17796	.ops = &snd_hda_bind_sw,
17797	.values = {
17798		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17799		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17800		HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17801		0
17802	},
17803};
17804
17805static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17806	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17807	HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17808	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17809	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17810	HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17811	HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17812
17813	{ } /* end */
17814};
17815
17816static const struct hda_bind_ctls alc663_asus_four_bind_switch = {
17817	.ops = &snd_hda_bind_sw,
17818	.values = {
17819		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17820		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17821		HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17822		0
17823	},
17824};
17825
17826static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17827	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17828	HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17829	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17830	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17831	HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17832	HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17833	{ } /* end */
17834};
17835
17836static const struct snd_kcontrol_new alc662_1bjd_mixer[] = {
17837	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17838	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17839	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17840	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17841	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17842	HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17843	HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17844	{ } /* end */
17845};
17846
17847static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17848	.ops = &snd_hda_bind_vol,
17849	.values = {
17850		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17851		HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17852		0
17853	},
17854};
17855
17856static const struct hda_bind_ctls alc663_asus_two_bind_switch = {
17857	.ops = &snd_hda_bind_sw,
17858	.values = {
17859		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17860		HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17861		0
17862	},
17863};
17864
17865static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17866	HDA_BIND_VOL("Master Playback Volume",
17867				&alc663_asus_two_bind_master_vol),
17868	HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17869	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17870	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17871	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17872	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17873	{ } /* end */
17874};
17875
17876static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17877	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17878	HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17879	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17880	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17881	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17882	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17883	{ } /* end */
17884};
17885
17886static const struct snd_kcontrol_new alc663_g71v_mixer[] = {
17887	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17888	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17889	HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17890	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17891	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17892
17893	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17894	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17895	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17896	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17897	{ } /* end */
17898};
17899
17900static const struct snd_kcontrol_new alc663_g50v_mixer[] = {
17901	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17902	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17903	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17904
17905	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17906	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17907	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17908	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17909	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17910	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17911	{ } /* end */
17912};
17913
17914static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17915	.ops = &snd_hda_bind_sw,
17916	.values = {
17917		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17918		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17919		HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17920		HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17921		HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17922		0
17923	},
17924};
17925
17926static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17927	.ops = &snd_hda_bind_sw,
17928	.values = {
17929		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17930		HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17931		0
17932	},
17933};
17934
17935static const struct snd_kcontrol_new alc663_mode7_mixer[] = {
17936	HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17937	HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17938	HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17939	HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17940	HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17941	HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17942	HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17943	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17944	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17945	{ } /* end */
17946};
17947
17948static const struct snd_kcontrol_new alc663_mode8_mixer[] = {
17949	HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17950	HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17951	HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17952	HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17953	HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17954	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17955	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17956	{ } /* end */
17957};
17958
17959
17960static const struct snd_kcontrol_new alc662_chmode_mixer[] = {
17961	{
17962		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17963		.name = "Channel Mode",
17964		.info = alc_ch_mode_info,
17965		.get = alc_ch_mode_get,
17966		.put = alc_ch_mode_put,
17967	},
17968	{ } /* end */
17969};
17970
17971static const struct hda_verb alc662_init_verbs[] = {
17972	/* ADC: mute amp left and right */
17973	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17974	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
17975
17976	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17977	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17978	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17979	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17980	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17981	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17982
17983	/* Front Pin: output 0 (0x0c) */
17984	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17985	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17986
17987	/* Rear Pin: output 1 (0x0d) */
17988	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17989	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17990
17991	/* CLFE Pin: output 2 (0x0e) */
17992	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17993	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17994
17995	/* Mic (rear) pin: input vref at 80% */
17996	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17997	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17998	/* Front Mic pin: input vref at 80% */
17999	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
18000	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
18001	/* Line In pin: input */
18002	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18003	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
18004	/* Line-2 In: Headphone output (output 0 - 0x0c) */
18005	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18006	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18007	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
18008	/* CD pin widget for input */
18009	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18010
18011	/* FIXME: use matrix-type input source selection */
18012	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
18013	/* Input mixer */
18014	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
18015	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
18016
18017	{ }
18018};
18019
18020static const struct hda_verb alc662_eapd_init_verbs[] = {
18021	/* always trun on EAPD */
18022	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
18023	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
18024	{ }
18025};
18026
18027static const struct hda_verb alc662_sue_init_verbs[] = {
18028	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
18029	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
18030	{}
18031};
18032
18033static const struct hda_verb alc662_eeepc_sue_init_verbs[] = {
18034	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18035	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18036	{}
18037};
18038
18039/* Set Unsolicited Event*/
18040static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
18041	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18042	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18043	{}
18044};
18045
18046static const struct hda_verb alc663_m51va_init_verbs[] = {
18047	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18048	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18049	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18050	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18051	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
18052	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18053	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18054	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18055	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18056	{}
18057};
18058
18059static const struct hda_verb alc663_21jd_amic_init_verbs[] = {
18060	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18061	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18062	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
18063	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18064	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18065	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18066	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18067	{}
18068};
18069
18070static const struct hda_verb alc662_1bjd_amic_init_verbs[] = {
18071	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18072	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18073	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18074	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
18075	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18076	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18077	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18078	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18079	{}
18080};
18081
18082static const struct hda_verb alc663_15jd_amic_init_verbs[] = {
18083	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18084	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18085	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
18086	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18087	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18088	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18089	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18090	{}
18091};
18092
18093static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
18094	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18095	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18096	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18097	{0x21, AC_VERB_SET_CONNECT_SEL, 0x0},	/* Headphone */
18098	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18099	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18100	{0x15, AC_VERB_SET_CONNECT_SEL, 0x0},	/* Headphone */
18101	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18102	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18103	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18104	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18105	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18106	{}
18107};
18108
18109static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
18110	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18111	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18112	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18113	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
18114	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18115	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18116	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
18117	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18118	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18119	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18120	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18121	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18122	{}
18123};
18124
18125static const struct hda_verb alc663_g71v_init_verbs[] = {
18126	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18127	/* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
18128	/* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
18129
18130	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18131	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18132	{0x21, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
18133
18134	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
18135	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
18136	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
18137	{}
18138};
18139
18140static const struct hda_verb alc663_g50v_init_verbs[] = {
18141	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18142	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18143	{0x21, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
18144
18145	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18146	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18147	{}
18148};
18149
18150static const struct hda_verb alc662_ecs_init_verbs[] = {
18151	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
18152	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18153	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18154	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18155	{}
18156};
18157
18158static const struct hda_verb alc272_dell_zm1_init_verbs[] = {
18159	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18160	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18161	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18162	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18163	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18164	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18165	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
18166	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18167	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18168	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18169	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18170	{}
18171};
18172
18173static const struct hda_verb alc272_dell_init_verbs[] = {
18174	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18175	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18176	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18177	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18178	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18179	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18180	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
18181	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18182	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18183	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18184	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18185	{}
18186};
18187
18188static const struct hda_verb alc663_mode7_init_verbs[] = {
18189	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18190	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18191	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18192	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18193	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18194	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18195	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
18196	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18197	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18198	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
18199	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18200	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18201	{0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18202	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18203	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18204	{}
18205};
18206
18207static const struct hda_verb alc663_mode8_init_verbs[] = {
18208	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18209	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18210	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18211	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
18212	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18213	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18214	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18215	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18216	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18217	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18218	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
18219	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18220	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18221	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18222	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18223	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18224	{}
18225};
18226
18227static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
18228	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
18229	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
18230	{ } /* end */
18231};
18232
18233static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
18234	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
18235	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
18236	{ } /* end */
18237};
18238
18239static void alc662_lenovo_101e_setup(struct hda_codec *codec)
18240{
18241	struct alc_spec *spec = codec->spec;
18242
18243	spec->autocfg.hp_pins[0] = 0x1b;
18244	spec->autocfg.line_out_pins[0] = 0x14;
18245	spec->autocfg.speaker_pins[0] = 0x15;
18246	spec->automute = 1;
18247	spec->detect_line = 1;
18248	spec->automute_lines = 1;
18249	spec->automute_mode = ALC_AUTOMUTE_AMP;
18250}
18251
18252static void alc662_eeepc_setup(struct hda_codec *codec)
18253{
18254	struct alc_spec *spec = codec->spec;
18255
18256	alc262_hippo1_setup(codec);
18257	spec->ext_mic.pin = 0x18;
18258	spec->ext_mic.mux_idx = 0;
18259	spec->int_mic.pin = 0x19;
18260	spec->int_mic.mux_idx = 1;
18261	spec->auto_mic = 1;
18262}
18263
18264static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
18265{
18266	struct alc_spec *spec = codec->spec;
18267
18268	spec->autocfg.hp_pins[0] = 0x14;
18269	spec->autocfg.speaker_pins[0] = 0x1b;
18270	spec->automute = 1;
18271	spec->automute_mode = ALC_AUTOMUTE_AMP;
18272}
18273
18274static void alc663_m51va_setup(struct hda_codec *codec)
18275{
18276	struct alc_spec *spec = codec->spec;
18277	spec->autocfg.hp_pins[0] = 0x21;
18278	spec->autocfg.speaker_pins[0] = 0x14;
18279	spec->automute_mixer_nid[0] = 0x0c;
18280	spec->automute = 1;
18281	spec->automute_mode = ALC_AUTOMUTE_MIXER;
18282	spec->ext_mic.pin = 0x18;
18283	spec->ext_mic.mux_idx = 0;
18284	spec->int_mic.pin = 0x12;
18285	spec->int_mic.mux_idx = 9;
18286	spec->auto_mic = 1;
18287}
18288
18289/* ***************** Mode1 ******************************/
18290static void alc663_mode1_setup(struct hda_codec *codec)
18291{
18292	struct alc_spec *spec = codec->spec;
18293	spec->autocfg.hp_pins[0] = 0x21;
18294	spec->autocfg.speaker_pins[0] = 0x14;
18295	spec->automute_mixer_nid[0] = 0x0c;
18296	spec->automute = 1;
18297	spec->automute_mode = ALC_AUTOMUTE_MIXER;
18298	spec->ext_mic.pin = 0x18;
18299	spec->ext_mic.mux_idx = 0;
18300	spec->int_mic.pin = 0x19;
18301	spec->int_mic.mux_idx = 1;
18302	spec->auto_mic = 1;
18303}
18304
18305/* ***************** Mode2 ******************************/
18306static void alc662_mode2_setup(struct hda_codec *codec)
18307{
18308	struct alc_spec *spec = codec->spec;
18309	spec->autocfg.hp_pins[0] = 0x1b;
18310	spec->autocfg.speaker_pins[0] = 0x14;
18311	spec->automute = 1;
18312	spec->automute_mode = ALC_AUTOMUTE_PIN;
18313	spec->ext_mic.pin = 0x18;
18314	spec->ext_mic.mux_idx = 0;
18315	spec->int_mic.pin = 0x19;
18316	spec->int_mic.mux_idx = 1;
18317	spec->auto_mic = 1;
18318}
18319
18320/* ***************** Mode3 ******************************/
18321static void alc663_mode3_setup(struct hda_codec *codec)
18322{
18323	struct alc_spec *spec = codec->spec;
18324	spec->autocfg.hp_pins[0] = 0x21;
18325	spec->autocfg.hp_pins[0] = 0x15;
18326	spec->autocfg.speaker_pins[0] = 0x14;
18327	spec->automute = 1;
18328	spec->automute_mode = ALC_AUTOMUTE_PIN;
18329	spec->ext_mic.pin = 0x18;
18330	spec->ext_mic.mux_idx = 0;
18331	spec->int_mic.pin = 0x19;
18332	spec->int_mic.mux_idx = 1;
18333	spec->auto_mic = 1;
18334}
18335
18336/* ***************** Mode4 ******************************/
18337static void alc663_mode4_setup(struct hda_codec *codec)
18338{
18339	struct alc_spec *spec = codec->spec;
18340	spec->autocfg.hp_pins[0] = 0x21;
18341	spec->autocfg.speaker_pins[0] = 0x14;
18342	spec->autocfg.speaker_pins[1] = 0x16;
18343	spec->automute_mixer_nid[0] = 0x0c;
18344	spec->automute_mixer_nid[1] = 0x0e;
18345	spec->automute = 1;
18346	spec->automute_mode = ALC_AUTOMUTE_MIXER;
18347	spec->ext_mic.pin = 0x18;
18348	spec->ext_mic.mux_idx = 0;
18349	spec->int_mic.pin = 0x19;
18350	spec->int_mic.mux_idx = 1;
18351	spec->auto_mic = 1;
18352}
18353
18354/* ***************** Mode5 ******************************/
18355static void alc663_mode5_setup(struct hda_codec *codec)
18356{
18357	struct alc_spec *spec = codec->spec;
18358	spec->autocfg.hp_pins[0] = 0x15;
18359	spec->autocfg.speaker_pins[0] = 0x14;
18360	spec->autocfg.speaker_pins[1] = 0x16;
18361	spec->automute_mixer_nid[0] = 0x0c;
18362	spec->automute_mixer_nid[1] = 0x0e;
18363	spec->automute = 1;
18364	spec->automute_mode = ALC_AUTOMUTE_MIXER;
18365	spec->ext_mic.pin = 0x18;
18366	spec->ext_mic.mux_idx = 0;
18367	spec->int_mic.pin = 0x19;
18368	spec->int_mic.mux_idx = 1;
18369	spec->auto_mic = 1;
18370}
18371
18372/* ***************** Mode6 ******************************/
18373static void alc663_mode6_setup(struct hda_codec *codec)
18374{
18375	struct alc_spec *spec = codec->spec;
18376	spec->autocfg.hp_pins[0] = 0x1b;
18377	spec->autocfg.hp_pins[0] = 0x15;
18378	spec->autocfg.speaker_pins[0] = 0x14;
18379	spec->automute_mixer_nid[0] = 0x0c;
18380	spec->automute = 1;
18381	spec->automute_mode = ALC_AUTOMUTE_MIXER;
18382	spec->ext_mic.pin = 0x18;
18383	spec->ext_mic.mux_idx = 0;
18384	spec->int_mic.pin = 0x19;
18385	spec->int_mic.mux_idx = 1;
18386	spec->auto_mic = 1;
18387}
18388
18389/* ***************** Mode7 ******************************/
18390static void alc663_mode7_setup(struct hda_codec *codec)
18391{
18392	struct alc_spec *spec = codec->spec;
18393	spec->autocfg.hp_pins[0] = 0x1b;
18394	spec->autocfg.hp_pins[0] = 0x21;
18395	spec->autocfg.speaker_pins[0] = 0x14;
18396	spec->autocfg.speaker_pins[0] = 0x17;
18397	spec->automute = 1;
18398	spec->automute_mode = ALC_AUTOMUTE_PIN;
18399	spec->ext_mic.pin = 0x18;
18400	spec->ext_mic.mux_idx = 0;
18401	spec->int_mic.pin = 0x19;
18402	spec->int_mic.mux_idx = 1;
18403	spec->auto_mic = 1;
18404}
18405
18406/* ***************** Mode8 ******************************/
18407static void alc663_mode8_setup(struct hda_codec *codec)
18408{
18409	struct alc_spec *spec = codec->spec;
18410	spec->autocfg.hp_pins[0] = 0x21;
18411	spec->autocfg.hp_pins[1] = 0x15;
18412	spec->autocfg.speaker_pins[0] = 0x14;
18413	spec->autocfg.speaker_pins[0] = 0x17;
18414	spec->automute = 1;
18415	spec->automute_mode = ALC_AUTOMUTE_PIN;
18416	spec->ext_mic.pin = 0x18;
18417	spec->ext_mic.mux_idx = 0;
18418	spec->int_mic.pin = 0x12;
18419	spec->int_mic.mux_idx = 9;
18420	spec->auto_mic = 1;
18421}
18422
18423static void alc663_g71v_setup(struct hda_codec *codec)
18424{
18425	struct alc_spec *spec = codec->spec;
18426	spec->autocfg.hp_pins[0] = 0x21;
18427	spec->autocfg.line_out_pins[0] = 0x15;
18428	spec->autocfg.speaker_pins[0] = 0x14;
18429	spec->automute = 1;
18430	spec->automute_mode = ALC_AUTOMUTE_AMP;
18431	spec->detect_line = 1;
18432	spec->automute_lines = 1;
18433	spec->ext_mic.pin = 0x18;
18434	spec->ext_mic.mux_idx = 0;
18435	spec->int_mic.pin = 0x12;
18436	spec->int_mic.mux_idx = 9;
18437	spec->auto_mic = 1;
18438}
18439
18440#define alc663_g50v_setup	alc663_m51va_setup
18441
18442static const struct snd_kcontrol_new alc662_ecs_mixer[] = {
18443	HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18444	ALC262_HIPPO_MASTER_SWITCH,
18445
18446	HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
18447	HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18448	HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
18449
18450	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18451	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18452	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18453	{ } /* end */
18454};
18455
18456static const struct snd_kcontrol_new alc272_nc10_mixer[] = {
18457	/* Master Playback automatically created from Speaker and Headphone */
18458	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18459	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18460	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18461	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18462
18463	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18464	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
18465	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
18466
18467	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18468	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18469	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18470	{ } /* end */
18471};
18472
18473#ifdef CONFIG_SND_HDA_POWER_SAVE
18474#define alc662_loopbacks	alc880_loopbacks
18475#endif
18476
18477
18478/* pcm configuration: identical with ALC880 */
18479#define alc662_pcm_analog_playback	alc880_pcm_analog_playback
18480#define alc662_pcm_analog_capture	alc880_pcm_analog_capture
18481#define alc662_pcm_digital_playback	alc880_pcm_digital_playback
18482#define alc662_pcm_digital_capture	alc880_pcm_digital_capture
18483
18484/*
18485 * configuration and preset
18486 */
18487static const char * const alc662_models[ALC662_MODEL_LAST] = {
18488	[ALC662_3ST_2ch_DIG]	= "3stack-dig",
18489	[ALC662_3ST_6ch_DIG]	= "3stack-6ch-dig",
18490	[ALC662_3ST_6ch]	= "3stack-6ch",
18491	[ALC662_5ST_DIG]	= "5stack-dig",
18492	[ALC662_LENOVO_101E]	= "lenovo-101e",
18493	[ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
18494	[ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
18495	[ALC662_ECS] = "ecs",
18496	[ALC663_ASUS_M51VA] = "m51va",
18497	[ALC663_ASUS_G71V] = "g71v",
18498	[ALC663_ASUS_H13] = "h13",
18499	[ALC663_ASUS_G50V] = "g50v",
18500	[ALC663_ASUS_MODE1] = "asus-mode1",
18501	[ALC662_ASUS_MODE2] = "asus-mode2",
18502	[ALC663_ASUS_MODE3] = "asus-mode3",
18503	[ALC663_ASUS_MODE4] = "asus-mode4",
18504	[ALC663_ASUS_MODE5] = "asus-mode5",
18505	[ALC663_ASUS_MODE6] = "asus-mode6",
18506	[ALC663_ASUS_MODE7] = "asus-mode7",
18507	[ALC663_ASUS_MODE8] = "asus-mode8",
18508	[ALC272_DELL]		= "dell",
18509	[ALC272_DELL_ZM1]	= "dell-zm1",
18510	[ALC272_SAMSUNG_NC10]	= "samsung-nc10",
18511	[ALC662_AUTO]		= "auto",
18512};
18513
18514static const struct snd_pci_quirk alc662_cfg_tbl[] = {
18515	SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
18516	SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18517	SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
18518	SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
18519	SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
18520	SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
18521	SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
18522	SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
18523	SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
18524	SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
18525	SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18526	SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
18527	SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
18528	SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18529	SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18530	SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18531	SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18532	SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
18533	SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
18534	SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18535	SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
18536	SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18537	SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18538	SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18539	SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
18540	SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
18541	SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18542	SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18543	SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
18544	SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
18545	SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18546	SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18547	SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
18548	SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
18549	SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
18550	SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18551	SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18552	/*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
18553	SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
18554	SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
18555	SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
18556	SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
18557	SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18558	SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
18559	SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18560	SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18561	SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
18562	SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
18563	SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18564	SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
18565	SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
18566	SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18567	SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18568	/*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18569	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18570	SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
18571	SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
18572	SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
18573	SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
18574	SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18575	SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18576	SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18577	SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
18578	SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18579		      ALC662_3ST_6ch_DIG),
18580	SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
18581	SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
18582	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18583		      ALC662_3ST_6ch_DIG),
18584	SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
18585	SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
18586	SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
18587	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
18588	SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
18589					ALC662_3ST_6ch_DIG),
18590	SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18591			   ALC663_ASUS_H13),
18592	SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
18593	{}
18594};
18595
18596static const struct alc_config_preset alc662_presets[] = {
18597	[ALC662_3ST_2ch_DIG] = {
18598		.mixers = { alc662_3ST_2ch_mixer },
18599		.init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18600		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18601		.dac_nids = alc662_dac_nids,
18602		.dig_out_nid = ALC662_DIGOUT_NID,
18603		.dig_in_nid = ALC662_DIGIN_NID,
18604		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18605		.channel_mode = alc662_3ST_2ch_modes,
18606		.input_mux = &alc662_capture_source,
18607	},
18608	[ALC662_3ST_6ch_DIG] = {
18609		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18610		.init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18611		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18612		.dac_nids = alc662_dac_nids,
18613		.dig_out_nid = ALC662_DIGOUT_NID,
18614		.dig_in_nid = ALC662_DIGIN_NID,
18615		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18616		.channel_mode = alc662_3ST_6ch_modes,
18617		.need_dac_fix = 1,
18618		.input_mux = &alc662_capture_source,
18619	},
18620	[ALC662_3ST_6ch] = {
18621		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18622		.init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18623		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18624		.dac_nids = alc662_dac_nids,
18625		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18626		.channel_mode = alc662_3ST_6ch_modes,
18627		.need_dac_fix = 1,
18628		.input_mux = &alc662_capture_source,
18629	},
18630	[ALC662_5ST_DIG] = {
18631		.mixers = { alc662_base_mixer, alc662_chmode_mixer },
18632		.init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18633		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18634		.dac_nids = alc662_dac_nids,
18635		.dig_out_nid = ALC662_DIGOUT_NID,
18636		.dig_in_nid = ALC662_DIGIN_NID,
18637		.num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18638		.channel_mode = alc662_5stack_modes,
18639		.input_mux = &alc662_capture_source,
18640	},
18641	[ALC662_LENOVO_101E] = {
18642		.mixers = { alc662_lenovo_101e_mixer },
18643		.init_verbs = { alc662_init_verbs,
18644				alc662_eapd_init_verbs,
18645				alc662_sue_init_verbs },
18646		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18647		.dac_nids = alc662_dac_nids,
18648		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18649		.channel_mode = alc662_3ST_2ch_modes,
18650		.input_mux = &alc662_lenovo_101e_capture_source,
18651		.unsol_event = alc_sku_unsol_event,
18652		.setup = alc662_lenovo_101e_setup,
18653		.init_hook = alc_inithook,
18654	},
18655	[ALC662_ASUS_EEEPC_P701] = {
18656		.mixers = { alc662_eeepc_p701_mixer },
18657		.init_verbs = { alc662_init_verbs,
18658				alc662_eapd_init_verbs,
18659				alc662_eeepc_sue_init_verbs },
18660		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18661		.dac_nids = alc662_dac_nids,
18662		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18663		.channel_mode = alc662_3ST_2ch_modes,
18664		.unsol_event = alc_sku_unsol_event,
18665		.setup = alc662_eeepc_setup,
18666		.init_hook = alc_inithook,
18667	},
18668	[ALC662_ASUS_EEEPC_EP20] = {
18669		.mixers = { alc662_eeepc_ep20_mixer,
18670			    alc662_chmode_mixer },
18671		.init_verbs = { alc662_init_verbs,
18672				alc662_eapd_init_verbs,
18673				alc662_eeepc_ep20_sue_init_verbs },
18674		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18675		.dac_nids = alc662_dac_nids,
18676		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18677		.channel_mode = alc662_3ST_6ch_modes,
18678		.input_mux = &alc662_lenovo_101e_capture_source,
18679		.unsol_event = alc_sku_unsol_event,
18680		.setup = alc662_eeepc_ep20_setup,
18681		.init_hook = alc_inithook,
18682	},
18683	[ALC662_ECS] = {
18684		.mixers = { alc662_ecs_mixer },
18685		.init_verbs = { alc662_init_verbs,
18686				alc662_eapd_init_verbs,
18687				alc662_ecs_init_verbs },
18688		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18689		.dac_nids = alc662_dac_nids,
18690		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18691		.channel_mode = alc662_3ST_2ch_modes,
18692		.unsol_event = alc_sku_unsol_event,
18693		.setup = alc662_eeepc_setup,
18694		.init_hook = alc_inithook,
18695	},
18696	[ALC663_ASUS_M51VA] = {
18697		.mixers = { alc663_m51va_mixer },
18698		.init_verbs = { alc662_init_verbs,
18699				alc662_eapd_init_verbs,
18700				alc663_m51va_init_verbs },
18701		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18702		.dac_nids = alc662_dac_nids,
18703		.dig_out_nid = ALC662_DIGOUT_NID,
18704		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18705		.channel_mode = alc662_3ST_2ch_modes,
18706		.unsol_event = alc_sku_unsol_event,
18707		.setup = alc663_m51va_setup,
18708		.init_hook = alc_inithook,
18709	},
18710	[ALC663_ASUS_G71V] = {
18711		.mixers = { alc663_g71v_mixer },
18712		.init_verbs = { alc662_init_verbs,
18713				alc662_eapd_init_verbs,
18714				alc663_g71v_init_verbs },
18715		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18716		.dac_nids = alc662_dac_nids,
18717		.dig_out_nid = ALC662_DIGOUT_NID,
18718		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18719		.channel_mode = alc662_3ST_2ch_modes,
18720		.unsol_event = alc_sku_unsol_event,
18721		.setup = alc663_g71v_setup,
18722		.init_hook = alc_inithook,
18723	},
18724	[ALC663_ASUS_H13] = {
18725		.mixers = { alc663_m51va_mixer },
18726		.init_verbs = { alc662_init_verbs,
18727				alc662_eapd_init_verbs,
18728				alc663_m51va_init_verbs },
18729		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18730		.dac_nids = alc662_dac_nids,
18731		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18732		.channel_mode = alc662_3ST_2ch_modes,
18733		.setup = alc663_m51va_setup,
18734		.unsol_event = alc_sku_unsol_event,
18735		.init_hook = alc_inithook,
18736	},
18737	[ALC663_ASUS_G50V] = {
18738		.mixers = { alc663_g50v_mixer },
18739		.init_verbs = { alc662_init_verbs,
18740				alc662_eapd_init_verbs,
18741				alc663_g50v_init_verbs },
18742		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18743		.dac_nids = alc662_dac_nids,
18744		.dig_out_nid = ALC662_DIGOUT_NID,
18745		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18746		.channel_mode = alc662_3ST_6ch_modes,
18747		.input_mux = &alc663_capture_source,
18748		.unsol_event = alc_sku_unsol_event,
18749		.setup = alc663_g50v_setup,
18750		.init_hook = alc_inithook,
18751	},
18752	[ALC663_ASUS_MODE1] = {
18753		.mixers = { alc663_m51va_mixer },
18754		.cap_mixer = alc662_auto_capture_mixer,
18755		.init_verbs = { alc662_init_verbs,
18756				alc662_eapd_init_verbs,
18757				alc663_21jd_amic_init_verbs },
18758		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18759		.hp_nid = 0x03,
18760		.dac_nids = alc662_dac_nids,
18761		.dig_out_nid = ALC662_DIGOUT_NID,
18762		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18763		.channel_mode = alc662_3ST_2ch_modes,
18764		.unsol_event = alc_sku_unsol_event,
18765		.setup = alc663_mode1_setup,
18766		.init_hook = alc_inithook,
18767	},
18768	[ALC662_ASUS_MODE2] = {
18769		.mixers = { alc662_1bjd_mixer },
18770		.cap_mixer = alc662_auto_capture_mixer,
18771		.init_verbs = { alc662_init_verbs,
18772				alc662_eapd_init_verbs,
18773				alc662_1bjd_amic_init_verbs },
18774		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18775		.dac_nids = alc662_dac_nids,
18776		.dig_out_nid = ALC662_DIGOUT_NID,
18777		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18778		.channel_mode = alc662_3ST_2ch_modes,
18779		.unsol_event = alc_sku_unsol_event,
18780		.setup = alc662_mode2_setup,
18781		.init_hook = alc_inithook,
18782	},
18783	[ALC663_ASUS_MODE3] = {
18784		.mixers = { alc663_two_hp_m1_mixer },
18785		.cap_mixer = alc662_auto_capture_mixer,
18786		.init_verbs = { alc662_init_verbs,
18787				alc662_eapd_init_verbs,
18788				alc663_two_hp_amic_m1_init_verbs },
18789		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18790		.hp_nid = 0x03,
18791		.dac_nids = alc662_dac_nids,
18792		.dig_out_nid = ALC662_DIGOUT_NID,
18793		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18794		.channel_mode = alc662_3ST_2ch_modes,
18795		.unsol_event = alc_sku_unsol_event,
18796		.setup = alc663_mode3_setup,
18797		.init_hook = alc_inithook,
18798	},
18799	[ALC663_ASUS_MODE4] = {
18800		.mixers = { alc663_asus_21jd_clfe_mixer },
18801		.cap_mixer = alc662_auto_capture_mixer,
18802		.init_verbs = { alc662_init_verbs,
18803				alc662_eapd_init_verbs,
18804				alc663_21jd_amic_init_verbs},
18805		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18806		.hp_nid = 0x03,
18807		.dac_nids = alc662_dac_nids,
18808		.dig_out_nid = ALC662_DIGOUT_NID,
18809		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18810		.channel_mode = alc662_3ST_2ch_modes,
18811		.unsol_event = alc_sku_unsol_event,
18812		.setup = alc663_mode4_setup,
18813		.init_hook = alc_inithook,
18814	},
18815	[ALC663_ASUS_MODE5] = {
18816		.mixers = { alc663_asus_15jd_clfe_mixer },
18817		.cap_mixer = alc662_auto_capture_mixer,
18818		.init_verbs = { alc662_init_verbs,
18819				alc662_eapd_init_verbs,
18820				alc663_15jd_amic_init_verbs },
18821		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18822		.hp_nid = 0x03,
18823		.dac_nids = alc662_dac_nids,
18824		.dig_out_nid = ALC662_DIGOUT_NID,
18825		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18826		.channel_mode = alc662_3ST_2ch_modes,
18827		.unsol_event = alc_sku_unsol_event,
18828		.setup = alc663_mode5_setup,
18829		.init_hook = alc_inithook,
18830	},
18831	[ALC663_ASUS_MODE6] = {
18832		.mixers = { alc663_two_hp_m2_mixer },
18833		.cap_mixer = alc662_auto_capture_mixer,
18834		.init_verbs = { alc662_init_verbs,
18835				alc662_eapd_init_verbs,
18836				alc663_two_hp_amic_m2_init_verbs },
18837		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18838		.hp_nid = 0x03,
18839		.dac_nids = alc662_dac_nids,
18840		.dig_out_nid = ALC662_DIGOUT_NID,
18841		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18842		.channel_mode = alc662_3ST_2ch_modes,
18843		.unsol_event = alc_sku_unsol_event,
18844		.setup = alc663_mode6_setup,
18845		.init_hook = alc_inithook,
18846	},
18847	[ALC663_ASUS_MODE7] = {
18848		.mixers = { alc663_mode7_mixer },
18849		.cap_mixer = alc662_auto_capture_mixer,
18850		.init_verbs = { alc662_init_verbs,
18851				alc662_eapd_init_verbs,
18852				alc663_mode7_init_verbs },
18853		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18854		.hp_nid = 0x03,
18855		.dac_nids = alc662_dac_nids,
18856		.dig_out_nid = ALC662_DIGOUT_NID,
18857		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18858		.channel_mode = alc662_3ST_2ch_modes,
18859		.unsol_event = alc_sku_unsol_event,
18860		.setup = alc663_mode7_setup,
18861		.init_hook = alc_inithook,
18862	},
18863	[ALC663_ASUS_MODE8] = {
18864		.mixers = { alc663_mode8_mixer },
18865		.cap_mixer = alc662_auto_capture_mixer,
18866		.init_verbs = { alc662_init_verbs,
18867				alc662_eapd_init_verbs,
18868				alc663_mode8_init_verbs },
18869		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18870		.hp_nid = 0x03,
18871		.dac_nids = alc662_dac_nids,
18872		.dig_out_nid = ALC662_DIGOUT_NID,
18873		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18874		.channel_mode = alc662_3ST_2ch_modes,
18875		.unsol_event = alc_sku_unsol_event,
18876		.setup = alc663_mode8_setup,
18877		.init_hook = alc_inithook,
18878	},
18879	[ALC272_DELL] = {
18880		.mixers = { alc663_m51va_mixer },
18881		.cap_mixer = alc272_auto_capture_mixer,
18882		.init_verbs = { alc662_init_verbs,
18883				alc662_eapd_init_verbs,
18884				alc272_dell_init_verbs },
18885		.num_dacs = ARRAY_SIZE(alc272_dac_nids),
18886		.dac_nids = alc272_dac_nids,
18887		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18888		.adc_nids = alc272_adc_nids,
18889		.num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18890		.capsrc_nids = alc272_capsrc_nids,
18891		.channel_mode = alc662_3ST_2ch_modes,
18892		.unsol_event = alc_sku_unsol_event,
18893		.setup = alc663_m51va_setup,
18894		.init_hook = alc_inithook,
18895	},
18896	[ALC272_DELL_ZM1] = {
18897		.mixers = { alc663_m51va_mixer },
18898		.cap_mixer = alc662_auto_capture_mixer,
18899		.init_verbs = { alc662_init_verbs,
18900				alc662_eapd_init_verbs,
18901				alc272_dell_zm1_init_verbs },
18902		.num_dacs = ARRAY_SIZE(alc272_dac_nids),
18903		.dac_nids = alc272_dac_nids,
18904		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18905		.adc_nids = alc662_adc_nids,
18906		.num_adc_nids = 1,
18907		.capsrc_nids = alc662_capsrc_nids,
18908		.channel_mode = alc662_3ST_2ch_modes,
18909		.unsol_event = alc_sku_unsol_event,
18910		.setup = alc663_m51va_setup,
18911		.init_hook = alc_inithook,
18912	},
18913	[ALC272_SAMSUNG_NC10] = {
18914		.mixers = { alc272_nc10_mixer },
18915		.init_verbs = { alc662_init_verbs,
18916				alc662_eapd_init_verbs,
18917				alc663_21jd_amic_init_verbs },
18918		.num_dacs = ARRAY_SIZE(alc272_dac_nids),
18919		.dac_nids = alc272_dac_nids,
18920		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18921		.channel_mode = alc662_3ST_2ch_modes,
18922		/*.input_mux = &alc272_nc10_capture_source,*/
18923		.unsol_event = alc_sku_unsol_event,
18924		.setup = alc663_mode4_setup,
18925		.init_hook = alc_inithook,
18926	},
18927};
18928
18929
18930/*
18931 * BIOS auto configuration
18932 */
18933
18934/* convert from MIX nid to DAC */
18935static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
18936{
18937	hda_nid_t list[5];
18938	int i, num;
18939
18940	num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
18941	for (i = 0; i < num; i++) {
18942		if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
18943			return list[i];
18944	}
18945	return 0;
18946}
18947
18948/* go down to the selector widget before the mixer */
18949static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
18950{
18951	hda_nid_t srcs[5];
18952	int num = snd_hda_get_connections(codec, pin, srcs,
18953					  ARRAY_SIZE(srcs));
18954	if (num != 1 ||
18955	    get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
18956		return pin;
18957	return srcs[0];
18958}
18959
18960/* get MIX nid connected to the given pin targeted to DAC */
18961static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
18962				   hda_nid_t dac)
18963{
18964	hda_nid_t mix[5];
18965	int i, num;
18966
18967	pin = alc_go_down_to_selector(codec, pin);
18968	num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18969	for (i = 0; i < num; i++) {
18970		if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
18971			return mix[i];
18972	}
18973	return 0;
18974}
18975
18976/* select the connection from pin to DAC if needed */
18977static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
18978			       hda_nid_t dac)
18979{
18980	hda_nid_t mix[5];
18981	int i, num;
18982
18983	pin = alc_go_down_to_selector(codec, pin);
18984	num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18985	if (num < 2)
18986		return 0;
18987	for (i = 0; i < num; i++) {
18988		if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
18989			snd_hda_codec_update_cache(codec, pin, 0,
18990						   AC_VERB_SET_CONNECT_SEL, i);
18991			return 0;
18992		}
18993	}
18994	return 0;
18995}
18996
18997/* look for an empty DAC slot */
18998static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
18999{
19000	struct alc_spec *spec = codec->spec;
19001	hda_nid_t srcs[5];
19002	int i, j, num;
19003
19004	pin = alc_go_down_to_selector(codec, pin);
19005	num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
19006	for (i = 0; i < num; i++) {
19007		hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
19008		if (!nid)
19009			continue;
19010		for (j = 0; j < spec->multiout.num_dacs; j++)
19011			if (spec->multiout.dac_nids[j] == nid)
19012				break;
19013		if (j >= spec->multiout.num_dacs)
19014			return nid;
19015	}
19016	return 0;
19017}
19018
19019/* fill in the dac_nids table from the parsed pin configuration */
19020static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
19021				     const struct auto_pin_cfg *cfg)
19022{
19023	struct alc_spec *spec = codec->spec;
19024	int i;
19025	hda_nid_t dac;
19026
19027	spec->multiout.dac_nids = spec->private_dac_nids;
19028	for (i = 0; i < cfg->line_outs; i++) {
19029		dac = alc_auto_look_for_dac(codec, cfg->line_out_pins[i]);
19030		if (!dac)
19031			continue;
19032		spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
19033	}
19034	return 0;
19035}
19036
19037static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
19038				       hda_nid_t nid, int idx, unsigned int chs)
19039{
19040	return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
19041			   HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
19042}
19043
19044static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
19045				      hda_nid_t nid, int idx, unsigned int chs)
19046{
19047	return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
19048			   HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
19049}
19050
19051#define alc662_add_vol_ctl(spec, pfx, nid, chs) \
19052	__alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
19053#define alc662_add_sw_ctl(spec, pfx, nid, chs) \
19054	__alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
19055#define alc662_add_stereo_vol(spec, pfx, nid) \
19056	alc662_add_vol_ctl(spec, pfx, nid, 3)
19057#define alc662_add_stereo_sw(spec, pfx, nid) \
19058	alc662_add_sw_ctl(spec, pfx, nid, 3)
19059
19060/* add playback controls from the parsed DAC table */
19061static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
19062					     const struct auto_pin_cfg *cfg)
19063{
19064	struct alc_spec *spec = codec->spec;
19065	static const char * const chname[4] = {
19066		"Front", "Surround", NULL /*CLFE*/, "Side"
19067	};
19068	const char *pfx = alc_get_line_out_pfx(spec, true);
19069	hda_nid_t nid, mix, pin;
19070	int i, err, noutputs;
19071
19072	noutputs = cfg->line_outs;
19073	if (spec->multi_ios > 0)
19074		noutputs += spec->multi_ios;
19075
19076	for (i = 0; i < noutputs; i++) {
19077		nid = spec->multiout.dac_nids[i];
19078		if (!nid)
19079			continue;
19080		if (i >= cfg->line_outs)
19081			pin = spec->multi_io[i - 1].pin;
19082		else
19083			pin = cfg->line_out_pins[i];
19084		mix = alc_auto_dac_to_mix(codec, pin, nid);
19085		if (!mix)
19086			continue;
19087		if (!pfx && i == 2) {
19088			/* Center/LFE */
19089			err = alc662_add_vol_ctl(spec, "Center", nid, 1);
19090			if (err < 0)
19091				return err;
19092			err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
19093			if (err < 0)
19094				return err;
19095			err = alc662_add_sw_ctl(spec, "Center", mix, 1);
19096			if (err < 0)
19097				return err;
19098			err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
19099			if (err < 0)
19100				return err;
19101		} else {
19102			const char *name = pfx;
19103			int index = i;
19104			if (!name) {
19105				name = chname[i];
19106				index = 0;
19107			}
19108			err = __alc662_add_vol_ctl(spec, name, nid, index, 3);
19109			if (err < 0)
19110				return err;
19111			err = __alc662_add_sw_ctl(spec, name, mix, index, 3);
19112			if (err < 0)
19113				return err;
19114		}
19115	}
19116	return 0;
19117}
19118
19119/* add playback controls for speaker and HP outputs */
19120/* return DAC nid if any new DAC is assigned */
19121static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
19122					const char *pfx)
19123{
19124	struct alc_spec *spec = codec->spec;
19125	hda_nid_t nid, mix;
19126	int err;
19127
19128	if (!pin)
19129		return 0;
19130	nid = alc_auto_look_for_dac(codec, pin);
19131	if (!nid) {
19132		/* the corresponding DAC is already occupied */
19133		if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19134			return 0; /* no way */
19135		/* create a switch only */
19136		return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
19137				   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
19138	}
19139
19140	mix = alc_auto_dac_to_mix(codec, pin, nid);
19141	if (!mix)
19142		return 0;
19143	err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19144	if (err < 0)
19145		return err;
19146	err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19147	if (err < 0)
19148		return err;
19149	return nid;
19150}
19151
19152/* create playback/capture controls for input pins */
19153#define alc662_auto_create_input_ctls \
19154	alc882_auto_create_input_ctls
19155
19156static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19157					      hda_nid_t nid, int pin_type,
19158					      hda_nid_t dac)
19159{
19160	int i, num;
19161	hda_nid_t srcs[HDA_MAX_CONNECTIONS];
19162
19163	alc_set_pin_output(codec, nid, pin_type);
19164	num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
19165	for (i = 0; i < num; i++) {
19166		if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
19167			continue;
19168		/* need the manual connection? */
19169		if (num > 1)
19170			snd_hda_codec_write(codec, nid, 0,
19171					    AC_VERB_SET_CONNECT_SEL, i);
19172		/* unmute mixer widget inputs */
19173		snd_hda_codec_write(codec, srcs[i], 0,
19174				    AC_VERB_SET_AMP_GAIN_MUTE,
19175				    AMP_IN_UNMUTE(0));
19176		snd_hda_codec_write(codec, srcs[i], 0,
19177				    AC_VERB_SET_AMP_GAIN_MUTE,
19178				    AMP_IN_UNMUTE(1));
19179		return;
19180	}
19181}
19182
19183static void alc662_auto_init_multi_out(struct hda_codec *codec)
19184{
19185	struct alc_spec *spec = codec->spec;
19186	int pin_type = get_pin_type(spec->autocfg.line_out_type);
19187	int i;
19188
19189	for (i = 0; i <= HDA_SIDE; i++) {
19190		hda_nid_t nid = spec->autocfg.line_out_pins[i];
19191		if (nid)
19192			alc662_auto_set_output_and_unmute(codec, nid, pin_type,
19193					spec->multiout.dac_nids[i]);
19194	}
19195}
19196
19197static void alc662_auto_init_hp_out(struct hda_codec *codec)
19198{
19199	struct alc_spec *spec = codec->spec;
19200	hda_nid_t pin;
19201
19202	pin = spec->autocfg.hp_pins[0];
19203	if (pin)
19204		alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19205						  spec->multiout.hp_nid);
19206	pin = spec->autocfg.speaker_pins[0];
19207	if (pin)
19208		alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19209					spec->multiout.extra_out_nid[0]);
19210}
19211
19212#define ALC662_PIN_CD_NID		ALC880_PIN_CD_NID
19213
19214static void alc662_auto_init_analog_input(struct hda_codec *codec)
19215{
19216	struct alc_spec *spec = codec->spec;
19217	struct auto_pin_cfg *cfg = &spec->autocfg;
19218	int i;
19219
19220	for (i = 0; i < cfg->num_inputs; i++) {
19221		hda_nid_t nid = cfg->inputs[i].pin;
19222		if (alc_is_input_pin(codec, nid)) {
19223			alc_set_input_pin(codec, nid, cfg->inputs[i].type);
19224			if (nid != ALC662_PIN_CD_NID &&
19225			    (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
19226				snd_hda_codec_write(codec, nid, 0,
19227						    AC_VERB_SET_AMP_GAIN_MUTE,
19228						    AMP_OUT_MUTE);
19229		}
19230	}
19231}
19232
19233#define alc662_auto_init_input_src	alc882_auto_init_input_src
19234
19235/*
19236 * multi-io helper
19237 */
19238static int alc_auto_fill_multi_ios(struct hda_codec *codec,
19239				   unsigned int location)
19240{
19241	struct alc_spec *spec = codec->spec;
19242	struct auto_pin_cfg *cfg = &spec->autocfg;
19243	int type, i, num_pins = 0;
19244
19245	for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
19246		for (i = 0; i < cfg->num_inputs; i++) {
19247			hda_nid_t nid = cfg->inputs[i].pin;
19248			hda_nid_t dac;
19249			unsigned int defcfg, caps;
19250			if (cfg->inputs[i].type != type)
19251				continue;
19252			defcfg = snd_hda_codec_get_pincfg(codec, nid);
19253			if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
19254				continue;
19255			if (location && get_defcfg_location(defcfg) != location)
19256				continue;
19257			caps = snd_hda_query_pin_caps(codec, nid);
19258			if (!(caps & AC_PINCAP_OUT))
19259				continue;
19260			dac = alc_auto_look_for_dac(codec, nid);
19261			if (!dac)
19262				continue;
19263			spec->multi_io[num_pins].pin = nid;
19264			spec->multi_io[num_pins].dac = dac;
19265			num_pins++;
19266			spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
19267		}
19268	}
19269	spec->multiout.num_dacs = 1;
19270	if (num_pins < 2)
19271		return 0;
19272	return num_pins;
19273}
19274
19275static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
19276				 struct snd_ctl_elem_info *uinfo)
19277{
19278	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19279	struct alc_spec *spec = codec->spec;
19280
19281	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
19282	uinfo->count = 1;
19283	uinfo->value.enumerated.items = spec->multi_ios + 1;
19284	if (uinfo->value.enumerated.item > spec->multi_ios)
19285		uinfo->value.enumerated.item = spec->multi_ios;
19286	sprintf(uinfo->value.enumerated.name, "%dch",
19287		(uinfo->value.enumerated.item + 1) * 2);
19288	return 0;
19289}
19290
19291static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
19292				struct snd_ctl_elem_value *ucontrol)
19293{
19294	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19295	struct alc_spec *spec = codec->spec;
19296	ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
19297	return 0;
19298}
19299
19300static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
19301{
19302	struct alc_spec *spec = codec->spec;
19303	hda_nid_t nid = spec->multi_io[idx].pin;
19304
19305	if (!spec->multi_io[idx].ctl_in)
19306		spec->multi_io[idx].ctl_in =
19307			snd_hda_codec_read(codec, nid, 0,
19308					   AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
19309	if (output) {
19310		snd_hda_codec_update_cache(codec, nid, 0,
19311					   AC_VERB_SET_PIN_WIDGET_CONTROL,
19312					   PIN_OUT);
19313		if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19314			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19315						 HDA_AMP_MUTE, 0);
19316		alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
19317	} else {
19318		if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19319			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19320						 HDA_AMP_MUTE, HDA_AMP_MUTE);
19321		snd_hda_codec_update_cache(codec, nid, 0,
19322					   AC_VERB_SET_PIN_WIDGET_CONTROL,
19323					   spec->multi_io[idx].ctl_in);
19324	}
19325	return 0;
19326}
19327
19328static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
19329				struct snd_ctl_elem_value *ucontrol)
19330{
19331	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19332	struct alc_spec *spec = codec->spec;
19333	int i, ch;
19334
19335	ch = ucontrol->value.enumerated.item[0];
19336	if (ch < 0 || ch > spec->multi_ios)
19337		return -EINVAL;
19338	if (ch == (spec->ext_channel_count - 1) / 2)
19339		return 0;
19340	spec->ext_channel_count = (ch + 1) * 2;
19341	for (i = 0; i < spec->multi_ios; i++)
19342		alc_set_multi_io(codec, i, i < ch);
19343	spec->multiout.max_channels = spec->ext_channel_count;
19344	return 1;
19345}
19346
19347static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
19348	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
19349	.name = "Channel Mode",
19350	.info = alc_auto_ch_mode_info,
19351	.get = alc_auto_ch_mode_get,
19352	.put = alc_auto_ch_mode_put,
19353};
19354
19355static int alc_auto_add_multi_channel_mode(struct hda_codec *codec)
19356{
19357	struct alc_spec *spec = codec->spec;
19358	struct auto_pin_cfg *cfg = &spec->autocfg;
19359	unsigned int location, defcfg;
19360	int num_pins;
19361
19362	if (cfg->line_outs != 1 ||
19363	    cfg->line_out_type != AUTO_PIN_LINE_OUT)
19364		return 0;
19365
19366	defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
19367	location = get_defcfg_location(defcfg);
19368
19369	num_pins = alc_auto_fill_multi_ios(codec, location);
19370	if (num_pins > 0) {
19371		struct snd_kcontrol_new *knew;
19372
19373		knew = alc_kcontrol_new(spec);
19374		if (!knew)
19375			return -ENOMEM;
19376		*knew = alc_auto_channel_mode_enum;
19377		knew->name = kstrdup("Channel Mode", GFP_KERNEL);
19378		if (!knew->name)
19379			return -ENOMEM;
19380
19381		spec->multi_ios = num_pins;
19382		spec->ext_channel_count = 2;
19383		spec->multiout.num_dacs = num_pins + 1;
19384	}
19385	return 0;
19386}
19387
19388static int alc662_parse_auto_config(struct hda_codec *codec)
19389{
19390	struct alc_spec *spec = codec->spec;
19391	int err;
19392	static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
19393
19394	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19395					   alc662_ignore);
19396	if (err < 0)
19397		return err;
19398	if (!spec->autocfg.line_outs)
19399		return 0; /* can't find valid BIOS pin config */
19400
19401	err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
19402	if (err < 0)
19403		return err;
19404	err = alc_auto_add_multi_channel_mode(codec);
19405	if (err < 0)
19406		return err;
19407	err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
19408	if (err < 0)
19409		return err;
19410	err = alc662_auto_create_extra_out(codec,
19411					   spec->autocfg.speaker_pins[0],
19412					   "Speaker");
19413	if (err < 0)
19414		return err;
19415	if (err)
19416		spec->multiout.extra_out_nid[0] = err;
19417	err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
19418					   "Headphone");
19419	if (err < 0)
19420		return err;
19421	if (err)
19422		spec->multiout.hp_nid = err;
19423	err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
19424	if (err < 0)
19425		return err;
19426
19427	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19428
19429	alc_auto_parse_digital(codec);
19430
19431	if (spec->kctls.list)
19432		add_mixer(spec, spec->kctls.list);
19433
19434	spec->num_mux_defs = 1;
19435	spec->input_mux = &spec->private_imux[0];
19436
19437	err = alc_auto_add_mic_boost(codec);
19438	if (err < 0)
19439		return err;
19440
19441	if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19442	    codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19443	    alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19444	else
19445	    alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
19446
19447	return 1;
19448}
19449
19450/* additional initialization for auto-configuration model */
19451static void alc662_auto_init(struct hda_codec *codec)
19452{
19453	struct alc_spec *spec = codec->spec;
19454	alc662_auto_init_multi_out(codec);
19455	alc662_auto_init_hp_out(codec);
19456	alc662_auto_init_analog_input(codec);
19457	alc662_auto_init_input_src(codec);
19458	alc_auto_init_digital(codec);
19459	if (spec->unsol_event)
19460		alc_inithook(codec);
19461}
19462
19463static void alc272_fixup_mario(struct hda_codec *codec,
19464			       const struct alc_fixup *fix, int action)
19465{
19466	if (action != ALC_FIXUP_ACT_PROBE)
19467		return;
19468	if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19469				      (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19470				      (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19471				      (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19472				      (0 << AC_AMPCAP_MUTE_SHIFT)))
19473		printk(KERN_WARNING
19474		       "hda_codec: failed to override amp caps for NID 0x2\n");
19475}
19476
19477enum {
19478	ALC662_FIXUP_ASPIRE,
19479	ALC662_FIXUP_IDEAPAD,
19480	ALC272_FIXUP_MARIO,
19481	ALC662_FIXUP_CZC_P10T,
19482	ALC662_FIXUP_SKU_IGNORE,
19483};
19484
19485static const struct alc_fixup alc662_fixups[] = {
19486	[ALC662_FIXUP_ASPIRE] = {
19487		.type = ALC_FIXUP_PINS,
19488		.v.pins = (const struct alc_pincfg[]) {
19489			{ 0x15, 0x99130112 }, /* subwoofer */
19490			{ }
19491		}
19492	},
19493	[ALC662_FIXUP_IDEAPAD] = {
19494		.type = ALC_FIXUP_PINS,
19495		.v.pins = (const struct alc_pincfg[]) {
19496			{ 0x17, 0x99130112 }, /* subwoofer */
19497			{ }
19498		}
19499	},
19500	[ALC272_FIXUP_MARIO] = {
19501		.type = ALC_FIXUP_FUNC,
19502		.v.func = alc272_fixup_mario,
19503	},
19504	[ALC662_FIXUP_CZC_P10T] = {
19505		.type = ALC_FIXUP_VERBS,
19506		.v.verbs = (const struct hda_verb[]) {
19507			{0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
19508			{}
19509		}
19510	},
19511	[ALC662_FIXUP_SKU_IGNORE] = {
19512		.type = ALC_FIXUP_SKU,
19513		.v.sku = ALC_FIXUP_SKU_IGNORE,
19514	},
19515};
19516
19517static const struct snd_pci_quirk alc662_fixup_tbl[] = {
19518	SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
19519	SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
19520	SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
19521	SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
19522	SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
19523	SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
19524	SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
19525	{}
19526};
19527
19528static const struct alc_model_fixup alc662_fixup_models[] = {
19529	{.id = ALC272_FIXUP_MARIO, .name = "mario"},
19530	{}
19531};
19532
19533
19534static int patch_alc662(struct hda_codec *codec)
19535{
19536	struct alc_spec *spec;
19537	int err, board_config;
19538	int coef;
19539
19540	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19541	if (!spec)
19542		return -ENOMEM;
19543
19544	codec->spec = spec;
19545
19546	alc_auto_parse_customize_define(codec);
19547
19548	alc_fix_pll_init(codec, 0x20, 0x04, 15);
19549
19550	coef = alc_read_coef_idx(codec, 0);
19551	if (coef == 0x8020 || coef == 0x8011)
19552		alc_codec_rename(codec, "ALC661");
19553	else if (coef & (1 << 14) &&
19554		codec->bus->pci->subsystem_vendor == 0x1025 &&
19555		spec->cdefine.platform_type == 1)
19556		alc_codec_rename(codec, "ALC272X");
19557	else if (coef == 0x4011)
19558		alc_codec_rename(codec, "ALC656");
19559
19560	board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19561						  alc662_models,
19562			  	                  alc662_cfg_tbl);
19563	if (board_config < 0) {
19564		printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19565		       codec->chip_name);
19566		board_config = ALC662_AUTO;
19567	}
19568
19569	if (board_config == ALC662_AUTO) {
19570		alc_pick_fixup(codec, alc662_fixup_models,
19571			       alc662_fixup_tbl, alc662_fixups);
19572		alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
19573		/* automatic parse from the BIOS config */
19574		err = alc662_parse_auto_config(codec);
19575		if (err < 0) {
19576			alc_free(codec);
19577			return err;
19578		} else if (!err) {
19579			printk(KERN_INFO
19580			       "hda_codec: Cannot set up configuration "
19581			       "from BIOS.  Using base mode...\n");
19582			board_config = ALC662_3ST_2ch_DIG;
19583		}
19584	}
19585
19586	if (has_cdefine_beep(codec)) {
19587		err = snd_hda_attach_beep_device(codec, 0x1);
19588		if (err < 0) {
19589			alc_free(codec);
19590			return err;
19591		}
19592	}
19593
19594	if (board_config != ALC662_AUTO)
19595		setup_preset(codec, &alc662_presets[board_config]);
19596
19597	spec->stream_analog_playback = &alc662_pcm_analog_playback;
19598	spec->stream_analog_capture = &alc662_pcm_analog_capture;
19599
19600	spec->stream_digital_playback = &alc662_pcm_digital_playback;
19601	spec->stream_digital_capture = &alc662_pcm_digital_capture;
19602
19603	if (!spec->adc_nids) {
19604		spec->adc_nids = alc662_adc_nids;
19605		spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19606	}
19607	if (!spec->capsrc_nids)
19608		spec->capsrc_nids = alc662_capsrc_nids;
19609
19610	if (!spec->cap_mixer)
19611		set_capture_mixer(codec);
19612
19613	if (has_cdefine_beep(codec)) {
19614		switch (codec->vendor_id) {
19615		case 0x10ec0662:
19616			set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19617			break;
19618		case 0x10ec0272:
19619		case 0x10ec0663:
19620		case 0x10ec0665:
19621			set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19622			break;
19623		case 0x10ec0273:
19624			set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19625			break;
19626		}
19627	}
19628	spec->vmaster_nid = 0x02;
19629
19630	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19631
19632	codec->patch_ops = alc_patch_ops;
19633	if (board_config == ALC662_AUTO)
19634		spec->init_hook = alc662_auto_init;
19635	spec->shutup = alc_eapd_shutup;
19636
19637	alc_init_jacks(codec);
19638
19639#ifdef CONFIG_SND_HDA_POWER_SAVE
19640	if (!spec->loopback.amplist)
19641		spec->loopback.amplist = alc662_loopbacks;
19642#endif
19643
19644	return 0;
19645}
19646
19647static int patch_alc888(struct hda_codec *codec)
19648{
19649	if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19650		kfree(codec->chip_name);
19651		if (codec->vendor_id == 0x10ec0887)
19652			codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19653		else
19654			codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
19655		if (!codec->chip_name) {
19656			alc_free(codec);
19657			return -ENOMEM;
19658		}
19659		return patch_alc662(codec);
19660	}
19661	return patch_alc882(codec);
19662}
19663
19664static int patch_alc899(struct hda_codec *codec)
19665{
19666	if ((alc_read_coef_idx(codec, 0) & 0x2000) != 0x2000) {
19667		kfree(codec->chip_name);
19668		codec->chip_name = kstrdup("ALC898", GFP_KERNEL);
19669	}
19670	return patch_alc882(codec);
19671}
19672
19673/*
19674 * ALC680 support
19675 */
19676#define ALC680_DIGIN_NID	ALC880_DIGIN_NID
19677#define ALC680_DIGOUT_NID	ALC880_DIGOUT_NID
19678#define alc680_modes		alc260_modes
19679
19680static const hda_nid_t alc680_dac_nids[3] = {
19681	/* Lout1, Lout2, hp */
19682	0x02, 0x03, 0x04
19683};
19684
19685static const hda_nid_t alc680_adc_nids[3] = {
19686	/* ADC0-2 */
19687	/* DMIC, MIC, Line-in*/
19688	0x07, 0x08, 0x09
19689};
19690
19691/*
19692 * Analog capture ADC cgange
19693 */
19694static void alc680_rec_autoswitch(struct hda_codec *codec)
19695{
19696	struct alc_spec *spec = codec->spec;
19697	struct auto_pin_cfg *cfg = &spec->autocfg;
19698	int pin_found = 0;
19699	int type_found = AUTO_PIN_LAST;
19700	hda_nid_t nid;
19701	int i;
19702
19703	for (i = 0; i < cfg->num_inputs; i++) {
19704		nid = cfg->inputs[i].pin;
19705		if (!is_jack_detectable(codec, nid))
19706			continue;
19707		if (snd_hda_jack_detect(codec, nid)) {
19708			if (cfg->inputs[i].type < type_found) {
19709				type_found = cfg->inputs[i].type;
19710				pin_found = nid;
19711			}
19712		}
19713	}
19714
19715	nid = 0x07;
19716	if (pin_found)
19717		snd_hda_get_connections(codec, pin_found, &nid, 1);
19718
19719	if (nid != spec->cur_adc)
19720		__snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19721	spec->cur_adc = nid;
19722	snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19723				   spec->cur_adc_format);
19724}
19725
19726static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19727				      struct hda_codec *codec,
19728				      unsigned int stream_tag,
19729				      unsigned int format,
19730				      struct snd_pcm_substream *substream)
19731{
19732	struct alc_spec *spec = codec->spec;
19733
19734	spec->cur_adc = 0x07;
19735	spec->cur_adc_stream_tag = stream_tag;
19736	spec->cur_adc_format = format;
19737
19738	alc680_rec_autoswitch(codec);
19739	return 0;
19740}
19741
19742static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19743				      struct hda_codec *codec,
19744				      struct snd_pcm_substream *substream)
19745{
19746	snd_hda_codec_cleanup_stream(codec, 0x07);
19747	snd_hda_codec_cleanup_stream(codec, 0x08);
19748	snd_hda_codec_cleanup_stream(codec, 0x09);
19749	return 0;
19750}
19751
19752static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19753	.substreams = 1, /* can be overridden */
19754	.channels_min = 2,
19755	.channels_max = 2,
19756	/* NID is set in alc_build_pcms */
19757	.ops = {
19758		.prepare = alc680_capture_pcm_prepare,
19759		.cleanup = alc680_capture_pcm_cleanup
19760	},
19761};
19762
19763static const struct snd_kcontrol_new alc680_base_mixer[] = {
19764	/* output mixer control */
19765	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19766	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19767	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19768	HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
19769	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19770	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19771	HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
19772	{ }
19773};
19774
19775static const struct hda_bind_ctls alc680_bind_cap_vol = {
19776	.ops = &snd_hda_bind_vol,
19777	.values = {
19778		HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19779		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19780		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19781		0
19782	},
19783};
19784
19785static const struct hda_bind_ctls alc680_bind_cap_switch = {
19786	.ops = &snd_hda_bind_sw,
19787	.values = {
19788		HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19789		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19790		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19791		0
19792	},
19793};
19794
19795static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19796	HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19797	HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
19798	{ } /* end */
19799};
19800
19801/*
19802 * generic initialization of ADC, input mixers and output mixers
19803 */
19804static const struct hda_verb alc680_init_verbs[] = {
19805	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19806	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19807	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19808
19809	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19810	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19811	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19812	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19813	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19814	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19815
19816	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19817	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19818	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19819	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19820	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19821
19822	{0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT   | AC_USRSP_EN},
19823	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT  | AC_USRSP_EN},
19824	{0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT  | AC_USRSP_EN},
19825
19826	{ }
19827};
19828
19829/* toggle speaker-output according to the hp-jack state */
19830static void alc680_base_setup(struct hda_codec *codec)
19831{
19832	struct alc_spec *spec = codec->spec;
19833
19834	spec->autocfg.hp_pins[0] = 0x16;
19835	spec->autocfg.speaker_pins[0] = 0x14;
19836	spec->autocfg.speaker_pins[1] = 0x15;
19837	spec->autocfg.num_inputs = 2;
19838	spec->autocfg.inputs[0].pin = 0x18;
19839	spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19840	spec->autocfg.inputs[1].pin = 0x19;
19841	spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
19842	spec->automute = 1;
19843	spec->automute_mode = ALC_AUTOMUTE_AMP;
19844}
19845
19846static void alc680_unsol_event(struct hda_codec *codec,
19847					   unsigned int res)
19848{
19849	if ((res >> 26) == ALC880_HP_EVENT)
19850		alc_hp_automute(codec);
19851	if ((res >> 26) == ALC880_MIC_EVENT)
19852		alc680_rec_autoswitch(codec);
19853}
19854
19855static void alc680_inithook(struct hda_codec *codec)
19856{
19857	alc_hp_automute(codec);
19858	alc680_rec_autoswitch(codec);
19859}
19860
19861/* create input playback/capture controls for the given pin */
19862static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19863				    const char *ctlname, int idx)
19864{
19865	hda_nid_t dac;
19866	int err;
19867
19868	switch (nid) {
19869	case 0x14:
19870		dac = 0x02;
19871		break;
19872	case 0x15:
19873		dac = 0x03;
19874		break;
19875	case 0x16:
19876		dac = 0x04;
19877		break;
19878	default:
19879		return 0;
19880	}
19881	if (spec->multiout.dac_nids[0] != dac &&
19882	    spec->multiout.dac_nids[1] != dac) {
19883		err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19884				  HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19885						      HDA_OUTPUT));
19886		if (err < 0)
19887			return err;
19888
19889		err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19890			  HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19891
19892		if (err < 0)
19893			return err;
19894		spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
19895	}
19896
19897	return 0;
19898}
19899
19900/* add playback controls from the parsed DAC table */
19901static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19902					     const struct auto_pin_cfg *cfg)
19903{
19904	hda_nid_t nid;
19905	int err;
19906
19907	spec->multiout.dac_nids = spec->private_dac_nids;
19908
19909	nid = cfg->line_out_pins[0];
19910	if (nid) {
19911		const char *name;
19912		if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19913			name = "Speaker";
19914		else
19915			name = "Front";
19916		err = alc680_new_analog_output(spec, nid, name, 0);
19917		if (err < 0)
19918			return err;
19919	}
19920
19921	nid = cfg->speaker_pins[0];
19922	if (nid) {
19923		err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19924		if (err < 0)
19925			return err;
19926	}
19927	nid = cfg->hp_pins[0];
19928	if (nid) {
19929		err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19930		if (err < 0)
19931			return err;
19932	}
19933
19934	return 0;
19935}
19936
19937static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19938					      hda_nid_t nid, int pin_type)
19939{
19940	alc_set_pin_output(codec, nid, pin_type);
19941}
19942
19943static void alc680_auto_init_multi_out(struct hda_codec *codec)
19944{
19945	struct alc_spec *spec = codec->spec;
19946	hda_nid_t nid = spec->autocfg.line_out_pins[0];
19947	if (nid) {
19948		int pin_type = get_pin_type(spec->autocfg.line_out_type);
19949		alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19950	}
19951}
19952
19953static void alc680_auto_init_hp_out(struct hda_codec *codec)
19954{
19955	struct alc_spec *spec = codec->spec;
19956	hda_nid_t pin;
19957
19958	pin = spec->autocfg.hp_pins[0];
19959	if (pin)
19960		alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19961	pin = spec->autocfg.speaker_pins[0];
19962	if (pin)
19963		alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19964}
19965
19966/* pcm configuration: identical with ALC880 */
19967#define alc680_pcm_analog_playback	alc880_pcm_analog_playback
19968#define alc680_pcm_analog_capture	alc880_pcm_analog_capture
19969#define alc680_pcm_analog_alt_capture	alc880_pcm_analog_alt_capture
19970#define alc680_pcm_digital_playback	alc880_pcm_digital_playback
19971#define alc680_pcm_digital_capture	alc880_pcm_digital_capture
19972
19973/*
19974 * BIOS auto configuration
19975 */
19976static int alc680_parse_auto_config(struct hda_codec *codec)
19977{
19978	struct alc_spec *spec = codec->spec;
19979	int err;
19980	static const hda_nid_t alc680_ignore[] = { 0 };
19981
19982	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19983					   alc680_ignore);
19984	if (err < 0)
19985		return err;
19986
19987	if (!spec->autocfg.line_outs) {
19988		if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19989			spec->multiout.max_channels = 2;
19990			spec->no_analog = 1;
19991			goto dig_only;
19992		}
19993		return 0; /* can't find valid BIOS pin config */
19994	}
19995	err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19996	if (err < 0)
19997		return err;
19998
19999	spec->multiout.max_channels = 2;
20000
20001 dig_only:
20002	/* digital only support output */
20003	alc_auto_parse_digital(codec);
20004	if (spec->kctls.list)
20005		add_mixer(spec, spec->kctls.list);
20006
20007	add_verb(spec, alc680_init_verbs);
20008
20009	err = alc_auto_add_mic_boost(codec);
20010	if (err < 0)
20011		return err;
20012
20013	return 1;
20014}
20015
20016#define alc680_auto_init_analog_input	alc882_auto_init_analog_input
20017
20018/* init callback for auto-configuration model -- overriding the default init */
20019static void alc680_auto_init(struct hda_codec *codec)
20020{
20021	struct alc_spec *spec = codec->spec;
20022	alc680_auto_init_multi_out(codec);
20023	alc680_auto_init_hp_out(codec);
20024	alc680_auto_init_analog_input(codec);
20025	alc_auto_init_digital(codec);
20026	if (spec->unsol_event)
20027		alc_inithook(codec);
20028}
20029
20030/*
20031 * configuration and preset
20032 */
20033static const char * const alc680_models[ALC680_MODEL_LAST] = {
20034	[ALC680_BASE]		= "base",
20035	[ALC680_AUTO]		= "auto",
20036};
20037
20038static const struct snd_pci_quirk alc680_cfg_tbl[] = {
20039	SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
20040	{}
20041};
20042
20043static const struct alc_config_preset alc680_presets[] = {
20044	[ALC680_BASE] = {
20045		.mixers = { alc680_base_mixer },
20046		.cap_mixer =  alc680_master_capture_mixer,
20047		.init_verbs = { alc680_init_verbs },
20048		.num_dacs = ARRAY_SIZE(alc680_dac_nids),
20049		.dac_nids = alc680_dac_nids,
20050		.dig_out_nid = ALC680_DIGOUT_NID,
20051		.num_channel_mode = ARRAY_SIZE(alc680_modes),
20052		.channel_mode = alc680_modes,
20053		.unsol_event = alc680_unsol_event,
20054		.setup = alc680_base_setup,
20055		.init_hook = alc680_inithook,
20056
20057	},
20058};
20059
20060static int patch_alc680(struct hda_codec *codec)
20061{
20062	struct alc_spec *spec;
20063	int board_config;
20064	int err;
20065
20066	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
20067	if (spec == NULL)
20068		return -ENOMEM;
20069
20070	codec->spec = spec;
20071
20072	board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
20073						  alc680_models,
20074						  alc680_cfg_tbl);
20075
20076	if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
20077		printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
20078		       codec->chip_name);
20079		board_config = ALC680_AUTO;
20080	}
20081
20082	if (board_config == ALC680_AUTO) {
20083		/* automatic parse from the BIOS config */
20084		err = alc680_parse_auto_config(codec);
20085		if (err < 0) {
20086			alc_free(codec);
20087			return err;
20088		} else if (!err) {
20089			printk(KERN_INFO
20090			       "hda_codec: Cannot set up configuration "
20091			       "from BIOS.  Using base mode...\n");
20092			board_config = ALC680_BASE;
20093		}
20094	}
20095
20096	if (board_config != ALC680_AUTO)
20097		setup_preset(codec, &alc680_presets[board_config]);
20098
20099	spec->stream_analog_playback = &alc680_pcm_analog_playback;
20100	spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
20101	spec->stream_digital_playback = &alc680_pcm_digital_playback;
20102	spec->stream_digital_capture = &alc680_pcm_digital_capture;
20103
20104	if (!spec->adc_nids) {
20105		spec->adc_nids = alc680_adc_nids;
20106		spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
20107	}
20108
20109	if (!spec->cap_mixer)
20110		set_capture_mixer(codec);
20111
20112	spec->vmaster_nid = 0x02;
20113
20114	codec->patch_ops = alc_patch_ops;
20115	if (board_config == ALC680_AUTO)
20116		spec->init_hook = alc680_auto_init;
20117
20118	return 0;
20119}
20120
20121/*
20122 * patch entries
20123 */
20124static const struct hda_codec_preset snd_hda_preset_realtek[] = {
20125	{ .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
20126	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
20127	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
20128	{ .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
20129	{ .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
20130	{ .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
20131	{ .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
20132	{ .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
20133	{ .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
20134	{ .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
20135	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
20136	  .patch = patch_alc861 },
20137	{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
20138	{ .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
20139	{ .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
20140	{ .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
20141	  .patch = patch_alc882 },
20142	{ .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
20143	  .patch = patch_alc662 },
20144	{ .id = 0x10ec0662, .rev = 0x100300, .name = "ALC662 rev3",
20145	  .patch = patch_alc662 },
20146	{ .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
20147	{ .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
20148	{ .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
20149	{ .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
20150	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
20151	{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
20152	{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
20153	{ .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
20154	  .patch = patch_alc882 },
20155	{ .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
20156	  .patch = patch_alc882 },
20157	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
20158	{ .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
20159	{ .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
20160	  .patch = patch_alc882 },
20161	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
20162	{ .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
20163	{ .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
20164	{ .id = 0x10ec0899, .name = "ALC899", .patch = patch_alc899 },
20165	{} /* terminator */
20166};
20167
20168MODULE_ALIAS("snd-hda-codec-id:10ec*");
20169
20170MODULE_LICENSE("GPL");
20171MODULE_DESCRIPTION("Realtek HD-audio codec");
20172
20173static struct hda_codec_preset_list realtek_list = {
20174	.preset = snd_hda_preset_realtek,
20175	.owner = THIS_MODULE,
20176};
20177
20178static int __init patch_realtek_init(void)
20179{
20180	return snd_hda_add_codec_preset(&realtek_list);
20181}
20182
20183static void __exit patch_realtek_exit(void)
20184{
20185	snd_hda_delete_codec_preset(&realtek_list);
20186}
20187
20188module_init(patch_realtek_init)
20189module_exit(patch_realtek_exit)
20190