patch_realtek.c revision e9bfcbffb7b26065a2b467e29bb6c7ec83d17646
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
513	type = get_wcaps_type(get_wcaps(codec, nid));
514	if (type == AC_WID_AUD_MIX) {
515		/* Matrix-mixer style (e.g. ALC882) */
516		unsigned int *cur_val = &spec->cur_mux[adc_idx];
517		unsigned int i, idx;
518
519		idx = ucontrol->value.enumerated.item[0];
520		if (idx >= imux->num_items)
521			idx = imux->num_items - 1;
522		if (*cur_val == idx)
523			return 0;
524		for (i = 0; i < imux->num_items; i++) {
525			unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
526			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
527						 imux->items[i].index,
528						 HDA_AMP_MUTE, v);
529		}
530		*cur_val = idx;
531		return 1;
532	} else {
533		/* MUX style (e.g. ALC880) */
534		return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
535					     &spec->cur_mux[adc_idx]);
536	}
537}
538
539/*
540 * channel mode setting
541 */
542static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
543			    struct snd_ctl_elem_info *uinfo)
544{
545	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
546	struct alc_spec *spec = codec->spec;
547	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
548				    spec->num_channel_mode);
549}
550
551static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
552			   struct snd_ctl_elem_value *ucontrol)
553{
554	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
555	struct alc_spec *spec = codec->spec;
556	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
557				   spec->num_channel_mode,
558				   spec->ext_channel_count);
559}
560
561static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
562			   struct snd_ctl_elem_value *ucontrol)
563{
564	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
565	struct alc_spec *spec = codec->spec;
566	int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
567				      spec->num_channel_mode,
568				      &spec->ext_channel_count);
569	if (err >= 0 && !spec->const_channel_count) {
570		spec->multiout.max_channels = spec->ext_channel_count;
571		if (spec->need_dac_fix)
572			spec->multiout.num_dacs = spec->multiout.max_channels / 2;
573	}
574	return err;
575}
576
577/*
578 * Control the mode of pin widget settings via the mixer.  "pc" is used
579 * instead of "%" to avoid consequences of accidentally treating the % as
580 * being part of a format specifier.  Maximum allowed length of a value is
581 * 63 characters plus NULL terminator.
582 *
583 * Note: some retasking pin complexes seem to ignore requests for input
584 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
585 * are requested.  Therefore order this list so that this behaviour will not
586 * cause problems when mixer clients move through the enum sequentially.
587 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
588 * March 2006.
589 */
590static const char * const alc_pin_mode_names[] = {
591	"Mic 50pc bias", "Mic 80pc bias",
592	"Line in", "Line out", "Headphone out",
593};
594static const unsigned char alc_pin_mode_values[] = {
595	PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
596};
597/* The control can present all 5 options, or it can limit the options based
598 * in the pin being assumed to be exclusively an input or an output pin.  In
599 * addition, "input" pins may or may not process the mic bias option
600 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
601 * accept requests for bias as of chip versions up to March 2006) and/or
602 * wiring in the computer.
603 */
604#define ALC_PIN_DIR_IN              0x00
605#define ALC_PIN_DIR_OUT             0x01
606#define ALC_PIN_DIR_INOUT           0x02
607#define ALC_PIN_DIR_IN_NOMICBIAS    0x03
608#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
609
610/* Info about the pin modes supported by the different pin direction modes.
611 * For each direction the minimum and maximum values are given.
612 */
613static const signed char alc_pin_mode_dir_info[5][2] = {
614	{ 0, 2 },    /* ALC_PIN_DIR_IN */
615	{ 3, 4 },    /* ALC_PIN_DIR_OUT */
616	{ 0, 4 },    /* ALC_PIN_DIR_INOUT */
617	{ 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
618	{ 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
619};
620#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
621#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
622#define alc_pin_mode_n_items(_dir) \
623	(alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
624
625static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
626			     struct snd_ctl_elem_info *uinfo)
627{
628	unsigned int item_num = uinfo->value.enumerated.item;
629	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
630
631	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
632	uinfo->count = 1;
633	uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
634
635	if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
636		item_num = alc_pin_mode_min(dir);
637	strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
638	return 0;
639}
640
641static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
642			    struct snd_ctl_elem_value *ucontrol)
643{
644	unsigned int i;
645	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
646	hda_nid_t nid = kcontrol->private_value & 0xffff;
647	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
648	long *valp = ucontrol->value.integer.value;
649	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
650						 AC_VERB_GET_PIN_WIDGET_CONTROL,
651						 0x00);
652
653	/* Find enumerated value for current pinctl setting */
654	i = alc_pin_mode_min(dir);
655	while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
656		i++;
657	*valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
658	return 0;
659}
660
661static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
662			    struct snd_ctl_elem_value *ucontrol)
663{
664	signed int change;
665	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
666	hda_nid_t nid = kcontrol->private_value & 0xffff;
667	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
668	long val = *ucontrol->value.integer.value;
669	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
670						 AC_VERB_GET_PIN_WIDGET_CONTROL,
671						 0x00);
672
673	if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
674		val = alc_pin_mode_min(dir);
675
676	change = pinctl != alc_pin_mode_values[val];
677	if (change) {
678		/* Set pin mode to that requested */
679		snd_hda_codec_write_cache(codec, nid, 0,
680					  AC_VERB_SET_PIN_WIDGET_CONTROL,
681					  alc_pin_mode_values[val]);
682
683		/* Also enable the retasking pin's input/output as required
684		 * for the requested pin mode.  Enum values of 2 or less are
685		 * input modes.
686		 *
687		 * Dynamically switching the input/output buffers probably
688		 * reduces noise slightly (particularly on input) so we'll
689		 * do it.  However, having both input and output buffers
690		 * enabled simultaneously doesn't seem to be problematic if
691		 * this turns out to be necessary in the future.
692		 */
693		if (val <= 2) {
694			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
695						 HDA_AMP_MUTE, HDA_AMP_MUTE);
696			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
697						 HDA_AMP_MUTE, 0);
698		} else {
699			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
700						 HDA_AMP_MUTE, HDA_AMP_MUTE);
701			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
702						 HDA_AMP_MUTE, 0);
703		}
704	}
705	return change;
706}
707
708#define ALC_PIN_MODE(xname, nid, dir) \
709	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
710	  .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
711	  .info = alc_pin_mode_info, \
712	  .get = alc_pin_mode_get, \
713	  .put = alc_pin_mode_put, \
714	  .private_value = nid | (dir<<16) }
715
716/* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
717 * together using a mask with more than one bit set.  This control is
718 * currently used only by the ALC260 test model.  At this stage they are not
719 * needed for any "production" models.
720 */
721#ifdef CONFIG_SND_DEBUG
722#define alc_gpio_data_info	snd_ctl_boolean_mono_info
723
724static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
725			     struct snd_ctl_elem_value *ucontrol)
726{
727	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
728	hda_nid_t nid = kcontrol->private_value & 0xffff;
729	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
730	long *valp = ucontrol->value.integer.value;
731	unsigned int val = snd_hda_codec_read(codec, nid, 0,
732					      AC_VERB_GET_GPIO_DATA, 0x00);
733
734	*valp = (val & mask) != 0;
735	return 0;
736}
737static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
738			     struct snd_ctl_elem_value *ucontrol)
739{
740	signed int change;
741	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
742	hda_nid_t nid = kcontrol->private_value & 0xffff;
743	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
744	long val = *ucontrol->value.integer.value;
745	unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
746						    AC_VERB_GET_GPIO_DATA,
747						    0x00);
748
749	/* Set/unset the masked GPIO bit(s) as needed */
750	change = (val == 0 ? 0 : mask) != (gpio_data & mask);
751	if (val == 0)
752		gpio_data &= ~mask;
753	else
754		gpio_data |= mask;
755	snd_hda_codec_write_cache(codec, nid, 0,
756				  AC_VERB_SET_GPIO_DATA, gpio_data);
757
758	return change;
759}
760#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
761	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
762	  .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
763	  .info = alc_gpio_data_info, \
764	  .get = alc_gpio_data_get, \
765	  .put = alc_gpio_data_put, \
766	  .private_value = nid | (mask<<16) }
767#endif   /* CONFIG_SND_DEBUG */
768
769/* A switch control to allow the enabling of the digital IO pins on the
770 * ALC260.  This is incredibly simplistic; the intention of this control is
771 * to provide something in the test model allowing digital outputs to be
772 * identified if present.  If models are found which can utilise these
773 * outputs a more complete mixer control can be devised for those models if
774 * necessary.
775 */
776#ifdef CONFIG_SND_DEBUG
777#define alc_spdif_ctrl_info	snd_ctl_boolean_mono_info
778
779static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
780			      struct snd_ctl_elem_value *ucontrol)
781{
782	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
783	hda_nid_t nid = kcontrol->private_value & 0xffff;
784	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
785	long *valp = ucontrol->value.integer.value;
786	unsigned int val = snd_hda_codec_read(codec, nid, 0,
787					      AC_VERB_GET_DIGI_CONVERT_1, 0x00);
788
789	*valp = (val & mask) != 0;
790	return 0;
791}
792static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
793			      struct snd_ctl_elem_value *ucontrol)
794{
795	signed int change;
796	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
797	hda_nid_t nid = kcontrol->private_value & 0xffff;
798	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
799	long val = *ucontrol->value.integer.value;
800	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
801						    AC_VERB_GET_DIGI_CONVERT_1,
802						    0x00);
803
804	/* Set/unset the masked control bit(s) as needed */
805	change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
806	if (val==0)
807		ctrl_data &= ~mask;
808	else
809		ctrl_data |= mask;
810	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
811				  ctrl_data);
812
813	return change;
814}
815#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
816	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
817	  .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
818	  .info = alc_spdif_ctrl_info, \
819	  .get = alc_spdif_ctrl_get, \
820	  .put = alc_spdif_ctrl_put, \
821	  .private_value = nid | (mask<<16) }
822#endif   /* CONFIG_SND_DEBUG */
823
824/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
825 * Again, this is only used in the ALC26x test models to help identify when
826 * the EAPD line must be asserted for features to work.
827 */
828#ifdef CONFIG_SND_DEBUG
829#define alc_eapd_ctrl_info	snd_ctl_boolean_mono_info
830
831static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
832			      struct snd_ctl_elem_value *ucontrol)
833{
834	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
835	hda_nid_t nid = kcontrol->private_value & 0xffff;
836	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
837	long *valp = ucontrol->value.integer.value;
838	unsigned int val = snd_hda_codec_read(codec, nid, 0,
839					      AC_VERB_GET_EAPD_BTLENABLE, 0x00);
840
841	*valp = (val & mask) != 0;
842	return 0;
843}
844
845static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
846			      struct snd_ctl_elem_value *ucontrol)
847{
848	int change;
849	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
850	hda_nid_t nid = kcontrol->private_value & 0xffff;
851	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
852	long val = *ucontrol->value.integer.value;
853	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
854						    AC_VERB_GET_EAPD_BTLENABLE,
855						    0x00);
856
857	/* Set/unset the masked control bit(s) as needed */
858	change = (!val ? 0 : mask) != (ctrl_data & mask);
859	if (!val)
860		ctrl_data &= ~mask;
861	else
862		ctrl_data |= mask;
863	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
864				  ctrl_data);
865
866	return change;
867}
868
869#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
870	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
871	  .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
872	  .info = alc_eapd_ctrl_info, \
873	  .get = alc_eapd_ctrl_get, \
874	  .put = alc_eapd_ctrl_put, \
875	  .private_value = nid | (mask<<16) }
876#endif   /* CONFIG_SND_DEBUG */
877
878/*
879 * set up the input pin config (depending on the given auto-pin type)
880 */
881static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
882			      int auto_pin_type)
883{
884	unsigned int val = PIN_IN;
885
886	if (auto_pin_type == AUTO_PIN_MIC) {
887		unsigned int pincap;
888		unsigned int oldval;
889		oldval = snd_hda_codec_read(codec, nid, 0,
890					    AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
891		pincap = snd_hda_query_pin_caps(codec, nid);
892		pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
893		/* if the default pin setup is vref50, we give it priority */
894		if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
895			val = PIN_VREF80;
896		else if (pincap & AC_PINCAP_VREF_50)
897			val = PIN_VREF50;
898		else if (pincap & AC_PINCAP_VREF_100)
899			val = PIN_VREF100;
900		else if (pincap & AC_PINCAP_VREF_GRD)
901			val = PIN_VREFGRD;
902	}
903	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
904}
905
906static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
907{
908	struct alc_spec *spec = codec->spec;
909	struct auto_pin_cfg *cfg = &spec->autocfg;
910
911	if (!cfg->line_outs) {
912		while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
913		       cfg->line_out_pins[cfg->line_outs])
914			cfg->line_outs++;
915	}
916	if (!cfg->speaker_outs) {
917		while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
918		       cfg->speaker_pins[cfg->speaker_outs])
919			cfg->speaker_outs++;
920	}
921	if (!cfg->hp_outs) {
922		while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
923		       cfg->hp_pins[cfg->hp_outs])
924			cfg->hp_outs++;
925	}
926}
927
928/*
929 */
930static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
931{
932	if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
933		return;
934	spec->mixers[spec->num_mixers++] = mix;
935}
936
937static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
938{
939	if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
940		return;
941	spec->init_verbs[spec->num_init_verbs++] = verb;
942}
943
944/*
945 * set up from the preset table
946 */
947static void setup_preset(struct hda_codec *codec,
948			 const struct alc_config_preset *preset)
949{
950	struct alc_spec *spec = codec->spec;
951	int i;
952
953	for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
954		add_mixer(spec, preset->mixers[i]);
955	spec->cap_mixer = preset->cap_mixer;
956	for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
957	     i++)
958		add_verb(spec, preset->init_verbs[i]);
959
960	spec->channel_mode = preset->channel_mode;
961	spec->num_channel_mode = preset->num_channel_mode;
962	spec->need_dac_fix = preset->need_dac_fix;
963	spec->const_channel_count = preset->const_channel_count;
964
965	if (preset->const_channel_count)
966		spec->multiout.max_channels = preset->const_channel_count;
967	else
968		spec->multiout.max_channels = spec->channel_mode[0].channels;
969	spec->ext_channel_count = spec->channel_mode[0].channels;
970
971	spec->multiout.num_dacs = preset->num_dacs;
972	spec->multiout.dac_nids = preset->dac_nids;
973	spec->multiout.dig_out_nid = preset->dig_out_nid;
974	spec->multiout.slave_dig_outs = preset->slave_dig_outs;
975	spec->multiout.hp_nid = preset->hp_nid;
976
977	spec->num_mux_defs = preset->num_mux_defs;
978	if (!spec->num_mux_defs)
979		spec->num_mux_defs = 1;
980	spec->input_mux = preset->input_mux;
981
982	spec->num_adc_nids = preset->num_adc_nids;
983	spec->adc_nids = preset->adc_nids;
984	spec->capsrc_nids = preset->capsrc_nids;
985	spec->dig_in_nid = preset->dig_in_nid;
986
987	spec->unsol_event = preset->unsol_event;
988	spec->init_hook = preset->init_hook;
989#ifdef CONFIG_SND_HDA_POWER_SAVE
990	spec->power_hook = preset->power_hook;
991	spec->loopback.amplist = preset->loopbacks;
992#endif
993
994	if (preset->setup)
995		preset->setup(codec);
996
997	alc_fixup_autocfg_pin_nums(codec);
998}
999
1000/* Enable GPIO mask and set output */
1001static const struct hda_verb alc_gpio1_init_verbs[] = {
1002	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
1003	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
1004	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
1005	{ }
1006};
1007
1008static const struct hda_verb alc_gpio2_init_verbs[] = {
1009	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
1010	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
1011	{0x01, AC_VERB_SET_GPIO_DATA, 0x02},
1012	{ }
1013};
1014
1015static const struct hda_verb alc_gpio3_init_verbs[] = {
1016	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
1017	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
1018	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
1019	{ }
1020};
1021
1022/*
1023 * Fix hardware PLL issue
1024 * On some codecs, the analog PLL gating control must be off while
1025 * the default value is 1.
1026 */
1027static void alc_fix_pll(struct hda_codec *codec)
1028{
1029	struct alc_spec *spec = codec->spec;
1030	unsigned int val;
1031
1032	if (!spec->pll_nid)
1033		return;
1034	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1035			    spec->pll_coef_idx);
1036	val = snd_hda_codec_read(codec, spec->pll_nid, 0,
1037				 AC_VERB_GET_PROC_COEF, 0);
1038	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1039			    spec->pll_coef_idx);
1040	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
1041			    val & ~(1 << spec->pll_coef_bit));
1042}
1043
1044static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1045			     unsigned int coef_idx, unsigned int coef_bit)
1046{
1047	struct alc_spec *spec = codec->spec;
1048	spec->pll_nid = nid;
1049	spec->pll_coef_idx = coef_idx;
1050	spec->pll_coef_bit = coef_bit;
1051	alc_fix_pll(codec);
1052}
1053
1054static int alc_init_jacks(struct hda_codec *codec)
1055{
1056#ifdef CONFIG_SND_HDA_INPUT_JACK
1057	struct alc_spec *spec = codec->spec;
1058	int err;
1059	unsigned int hp_nid = spec->autocfg.hp_pins[0];
1060	unsigned int mic_nid = spec->ext_mic.pin;
1061	unsigned int dock_nid = spec->dock_mic.pin;
1062
1063	if (hp_nid) {
1064		err = snd_hda_input_jack_add(codec, hp_nid,
1065					     SND_JACK_HEADPHONE, NULL);
1066		if (err < 0)
1067			return err;
1068		snd_hda_input_jack_report(codec, hp_nid);
1069	}
1070
1071	if (mic_nid) {
1072		err = snd_hda_input_jack_add(codec, mic_nid,
1073					     SND_JACK_MICROPHONE, NULL);
1074		if (err < 0)
1075			return err;
1076		snd_hda_input_jack_report(codec, mic_nid);
1077	}
1078	if (dock_nid) {
1079		err = snd_hda_input_jack_add(codec, dock_nid,
1080					     SND_JACK_MICROPHONE, NULL);
1081		if (err < 0)
1082			return err;
1083		snd_hda_input_jack_report(codec, dock_nid);
1084	}
1085#endif /* CONFIG_SND_HDA_INPUT_JACK */
1086	return 0;
1087}
1088
1089static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
1090{
1091	int i, present = 0;
1092
1093	for (i = 0; i < num_pins; i++) {
1094		hda_nid_t nid = pins[i];
1095		if (!nid)
1096			break;
1097		snd_hda_input_jack_report(codec, nid);
1098		present |= snd_hda_jack_detect(codec, nid);
1099	}
1100	return present;
1101}
1102
1103static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
1104			bool mute, bool hp_out)
1105{
1106	struct alc_spec *spec = codec->spec;
1107	unsigned int mute_bits = mute ? HDA_AMP_MUTE : 0;
1108	unsigned int pin_bits = mute ? 0 : (hp_out ? PIN_HP : PIN_OUT);
1109	int i;
1110
1111	for (i = 0; i < num_pins; i++) {
1112		hda_nid_t nid = pins[i];
1113		if (!nid)
1114			break;
1115		switch (spec->automute_mode) {
1116		case ALC_AUTOMUTE_PIN:
1117			snd_hda_codec_write(codec, nid, 0,
1118					    AC_VERB_SET_PIN_WIDGET_CONTROL,
1119					    pin_bits);
1120			break;
1121		case ALC_AUTOMUTE_AMP:
1122			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1123						 HDA_AMP_MUTE, mute_bits);
1124			break;
1125		case ALC_AUTOMUTE_MIXER:
1126			nid = spec->automute_mixer_nid[i];
1127			if (!nid)
1128				break;
1129			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
1130						 HDA_AMP_MUTE, mute_bits);
1131			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 1,
1132						 HDA_AMP_MUTE, mute_bits);
1133			break;
1134		}
1135	}
1136}
1137
1138/* Toggle internal speakers muting */
1139static void update_speakers(struct hda_codec *codec)
1140{
1141	struct alc_spec *spec = codec->spec;
1142	int on;
1143
1144	/* Control HP pins/amps depending on master_mute state;
1145	 * in general, HP pins/amps control should be enabled in all cases,
1146	 * but currently set only for master_mute, just to be safe
1147	 */
1148	do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1149		    spec->autocfg.hp_pins, spec->master_mute, true);
1150
1151	if (!spec->automute)
1152		on = 0;
1153	else
1154		on = spec->jack_present | spec->line_jack_present;
1155	on |= spec->master_mute;
1156	do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins),
1157		    spec->autocfg.speaker_pins, on, false);
1158
1159	/* toggle line-out mutes if needed, too */
1160	/* if LO is a copy of either HP or Speaker, don't need to handle it */
1161	if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] ||
1162	    spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0])
1163		return;
1164	if (!spec->automute || (spec->automute_hp_lo && !spec->automute_lines))
1165		on = 0;
1166	else
1167		on = spec->jack_present;
1168	on |= spec->master_mute;
1169	do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1170		    spec->autocfg.line_out_pins, on, false);
1171}
1172
1173static void alc_hp_automute(struct hda_codec *codec)
1174{
1175	struct alc_spec *spec = codec->spec;
1176
1177	if (!spec->automute)
1178		return;
1179	spec->jack_present =
1180		detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1181			     spec->autocfg.hp_pins);
1182	update_speakers(codec);
1183}
1184
1185static void alc_line_automute(struct hda_codec *codec)
1186{
1187	struct alc_spec *spec = codec->spec;
1188
1189	if (!spec->automute || !spec->detect_line)
1190		return;
1191	spec->line_jack_present =
1192		detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1193			     spec->autocfg.line_out_pins);
1194	update_speakers(codec);
1195}
1196
1197static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1198				hda_nid_t nid)
1199{
1200	hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1201	int i, nums;
1202
1203	nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1204	for (i = 0; i < nums; i++)
1205		if (conn[i] == nid)
1206			return i;
1207	return -1;
1208}
1209
1210/* switch the current ADC according to the jack state */
1211static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1212{
1213	struct alc_spec *spec = codec->spec;
1214	unsigned int present;
1215	hda_nid_t new_adc;
1216
1217	present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1218	if (present)
1219		spec->cur_adc_idx = 1;
1220	else
1221		spec->cur_adc_idx = 0;
1222	new_adc = spec->adc_nids[spec->cur_adc_idx];
1223	if (spec->cur_adc && spec->cur_adc != new_adc) {
1224		/* stream is running, let's swap the current ADC */
1225		__snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
1226		spec->cur_adc = new_adc;
1227		snd_hda_codec_setup_stream(codec, new_adc,
1228					   spec->cur_adc_stream_tag, 0,
1229					   spec->cur_adc_format);
1230	}
1231}
1232
1233static void alc_mic_automute(struct hda_codec *codec)
1234{
1235	struct alc_spec *spec = codec->spec;
1236	struct alc_mic_route *dead1, *dead2, *alive;
1237	unsigned int present, type;
1238	hda_nid_t cap_nid;
1239
1240	if (!spec->auto_mic)
1241		return;
1242	if (!spec->int_mic.pin || !spec->ext_mic.pin)
1243		return;
1244	if (snd_BUG_ON(!spec->adc_nids))
1245		return;
1246
1247	if (spec->dual_adc_switch) {
1248		alc_dual_mic_adc_auto_switch(codec);
1249		return;
1250	}
1251
1252	cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1253
1254	alive = &spec->int_mic;
1255	dead1 = &spec->ext_mic;
1256	dead2 = &spec->dock_mic;
1257
1258	present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1259	if (present) {
1260		alive = &spec->ext_mic;
1261		dead1 = &spec->int_mic;
1262		dead2 = &spec->dock_mic;
1263	}
1264	if (!present && spec->dock_mic.pin > 0) {
1265		present = snd_hda_jack_detect(codec, spec->dock_mic.pin);
1266		if (present) {
1267			alive = &spec->dock_mic;
1268			dead1 = &spec->int_mic;
1269			dead2 = &spec->ext_mic;
1270		}
1271		snd_hda_input_jack_report(codec, spec->dock_mic.pin);
1272	}
1273
1274	type = get_wcaps_type(get_wcaps(codec, cap_nid));
1275	if (type == AC_WID_AUD_MIX) {
1276		/* Matrix-mixer style (e.g. ALC882) */
1277		snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1278					 alive->mux_idx,
1279					 HDA_AMP_MUTE, 0);
1280		if (dead1->pin > 0)
1281			snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1282						 dead1->mux_idx,
1283						 HDA_AMP_MUTE, HDA_AMP_MUTE);
1284		if (dead2->pin > 0)
1285			snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1286						 dead2->mux_idx,
1287						 HDA_AMP_MUTE, HDA_AMP_MUTE);
1288	} else {
1289		/* MUX style (e.g. ALC880) */
1290		snd_hda_codec_write_cache(codec, cap_nid, 0,
1291					  AC_VERB_SET_CONNECT_SEL,
1292					  alive->mux_idx);
1293	}
1294	snd_hda_input_jack_report(codec, spec->ext_mic.pin);
1295
1296	/* FIXME: analog mixer */
1297}
1298
1299/* unsolicited event for HP jack sensing */
1300static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1301{
1302	if (codec->vendor_id == 0x10ec0880)
1303		res >>= 28;
1304	else
1305		res >>= 26;
1306	switch (res) {
1307	case ALC880_HP_EVENT:
1308		alc_hp_automute(codec);
1309		break;
1310	case ALC880_FRONT_EVENT:
1311		alc_line_automute(codec);
1312		break;
1313	case ALC880_MIC_EVENT:
1314		alc_mic_automute(codec);
1315		break;
1316	}
1317}
1318
1319static void alc_inithook(struct hda_codec *codec)
1320{
1321	alc_hp_automute(codec);
1322	alc_line_automute(codec);
1323	alc_mic_automute(codec);
1324}
1325
1326/* additional initialization for ALC888 variants */
1327static void alc888_coef_init(struct hda_codec *codec)
1328{
1329	unsigned int tmp;
1330
1331	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1332	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1333	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1334	if ((tmp & 0xf0) == 0x20)
1335		/* alc888S-VC */
1336		snd_hda_codec_read(codec, 0x20, 0,
1337				   AC_VERB_SET_PROC_COEF, 0x830);
1338	 else
1339		 /* alc888-VB */
1340		 snd_hda_codec_read(codec, 0x20, 0,
1341				    AC_VERB_SET_PROC_COEF, 0x3030);
1342}
1343
1344static void alc889_coef_init(struct hda_codec *codec)
1345{
1346	unsigned int tmp;
1347
1348	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1349	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1350	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1351	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1352}
1353
1354/* turn on/off EAPD control (only if available) */
1355static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1356{
1357	if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1358		return;
1359	if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1360		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1361				    on ? 2 : 0);
1362}
1363
1364/* turn on/off EAPD controls of the codec */
1365static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
1366{
1367	/* We currently only handle front, HP */
1368	switch (codec->vendor_id) {
1369	case 0x10ec0260:
1370		set_eapd(codec, 0x0f, on);
1371		set_eapd(codec, 0x10, on);
1372		break;
1373	case 0x10ec0262:
1374	case 0x10ec0267:
1375	case 0x10ec0268:
1376	case 0x10ec0269:
1377	case 0x10ec0270:
1378	case 0x10ec0272:
1379	case 0x10ec0660:
1380	case 0x10ec0662:
1381	case 0x10ec0663:
1382	case 0x10ec0665:
1383	case 0x10ec0862:
1384	case 0x10ec0889:
1385	case 0x10ec0892:
1386		set_eapd(codec, 0x14, on);
1387		set_eapd(codec, 0x15, on);
1388		break;
1389	}
1390}
1391
1392/* generic shutup callback;
1393 * just turning off EPAD and a little pause for avoiding pop-noise
1394 */
1395static void alc_eapd_shutup(struct hda_codec *codec)
1396{
1397	alc_auto_setup_eapd(codec, false);
1398	msleep(200);
1399}
1400
1401static void alc_auto_init_amp(struct hda_codec *codec, int type)
1402{
1403	unsigned int tmp;
1404
1405	switch (type) {
1406	case ALC_INIT_GPIO1:
1407		snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1408		break;
1409	case ALC_INIT_GPIO2:
1410		snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1411		break;
1412	case ALC_INIT_GPIO3:
1413		snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1414		break;
1415	case ALC_INIT_DEFAULT:
1416		alc_auto_setup_eapd(codec, true);
1417		switch (codec->vendor_id) {
1418		case 0x10ec0260:
1419			snd_hda_codec_write(codec, 0x1a, 0,
1420					    AC_VERB_SET_COEF_INDEX, 7);
1421			tmp = snd_hda_codec_read(codec, 0x1a, 0,
1422						 AC_VERB_GET_PROC_COEF, 0);
1423			snd_hda_codec_write(codec, 0x1a, 0,
1424					    AC_VERB_SET_COEF_INDEX, 7);
1425			snd_hda_codec_write(codec, 0x1a, 0,
1426					    AC_VERB_SET_PROC_COEF,
1427					    tmp | 0x2010);
1428			break;
1429		case 0x10ec0262:
1430		case 0x10ec0880:
1431		case 0x10ec0882:
1432		case 0x10ec0883:
1433		case 0x10ec0885:
1434		case 0x10ec0887:
1435		/*case 0x10ec0889:*/ /* this causes an SPDIF problem */
1436			alc889_coef_init(codec);
1437			break;
1438		case 0x10ec0888:
1439			alc888_coef_init(codec);
1440			break;
1441#if 0 /* XXX: This may cause the silent output on speaker on some machines */
1442		case 0x10ec0267:
1443		case 0x10ec0268:
1444			snd_hda_codec_write(codec, 0x20, 0,
1445					    AC_VERB_SET_COEF_INDEX, 7);
1446			tmp = snd_hda_codec_read(codec, 0x20, 0,
1447						 AC_VERB_GET_PROC_COEF, 0);
1448			snd_hda_codec_write(codec, 0x20, 0,
1449					    AC_VERB_SET_COEF_INDEX, 7);
1450			snd_hda_codec_write(codec, 0x20, 0,
1451					    AC_VERB_SET_PROC_COEF,
1452					    tmp | 0x3000);
1453			break;
1454#endif /* XXX */
1455		}
1456		break;
1457	}
1458}
1459
1460static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
1461				  struct snd_ctl_elem_info *uinfo)
1462{
1463	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1464	struct alc_spec *spec = codec->spec;
1465	static const char * const texts2[] = {
1466		"Disabled", "Enabled"
1467	};
1468	static const char * const texts3[] = {
1469		"Disabled", "Speaker Only", "Line-Out+Speaker"
1470	};
1471	const char * const *texts;
1472
1473	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1474	uinfo->count = 1;
1475	if (spec->automute_hp_lo) {
1476		uinfo->value.enumerated.items = 3;
1477		texts = texts3;
1478	} else {
1479		uinfo->value.enumerated.items = 2;
1480		texts = texts2;
1481	}
1482	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1483		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1484	strcpy(uinfo->value.enumerated.name,
1485	       texts[uinfo->value.enumerated.item]);
1486	return 0;
1487}
1488
1489static int alc_automute_mode_get(struct snd_kcontrol *kcontrol,
1490				 struct snd_ctl_elem_value *ucontrol)
1491{
1492	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1493	struct alc_spec *spec = codec->spec;
1494	unsigned int val;
1495	if (!spec->automute)
1496		val = 0;
1497	else if (!spec->automute_hp_lo || !spec->automute_lines)
1498		val = 1;
1499	else
1500		val = 2;
1501	ucontrol->value.enumerated.item[0] = val;
1502	return 0;
1503}
1504
1505static int alc_automute_mode_put(struct snd_kcontrol *kcontrol,
1506				 struct snd_ctl_elem_value *ucontrol)
1507{
1508	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1509	struct alc_spec *spec = codec->spec;
1510
1511	switch (ucontrol->value.enumerated.item[0]) {
1512	case 0:
1513		if (!spec->automute)
1514			return 0;
1515		spec->automute = 0;
1516		break;
1517	case 1:
1518		if (spec->automute &&
1519		    (!spec->automute_hp_lo || !spec->automute_lines))
1520			return 0;
1521		spec->automute = 1;
1522		spec->automute_lines = 0;
1523		break;
1524	case 2:
1525		if (!spec->automute_hp_lo)
1526			return -EINVAL;
1527		if (spec->automute && spec->automute_lines)
1528			return 0;
1529		spec->automute = 1;
1530		spec->automute_lines = 1;
1531		break;
1532	default:
1533		return -EINVAL;
1534	}
1535	update_speakers(codec);
1536	return 1;
1537}
1538
1539static const struct snd_kcontrol_new alc_automute_mode_enum = {
1540	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1541	.name = "Auto-Mute Mode",
1542	.info = alc_automute_mode_info,
1543	.get = alc_automute_mode_get,
1544	.put = alc_automute_mode_put,
1545};
1546
1547static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec);
1548
1549static int alc_add_automute_mode_enum(struct hda_codec *codec)
1550{
1551	struct alc_spec *spec = codec->spec;
1552	struct snd_kcontrol_new *knew;
1553
1554	knew = alc_kcontrol_new(spec);
1555	if (!knew)
1556		return -ENOMEM;
1557	*knew = alc_automute_mode_enum;
1558	knew->name = kstrdup("Auto-Mute Mode", GFP_KERNEL);
1559	if (!knew->name)
1560		return -ENOMEM;
1561	return 0;
1562}
1563
1564static void alc_init_auto_hp(struct hda_codec *codec)
1565{
1566	struct alc_spec *spec = codec->spec;
1567	struct auto_pin_cfg *cfg = &spec->autocfg;
1568	int present = 0;
1569	int i;
1570
1571	if (cfg->hp_pins[0])
1572		present++;
1573	if (cfg->line_out_pins[0])
1574		present++;
1575	if (cfg->speaker_pins[0])
1576		present++;
1577	if (present < 2) /* need two different output types */
1578		return;
1579	if (present == 3)
1580		spec->automute_hp_lo = 1; /* both HP and LO automute */
1581
1582	if (!cfg->speaker_pins[0] &&
1583	    cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
1584		memcpy(cfg->speaker_pins, cfg->line_out_pins,
1585		       sizeof(cfg->speaker_pins));
1586		cfg->speaker_outs = cfg->line_outs;
1587	}
1588
1589	if (!cfg->hp_pins[0] &&
1590	    cfg->line_out_type == AUTO_PIN_HP_OUT) {
1591		memcpy(cfg->hp_pins, cfg->line_out_pins,
1592		       sizeof(cfg->hp_pins));
1593		cfg->hp_outs = cfg->line_outs;
1594	}
1595
1596	for (i = 0; i < cfg->hp_outs; i++) {
1597		hda_nid_t nid = cfg->hp_pins[i];
1598		if (!is_jack_detectable(codec, nid))
1599			continue;
1600		snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1601			    nid);
1602		snd_hda_codec_write_cache(codec, nid, 0,
1603				  AC_VERB_SET_UNSOLICITED_ENABLE,
1604				  AC_USRSP_EN | ALC880_HP_EVENT);
1605		spec->automute = 1;
1606		spec->automute_mode = ALC_AUTOMUTE_PIN;
1607	}
1608	if (spec->automute && cfg->line_out_pins[0] &&
1609	    cfg->speaker_pins[0] &&
1610	    cfg->line_out_pins[0] != cfg->hp_pins[0] &&
1611	    cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
1612		for (i = 0; i < cfg->line_outs; i++) {
1613			hda_nid_t nid = cfg->line_out_pins[i];
1614			if (!is_jack_detectable(codec, nid))
1615				continue;
1616			snd_printdd("realtek: Enable Line-Out auto-muting "
1617				    "on NID 0x%x\n", nid);
1618			snd_hda_codec_write_cache(codec, nid, 0,
1619					AC_VERB_SET_UNSOLICITED_ENABLE,
1620					AC_USRSP_EN | ALC880_FRONT_EVENT);
1621			spec->detect_line = 1;
1622		}
1623		spec->automute_lines = spec->detect_line;
1624	}
1625
1626	if (spec->automute) {
1627		/* create a control for automute mode */
1628		alc_add_automute_mode_enum(codec);
1629		spec->unsol_event = alc_sku_unsol_event;
1630	}
1631}
1632
1633static void alc_init_auto_mic(struct hda_codec *codec)
1634{
1635	struct alc_spec *spec = codec->spec;
1636	struct auto_pin_cfg *cfg = &spec->autocfg;
1637	hda_nid_t fixed, ext, dock;
1638	int i;
1639
1640	fixed = ext = dock = 0;
1641	for (i = 0; i < cfg->num_inputs; i++) {
1642		hda_nid_t nid = cfg->inputs[i].pin;
1643		unsigned int defcfg;
1644		defcfg = snd_hda_codec_get_pincfg(codec, nid);
1645		switch (snd_hda_get_input_pin_attr(defcfg)) {
1646		case INPUT_PIN_ATTR_INT:
1647			if (fixed)
1648				return; /* already occupied */
1649			if (cfg->inputs[i].type != AUTO_PIN_MIC)
1650				return; /* invalid type */
1651			fixed = nid;
1652			break;
1653		case INPUT_PIN_ATTR_UNUSED:
1654			return; /* invalid entry */
1655		case INPUT_PIN_ATTR_DOCK:
1656			if (dock)
1657				return; /* already occupied */
1658			if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
1659				return; /* invalid type */
1660			dock = nid;
1661			break;
1662		default:
1663			if (ext)
1664				return; /* already occupied */
1665			if (cfg->inputs[i].type != AUTO_PIN_MIC)
1666				return; /* invalid type */
1667			ext = nid;
1668			break;
1669		}
1670	}
1671	if (!ext && dock) {
1672		ext = dock;
1673		dock = 0;
1674	}
1675	if (!ext || !fixed)
1676		return;
1677	if (!is_jack_detectable(codec, ext))
1678		return; /* no unsol support */
1679	if (dock && !is_jack_detectable(codec, dock))
1680		return; /* no unsol support */
1681	snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n",
1682		    ext, fixed, dock);
1683	spec->ext_mic.pin = ext;
1684	spec->dock_mic.pin = dock;
1685	spec->int_mic.pin = fixed;
1686	spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1687	spec->dock_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1688	spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1689	spec->auto_mic = 1;
1690	snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1691				  AC_VERB_SET_UNSOLICITED_ENABLE,
1692				  AC_USRSP_EN | ALC880_MIC_EVENT);
1693	spec->unsol_event = alc_sku_unsol_event;
1694}
1695
1696/* Could be any non-zero and even value. When used as fixup, tells
1697 * the driver to ignore any present sku defines.
1698 */
1699#define ALC_FIXUP_SKU_IGNORE (2)
1700
1701static int alc_auto_parse_customize_define(struct hda_codec *codec)
1702{
1703	unsigned int ass, tmp, i;
1704	unsigned nid = 0;
1705	struct alc_spec *spec = codec->spec;
1706
1707	spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1708
1709	if (spec->cdefine.fixup) {
1710		ass = spec->cdefine.sku_cfg;
1711		if (ass == ALC_FIXUP_SKU_IGNORE)
1712			return -1;
1713		goto do_sku;
1714	}
1715
1716	ass = codec->subsystem_id & 0xffff;
1717	if (ass != codec->bus->pci->subsystem_device && (ass & 1))
1718		goto do_sku;
1719
1720	nid = 0x1d;
1721	if (codec->vendor_id == 0x10ec0260)
1722		nid = 0x17;
1723	ass = snd_hda_codec_get_pincfg(codec, nid);
1724
1725	if (!(ass & 1)) {
1726		printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1727		       codec->chip_name, ass);
1728		return -1;
1729	}
1730
1731	/* check sum */
1732	tmp = 0;
1733	for (i = 1; i < 16; i++) {
1734		if ((ass >> i) & 1)
1735			tmp++;
1736	}
1737	if (((ass >> 16) & 0xf) != tmp)
1738		return -1;
1739
1740	spec->cdefine.port_connectivity = ass >> 30;
1741	spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1742	spec->cdefine.check_sum = (ass >> 16) & 0xf;
1743	spec->cdefine.customization = ass >> 8;
1744do_sku:
1745	spec->cdefine.sku_cfg = ass;
1746	spec->cdefine.external_amp = (ass & 0x38) >> 3;
1747	spec->cdefine.platform_type = (ass & 0x4) >> 2;
1748	spec->cdefine.swap = (ass & 0x2) >> 1;
1749	spec->cdefine.override = ass & 0x1;
1750
1751	snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1752		   nid, spec->cdefine.sku_cfg);
1753	snd_printd("SKU: port_connectivity=0x%x\n",
1754		   spec->cdefine.port_connectivity);
1755	snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1756	snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1757	snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1758	snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1759	snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1760	snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1761	snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1762
1763	return 0;
1764}
1765
1766/* check subsystem ID and set up device-specific initialization;
1767 * return 1 if initialized, 0 if invalid SSID
1768 */
1769/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1770 *	31 ~ 16 :	Manufacture ID
1771 *	15 ~ 8	:	SKU ID
1772 *	7  ~ 0	:	Assembly ID
1773 *	port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1774 */
1775static int alc_subsystem_id(struct hda_codec *codec,
1776			    hda_nid_t porta, hda_nid_t porte,
1777			    hda_nid_t portd, hda_nid_t porti)
1778{
1779	unsigned int ass, tmp, i;
1780	unsigned nid;
1781	struct alc_spec *spec = codec->spec;
1782
1783	if (spec->cdefine.fixup) {
1784		ass = spec->cdefine.sku_cfg;
1785		if (ass == ALC_FIXUP_SKU_IGNORE)
1786			return 0;
1787		goto do_sku;
1788	}
1789
1790	ass = codec->subsystem_id & 0xffff;
1791	if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1792		goto do_sku;
1793
1794	/* invalid SSID, check the special NID pin defcfg instead */
1795	/*
1796	 * 31~30	: port connectivity
1797	 * 29~21	: reserve
1798	 * 20		: PCBEEP input
1799	 * 19~16	: Check sum (15:1)
1800	 * 15~1		: Custom
1801	 * 0		: override
1802	*/
1803	nid = 0x1d;
1804	if (codec->vendor_id == 0x10ec0260)
1805		nid = 0x17;
1806	ass = snd_hda_codec_get_pincfg(codec, nid);
1807	snd_printd("realtek: No valid SSID, "
1808		   "checking pincfg 0x%08x for NID 0x%x\n",
1809		   ass, nid);
1810	if (!(ass & 1))
1811		return 0;
1812	if ((ass >> 30) != 1)	/* no physical connection */
1813		return 0;
1814
1815	/* check sum */
1816	tmp = 0;
1817	for (i = 1; i < 16; i++) {
1818		if ((ass >> i) & 1)
1819			tmp++;
1820	}
1821	if (((ass >> 16) & 0xf) != tmp)
1822		return 0;
1823do_sku:
1824	snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1825		   ass & 0xffff, codec->vendor_id);
1826	/*
1827	 * 0 : override
1828	 * 1 :	Swap Jack
1829	 * 2 : 0 --> Desktop, 1 --> Laptop
1830	 * 3~5 : External Amplifier control
1831	 * 7~6 : Reserved
1832	*/
1833	tmp = (ass & 0x38) >> 3;	/* external Amp control */
1834	switch (tmp) {
1835	case 1:
1836		spec->init_amp = ALC_INIT_GPIO1;
1837		break;
1838	case 3:
1839		spec->init_amp = ALC_INIT_GPIO2;
1840		break;
1841	case 7:
1842		spec->init_amp = ALC_INIT_GPIO3;
1843		break;
1844	case 5:
1845	default:
1846		spec->init_amp = ALC_INIT_DEFAULT;
1847		break;
1848	}
1849
1850	/* is laptop or Desktop and enable the function "Mute internal speaker
1851	 * when the external headphone out jack is plugged"
1852	 */
1853	if (!(ass & 0x8000))
1854		return 1;
1855	/*
1856	 * 10~8 : Jack location
1857	 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1858	 * 14~13: Resvered
1859	 * 15   : 1 --> enable the function "Mute internal speaker
1860	 *	        when the external headphone out jack is plugged"
1861	 */
1862	if (!spec->autocfg.hp_pins[0]) {
1863		hda_nid_t nid;
1864		tmp = (ass >> 11) & 0x3;	/* HP to chassis */
1865		if (tmp == 0)
1866			nid = porta;
1867		else if (tmp == 1)
1868			nid = porte;
1869		else if (tmp == 2)
1870			nid = portd;
1871		else if (tmp == 3)
1872			nid = porti;
1873		else
1874			return 1;
1875		for (i = 0; i < spec->autocfg.line_outs; i++)
1876			if (spec->autocfg.line_out_pins[i] == nid)
1877				return 1;
1878		spec->autocfg.hp_pins[0] = nid;
1879	}
1880	return 1;
1881}
1882
1883static void alc_ssid_check(struct hda_codec *codec,
1884			   hda_nid_t porta, hda_nid_t porte,
1885			   hda_nid_t portd, hda_nid_t porti)
1886{
1887	if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
1888		struct alc_spec *spec = codec->spec;
1889		snd_printd("realtek: "
1890			   "Enable default setup for auto mode as fallback\n");
1891		spec->init_amp = ALC_INIT_DEFAULT;
1892	}
1893
1894	alc_init_auto_hp(codec);
1895	alc_init_auto_mic(codec);
1896}
1897
1898/*
1899 * Fix-up pin default configurations and add default verbs
1900 */
1901
1902struct alc_pincfg {
1903	hda_nid_t nid;
1904	u32 val;
1905};
1906
1907struct alc_model_fixup {
1908	const int id;
1909	const char *name;
1910};
1911
1912struct alc_fixup {
1913	int type;
1914	bool chained;
1915	int chain_id;
1916	union {
1917		unsigned int sku;
1918		const struct alc_pincfg *pins;
1919		const struct hda_verb *verbs;
1920		void (*func)(struct hda_codec *codec,
1921			     const struct alc_fixup *fix,
1922			     int action);
1923	} v;
1924};
1925
1926enum {
1927	ALC_FIXUP_INVALID,
1928	ALC_FIXUP_SKU,
1929	ALC_FIXUP_PINS,
1930	ALC_FIXUP_VERBS,
1931	ALC_FIXUP_FUNC,
1932};
1933
1934enum {
1935	ALC_FIXUP_ACT_PRE_PROBE,
1936	ALC_FIXUP_ACT_PROBE,
1937	ALC_FIXUP_ACT_INIT,
1938};
1939
1940static void alc_apply_fixup(struct hda_codec *codec, int action)
1941{
1942	struct alc_spec *spec = codec->spec;
1943	int id = spec->fixup_id;
1944#ifdef CONFIG_SND_DEBUG_VERBOSE
1945	const char *modelname = spec->fixup_name;
1946#endif
1947	int depth = 0;
1948
1949	if (!spec->fixup_list)
1950		return;
1951
1952	while (id >= 0) {
1953		const struct alc_fixup *fix = spec->fixup_list + id;
1954		const struct alc_pincfg *cfg;
1955
1956		switch (fix->type) {
1957		case ALC_FIXUP_SKU:
1958			if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
1959				break;;
1960			snd_printdd(KERN_INFO "hda_codec: %s: "
1961				    "Apply sku override for %s\n",
1962				    codec->chip_name, modelname);
1963			spec->cdefine.sku_cfg = fix->v.sku;
1964			spec->cdefine.fixup = 1;
1965			break;
1966		case ALC_FIXUP_PINS:
1967			cfg = fix->v.pins;
1968			if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
1969				break;
1970			snd_printdd(KERN_INFO "hda_codec: %s: "
1971				    "Apply pincfg for %s\n",
1972				    codec->chip_name, modelname);
1973			for (; cfg->nid; cfg++)
1974				snd_hda_codec_set_pincfg(codec, cfg->nid,
1975							 cfg->val);
1976			break;
1977		case ALC_FIXUP_VERBS:
1978			if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
1979				break;
1980			snd_printdd(KERN_INFO "hda_codec: %s: "
1981				    "Apply fix-verbs for %s\n",
1982				    codec->chip_name, modelname);
1983			add_verb(codec->spec, fix->v.verbs);
1984			break;
1985		case ALC_FIXUP_FUNC:
1986			if (!fix->v.func)
1987				break;
1988			snd_printdd(KERN_INFO "hda_codec: %s: "
1989				    "Apply fix-func for %s\n",
1990				    codec->chip_name, modelname);
1991			fix->v.func(codec, fix, action);
1992			break;
1993		default:
1994			snd_printk(KERN_ERR "hda_codec: %s: "
1995				   "Invalid fixup type %d\n",
1996				   codec->chip_name, fix->type);
1997			break;
1998		}
1999		if (!fix->chained)
2000			break;
2001		if (++depth > 10)
2002			break;
2003		id = fix->chain_id;
2004	}
2005}
2006
2007static void alc_pick_fixup(struct hda_codec *codec,
2008			   const struct alc_model_fixup *models,
2009			   const struct snd_pci_quirk *quirk,
2010			   const struct alc_fixup *fixlist)
2011{
2012	struct alc_spec *spec = codec->spec;
2013	int id = -1;
2014	const char *name = NULL;
2015
2016	if (codec->modelname && models) {
2017		while (models->name) {
2018			if (!strcmp(codec->modelname, models->name)) {
2019				id = models->id;
2020				name = models->name;
2021				break;
2022			}
2023			models++;
2024		}
2025	}
2026	if (id < 0) {
2027		quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
2028		if (quirk) {
2029			id = quirk->value;
2030#ifdef CONFIG_SND_DEBUG_VERBOSE
2031			name = quirk->name;
2032#endif
2033		}
2034	}
2035
2036	spec->fixup_id = id;
2037	if (id >= 0) {
2038		spec->fixup_list = fixlist;
2039		spec->fixup_name = name;
2040	}
2041}
2042
2043static int alc_read_coef_idx(struct hda_codec *codec,
2044			unsigned int coef_idx)
2045{
2046	unsigned int val;
2047	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2048		    		coef_idx);
2049	val = snd_hda_codec_read(codec, 0x20, 0,
2050			 	AC_VERB_GET_PROC_COEF, 0);
2051	return val;
2052}
2053
2054static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
2055							unsigned int coef_val)
2056{
2057	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2058			    coef_idx);
2059	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
2060			    coef_val);
2061}
2062
2063/* set right pin controls for digital I/O */
2064static void alc_auto_init_digital(struct hda_codec *codec)
2065{
2066	struct alc_spec *spec = codec->spec;
2067	int i;
2068	hda_nid_t pin;
2069
2070	for (i = 0; i < spec->autocfg.dig_outs; i++) {
2071		pin = spec->autocfg.dig_out_pins[i];
2072		if (pin) {
2073			snd_hda_codec_write(codec, pin, 0,
2074					    AC_VERB_SET_PIN_WIDGET_CONTROL,
2075					    PIN_OUT);
2076		}
2077	}
2078	pin = spec->autocfg.dig_in_pin;
2079	if (pin)
2080		snd_hda_codec_write(codec, pin, 0,
2081				    AC_VERB_SET_PIN_WIDGET_CONTROL,
2082				    PIN_IN);
2083}
2084
2085/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
2086static void alc_auto_parse_digital(struct hda_codec *codec)
2087{
2088	struct alc_spec *spec = codec->spec;
2089	int i, err;
2090	hda_nid_t dig_nid;
2091
2092	/* support multiple SPDIFs; the secondary is set up as a slave */
2093	for (i = 0; i < spec->autocfg.dig_outs; i++) {
2094		err = snd_hda_get_connections(codec,
2095					      spec->autocfg.dig_out_pins[i],
2096					      &dig_nid, 1);
2097		if (err < 0)
2098			continue;
2099		if (!i) {
2100			spec->multiout.dig_out_nid = dig_nid;
2101			spec->dig_out_type = spec->autocfg.dig_out_type[0];
2102		} else {
2103			spec->multiout.slave_dig_outs = spec->slave_dig_outs;
2104			if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
2105				break;
2106			spec->slave_dig_outs[i - 1] = dig_nid;
2107		}
2108	}
2109
2110	if (spec->autocfg.dig_in_pin) {
2111		dig_nid = codec->start_nid;
2112		for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
2113			unsigned int wcaps = get_wcaps(codec, dig_nid);
2114			if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
2115				continue;
2116			if (!(wcaps & AC_WCAP_DIGITAL))
2117				continue;
2118			if (!(wcaps & AC_WCAP_CONN_LIST))
2119				continue;
2120			err = get_connection_index(codec, dig_nid,
2121						   spec->autocfg.dig_in_pin);
2122			if (err >= 0) {
2123				spec->dig_in_nid = dig_nid;
2124				break;
2125			}
2126		}
2127	}
2128}
2129
2130/*
2131 * ALC888
2132 */
2133
2134/*
2135 * 2ch mode
2136 */
2137static const struct hda_verb alc888_4ST_ch2_intel_init[] = {
2138/* Mic-in jack as mic in */
2139	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2140	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2141/* Line-in jack as Line in */
2142	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2143	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2144/* Line-Out as Front */
2145	{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2146	{ } /* end */
2147};
2148
2149/*
2150 * 4ch mode
2151 */
2152static const struct hda_verb alc888_4ST_ch4_intel_init[] = {
2153/* Mic-in jack as mic in */
2154	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2155	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2156/* Line-in jack as Surround */
2157	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2158	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2159/* Line-Out as Front */
2160	{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2161	{ } /* end */
2162};
2163
2164/*
2165 * 6ch mode
2166 */
2167static const struct hda_verb alc888_4ST_ch6_intel_init[] = {
2168/* Mic-in jack as CLFE */
2169	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2170	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2171/* Line-in jack as Surround */
2172	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2173	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2174/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
2175	{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2176	{ } /* end */
2177};
2178
2179/*
2180 * 8ch mode
2181 */
2182static const struct hda_verb alc888_4ST_ch8_intel_init[] = {
2183/* Mic-in jack as CLFE */
2184	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2185	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2186/* Line-in jack as Surround */
2187	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2188	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2189/* Line-Out as Side */
2190	{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2191	{ } /* end */
2192};
2193
2194static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
2195	{ 2, alc888_4ST_ch2_intel_init },
2196	{ 4, alc888_4ST_ch4_intel_init },
2197	{ 6, alc888_4ST_ch6_intel_init },
2198	{ 8, alc888_4ST_ch8_intel_init },
2199};
2200
2201/*
2202 * ALC888 Fujitsu Siemens Amillo xa3530
2203 */
2204
2205static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
2206/* Front Mic: set to PIN_IN (empty by default) */
2207	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2208/* Connect Internal HP to Front */
2209	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2210	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2211	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2212/* Connect Bass HP to Front */
2213	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2214	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2215	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2216/* Connect Line-Out side jack (SPDIF) to Side */
2217	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2218	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2219	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2220/* Connect Mic jack to CLFE */
2221	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2222	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2223	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
2224/* Connect Line-in jack to Surround */
2225	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2226	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2227	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
2228/* Connect HP out jack to Front */
2229	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2230	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2231	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2232/* Enable unsolicited event for HP jack and Line-out jack */
2233	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2234	{0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2235	{}
2236};
2237
2238static void alc889_automute_setup(struct hda_codec *codec)
2239{
2240	struct alc_spec *spec = codec->spec;
2241
2242	spec->autocfg.hp_pins[0] = 0x15;
2243	spec->autocfg.speaker_pins[0] = 0x14;
2244	spec->autocfg.speaker_pins[1] = 0x16;
2245	spec->autocfg.speaker_pins[2] = 0x17;
2246	spec->autocfg.speaker_pins[3] = 0x19;
2247	spec->autocfg.speaker_pins[4] = 0x1a;
2248	spec->automute = 1;
2249	spec->automute_mode = ALC_AUTOMUTE_AMP;
2250}
2251
2252static void alc889_intel_init_hook(struct hda_codec *codec)
2253{
2254	alc889_coef_init(codec);
2255	alc_hp_automute(codec);
2256}
2257
2258static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
2259{
2260	struct alc_spec *spec = codec->spec;
2261
2262	spec->autocfg.hp_pins[0] = 0x17; /* line-out */
2263	spec->autocfg.hp_pins[1] = 0x1b; /* hp */
2264	spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
2265	spec->autocfg.speaker_pins[1] = 0x15; /* bass */
2266	spec->automute = 1;
2267	spec->automute_mode = ALC_AUTOMUTE_AMP;
2268}
2269
2270/*
2271 * ALC888 Acer Aspire 4930G model
2272 */
2273
2274static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
2275/* Front Mic: set to PIN_IN (empty by default) */
2276	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2277/* Unselect Front Mic by default in input mixer 3 */
2278	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2279/* Enable unsolicited event for HP jack */
2280	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2281/* Connect Internal HP to front */
2282	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2283	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2284	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2285/* Connect HP out to front */
2286	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2287	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2288	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2289	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2290	{ }
2291};
2292
2293/*
2294 * ALC888 Acer Aspire 6530G model
2295 */
2296
2297static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
2298/* Route to built-in subwoofer as well as speakers */
2299	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2300	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2301	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2302	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2303/* Bias voltage on for external mic port */
2304	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2305/* Front Mic: set to PIN_IN (empty by default) */
2306	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2307/* Unselect Front Mic by default in input mixer 3 */
2308	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2309/* Enable unsolicited event for HP jack */
2310	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2311/* Enable speaker output */
2312	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2313	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2314	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2315/* Enable headphone output */
2316	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2317	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2318	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2319	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2320	{ }
2321};
2322
2323/*
2324 *ALC888 Acer Aspire 7730G model
2325 */
2326
2327static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
2328/* Bias voltage on for external mic port */
2329	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2330/* Front Mic: set to PIN_IN (empty by default) */
2331	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2332/* Unselect Front Mic by default in input mixer 3 */
2333	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2334/* Enable unsolicited event for HP jack */
2335	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2336/* Enable speaker output */
2337	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2338	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2339	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2340/* Enable headphone output */
2341	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2342	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2343	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2344	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2345/*Enable internal subwoofer */
2346	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2347	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2348	{0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2349	{0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2350	{ }
2351};
2352
2353/*
2354 * ALC889 Acer Aspire 8930G model
2355 */
2356
2357static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
2358/* Front Mic: set to PIN_IN (empty by default) */
2359	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2360/* Unselect Front Mic by default in input mixer 3 */
2361	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2362/* Enable unsolicited event for HP jack */
2363	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2364/* Connect Internal Front to Front */
2365	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2366	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2367	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2368/* Connect Internal Rear to Rear */
2369	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2370	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2371	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2372/* Connect Internal CLFE to CLFE */
2373	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2374	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2375	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2376/* Connect HP out to Front */
2377	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2378	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2379	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2380/* Enable all DACs */
2381/*  DAC DISABLE/MUTE 1? */
2382/*  setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2383	{0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2384	{0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2385/*  DAC DISABLE/MUTE 2? */
2386/*  some bit here disables the other DACs. Init=0x4900 */
2387	{0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2388	{0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2389/* DMIC fix
2390 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2391 * which makes the stereo useless. However, either the mic or the ALC889
2392 * makes the signal become a difference/sum signal instead of standard
2393 * stereo, which is annoying. So instead we flip this bit which makes the
2394 * codec replicate the sum signal to both channels, turning it into a
2395 * normal mono mic.
2396 */
2397/*  DMIC_CONTROL? Init value = 0x0001 */
2398	{0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2399	{0x20, AC_VERB_SET_PROC_COEF, 0x0003},
2400	{ }
2401};
2402
2403static const struct hda_input_mux alc888_2_capture_sources[2] = {
2404	/* Front mic only available on one ADC */
2405	{
2406		.num_items = 4,
2407		.items = {
2408			{ "Mic", 0x0 },
2409			{ "Line", 0x2 },
2410			{ "CD", 0x4 },
2411			{ "Front Mic", 0xb },
2412		},
2413	},
2414	{
2415		.num_items = 3,
2416		.items = {
2417			{ "Mic", 0x0 },
2418			{ "Line", 0x2 },
2419			{ "CD", 0x4 },
2420		},
2421	}
2422};
2423
2424static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2425	/* Interal mic only available on one ADC */
2426	{
2427		.num_items = 5,
2428		.items = {
2429			{ "Mic", 0x0 },
2430			{ "Line In", 0x2 },
2431			{ "CD", 0x4 },
2432			{ "Input Mix", 0xa },
2433			{ "Internal Mic", 0xb },
2434		},
2435	},
2436	{
2437		.num_items = 4,
2438		.items = {
2439			{ "Mic", 0x0 },
2440			{ "Line In", 0x2 },
2441			{ "CD", 0x4 },
2442			{ "Input Mix", 0xa },
2443		},
2444	}
2445};
2446
2447static const struct hda_input_mux alc889_capture_sources[3] = {
2448	/* Digital mic only available on first "ADC" */
2449	{
2450		.num_items = 5,
2451		.items = {
2452			{ "Mic", 0x0 },
2453			{ "Line", 0x2 },
2454			{ "CD", 0x4 },
2455			{ "Front Mic", 0xb },
2456			{ "Input Mix", 0xa },
2457		},
2458	},
2459	{
2460		.num_items = 4,
2461		.items = {
2462			{ "Mic", 0x0 },
2463			{ "Line", 0x2 },
2464			{ "CD", 0x4 },
2465			{ "Input Mix", 0xa },
2466		},
2467	},
2468	{
2469		.num_items = 4,
2470		.items = {
2471			{ "Mic", 0x0 },
2472			{ "Line", 0x2 },
2473			{ "CD", 0x4 },
2474			{ "Input Mix", 0xa },
2475		},
2476	}
2477};
2478
2479static const struct snd_kcontrol_new alc888_base_mixer[] = {
2480	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2481	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2482	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2483	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2484	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2485		HDA_OUTPUT),
2486	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2487	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2488	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2489	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2490	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2491	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2492	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2493	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2494	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2495	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2496	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2497	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2498	{ } /* end */
2499};
2500
2501static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
2502	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2503	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2504	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2505	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2506	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2507		HDA_OUTPUT),
2508	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2509	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2510	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2511	HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
2512	HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
2513	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2514	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2515	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2516	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2517	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2518	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2519	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2520	{ } /* end */
2521};
2522
2523static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2524	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2525	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2526	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2527	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2528	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2529		HDA_OUTPUT),
2530	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2531	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2532	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2533	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2534	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2535	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2536	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2537	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2538	{ } /* end */
2539};
2540
2541
2542static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
2543{
2544	struct alc_spec *spec = codec->spec;
2545
2546	spec->autocfg.hp_pins[0] = 0x15;
2547	spec->autocfg.speaker_pins[0] = 0x14;
2548	spec->autocfg.speaker_pins[1] = 0x16;
2549	spec->autocfg.speaker_pins[2] = 0x17;
2550	spec->automute = 1;
2551	spec->automute_mode = ALC_AUTOMUTE_AMP;
2552}
2553
2554static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
2555{
2556	struct alc_spec *spec = codec->spec;
2557
2558	spec->autocfg.hp_pins[0] = 0x15;
2559	spec->autocfg.speaker_pins[0] = 0x14;
2560	spec->autocfg.speaker_pins[1] = 0x16;
2561	spec->autocfg.speaker_pins[2] = 0x17;
2562	spec->automute = 1;
2563	spec->automute_mode = ALC_AUTOMUTE_AMP;
2564}
2565
2566static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2567{
2568	struct alc_spec *spec = codec->spec;
2569
2570	spec->autocfg.hp_pins[0] = 0x15;
2571	spec->autocfg.speaker_pins[0] = 0x14;
2572	spec->autocfg.speaker_pins[1] = 0x16;
2573	spec->autocfg.speaker_pins[2] = 0x17;
2574	spec->automute = 1;
2575	spec->automute_mode = ALC_AUTOMUTE_AMP;
2576}
2577
2578static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
2579{
2580	struct alc_spec *spec = codec->spec;
2581
2582	spec->autocfg.hp_pins[0] = 0x15;
2583	spec->autocfg.speaker_pins[0] = 0x14;
2584	spec->autocfg.speaker_pins[1] = 0x16;
2585	spec->autocfg.speaker_pins[2] = 0x1b;
2586	spec->automute = 1;
2587	spec->automute_mode = ALC_AUTOMUTE_AMP;
2588}
2589
2590/*
2591 * ALC880 3-stack model
2592 *
2593 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
2594 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2595 *                 F-Mic = 0x1b, HP = 0x19
2596 */
2597
2598static const hda_nid_t alc880_dac_nids[4] = {
2599	/* front, rear, clfe, rear_surr */
2600	0x02, 0x05, 0x04, 0x03
2601};
2602
2603static const hda_nid_t alc880_adc_nids[3] = {
2604	/* ADC0-2 */
2605	0x07, 0x08, 0x09,
2606};
2607
2608/* The datasheet says the node 0x07 is connected from inputs,
2609 * but it shows zero connection in the real implementation on some devices.
2610 * Note: this is a 915GAV bug, fixed on 915GLV
2611 */
2612static const hda_nid_t alc880_adc_nids_alt[2] = {
2613	/* ADC1-2 */
2614	0x08, 0x09,
2615};
2616
2617#define ALC880_DIGOUT_NID	0x06
2618#define ALC880_DIGIN_NID	0x0a
2619
2620static const struct hda_input_mux alc880_capture_source = {
2621	.num_items = 4,
2622	.items = {
2623		{ "Mic", 0x0 },
2624		{ "Front Mic", 0x3 },
2625		{ "Line", 0x2 },
2626		{ "CD", 0x4 },
2627	},
2628};
2629
2630/* channel source setting (2/6 channel selection for 3-stack) */
2631/* 2ch mode */
2632static const struct hda_verb alc880_threestack_ch2_init[] = {
2633	/* set line-in to input, mute it */
2634	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2635	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2636	/* set mic-in to input vref 80%, mute it */
2637	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2638	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2639	{ } /* end */
2640};
2641
2642/* 6ch mode */
2643static const struct hda_verb alc880_threestack_ch6_init[] = {
2644	/* set line-in to output, unmute it */
2645	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2646	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2647	/* set mic-in to output, unmute it */
2648	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2649	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2650	{ } /* end */
2651};
2652
2653static const struct hda_channel_mode alc880_threestack_modes[2] = {
2654	{ 2, alc880_threestack_ch2_init },
2655	{ 6, alc880_threestack_ch6_init },
2656};
2657
2658static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
2659	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2660	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2661	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2662	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2663	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2664	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2665	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2666	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2667	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2668	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2669	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2670	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2671	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2672	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2673	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2674	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
2675	HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2676	{
2677		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2678		.name = "Channel Mode",
2679		.info = alc_ch_mode_info,
2680		.get = alc_ch_mode_get,
2681		.put = alc_ch_mode_put,
2682	},
2683	{ } /* end */
2684};
2685
2686/* capture mixer elements */
2687static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2688			    struct snd_ctl_elem_info *uinfo)
2689{
2690	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2691	struct alc_spec *spec = codec->spec;
2692	int err;
2693
2694	mutex_lock(&codec->control_mutex);
2695	kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2696						      HDA_INPUT);
2697	err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
2698	mutex_unlock(&codec->control_mutex);
2699	return err;
2700}
2701
2702static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2703			   unsigned int size, unsigned int __user *tlv)
2704{
2705	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2706	struct alc_spec *spec = codec->spec;
2707	int err;
2708
2709	mutex_lock(&codec->control_mutex);
2710	kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2711						      HDA_INPUT);
2712	err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
2713	mutex_unlock(&codec->control_mutex);
2714	return err;
2715}
2716
2717typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2718			     struct snd_ctl_elem_value *ucontrol);
2719
2720static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2721				 struct snd_ctl_elem_value *ucontrol,
2722				 getput_call_t func, bool check_adc_switch)
2723{
2724	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2725	struct alc_spec *spec = codec->spec;
2726	int i, err = 0;
2727
2728	mutex_lock(&codec->control_mutex);
2729	if (check_adc_switch && spec->dual_adc_switch) {
2730		for (i = 0; i < spec->num_adc_nids; i++) {
2731			kcontrol->private_value =
2732				HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
2733						    3, 0, HDA_INPUT);
2734			err = func(kcontrol, ucontrol);
2735			if (err < 0)
2736				goto error;
2737		}
2738	} else {
2739		i = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2740		kcontrol->private_value =
2741			HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
2742					    3, 0, HDA_INPUT);
2743		err = func(kcontrol, ucontrol);
2744	}
2745 error:
2746	mutex_unlock(&codec->control_mutex);
2747	return err;
2748}
2749
2750static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2751			   struct snd_ctl_elem_value *ucontrol)
2752{
2753	return alc_cap_getput_caller(kcontrol, ucontrol,
2754				     snd_hda_mixer_amp_volume_get, false);
2755}
2756
2757static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2758			   struct snd_ctl_elem_value *ucontrol)
2759{
2760	return alc_cap_getput_caller(kcontrol, ucontrol,
2761				     snd_hda_mixer_amp_volume_put, true);
2762}
2763
2764/* capture mixer elements */
2765#define alc_cap_sw_info		snd_ctl_boolean_stereo_info
2766
2767static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2768			  struct snd_ctl_elem_value *ucontrol)
2769{
2770	return alc_cap_getput_caller(kcontrol, ucontrol,
2771				     snd_hda_mixer_amp_switch_get, false);
2772}
2773
2774static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2775			  struct snd_ctl_elem_value *ucontrol)
2776{
2777	return alc_cap_getput_caller(kcontrol, ucontrol,
2778				     snd_hda_mixer_amp_switch_put, true);
2779}
2780
2781#define _DEFINE_CAPMIX(num) \
2782	{ \
2783		.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2784		.name = "Capture Switch", \
2785		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2786		.count = num, \
2787		.info = alc_cap_sw_info, \
2788		.get = alc_cap_sw_get, \
2789		.put = alc_cap_sw_put, \
2790	}, \
2791	{ \
2792		.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2793		.name = "Capture Volume", \
2794		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2795			   SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2796			   SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2797		.count = num, \
2798		.info = alc_cap_vol_info, \
2799		.get = alc_cap_vol_get, \
2800		.put = alc_cap_vol_put, \
2801		.tlv = { .c = alc_cap_vol_tlv }, \
2802	}
2803
2804#define _DEFINE_CAPSRC(num) \
2805	{ \
2806		.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2807		/* .name = "Capture Source", */ \
2808		.name = "Input Source", \
2809		.count = num, \
2810		.info = alc_mux_enum_info, \
2811		.get = alc_mux_enum_get, \
2812		.put = alc_mux_enum_put, \
2813	}
2814
2815#define DEFINE_CAPMIX(num) \
2816static const struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2817	_DEFINE_CAPMIX(num),				      \
2818	_DEFINE_CAPSRC(num),				      \
2819	{ } /* end */					      \
2820}
2821
2822#define DEFINE_CAPMIX_NOSRC(num) \
2823static const struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2824	_DEFINE_CAPMIX(num),					    \
2825	{ } /* end */						    \
2826}
2827
2828/* up to three ADCs */
2829DEFINE_CAPMIX(1);
2830DEFINE_CAPMIX(2);
2831DEFINE_CAPMIX(3);
2832DEFINE_CAPMIX_NOSRC(1);
2833DEFINE_CAPMIX_NOSRC(2);
2834DEFINE_CAPMIX_NOSRC(3);
2835
2836/*
2837 * ALC880 5-stack model
2838 *
2839 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2840 *      Side = 0x02 (0xd)
2841 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2842 *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2843 */
2844
2845/* additional mixers to alc880_three_stack_mixer */
2846static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2847	HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2848	HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
2849	{ } /* end */
2850};
2851
2852/* channel source setting (6/8 channel selection for 5-stack) */
2853/* 6ch mode */
2854static const struct hda_verb alc880_fivestack_ch6_init[] = {
2855	/* set line-in to input, mute it */
2856	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2857	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2858	{ } /* end */
2859};
2860
2861/* 8ch mode */
2862static const struct hda_verb alc880_fivestack_ch8_init[] = {
2863	/* set line-in to output, unmute it */
2864	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2865	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2866	{ } /* end */
2867};
2868
2869static const struct hda_channel_mode alc880_fivestack_modes[2] = {
2870	{ 6, alc880_fivestack_ch6_init },
2871	{ 8, alc880_fivestack_ch8_init },
2872};
2873
2874
2875/*
2876 * ALC880 6-stack model
2877 *
2878 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2879 *      Side = 0x05 (0x0f)
2880 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2881 *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2882 */
2883
2884static const hda_nid_t alc880_6st_dac_nids[4] = {
2885	/* front, rear, clfe, rear_surr */
2886	0x02, 0x03, 0x04, 0x05
2887};
2888
2889static const struct hda_input_mux alc880_6stack_capture_source = {
2890	.num_items = 4,
2891	.items = {
2892		{ "Mic", 0x0 },
2893		{ "Front Mic", 0x1 },
2894		{ "Line", 0x2 },
2895		{ "CD", 0x4 },
2896	},
2897};
2898
2899/* fixed 8-channels */
2900static const struct hda_channel_mode alc880_sixstack_modes[1] = {
2901	{ 8, NULL },
2902};
2903
2904static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2905	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2906	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2907	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2908	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2909	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2910	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2911	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2912	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2913	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2914	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2915	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2916	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2917	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2918	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2919	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2920	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2921	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2922	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2923	{
2924		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2925		.name = "Channel Mode",
2926		.info = alc_ch_mode_info,
2927		.get = alc_ch_mode_get,
2928		.put = alc_ch_mode_put,
2929	},
2930	{ } /* end */
2931};
2932
2933
2934/*
2935 * ALC880 W810 model
2936 *
2937 * W810 has rear IO for:
2938 * Front (DAC 02)
2939 * Surround (DAC 03)
2940 * Center/LFE (DAC 04)
2941 * Digital out (06)
2942 *
2943 * The system also has a pair of internal speakers, and a headphone jack.
2944 * These are both connected to Line2 on the codec, hence to DAC 02.
2945 *
2946 * There is a variable resistor to control the speaker or headphone
2947 * volume. This is a hardware-only device without a software API.
2948 *
2949 * Plugging headphones in will disable the internal speakers. This is
2950 * implemented in hardware, not via the driver using jack sense. In
2951 * a similar fashion, plugging into the rear socket marked "front" will
2952 * disable both the speakers and headphones.
2953 *
2954 * For input, there's a microphone jack, and an "audio in" jack.
2955 * These may not do anything useful with this driver yet, because I
2956 * haven't setup any initialization verbs for these yet...
2957 */
2958
2959static const hda_nid_t alc880_w810_dac_nids[3] = {
2960	/* front, rear/surround, clfe */
2961	0x02, 0x03, 0x04
2962};
2963
2964/* fixed 6 channels */
2965static const struct hda_channel_mode alc880_w810_modes[1] = {
2966	{ 6, NULL }
2967};
2968
2969/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
2970static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2971	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2972	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2973	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2974	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2975	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2976	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2977	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2978	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2979	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2980	{ } /* end */
2981};
2982
2983
2984/*
2985 * Z710V model
2986 *
2987 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
2988 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2989 *                 Line = 0x1a
2990 */
2991
2992static const hda_nid_t alc880_z71v_dac_nids[1] = {
2993	0x02
2994};
2995#define ALC880_Z71V_HP_DAC	0x03
2996
2997/* fixed 2 channels */
2998static const struct hda_channel_mode alc880_2_jack_modes[1] = {
2999	{ 2, NULL }
3000};
3001
3002static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
3003	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3004	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3005	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3006	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
3007	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3008	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3009	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3010	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3011	{ } /* end */
3012};
3013
3014
3015/*
3016 * ALC880 F1734 model
3017 *
3018 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
3019 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
3020 */
3021
3022static const hda_nid_t alc880_f1734_dac_nids[1] = {
3023	0x03
3024};
3025#define ALC880_F1734_HP_DAC	0x02
3026
3027static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
3028	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3029	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3030	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3031	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3032	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3033	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3034	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3035	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3036	{ } /* end */
3037};
3038
3039static const struct hda_input_mux alc880_f1734_capture_source = {
3040	.num_items = 2,
3041	.items = {
3042		{ "Mic", 0x1 },
3043		{ "CD", 0x4 },
3044	},
3045};
3046
3047
3048/*
3049 * ALC880 ASUS model
3050 *
3051 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3052 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3053 *  Mic = 0x18, Line = 0x1a
3054 */
3055
3056#define alc880_asus_dac_nids	alc880_w810_dac_nids	/* identical with w810 */
3057#define alc880_asus_modes	alc880_threestack_modes	/* 2/6 channel mode */
3058
3059static const struct snd_kcontrol_new alc880_asus_mixer[] = {
3060	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3061	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3062	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3063	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3064	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3065	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3066	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3067	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3068	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3069	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3070	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3071	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3072	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3073	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3074	{
3075		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3076		.name = "Channel Mode",
3077		.info = alc_ch_mode_info,
3078		.get = alc_ch_mode_get,
3079		.put = alc_ch_mode_put,
3080	},
3081	{ } /* end */
3082};
3083
3084/*
3085 * ALC880 ASUS W1V model
3086 *
3087 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3088 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3089 *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
3090 */
3091
3092/* additional mixers to alc880_asus_mixer */
3093static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
3094	HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
3095	HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
3096	{ } /* end */
3097};
3098
3099/* TCL S700 */
3100static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
3101	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3102	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
3103	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
3104	HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
3105	HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
3106	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
3107	HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
3108	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
3109	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
3110	{ } /* end */
3111};
3112
3113/* Uniwill */
3114static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
3115	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3116	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3117	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3118	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3119	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3120	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3121	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3122	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3123	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3124	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3125	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3126	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3127	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3128	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3129	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3130	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3131	{
3132		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3133		.name = "Channel Mode",
3134		.info = alc_ch_mode_info,
3135		.get = alc_ch_mode_get,
3136		.put = alc_ch_mode_put,
3137	},
3138	{ } /* end */
3139};
3140
3141static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
3142	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3143	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3144	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3145	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3146	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3147	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3148	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3149	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3150	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3151	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3152	{ } /* end */
3153};
3154
3155static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
3156	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3157	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3158	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3159	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3160	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3161	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3162	{ } /* end */
3163};
3164
3165/*
3166 * virtual master controls
3167 */
3168
3169/*
3170 * slave controls for virtual master
3171 */
3172static const char * const alc_slave_vols[] = {
3173	"Front Playback Volume",
3174	"Surround Playback Volume",
3175	"Center Playback Volume",
3176	"LFE Playback Volume",
3177	"Side Playback Volume",
3178	"Headphone Playback Volume",
3179	"Speaker Playback Volume",
3180	"Mono Playback Volume",
3181	"Line-Out Playback Volume",
3182	NULL,
3183};
3184
3185static const char * const alc_slave_sws[] = {
3186	"Front Playback Switch",
3187	"Surround Playback Switch",
3188	"Center Playback Switch",
3189	"LFE Playback Switch",
3190	"Side Playback Switch",
3191	"Headphone Playback Switch",
3192	"Speaker Playback Switch",
3193	"Mono Playback Switch",
3194	"IEC958 Playback Switch",
3195	"Line-Out Playback Switch",
3196	NULL,
3197};
3198
3199/*
3200 * build control elements
3201 */
3202
3203#define NID_MAPPING		(-1)
3204
3205#define SUBDEV_SPEAKER_		(0 << 6)
3206#define SUBDEV_HP_		(1 << 6)
3207#define SUBDEV_LINE_		(2 << 6)
3208#define SUBDEV_SPEAKER(x)	(SUBDEV_SPEAKER_ | ((x) & 0x3f))
3209#define SUBDEV_HP(x)		(SUBDEV_HP_ | ((x) & 0x3f))
3210#define SUBDEV_LINE(x)		(SUBDEV_LINE_ | ((x) & 0x3f))
3211
3212static void alc_free_kctls(struct hda_codec *codec);
3213
3214#ifdef CONFIG_SND_HDA_INPUT_BEEP
3215/* additional beep mixers; the actual parameters are overwritten at build */
3216static const struct snd_kcontrol_new alc_beep_mixer[] = {
3217	HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
3218	HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
3219	{ } /* end */
3220};
3221#endif
3222
3223static int alc_build_controls(struct hda_codec *codec)
3224{
3225	struct alc_spec *spec = codec->spec;
3226	struct snd_kcontrol *kctl = NULL;
3227	const struct snd_kcontrol_new *knew;
3228	int i, j, err;
3229	unsigned int u;
3230	hda_nid_t nid;
3231
3232	for (i = 0; i < spec->num_mixers; i++) {
3233		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
3234		if (err < 0)
3235			return err;
3236	}
3237	if (spec->cap_mixer) {
3238		err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
3239		if (err < 0)
3240			return err;
3241	}
3242	if (spec->multiout.dig_out_nid) {
3243		err = snd_hda_create_spdif_out_ctls(codec,
3244						    spec->multiout.dig_out_nid);
3245		if (err < 0)
3246			return err;
3247		if (!spec->no_analog) {
3248			err = snd_hda_create_spdif_share_sw(codec,
3249							    &spec->multiout);
3250			if (err < 0)
3251				return err;
3252			spec->multiout.share_spdif = 1;
3253		}
3254	}
3255	if (spec->dig_in_nid) {
3256		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
3257		if (err < 0)
3258			return err;
3259	}
3260
3261#ifdef CONFIG_SND_HDA_INPUT_BEEP
3262	/* create beep controls if needed */
3263	if (spec->beep_amp) {
3264		const struct snd_kcontrol_new *knew;
3265		for (knew = alc_beep_mixer; knew->name; knew++) {
3266			struct snd_kcontrol *kctl;
3267			kctl = snd_ctl_new1(knew, codec);
3268			if (!kctl)
3269				return -ENOMEM;
3270			kctl->private_value = spec->beep_amp;
3271			err = snd_hda_ctl_add(codec, 0, kctl);
3272			if (err < 0)
3273				return err;
3274		}
3275	}
3276#endif
3277
3278	/* if we have no master control, let's create it */
3279	if (!spec->no_analog &&
3280	    !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
3281		unsigned int vmaster_tlv[4];
3282		snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
3283					HDA_OUTPUT, vmaster_tlv);
3284		err = snd_hda_add_vmaster(codec, "Master Playback Volume",
3285					  vmaster_tlv, alc_slave_vols);
3286		if (err < 0)
3287			return err;
3288	}
3289	if (!spec->no_analog &&
3290	    !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
3291		err = snd_hda_add_vmaster(codec, "Master Playback Switch",
3292					  NULL, alc_slave_sws);
3293		if (err < 0)
3294			return err;
3295	}
3296
3297	/* assign Capture Source enums to NID */
3298	if (spec->capsrc_nids || spec->adc_nids) {
3299		kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
3300		if (!kctl)
3301			kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3302		for (i = 0; kctl && i < kctl->count; i++) {
3303			const hda_nid_t *nids = spec->capsrc_nids;
3304			if (!nids)
3305				nids = spec->adc_nids;
3306			err = snd_hda_add_nid(codec, kctl, i, nids[i]);
3307			if (err < 0)
3308				return err;
3309		}
3310	}
3311	if (spec->cap_mixer) {
3312		const char *kname = kctl ? kctl->id.name : NULL;
3313		for (knew = spec->cap_mixer; knew->name; knew++) {
3314			if (kname && strcmp(knew->name, kname) == 0)
3315				continue;
3316			kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3317			for (i = 0; kctl && i < kctl->count; i++) {
3318				err = snd_hda_add_nid(codec, kctl, i,
3319						      spec->adc_nids[i]);
3320				if (err < 0)
3321					return err;
3322			}
3323		}
3324	}
3325
3326	/* other nid->control mapping */
3327	for (i = 0; i < spec->num_mixers; i++) {
3328		for (knew = spec->mixers[i]; knew->name; knew++) {
3329			if (knew->iface != NID_MAPPING)
3330				continue;
3331			kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3332			if (kctl == NULL)
3333				continue;
3334			u = knew->subdevice;
3335			for (j = 0; j < 4; j++, u >>= 8) {
3336				nid = u & 0x3f;
3337				if (nid == 0)
3338					continue;
3339				switch (u & 0xc0) {
3340				case SUBDEV_SPEAKER_:
3341					nid = spec->autocfg.speaker_pins[nid];
3342					break;
3343				case SUBDEV_LINE_:
3344					nid = spec->autocfg.line_out_pins[nid];
3345					break;
3346				case SUBDEV_HP_:
3347					nid = spec->autocfg.hp_pins[nid];
3348					break;
3349				default:
3350					continue;
3351				}
3352				err = snd_hda_add_nid(codec, kctl, 0, nid);
3353				if (err < 0)
3354					return err;
3355			}
3356			u = knew->private_value;
3357			for (j = 0; j < 4; j++, u >>= 8) {
3358				nid = u & 0xff;
3359				if (nid == 0)
3360					continue;
3361				err = snd_hda_add_nid(codec, kctl, 0, nid);
3362				if (err < 0)
3363					return err;
3364			}
3365		}
3366	}
3367
3368	alc_free_kctls(codec); /* no longer needed */
3369
3370	return 0;
3371}
3372
3373
3374/*
3375 * initialize the codec volumes, etc
3376 */
3377
3378/*
3379 * generic initialization of ADC, input mixers and output mixers
3380 */
3381static const struct hda_verb alc880_volume_init_verbs[] = {
3382	/*
3383	 * Unmute ADC0-2 and set the default input to mic-in
3384	 */
3385	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3386	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3387	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3388	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3389	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3390	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3391
3392	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3393	 * mixer widget
3394	 * Note: PASD motherboards uses the Line In 2 as the input for front
3395	 * panel mic (mic 2)
3396	 */
3397	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
3398	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3399	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3400	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3401	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3402	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3403	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3404	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3405
3406	/*
3407	 * Set up output mixers (0x0c - 0x0f)
3408	 */
3409	/* set vol=0 to output mixers */
3410	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3411	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3412	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3413	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3414	/* set up input amps for analog loopback */
3415	/* Amp Indices: DAC = 0, mixer = 1 */
3416	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3417	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3418	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3419	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3420	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3421	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3422	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3423	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3424
3425	{ }
3426};
3427
3428/*
3429 * 3-stack pin configuration:
3430 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3431 */
3432static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
3433	/*
3434	 * preset connection lists of input pins
3435	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3436	 */
3437	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3438	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3439	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3440
3441	/*
3442	 * Set pin mode and muting
3443	 */
3444	/* set front pin widgets 0x14 for output */
3445	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3446	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3447	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3448	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3449	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3450	/* Mic2 (as headphone out) for HP output */
3451	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3452	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3453	/* Line In pin widget for input */
3454	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3455	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3456	/* Line2 (as front mic) pin widget for input and vref at 80% */
3457	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3458	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3459	/* CD pin widget for input */
3460	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3461
3462	{ }
3463};
3464
3465/*
3466 * 5-stack pin configuration:
3467 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3468 * line-in/side = 0x1a, f-mic = 0x1b
3469 */
3470static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
3471	/*
3472	 * preset connection lists of input pins
3473	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3474	 */
3475	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3476	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
3477
3478	/*
3479	 * Set pin mode and muting
3480	 */
3481	/* set pin widgets 0x14-0x17 for output */
3482	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3483	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3484	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3485	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3486	/* unmute pins for output (no gain on this amp) */
3487	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3488	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3489	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3490	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3491
3492	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3493	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3494	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3495	/* Mic2 (as headphone out) for HP output */
3496	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3497	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3498	/* Line In pin widget for input */
3499	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3500	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3501	/* Line2 (as front mic) pin widget for input and vref at 80% */
3502	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3503	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3504	/* CD pin widget for input */
3505	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3506
3507	{ }
3508};
3509
3510/*
3511 * W810 pin configuration:
3512 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3513 */
3514static const struct hda_verb alc880_pin_w810_init_verbs[] = {
3515	/* hphone/speaker input selector: front DAC */
3516	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
3517
3518	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3519	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3520	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3521	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3522	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3523	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3524
3525	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3526	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3527
3528	{ }
3529};
3530
3531/*
3532 * Z71V pin configuration:
3533 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3534 */
3535static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
3536	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3537	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3538	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3539	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3540
3541	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3542	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3543	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3544	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3545
3546	{ }
3547};
3548
3549/*
3550 * 6-stack pin configuration:
3551 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3552 * f-mic = 0x19, line = 0x1a, HP = 0x1b
3553 */
3554static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
3555	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3556
3557	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3558	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3559	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3560	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3561	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3562	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3563	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3564	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3565
3566	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3567	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3568	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3569	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3570	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3571	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3572	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3573	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3574	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3575
3576	{ }
3577};
3578
3579/*
3580 * Uniwill pin configuration:
3581 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3582 * line = 0x1a
3583 */
3584static const struct hda_verb alc880_uniwill_init_verbs[] = {
3585	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3586
3587	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3588	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3589	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3590	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3591	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3592	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3593	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3594	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3595	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3596	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3597	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3598	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3599	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3600	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3601
3602	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3603	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3604	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3605	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3606	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3607	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3608	/* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3609	/* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3610	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3611
3612	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3613	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3614
3615	{ }
3616};
3617
3618/*
3619* Uniwill P53
3620* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
3621 */
3622static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3623	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3624
3625	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3626	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3627	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3628	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3629	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3630	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3631	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3632	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3633	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3634	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3635	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3636	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3637
3638	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3639	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3640	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3641	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3642	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3643	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3644
3645	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3646	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3647
3648	{ }
3649};
3650
3651static const struct hda_verb alc880_beep_init_verbs[] = {
3652	{ 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3653	{ }
3654};
3655
3656/* auto-toggle front mic */
3657static void alc88x_simple_mic_automute(struct hda_codec *codec)
3658{
3659 	unsigned int present;
3660	unsigned char bits;
3661
3662	present = snd_hda_jack_detect(codec, 0x18);
3663	bits = present ? HDA_AMP_MUTE : 0;
3664	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
3665}
3666
3667static void alc880_uniwill_setup(struct hda_codec *codec)
3668{
3669	struct alc_spec *spec = codec->spec;
3670
3671	spec->autocfg.hp_pins[0] = 0x14;
3672	spec->autocfg.speaker_pins[0] = 0x15;
3673	spec->autocfg.speaker_pins[0] = 0x16;
3674	spec->automute = 1;
3675	spec->automute_mode = ALC_AUTOMUTE_AMP;
3676}
3677
3678static void alc880_uniwill_init_hook(struct hda_codec *codec)
3679{
3680	alc_hp_automute(codec);
3681	alc88x_simple_mic_automute(codec);
3682}
3683
3684static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3685				       unsigned int res)
3686{
3687	/* Looks like the unsol event is incompatible with the standard
3688	 * definition.  4bit tag is placed at 28 bit!
3689	 */
3690	switch (res >> 28) {
3691	case ALC880_MIC_EVENT:
3692		alc88x_simple_mic_automute(codec);
3693		break;
3694	default:
3695		alc_sku_unsol_event(codec, res);
3696		break;
3697	}
3698}
3699
3700static void alc880_uniwill_p53_setup(struct hda_codec *codec)
3701{
3702	struct alc_spec *spec = codec->spec;
3703
3704	spec->autocfg.hp_pins[0] = 0x14;
3705	spec->autocfg.speaker_pins[0] = 0x15;
3706	spec->automute = 1;
3707	spec->automute_mode = ALC_AUTOMUTE_AMP;
3708}
3709
3710static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3711{
3712	unsigned int present;
3713
3714	present = snd_hda_codec_read(codec, 0x21, 0,
3715				     AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3716	present &= HDA_AMP_VOLMASK;
3717	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3718				 HDA_AMP_VOLMASK, present);
3719	snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3720				 HDA_AMP_VOLMASK, present);
3721}
3722
3723static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3724					   unsigned int res)
3725{
3726	/* Looks like the unsol event is incompatible with the standard
3727	 * definition.  4bit tag is placed at 28 bit!
3728	 */
3729	if ((res >> 28) == ALC880_DCVOL_EVENT)
3730		alc880_uniwill_p53_dcvol_automute(codec);
3731	else
3732		alc_sku_unsol_event(codec, res);
3733}
3734
3735/*
3736 * F1734 pin configuration:
3737 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3738 */
3739static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
3740	{0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
3741	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3742	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3743	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3744	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3745
3746	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3747	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3748	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3749	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3750
3751	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3752	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3753	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3754	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3755	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3756	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3757	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3758	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3759	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3760
3761	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3762	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3763
3764	{ }
3765};
3766
3767/*
3768 * ASUS pin configuration:
3769 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3770 */
3771static const struct hda_verb alc880_pin_asus_init_verbs[] = {
3772	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3773	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3774	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3775	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3776
3777	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3778	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3779	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3780	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3781	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3782	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3783	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3784	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3785
3786	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3787	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3788	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3789	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3790	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3791	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3792	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3793	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3794	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3795
3796	{ }
3797};
3798
3799/* Enable GPIO mask and set output */
3800#define alc880_gpio1_init_verbs	alc_gpio1_init_verbs
3801#define alc880_gpio2_init_verbs	alc_gpio2_init_verbs
3802#define alc880_gpio3_init_verbs	alc_gpio3_init_verbs
3803
3804/* Clevo m520g init */
3805static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
3806	/* headphone output */
3807	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3808	/* line-out */
3809	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3810	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3811	/* Line-in */
3812	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3813	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3814	/* CD */
3815	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3816	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3817	/* Mic1 (rear panel) */
3818	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3819	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3820	/* Mic2 (front panel) */
3821	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3822	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3823	/* headphone */
3824	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3825	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3826        /* change to EAPD mode */
3827	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3828	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
3829
3830	{ }
3831};
3832
3833static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
3834	/* change to EAPD mode */
3835	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3836	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
3837
3838	/* Headphone output */
3839	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3840	/* Front output*/
3841	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3842	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3843
3844	/* Line In pin widget for input */
3845	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3846	/* CD pin widget for input */
3847	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3848	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3849	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3850
3851	/* change to EAPD mode */
3852	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3853	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
3854
3855	{ }
3856};
3857
3858/*
3859 * LG m1 express dual
3860 *
3861 * Pin assignment:
3862 *   Rear Line-In/Out (blue): 0x14
3863 *   Build-in Mic-In: 0x15
3864 *   Speaker-out: 0x17
3865 *   HP-Out (green): 0x1b
3866 *   Mic-In/Out (red): 0x19
3867 *   SPDIF-Out: 0x1e
3868 */
3869
3870/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3871static const hda_nid_t alc880_lg_dac_nids[3] = {
3872	0x05, 0x02, 0x03
3873};
3874
3875/* seems analog CD is not working */
3876static const struct hda_input_mux alc880_lg_capture_source = {
3877	.num_items = 3,
3878	.items = {
3879		{ "Mic", 0x1 },
3880		{ "Line", 0x5 },
3881		{ "Internal Mic", 0x6 },
3882	},
3883};
3884
3885/* 2,4,6 channel modes */
3886static const struct hda_verb alc880_lg_ch2_init[] = {
3887	/* set line-in and mic-in to input */
3888	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3889	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3890	{ }
3891};
3892
3893static const struct hda_verb alc880_lg_ch4_init[] = {
3894	/* set line-in to out and mic-in to input */
3895	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3896	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3897	{ }
3898};
3899
3900static const struct hda_verb alc880_lg_ch6_init[] = {
3901	/* set line-in and mic-in to output */
3902	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3903	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3904	{ }
3905};
3906
3907static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
3908	{ 2, alc880_lg_ch2_init },
3909	{ 4, alc880_lg_ch4_init },
3910	{ 6, alc880_lg_ch6_init },
3911};
3912
3913static const struct snd_kcontrol_new alc880_lg_mixer[] = {
3914	HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3915	HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
3916	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3917	HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3918	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3919	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3920	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3921	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3922	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3923	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3924	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3925	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3926	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3927	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3928	{
3929		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3930		.name = "Channel Mode",
3931		.info = alc_ch_mode_info,
3932		.get = alc_ch_mode_get,
3933		.put = alc_ch_mode_put,
3934	},
3935	{ } /* end */
3936};
3937
3938static const struct hda_verb alc880_lg_init_verbs[] = {
3939	/* set capture source to mic-in */
3940	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3941	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3942	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3943	/* mute all amp mixer inputs */
3944	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
3945	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3946	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3947	/* line-in to input */
3948	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3949	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3950	/* built-in mic */
3951	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3952	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3953	/* speaker-out */
3954	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3955	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3956	/* mic-in to input */
3957	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3958	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3959	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3960	/* HP-out */
3961	{0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3962	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3963	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3964	/* jack sense */
3965	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3966	{ }
3967};
3968
3969/* toggle speaker-output according to the hp-jack state */
3970static void alc880_lg_setup(struct hda_codec *codec)
3971{
3972	struct alc_spec *spec = codec->spec;
3973
3974	spec->autocfg.hp_pins[0] = 0x1b;
3975	spec->autocfg.speaker_pins[0] = 0x17;
3976	spec->automute = 1;
3977	spec->automute_mode = ALC_AUTOMUTE_AMP;
3978}
3979
3980/*
3981 * LG LW20
3982 *
3983 * Pin assignment:
3984 *   Speaker-out: 0x14
3985 *   Mic-In: 0x18
3986 *   Built-in Mic-In: 0x19
3987 *   Line-In: 0x1b
3988 *   HP-Out: 0x1a
3989 *   SPDIF-Out: 0x1e
3990 */
3991
3992static const struct hda_input_mux alc880_lg_lw_capture_source = {
3993	.num_items = 3,
3994	.items = {
3995		{ "Mic", 0x0 },
3996		{ "Internal Mic", 0x1 },
3997		{ "Line In", 0x2 },
3998	},
3999};
4000
4001#define alc880_lg_lw_modes alc880_threestack_modes
4002
4003static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
4004	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4005	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4006	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4007	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
4008	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
4009	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4010	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
4011	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
4012	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4013	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4014	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4015	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4016	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
4017	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
4018	{
4019		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4020		.name = "Channel Mode",
4021		.info = alc_ch_mode_info,
4022		.get = alc_ch_mode_get,
4023		.put = alc_ch_mode_put,
4024	},
4025	{ } /* end */
4026};
4027
4028static const struct hda_verb alc880_lg_lw_init_verbs[] = {
4029	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4030	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
4031	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
4032
4033	/* set capture source to mic-in */
4034	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4035	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4036	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4037	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
4038	/* speaker-out */
4039	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4040	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4041	/* HP-out */
4042	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4043	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4044	/* mic-in to input */
4045	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4046	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4047	/* built-in mic */
4048	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4049	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4050	/* jack sense */
4051	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4052	{ }
4053};
4054
4055/* toggle speaker-output according to the hp-jack state */
4056static void alc880_lg_lw_setup(struct hda_codec *codec)
4057{
4058	struct alc_spec *spec = codec->spec;
4059
4060	spec->autocfg.hp_pins[0] = 0x1b;
4061	spec->autocfg.speaker_pins[0] = 0x14;
4062	spec->automute = 1;
4063	spec->automute_mode = ALC_AUTOMUTE_AMP;
4064}
4065
4066static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
4067	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4068	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
4069	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4070	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4071	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4072	HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
4073	{ } /* end */
4074};
4075
4076static const struct hda_input_mux alc880_medion_rim_capture_source = {
4077	.num_items = 2,
4078	.items = {
4079		{ "Mic", 0x0 },
4080		{ "Internal Mic", 0x1 },
4081	},
4082};
4083
4084static const struct hda_verb alc880_medion_rim_init_verbs[] = {
4085	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4086
4087	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4088	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4089
4090	/* Mic1 (rear panel) pin widget for input and vref at 80% */
4091	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4092	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4093	/* Mic2 (as headphone out) for HP output */
4094	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4095	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4096	/* Internal Speaker */
4097	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4098	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4099
4100	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
4101	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
4102
4103	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4104	{ }
4105};
4106
4107/* toggle speaker-output according to the hp-jack state */
4108static void alc880_medion_rim_automute(struct hda_codec *codec)
4109{
4110	struct alc_spec *spec = codec->spec;
4111	alc_hp_automute(codec);
4112	/* toggle EAPD */
4113	if (spec->jack_present)
4114		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
4115	else
4116		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
4117}
4118
4119static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
4120					  unsigned int res)
4121{
4122	/* Looks like the unsol event is incompatible with the standard
4123	 * definition.  4bit tag is placed at 28 bit!
4124	 */
4125	if ((res >> 28) == ALC880_HP_EVENT)
4126		alc880_medion_rim_automute(codec);
4127}
4128
4129static void alc880_medion_rim_setup(struct hda_codec *codec)
4130{
4131	struct alc_spec *spec = codec->spec;
4132
4133	spec->autocfg.hp_pins[0] = 0x14;
4134	spec->autocfg.speaker_pins[0] = 0x1b;
4135	spec->automute = 1;
4136	spec->automute_mode = ALC_AUTOMUTE_AMP;
4137}
4138
4139#ifdef CONFIG_SND_HDA_POWER_SAVE
4140static const struct hda_amp_list alc880_loopbacks[] = {
4141	{ 0x0b, HDA_INPUT, 0 },
4142	{ 0x0b, HDA_INPUT, 1 },
4143	{ 0x0b, HDA_INPUT, 2 },
4144	{ 0x0b, HDA_INPUT, 3 },
4145	{ 0x0b, HDA_INPUT, 4 },
4146	{ } /* end */
4147};
4148
4149static const struct hda_amp_list alc880_lg_loopbacks[] = {
4150	{ 0x0b, HDA_INPUT, 1 },
4151	{ 0x0b, HDA_INPUT, 6 },
4152	{ 0x0b, HDA_INPUT, 7 },
4153	{ } /* end */
4154};
4155#endif
4156
4157/*
4158 * Common callbacks
4159 */
4160
4161static void alc_init_special_input_src(struct hda_codec *codec);
4162
4163static int alc_init(struct hda_codec *codec)
4164{
4165	struct alc_spec *spec = codec->spec;
4166	unsigned int i;
4167
4168	alc_fix_pll(codec);
4169	alc_auto_init_amp(codec, spec->init_amp);
4170
4171	for (i = 0; i < spec->num_init_verbs; i++)
4172		snd_hda_sequence_write(codec, spec->init_verbs[i]);
4173	alc_init_special_input_src(codec);
4174
4175	if (spec->init_hook)
4176		spec->init_hook(codec);
4177
4178	alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
4179
4180	hda_call_check_power_status(codec, 0x01);
4181	return 0;
4182}
4183
4184static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
4185{
4186	struct alc_spec *spec = codec->spec;
4187
4188	if (spec->unsol_event)
4189		spec->unsol_event(codec, res);
4190}
4191
4192#ifdef CONFIG_SND_HDA_POWER_SAVE
4193static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
4194{
4195	struct alc_spec *spec = codec->spec;
4196	return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
4197}
4198#endif
4199
4200/*
4201 * Analog playback callbacks
4202 */
4203static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
4204				    struct hda_codec *codec,
4205				    struct snd_pcm_substream *substream)
4206{
4207	struct alc_spec *spec = codec->spec;
4208	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
4209					     hinfo);
4210}
4211
4212static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4213				       struct hda_codec *codec,
4214				       unsigned int stream_tag,
4215				       unsigned int format,
4216				       struct snd_pcm_substream *substream)
4217{
4218	struct alc_spec *spec = codec->spec;
4219	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
4220						stream_tag, format, substream);
4221}
4222
4223static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4224				       struct hda_codec *codec,
4225				       struct snd_pcm_substream *substream)
4226{
4227	struct alc_spec *spec = codec->spec;
4228	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
4229}
4230
4231/*
4232 * Digital out
4233 */
4234static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
4235					struct hda_codec *codec,
4236					struct snd_pcm_substream *substream)
4237{
4238	struct alc_spec *spec = codec->spec;
4239	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
4240}
4241
4242static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4243					   struct hda_codec *codec,
4244					   unsigned int stream_tag,
4245					   unsigned int format,
4246					   struct snd_pcm_substream *substream)
4247{
4248	struct alc_spec *spec = codec->spec;
4249	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
4250					     stream_tag, format, substream);
4251}
4252
4253static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4254					   struct hda_codec *codec,
4255					   struct snd_pcm_substream *substream)
4256{
4257	struct alc_spec *spec = codec->spec;
4258	return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
4259}
4260
4261static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
4262					 struct hda_codec *codec,
4263					 struct snd_pcm_substream *substream)
4264{
4265	struct alc_spec *spec = codec->spec;
4266	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
4267}
4268
4269/*
4270 * Analog capture
4271 */
4272static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4273				      struct hda_codec *codec,
4274				      unsigned int stream_tag,
4275				      unsigned int format,
4276				      struct snd_pcm_substream *substream)
4277{
4278	struct alc_spec *spec = codec->spec;
4279
4280	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
4281				   stream_tag, 0, format);
4282	return 0;
4283}
4284
4285static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4286				      struct hda_codec *codec,
4287				      struct snd_pcm_substream *substream)
4288{
4289	struct alc_spec *spec = codec->spec;
4290
4291	snd_hda_codec_cleanup_stream(codec,
4292				     spec->adc_nids[substream->number + 1]);
4293	return 0;
4294}
4295
4296/* analog capture with dynamic dual-adc changes */
4297static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4298				       struct hda_codec *codec,
4299				       unsigned int stream_tag,
4300				       unsigned int format,
4301				       struct snd_pcm_substream *substream)
4302{
4303	struct alc_spec *spec = codec->spec;
4304	spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
4305	spec->cur_adc_stream_tag = stream_tag;
4306	spec->cur_adc_format = format;
4307	snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
4308	return 0;
4309}
4310
4311static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4312				       struct hda_codec *codec,
4313				       struct snd_pcm_substream *substream)
4314{
4315	struct alc_spec *spec = codec->spec;
4316	snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4317	spec->cur_adc = 0;
4318	return 0;
4319}
4320
4321static const struct hda_pcm_stream dualmic_pcm_analog_capture = {
4322	.substreams = 1,
4323	.channels_min = 2,
4324	.channels_max = 2,
4325	.nid = 0, /* fill later */
4326	.ops = {
4327		.prepare = dualmic_capture_pcm_prepare,
4328		.cleanup = dualmic_capture_pcm_cleanup
4329	},
4330};
4331
4332/*
4333 */
4334static const struct hda_pcm_stream alc880_pcm_analog_playback = {
4335	.substreams = 1,
4336	.channels_min = 2,
4337	.channels_max = 8,
4338	/* NID is set in alc_build_pcms */
4339	.ops = {
4340		.open = alc880_playback_pcm_open,
4341		.prepare = alc880_playback_pcm_prepare,
4342		.cleanup = alc880_playback_pcm_cleanup
4343	},
4344};
4345
4346static const struct hda_pcm_stream alc880_pcm_analog_capture = {
4347	.substreams = 1,
4348	.channels_min = 2,
4349	.channels_max = 2,
4350	/* NID is set in alc_build_pcms */
4351};
4352
4353static const struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
4354	.substreams = 1,
4355	.channels_min = 2,
4356	.channels_max = 2,
4357	/* NID is set in alc_build_pcms */
4358};
4359
4360static const struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
4361	.substreams = 2, /* can be overridden */
4362	.channels_min = 2,
4363	.channels_max = 2,
4364	/* NID is set in alc_build_pcms */
4365	.ops = {
4366		.prepare = alc880_alt_capture_pcm_prepare,
4367		.cleanup = alc880_alt_capture_pcm_cleanup
4368	},
4369};
4370
4371static const struct hda_pcm_stream alc880_pcm_digital_playback = {
4372	.substreams = 1,
4373	.channels_min = 2,
4374	.channels_max = 2,
4375	/* NID is set in alc_build_pcms */
4376	.ops = {
4377		.open = alc880_dig_playback_pcm_open,
4378		.close = alc880_dig_playback_pcm_close,
4379		.prepare = alc880_dig_playback_pcm_prepare,
4380		.cleanup = alc880_dig_playback_pcm_cleanup
4381	},
4382};
4383
4384static const struct hda_pcm_stream alc880_pcm_digital_capture = {
4385	.substreams = 1,
4386	.channels_min = 2,
4387	.channels_max = 2,
4388	/* NID is set in alc_build_pcms */
4389};
4390
4391/* Used by alc_build_pcms to flag that a PCM has no playback stream */
4392static const struct hda_pcm_stream alc_pcm_null_stream = {
4393	.substreams = 0,
4394	.channels_min = 0,
4395	.channels_max = 0,
4396};
4397
4398static int alc_build_pcms(struct hda_codec *codec)
4399{
4400	struct alc_spec *spec = codec->spec;
4401	struct hda_pcm *info = spec->pcm_rec;
4402	int i;
4403
4404	codec->num_pcms = 1;
4405	codec->pcm_info = info;
4406
4407	if (spec->no_analog)
4408		goto skip_analog;
4409
4410	snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4411		 "%s Analog", codec->chip_name);
4412	info->name = spec->stream_name_analog;
4413
4414	if (spec->stream_analog_playback) {
4415		if (snd_BUG_ON(!spec->multiout.dac_nids))
4416			return -EINVAL;
4417		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
4418		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4419	}
4420	if (spec->stream_analog_capture) {
4421		if (snd_BUG_ON(!spec->adc_nids))
4422			return -EINVAL;
4423		info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
4424		info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4425	}
4426
4427	if (spec->channel_mode) {
4428		info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4429		for (i = 0; i < spec->num_channel_mode; i++) {
4430			if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4431				info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4432			}
4433		}
4434	}
4435
4436 skip_analog:
4437	/* SPDIF for stream index #1 */
4438	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
4439		snprintf(spec->stream_name_digital,
4440			 sizeof(spec->stream_name_digital),
4441			 "%s Digital", codec->chip_name);
4442		codec->num_pcms = 2;
4443	        codec->slave_dig_outs = spec->multiout.slave_dig_outs;
4444		info = spec->pcm_rec + 1;
4445		info->name = spec->stream_name_digital;
4446		if (spec->dig_out_type)
4447			info->pcm_type = spec->dig_out_type;
4448		else
4449			info->pcm_type = HDA_PCM_TYPE_SPDIF;
4450		if (spec->multiout.dig_out_nid &&
4451		    spec->stream_digital_playback) {
4452			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4453			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4454		}
4455		if (spec->dig_in_nid &&
4456		    spec->stream_digital_capture) {
4457			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4458			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4459		}
4460		/* FIXME: do we need this for all Realtek codec models? */
4461		codec->spdif_status_reset = 1;
4462	}
4463
4464	if (spec->no_analog)
4465		return 0;
4466
4467	/* If the use of more than one ADC is requested for the current
4468	 * model, configure a second analog capture-only PCM.
4469	 */
4470	/* Additional Analaog capture for index #2 */
4471	if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4472	    (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
4473		codec->num_pcms = 3;
4474		info = spec->pcm_rec + 2;
4475		info->name = spec->stream_name_analog;
4476		if (spec->alt_dac_nid) {
4477			info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4478				*spec->stream_analog_alt_playback;
4479			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4480				spec->alt_dac_nid;
4481		} else {
4482			info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4483				alc_pcm_null_stream;
4484			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4485		}
4486		if (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture) {
4487			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4488				*spec->stream_analog_alt_capture;
4489			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4490				spec->adc_nids[1];
4491			info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4492				spec->num_adc_nids - 1;
4493		} else {
4494			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4495				alc_pcm_null_stream;
4496			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
4497		}
4498	}
4499
4500	return 0;
4501}
4502
4503static inline void alc_shutup(struct hda_codec *codec)
4504{
4505	struct alc_spec *spec = codec->spec;
4506
4507	if (spec && spec->shutup)
4508		spec->shutup(codec);
4509	snd_hda_shutup_pins(codec);
4510}
4511
4512static void alc_free_kctls(struct hda_codec *codec)
4513{
4514	struct alc_spec *spec = codec->spec;
4515
4516	if (spec->kctls.list) {
4517		struct snd_kcontrol_new *kctl = spec->kctls.list;
4518		int i;
4519		for (i = 0; i < spec->kctls.used; i++)
4520			kfree(kctl[i].name);
4521	}
4522	snd_array_free(&spec->kctls);
4523}
4524
4525static void alc_free(struct hda_codec *codec)
4526{
4527	struct alc_spec *spec = codec->spec;
4528
4529	if (!spec)
4530		return;
4531
4532	alc_shutup(codec);
4533	snd_hda_input_jack_free(codec);
4534	alc_free_kctls(codec);
4535	kfree(spec);
4536	snd_hda_detach_beep_device(codec);
4537}
4538
4539#ifdef CONFIG_SND_HDA_POWER_SAVE
4540static void alc_power_eapd(struct hda_codec *codec)
4541{
4542	alc_auto_setup_eapd(codec, false);
4543}
4544
4545static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4546{
4547	struct alc_spec *spec = codec->spec;
4548	alc_shutup(codec);
4549	if (spec && spec->power_hook)
4550		spec->power_hook(codec);
4551	return 0;
4552}
4553#endif
4554
4555#ifdef SND_HDA_NEEDS_RESUME
4556static int alc_resume(struct hda_codec *codec)
4557{
4558	msleep(150); /* to avoid pop noise */
4559	codec->patch_ops.init(codec);
4560	snd_hda_codec_resume_amp(codec);
4561	snd_hda_codec_resume_cache(codec);
4562	hda_call_check_power_status(codec, 0x01);
4563	return 0;
4564}
4565#endif
4566
4567/*
4568 */
4569static const struct hda_codec_ops alc_patch_ops = {
4570	.build_controls = alc_build_controls,
4571	.build_pcms = alc_build_pcms,
4572	.init = alc_init,
4573	.free = alc_free,
4574	.unsol_event = alc_unsol_event,
4575#ifdef SND_HDA_NEEDS_RESUME
4576	.resume = alc_resume,
4577#endif
4578#ifdef CONFIG_SND_HDA_POWER_SAVE
4579	.suspend = alc_suspend,
4580	.check_power_status = alc_check_power_status,
4581#endif
4582	.reboot_notify = alc_shutup,
4583};
4584
4585/* replace the codec chip_name with the given string */
4586static int alc_codec_rename(struct hda_codec *codec, const char *name)
4587{
4588	kfree(codec->chip_name);
4589	codec->chip_name = kstrdup(name, GFP_KERNEL);
4590	if (!codec->chip_name) {
4591		alc_free(codec);
4592		return -ENOMEM;
4593	}
4594	return 0;
4595}
4596
4597/*
4598 * Test configuration for debugging
4599 *
4600 * Almost all inputs/outputs are enabled.  I/O pins can be configured via
4601 * enum controls.
4602 */
4603#ifdef CONFIG_SND_DEBUG
4604static const hda_nid_t alc880_test_dac_nids[4] = {
4605	0x02, 0x03, 0x04, 0x05
4606};
4607
4608static const struct hda_input_mux alc880_test_capture_source = {
4609	.num_items = 7,
4610	.items = {
4611		{ "In-1", 0x0 },
4612		{ "In-2", 0x1 },
4613		{ "In-3", 0x2 },
4614		{ "In-4", 0x3 },
4615		{ "CD", 0x4 },
4616		{ "Front", 0x5 },
4617		{ "Surround", 0x6 },
4618	},
4619};
4620
4621static const struct hda_channel_mode alc880_test_modes[4] = {
4622	{ 2, NULL },
4623	{ 4, NULL },
4624	{ 6, NULL },
4625	{ 8, NULL },
4626};
4627
4628static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4629				 struct snd_ctl_elem_info *uinfo)
4630{
4631	static const char * const texts[] = {
4632		"N/A", "Line Out", "HP Out",
4633		"In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4634	};
4635	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4636	uinfo->count = 1;
4637	uinfo->value.enumerated.items = 8;
4638	if (uinfo->value.enumerated.item >= 8)
4639		uinfo->value.enumerated.item = 7;
4640	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4641	return 0;
4642}
4643
4644static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4645				struct snd_ctl_elem_value *ucontrol)
4646{
4647	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4648	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4649	unsigned int pin_ctl, item = 0;
4650
4651	pin_ctl = snd_hda_codec_read(codec, nid, 0,
4652				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4653	if (pin_ctl & AC_PINCTL_OUT_EN) {
4654		if (pin_ctl & AC_PINCTL_HP_EN)
4655			item = 2;
4656		else
4657			item = 1;
4658	} else if (pin_ctl & AC_PINCTL_IN_EN) {
4659		switch (pin_ctl & AC_PINCTL_VREFEN) {
4660		case AC_PINCTL_VREF_HIZ: item = 3; break;
4661		case AC_PINCTL_VREF_50:  item = 4; break;
4662		case AC_PINCTL_VREF_GRD: item = 5; break;
4663		case AC_PINCTL_VREF_80:  item = 6; break;
4664		case AC_PINCTL_VREF_100: item = 7; break;
4665		}
4666	}
4667	ucontrol->value.enumerated.item[0] = item;
4668	return 0;
4669}
4670
4671static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4672				struct snd_ctl_elem_value *ucontrol)
4673{
4674	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4675	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4676	static const unsigned int ctls[] = {
4677		0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4678		AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4679		AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4680		AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4681		AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4682		AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4683	};
4684	unsigned int old_ctl, new_ctl;
4685
4686	old_ctl = snd_hda_codec_read(codec, nid, 0,
4687				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4688	new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4689	if (old_ctl != new_ctl) {
4690		int val;
4691		snd_hda_codec_write_cache(codec, nid, 0,
4692					  AC_VERB_SET_PIN_WIDGET_CONTROL,
4693					  new_ctl);
4694		val = ucontrol->value.enumerated.item[0] >= 3 ?
4695			HDA_AMP_MUTE : 0;
4696		snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4697					 HDA_AMP_MUTE, val);
4698		return 1;
4699	}
4700	return 0;
4701}
4702
4703static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4704				 struct snd_ctl_elem_info *uinfo)
4705{
4706	static const char * const texts[] = {
4707		"Front", "Surround", "CLFE", "Side"
4708	};
4709	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4710	uinfo->count = 1;
4711	uinfo->value.enumerated.items = 4;
4712	if (uinfo->value.enumerated.item >= 4)
4713		uinfo->value.enumerated.item = 3;
4714	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4715	return 0;
4716}
4717
4718static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4719				struct snd_ctl_elem_value *ucontrol)
4720{
4721	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4722	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4723	unsigned int sel;
4724
4725	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4726	ucontrol->value.enumerated.item[0] = sel & 3;
4727	return 0;
4728}
4729
4730static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4731				struct snd_ctl_elem_value *ucontrol)
4732{
4733	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4734	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4735	unsigned int sel;
4736
4737	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4738	if (ucontrol->value.enumerated.item[0] != sel) {
4739		sel = ucontrol->value.enumerated.item[0] & 3;
4740		snd_hda_codec_write_cache(codec, nid, 0,
4741					  AC_VERB_SET_CONNECT_SEL, sel);
4742		return 1;
4743	}
4744	return 0;
4745}
4746
4747#define PIN_CTL_TEST(xname,nid) {			\
4748		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
4749			.name = xname,		       \
4750			.subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4751			.info = alc_test_pin_ctl_info, \
4752			.get = alc_test_pin_ctl_get,   \
4753			.put = alc_test_pin_ctl_put,   \
4754			.private_value = nid	       \
4755			}
4756
4757#define PIN_SRC_TEST(xname,nid) {			\
4758		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
4759			.name = xname,		       \
4760			.subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4761			.info = alc_test_pin_src_info, \
4762			.get = alc_test_pin_src_get,   \
4763			.put = alc_test_pin_src_put,   \
4764			.private_value = nid	       \
4765			}
4766
4767static const struct snd_kcontrol_new alc880_test_mixer[] = {
4768	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4769	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4770	HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4771	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4772	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4773	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4774	HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4775	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4776	PIN_CTL_TEST("Front Pin Mode", 0x14),
4777	PIN_CTL_TEST("Surround Pin Mode", 0x15),
4778	PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4779	PIN_CTL_TEST("Side Pin Mode", 0x17),
4780	PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4781	PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4782	PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4783	PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4784	PIN_SRC_TEST("In-1 Pin Source", 0x18),
4785	PIN_SRC_TEST("In-2 Pin Source", 0x19),
4786	PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4787	PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4788	HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4789	HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4790	HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4791	HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4792	HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4793	HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4794	HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4795	HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4796	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4797	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
4798	{
4799		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4800		.name = "Channel Mode",
4801		.info = alc_ch_mode_info,
4802		.get = alc_ch_mode_get,
4803		.put = alc_ch_mode_put,
4804	},
4805	{ } /* end */
4806};
4807
4808static const struct hda_verb alc880_test_init_verbs[] = {
4809	/* Unmute inputs of 0x0c - 0x0f */
4810	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4811	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4812	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4813	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4814	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4815	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4816	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4817	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4818	/* Vol output for 0x0c-0x0f */
4819	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4820	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4821	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4822	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4823	/* Set output pins 0x14-0x17 */
4824	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4825	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4826	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4827	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4828	/* Unmute output pins 0x14-0x17 */
4829	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4830	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4831	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4832	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4833	/* Set input pins 0x18-0x1c */
4834	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4835	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4836	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4837	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4838	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4839	/* Mute input pins 0x18-0x1b */
4840	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4841	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4842	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4843	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4844	/* ADC set up */
4845	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4846	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4847	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4848	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4849	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4850	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4851	/* Analog input/passthru */
4852	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4853	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4854	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4855	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4856	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4857	{ }
4858};
4859#endif
4860
4861/*
4862 */
4863
4864static const char * const alc880_models[ALC880_MODEL_LAST] = {
4865	[ALC880_3ST]		= "3stack",
4866	[ALC880_TCL_S700]	= "tcl",
4867	[ALC880_3ST_DIG]	= "3stack-digout",
4868	[ALC880_CLEVO]		= "clevo",
4869	[ALC880_5ST]		= "5stack",
4870	[ALC880_5ST_DIG]	= "5stack-digout",
4871	[ALC880_W810]		= "w810",
4872	[ALC880_Z71V]		= "z71v",
4873	[ALC880_6ST]		= "6stack",
4874	[ALC880_6ST_DIG]	= "6stack-digout",
4875	[ALC880_ASUS]		= "asus",
4876	[ALC880_ASUS_W1V]	= "asus-w1v",
4877	[ALC880_ASUS_DIG]	= "asus-dig",
4878	[ALC880_ASUS_DIG2]	= "asus-dig2",
4879	[ALC880_UNIWILL_DIG]	= "uniwill",
4880	[ALC880_UNIWILL_P53]	= "uniwill-p53",
4881	[ALC880_FUJITSU]	= "fujitsu",
4882	[ALC880_F1734]		= "F1734",
4883	[ALC880_LG]		= "lg",
4884	[ALC880_LG_LW]		= "lg-lw",
4885	[ALC880_MEDION_RIM]	= "medion",
4886#ifdef CONFIG_SND_DEBUG
4887	[ALC880_TEST]		= "test",
4888#endif
4889	[ALC880_AUTO]		= "auto",
4890};
4891
4892static const struct snd_pci_quirk alc880_cfg_tbl[] = {
4893	SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
4894	SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4895	SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4896	SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4897	SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4898	SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4899	SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4900	SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4901	SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
4902	SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4903	SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4904	SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4905	SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4906	SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4907	SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4908	SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4909	SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4910	/* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4911	SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4912	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
4913	SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
4914	SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4915	SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4916	SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
4917	SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
4918	SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
4919	SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4920	SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
4921	SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4922	SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
4923	SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4924	SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4925	SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4926	SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
4927	SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4928	SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
4929	SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
4930	SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
4931	SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
4932	SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
4933	SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4934	SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
4935	SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
4936	SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
4937	SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
4938	SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
4939	SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
4940	SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
4941	SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
4942	SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
4943	SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
4944	SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4945	SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
4946	SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
4947	SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
4948	SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4949	SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4950	SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4951	SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
4952	SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4953	SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
4954	SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
4955	SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
4956	SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4957	SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
4958	SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4959	SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4960	SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
4961	/* default Intel */
4962	SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
4963	SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4964	SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
4965	{}
4966};
4967
4968/*
4969 * ALC880 codec presets
4970 */
4971static const struct alc_config_preset alc880_presets[] = {
4972	[ALC880_3ST] = {
4973		.mixers = { alc880_three_stack_mixer },
4974		.init_verbs = { alc880_volume_init_verbs,
4975				alc880_pin_3stack_init_verbs },
4976		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
4977		.dac_nids = alc880_dac_nids,
4978		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4979		.channel_mode = alc880_threestack_modes,
4980		.need_dac_fix = 1,
4981		.input_mux = &alc880_capture_source,
4982	},
4983	[ALC880_3ST_DIG] = {
4984		.mixers = { alc880_three_stack_mixer },
4985		.init_verbs = { alc880_volume_init_verbs,
4986				alc880_pin_3stack_init_verbs },
4987		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
4988		.dac_nids = alc880_dac_nids,
4989		.dig_out_nid = ALC880_DIGOUT_NID,
4990		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4991		.channel_mode = alc880_threestack_modes,
4992		.need_dac_fix = 1,
4993		.input_mux = &alc880_capture_source,
4994	},
4995	[ALC880_TCL_S700] = {
4996		.mixers = { alc880_tcl_s700_mixer },
4997		.init_verbs = { alc880_volume_init_verbs,
4998				alc880_pin_tcl_S700_init_verbs,
4999				alc880_gpio2_init_verbs },
5000		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
5001		.dac_nids = alc880_dac_nids,
5002		.adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
5003		.num_adc_nids = 1, /* single ADC */
5004		.hp_nid = 0x03,
5005		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5006		.channel_mode = alc880_2_jack_modes,
5007		.input_mux = &alc880_capture_source,
5008	},
5009	[ALC880_5ST] = {
5010		.mixers = { alc880_three_stack_mixer,
5011			    alc880_five_stack_mixer},
5012		.init_verbs = { alc880_volume_init_verbs,
5013				alc880_pin_5stack_init_verbs },
5014		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
5015		.dac_nids = alc880_dac_nids,
5016		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5017		.channel_mode = alc880_fivestack_modes,
5018		.input_mux = &alc880_capture_source,
5019	},
5020	[ALC880_5ST_DIG] = {
5021		.mixers = { alc880_three_stack_mixer,
5022			    alc880_five_stack_mixer },
5023		.init_verbs = { alc880_volume_init_verbs,
5024				alc880_pin_5stack_init_verbs },
5025		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
5026		.dac_nids = alc880_dac_nids,
5027		.dig_out_nid = ALC880_DIGOUT_NID,
5028		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5029		.channel_mode = alc880_fivestack_modes,
5030		.input_mux = &alc880_capture_source,
5031	},
5032	[ALC880_6ST] = {
5033		.mixers = { alc880_six_stack_mixer },
5034		.init_verbs = { alc880_volume_init_verbs,
5035				alc880_pin_6stack_init_verbs },
5036		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5037		.dac_nids = alc880_6st_dac_nids,
5038		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5039		.channel_mode = alc880_sixstack_modes,
5040		.input_mux = &alc880_6stack_capture_source,
5041	},
5042	[ALC880_6ST_DIG] = {
5043		.mixers = { alc880_six_stack_mixer },
5044		.init_verbs = { alc880_volume_init_verbs,
5045				alc880_pin_6stack_init_verbs },
5046		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5047		.dac_nids = alc880_6st_dac_nids,
5048		.dig_out_nid = ALC880_DIGOUT_NID,
5049		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5050		.channel_mode = alc880_sixstack_modes,
5051		.input_mux = &alc880_6stack_capture_source,
5052	},
5053	[ALC880_W810] = {
5054		.mixers = { alc880_w810_base_mixer },
5055		.init_verbs = { alc880_volume_init_verbs,
5056				alc880_pin_w810_init_verbs,
5057				alc880_gpio2_init_verbs },
5058		.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
5059		.dac_nids = alc880_w810_dac_nids,
5060		.dig_out_nid = ALC880_DIGOUT_NID,
5061		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5062		.channel_mode = alc880_w810_modes,
5063		.input_mux = &alc880_capture_source,
5064	},
5065	[ALC880_Z71V] = {
5066		.mixers = { alc880_z71v_mixer },
5067		.init_verbs = { alc880_volume_init_verbs,
5068				alc880_pin_z71v_init_verbs },
5069		.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
5070		.dac_nids = alc880_z71v_dac_nids,
5071		.dig_out_nid = ALC880_DIGOUT_NID,
5072		.hp_nid = 0x03,
5073		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5074		.channel_mode = alc880_2_jack_modes,
5075		.input_mux = &alc880_capture_source,
5076	},
5077	[ALC880_F1734] = {
5078		.mixers = { alc880_f1734_mixer },
5079		.init_verbs = { alc880_volume_init_verbs,
5080				alc880_pin_f1734_init_verbs },
5081		.num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
5082		.dac_nids = alc880_f1734_dac_nids,
5083		.hp_nid = 0x02,
5084		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5085		.channel_mode = alc880_2_jack_modes,
5086		.input_mux = &alc880_f1734_capture_source,
5087		.unsol_event = alc880_uniwill_p53_unsol_event,
5088		.setup = alc880_uniwill_p53_setup,
5089		.init_hook = alc_hp_automute,
5090	},
5091	[ALC880_ASUS] = {
5092		.mixers = { alc880_asus_mixer },
5093		.init_verbs = { alc880_volume_init_verbs,
5094				alc880_pin_asus_init_verbs,
5095				alc880_gpio1_init_verbs },
5096		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5097		.dac_nids = alc880_asus_dac_nids,
5098		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5099		.channel_mode = alc880_asus_modes,
5100		.need_dac_fix = 1,
5101		.input_mux = &alc880_capture_source,
5102	},
5103	[ALC880_ASUS_DIG] = {
5104		.mixers = { alc880_asus_mixer },
5105		.init_verbs = { alc880_volume_init_verbs,
5106				alc880_pin_asus_init_verbs,
5107				alc880_gpio1_init_verbs },
5108		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5109		.dac_nids = alc880_asus_dac_nids,
5110		.dig_out_nid = ALC880_DIGOUT_NID,
5111		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5112		.channel_mode = alc880_asus_modes,
5113		.need_dac_fix = 1,
5114		.input_mux = &alc880_capture_source,
5115	},
5116	[ALC880_ASUS_DIG2] = {
5117		.mixers = { alc880_asus_mixer },
5118		.init_verbs = { alc880_volume_init_verbs,
5119				alc880_pin_asus_init_verbs,
5120				alc880_gpio2_init_verbs }, /* use GPIO2 */
5121		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5122		.dac_nids = alc880_asus_dac_nids,
5123		.dig_out_nid = ALC880_DIGOUT_NID,
5124		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5125		.channel_mode = alc880_asus_modes,
5126		.need_dac_fix = 1,
5127		.input_mux = &alc880_capture_source,
5128	},
5129	[ALC880_ASUS_W1V] = {
5130		.mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
5131		.init_verbs = { alc880_volume_init_verbs,
5132				alc880_pin_asus_init_verbs,
5133				alc880_gpio1_init_verbs },
5134		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5135		.dac_nids = alc880_asus_dac_nids,
5136		.dig_out_nid = ALC880_DIGOUT_NID,
5137		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5138		.channel_mode = alc880_asus_modes,
5139		.need_dac_fix = 1,
5140		.input_mux = &alc880_capture_source,
5141	},
5142	[ALC880_UNIWILL_DIG] = {
5143		.mixers = { alc880_asus_mixer },
5144		.init_verbs = { alc880_volume_init_verbs,
5145				alc880_pin_asus_init_verbs },
5146		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5147		.dac_nids = alc880_asus_dac_nids,
5148		.dig_out_nid = ALC880_DIGOUT_NID,
5149		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5150		.channel_mode = alc880_asus_modes,
5151		.need_dac_fix = 1,
5152		.input_mux = &alc880_capture_source,
5153	},
5154	[ALC880_UNIWILL] = {
5155		.mixers = { alc880_uniwill_mixer },
5156		.init_verbs = { alc880_volume_init_verbs,
5157				alc880_uniwill_init_verbs },
5158		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5159		.dac_nids = alc880_asus_dac_nids,
5160		.dig_out_nid = ALC880_DIGOUT_NID,
5161		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5162		.channel_mode = alc880_threestack_modes,
5163		.need_dac_fix = 1,
5164		.input_mux = &alc880_capture_source,
5165		.unsol_event = alc880_uniwill_unsol_event,
5166		.setup = alc880_uniwill_setup,
5167		.init_hook = alc880_uniwill_init_hook,
5168	},
5169	[ALC880_UNIWILL_P53] = {
5170		.mixers = { alc880_uniwill_p53_mixer },
5171		.init_verbs = { alc880_volume_init_verbs,
5172				alc880_uniwill_p53_init_verbs },
5173		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5174		.dac_nids = alc880_asus_dac_nids,
5175		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5176		.channel_mode = alc880_threestack_modes,
5177		.input_mux = &alc880_capture_source,
5178		.unsol_event = alc880_uniwill_p53_unsol_event,
5179		.setup = alc880_uniwill_p53_setup,
5180		.init_hook = alc_hp_automute,
5181	},
5182	[ALC880_FUJITSU] = {
5183		.mixers = { alc880_fujitsu_mixer },
5184		.init_verbs = { alc880_volume_init_verbs,
5185				alc880_uniwill_p53_init_verbs,
5186	       			alc880_beep_init_verbs },
5187		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
5188		.dac_nids = alc880_dac_nids,
5189		.dig_out_nid = ALC880_DIGOUT_NID,
5190		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5191		.channel_mode = alc880_2_jack_modes,
5192		.input_mux = &alc880_capture_source,
5193		.unsol_event = alc880_uniwill_p53_unsol_event,
5194		.setup = alc880_uniwill_p53_setup,
5195		.init_hook = alc_hp_automute,
5196	},
5197	[ALC880_CLEVO] = {
5198		.mixers = { alc880_three_stack_mixer },
5199		.init_verbs = { alc880_volume_init_verbs,
5200				alc880_pin_clevo_init_verbs },
5201		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
5202		.dac_nids = alc880_dac_nids,
5203		.hp_nid = 0x03,
5204		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5205		.channel_mode = alc880_threestack_modes,
5206		.need_dac_fix = 1,
5207		.input_mux = &alc880_capture_source,
5208	},
5209	[ALC880_LG] = {
5210		.mixers = { alc880_lg_mixer },
5211		.init_verbs = { alc880_volume_init_verbs,
5212				alc880_lg_init_verbs },
5213		.num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
5214		.dac_nids = alc880_lg_dac_nids,
5215		.dig_out_nid = ALC880_DIGOUT_NID,
5216		.num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
5217		.channel_mode = alc880_lg_ch_modes,
5218		.need_dac_fix = 1,
5219		.input_mux = &alc880_lg_capture_source,
5220		.unsol_event = alc_sku_unsol_event,
5221		.setup = alc880_lg_setup,
5222		.init_hook = alc_hp_automute,
5223#ifdef CONFIG_SND_HDA_POWER_SAVE
5224		.loopbacks = alc880_lg_loopbacks,
5225#endif
5226	},
5227	[ALC880_LG_LW] = {
5228		.mixers = { alc880_lg_lw_mixer },
5229		.init_verbs = { alc880_volume_init_verbs,
5230				alc880_lg_lw_init_verbs },
5231		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
5232		.dac_nids = alc880_dac_nids,
5233		.dig_out_nid = ALC880_DIGOUT_NID,
5234		.num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
5235		.channel_mode = alc880_lg_lw_modes,
5236		.input_mux = &alc880_lg_lw_capture_source,
5237		.unsol_event = alc_sku_unsol_event,
5238		.setup = alc880_lg_lw_setup,
5239		.init_hook = alc_hp_automute,
5240	},
5241	[ALC880_MEDION_RIM] = {
5242		.mixers = { alc880_medion_rim_mixer },
5243		.init_verbs = { alc880_volume_init_verbs,
5244				alc880_medion_rim_init_verbs,
5245				alc_gpio2_init_verbs },
5246		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
5247		.dac_nids = alc880_dac_nids,
5248		.dig_out_nid = ALC880_DIGOUT_NID,
5249		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5250		.channel_mode = alc880_2_jack_modes,
5251		.input_mux = &alc880_medion_rim_capture_source,
5252		.unsol_event = alc880_medion_rim_unsol_event,
5253		.setup = alc880_medion_rim_setup,
5254		.init_hook = alc880_medion_rim_automute,
5255	},
5256#ifdef CONFIG_SND_DEBUG
5257	[ALC880_TEST] = {
5258		.mixers = { alc880_test_mixer },
5259		.init_verbs = { alc880_test_init_verbs },
5260		.num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
5261		.dac_nids = alc880_test_dac_nids,
5262		.dig_out_nid = ALC880_DIGOUT_NID,
5263		.num_channel_mode = ARRAY_SIZE(alc880_test_modes),
5264		.channel_mode = alc880_test_modes,
5265		.input_mux = &alc880_test_capture_source,
5266	},
5267#endif
5268};
5269
5270/*
5271 * Automatic parse of I/O pins from the BIOS configuration
5272 */
5273
5274enum {
5275	ALC_CTL_WIDGET_VOL,
5276	ALC_CTL_WIDGET_MUTE,
5277	ALC_CTL_BIND_MUTE,
5278};
5279static const struct snd_kcontrol_new alc880_control_templates[] = {
5280	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
5281	HDA_CODEC_MUTE(NULL, 0, 0, 0),
5282	HDA_BIND_MUTE(NULL, 0, 0, 0),
5283};
5284
5285static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
5286{
5287	snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
5288	return snd_array_new(&spec->kctls);
5289}
5290
5291/* add dynamic controls */
5292static int add_control(struct alc_spec *spec, int type, const char *name,
5293		       int cidx, unsigned long val)
5294{
5295	struct snd_kcontrol_new *knew;
5296
5297	knew = alc_kcontrol_new(spec);
5298	if (!knew)
5299		return -ENOMEM;
5300	*knew = alc880_control_templates[type];
5301	knew->name = kstrdup(name, GFP_KERNEL);
5302	if (!knew->name)
5303		return -ENOMEM;
5304	knew->index = cidx;
5305	if (get_amp_nid_(val))
5306		knew->subdevice = HDA_SUBDEV_AMP_FLAG;
5307	knew->private_value = val;
5308	return 0;
5309}
5310
5311static int add_control_with_pfx(struct alc_spec *spec, int type,
5312				const char *pfx, const char *dir,
5313				const char *sfx, int cidx, unsigned long val)
5314{
5315	char name[32];
5316	snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
5317	return add_control(spec, type, name, cidx, val);
5318}
5319
5320#define add_pb_vol_ctrl(spec, type, pfx, val)			\
5321	add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5322#define add_pb_sw_ctrl(spec, type, pfx, val)			\
5323	add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5324#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val)			\
5325	add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5326#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val)			\
5327	add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
5328
5329#define alc880_is_fixed_pin(nid)	((nid) >= 0x14 && (nid) <= 0x17)
5330#define alc880_fixed_pin_idx(nid)	((nid) - 0x14)
5331#define alc880_is_multi_pin(nid)	((nid) >= 0x18)
5332#define alc880_multi_pin_idx(nid)	((nid) - 0x18)
5333#define alc880_idx_to_dac(nid)		((nid) + 0x02)
5334#define alc880_dac_to_idx(nid)		((nid) - 0x02)
5335#define alc880_idx_to_mixer(nid)	((nid) + 0x0c)
5336#define alc880_idx_to_selector(nid)	((nid) + 0x10)
5337#define ALC880_PIN_CD_NID		0x1c
5338
5339/* fill in the dac_nids table from the parsed pin configuration */
5340static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5341				     const struct auto_pin_cfg *cfg)
5342{
5343	hda_nid_t nid;
5344	int assigned[4];
5345	int i, j;
5346
5347	memset(assigned, 0, sizeof(assigned));
5348	spec->multiout.dac_nids = spec->private_dac_nids;
5349
5350	/* check the pins hardwired to audio widget */
5351	for (i = 0; i < cfg->line_outs; i++) {
5352		nid = cfg->line_out_pins[i];
5353		if (alc880_is_fixed_pin(nid)) {
5354			int idx = alc880_fixed_pin_idx(nid);
5355			spec->private_dac_nids[i] = alc880_idx_to_dac(idx);
5356			assigned[idx] = 1;
5357		}
5358	}
5359	/* left pins can be connect to any audio widget */
5360	for (i = 0; i < cfg->line_outs; i++) {
5361		nid = cfg->line_out_pins[i];
5362		if (alc880_is_fixed_pin(nid))
5363			continue;
5364		/* search for an empty channel */
5365		for (j = 0; j < cfg->line_outs; j++) {
5366			if (!assigned[j]) {
5367				spec->private_dac_nids[i] =
5368					alc880_idx_to_dac(j);
5369				assigned[j] = 1;
5370				break;
5371			}
5372		}
5373	}
5374	spec->multiout.num_dacs = cfg->line_outs;
5375	return 0;
5376}
5377
5378static const char *alc_get_line_out_pfx(struct alc_spec *spec,
5379					bool can_be_master)
5380{
5381	struct auto_pin_cfg *cfg = &spec->autocfg;
5382
5383	if (cfg->line_outs == 1 && !spec->multi_ios &&
5384	    !cfg->hp_outs && !cfg->speaker_outs && can_be_master)
5385		return "Master";
5386
5387	switch (cfg->line_out_type) {
5388	case AUTO_PIN_SPEAKER_OUT:
5389		if (cfg->line_outs == 1)
5390			return "Speaker";
5391		break;
5392	case AUTO_PIN_HP_OUT:
5393		return "Headphone";
5394	default:
5395		if (cfg->line_outs == 1 && !spec->multi_ios)
5396			return "PCM";
5397		break;
5398	}
5399	return NULL;
5400}
5401
5402/* add playback controls from the parsed DAC table */
5403static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5404					     const struct auto_pin_cfg *cfg)
5405{
5406	static const char * const chname[4] = {
5407		"Front", "Surround", NULL /*CLFE*/, "Side"
5408	};
5409	const char *pfx = alc_get_line_out_pfx(spec, false);
5410	hda_nid_t nid;
5411	int i, err, noutputs;
5412
5413	noutputs = cfg->line_outs;
5414	if (spec->multi_ios > 0)
5415		noutputs += spec->multi_ios;
5416
5417	for (i = 0; i < noutputs; i++) {
5418		if (!spec->multiout.dac_nids[i])
5419			continue;
5420		nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
5421		if (!pfx && i == 2) {
5422			/* Center/LFE */
5423			err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5424					      "Center",
5425					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
5426							      HDA_OUTPUT));
5427			if (err < 0)
5428				return err;
5429			err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5430					      "LFE",
5431					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
5432							      HDA_OUTPUT));
5433			if (err < 0)
5434				return err;
5435			err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5436					     "Center",
5437					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
5438							      HDA_INPUT));
5439			if (err < 0)
5440				return err;
5441			err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5442					     "LFE",
5443					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
5444							      HDA_INPUT));
5445			if (err < 0)
5446				return err;
5447		} else {
5448			const char *name = pfx;
5449			int index = i;
5450			if (!name) {
5451				name = chname[i];
5452				index = 0;
5453			}
5454			err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5455						name, index,
5456					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5457							      HDA_OUTPUT));
5458			if (err < 0)
5459				return err;
5460			err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5461					       name, index,
5462					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5463							      HDA_INPUT));
5464			if (err < 0)
5465				return err;
5466		}
5467	}
5468	return 0;
5469}
5470
5471/* add playback controls for speaker and HP outputs */
5472static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5473					const char *pfx)
5474{
5475	hda_nid_t nid;
5476	int err;
5477
5478	if (!pin)
5479		return 0;
5480
5481	if (alc880_is_fixed_pin(pin)) {
5482		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
5483		/* specify the DAC as the extra output */
5484		if (!spec->multiout.hp_nid)
5485			spec->multiout.hp_nid = nid;
5486		else
5487			spec->multiout.extra_out_nid[0] = nid;
5488		/* control HP volume/switch on the output mixer amp */
5489		nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
5490		err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
5491				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5492		if (err < 0)
5493			return err;
5494		err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
5495				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5496		if (err < 0)
5497			return err;
5498	} else if (alc880_is_multi_pin(pin)) {
5499		/* set manual connection */
5500		/* we have only a switch on HP-out PIN */
5501		err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
5502				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5503		if (err < 0)
5504			return err;
5505	}
5506	return 0;
5507}
5508
5509/* create input playback/capture controls for the given pin */
5510static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
5511			    const char *ctlname, int ctlidx,
5512			    int idx, hda_nid_t mix_nid)
5513{
5514	int err;
5515
5516	err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
5517			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5518	if (err < 0)
5519		return err;
5520	err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
5521			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5522	if (err < 0)
5523		return err;
5524	return 0;
5525}
5526
5527static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5528{
5529	unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5530	return (pincap & AC_PINCAP_IN) != 0;
5531}
5532
5533/* create playback/capture controls for input pins */
5534static int alc_auto_create_input_ctls(struct hda_codec *codec,
5535				      const struct auto_pin_cfg *cfg,
5536				      hda_nid_t mixer,
5537				      hda_nid_t cap1, hda_nid_t cap2)
5538{
5539	struct alc_spec *spec = codec->spec;
5540	struct hda_input_mux *imux = &spec->private_imux[0];
5541	int i, err, idx, type_idx = 0;
5542	const char *prev_label = NULL;
5543
5544	for (i = 0; i < cfg->num_inputs; i++) {
5545		hda_nid_t pin;
5546		const char *label;
5547
5548		pin = cfg->inputs[i].pin;
5549		if (!alc_is_input_pin(codec, pin))
5550			continue;
5551
5552		label = hda_get_autocfg_input_label(codec, cfg, i);
5553		if (prev_label && !strcmp(label, prev_label))
5554			type_idx++;
5555		else
5556			type_idx = 0;
5557		prev_label = label;
5558
5559		if (mixer) {
5560			idx = get_connection_index(codec, mixer, pin);
5561			if (idx >= 0) {
5562				err = new_analog_input(spec, pin,
5563						       label, type_idx,
5564						       idx, mixer);
5565				if (err < 0)
5566					return err;
5567			}
5568		}
5569
5570		if (!cap1)
5571			continue;
5572		idx = get_connection_index(codec, cap1, pin);
5573		if (idx < 0 && cap2)
5574			idx = get_connection_index(codec, cap2, pin);
5575		if (idx >= 0)
5576			snd_hda_add_imux_item(imux, label, idx, NULL);
5577	}
5578	return 0;
5579}
5580
5581static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5582						const struct auto_pin_cfg *cfg)
5583{
5584	return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5585}
5586
5587static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5588			       unsigned int pin_type)
5589{
5590	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5591			    pin_type);
5592	/* unmute pin */
5593	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5594			    AMP_OUT_UNMUTE);
5595}
5596
5597static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5598					      hda_nid_t nid, int pin_type,
5599					      int dac_idx)
5600{
5601	alc_set_pin_output(codec, nid, pin_type);
5602	/* need the manual connection? */
5603	if (alc880_is_multi_pin(nid)) {
5604		struct alc_spec *spec = codec->spec;
5605		int idx = alc880_multi_pin_idx(nid);
5606		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5607				    AC_VERB_SET_CONNECT_SEL,
5608				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5609	}
5610}
5611
5612static int get_pin_type(int line_out_type)
5613{
5614	if (line_out_type == AUTO_PIN_HP_OUT)
5615		return PIN_HP;
5616	else
5617		return PIN_OUT;
5618}
5619
5620static void alc880_auto_init_multi_out(struct hda_codec *codec)
5621{
5622	struct alc_spec *spec = codec->spec;
5623	int i;
5624
5625	for (i = 0; i < spec->autocfg.line_outs; i++) {
5626		hda_nid_t nid = spec->autocfg.line_out_pins[i];
5627		int pin_type = get_pin_type(spec->autocfg.line_out_type);
5628		alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
5629	}
5630}
5631
5632static void alc880_auto_init_extra_out(struct hda_codec *codec)
5633{
5634	struct alc_spec *spec = codec->spec;
5635	hda_nid_t pin;
5636
5637	pin = spec->autocfg.speaker_pins[0];
5638	if (pin) /* connect to front */
5639		alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
5640	pin = spec->autocfg.hp_pins[0];
5641	if (pin) /* connect to front */
5642		alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5643}
5644
5645static void alc880_auto_init_analog_input(struct hda_codec *codec)
5646{
5647	struct alc_spec *spec = codec->spec;
5648	struct auto_pin_cfg *cfg = &spec->autocfg;
5649	int i;
5650
5651	for (i = 0; i < cfg->num_inputs; i++) {
5652		hda_nid_t nid = cfg->inputs[i].pin;
5653		if (alc_is_input_pin(codec, nid)) {
5654			alc_set_input_pin(codec, nid, cfg->inputs[i].type);
5655			if (nid != ALC880_PIN_CD_NID &&
5656			    (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
5657				snd_hda_codec_write(codec, nid, 0,
5658						    AC_VERB_SET_AMP_GAIN_MUTE,
5659						    AMP_OUT_MUTE);
5660		}
5661	}
5662}
5663
5664static void alc880_auto_init_input_src(struct hda_codec *codec)
5665{
5666	struct alc_spec *spec = codec->spec;
5667	int c;
5668
5669	for (c = 0; c < spec->num_adc_nids; c++) {
5670		unsigned int mux_idx;
5671		const struct hda_input_mux *imux;
5672		mux_idx = c >= spec->num_mux_defs ? 0 : c;
5673		imux = &spec->input_mux[mux_idx];
5674		if (!imux->num_items && mux_idx > 0)
5675			imux = &spec->input_mux[0];
5676		if (imux)
5677			snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5678					    AC_VERB_SET_CONNECT_SEL,
5679					    imux->items[0].index);
5680	}
5681}
5682
5683static int alc_auto_add_multi_channel_mode(struct hda_codec *codec);
5684
5685/* parse the BIOS configuration and set up the alc_spec */
5686/* return 1 if successful, 0 if the proper config is not found,
5687 * or a negative error code
5688 */
5689static int alc880_parse_auto_config(struct hda_codec *codec)
5690{
5691	struct alc_spec *spec = codec->spec;
5692	int err;
5693	static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
5694
5695	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5696					   alc880_ignore);
5697	if (err < 0)
5698		return err;
5699	if (!spec->autocfg.line_outs)
5700		return 0; /* can't find valid BIOS pin config */
5701
5702	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5703	if (err < 0)
5704		return err;
5705	err = alc_auto_add_multi_channel_mode(codec);
5706	if (err < 0)
5707		return err;
5708	err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5709	if (err < 0)
5710		return err;
5711	err = alc880_auto_create_extra_out(spec,
5712					   spec->autocfg.speaker_pins[0],
5713					   "Speaker");
5714	if (err < 0)
5715		return err;
5716	err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5717					   "Headphone");
5718	if (err < 0)
5719		return err;
5720	err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
5721	if (err < 0)
5722		return err;
5723
5724	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5725
5726	alc_auto_parse_digital(codec);
5727
5728	if (spec->kctls.list)
5729		add_mixer(spec, spec->kctls.list);
5730
5731	add_verb(spec, alc880_volume_init_verbs);
5732
5733	spec->num_mux_defs = 1;
5734	spec->input_mux = &spec->private_imux[0];
5735
5736	alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
5737
5738	return 1;
5739}
5740
5741/* additional initialization for auto-configuration model */
5742static void alc880_auto_init(struct hda_codec *codec)
5743{
5744	struct alc_spec *spec = codec->spec;
5745	alc880_auto_init_multi_out(codec);
5746	alc880_auto_init_extra_out(codec);
5747	alc880_auto_init_analog_input(codec);
5748	alc880_auto_init_input_src(codec);
5749	alc_auto_init_digital(codec);
5750	if (spec->unsol_event)
5751		alc_inithook(codec);
5752}
5753
5754/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5755 * one of two digital mic pins, e.g. on ALC272
5756 */
5757static void fixup_automic_adc(struct hda_codec *codec)
5758{
5759	struct alc_spec *spec = codec->spec;
5760	int i;
5761
5762	for (i = 0; i < spec->num_adc_nids; i++) {
5763		hda_nid_t cap = spec->capsrc_nids ?
5764			spec->capsrc_nids[i] : spec->adc_nids[i];
5765		int iidx, eidx;
5766
5767		iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5768		if (iidx < 0)
5769			continue;
5770		eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5771		if (eidx < 0)
5772			continue;
5773		spec->int_mic.mux_idx = iidx;
5774		spec->ext_mic.mux_idx = eidx;
5775		if (spec->capsrc_nids)
5776			spec->capsrc_nids += i;
5777		spec->adc_nids += i;
5778		spec->num_adc_nids = 1;
5779		/* optional dock-mic */
5780		eidx = get_connection_index(codec, cap, spec->dock_mic.pin);
5781		if (eidx < 0)
5782			spec->dock_mic.pin = 0;
5783		else
5784			spec->dock_mic.mux_idx = eidx;
5785		return;
5786	}
5787	snd_printd(KERN_INFO "hda_codec: %s: "
5788		   "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5789		   codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5790	spec->auto_mic = 0; /* disable auto-mic to be sure */
5791}
5792
5793/* select or unmute the given capsrc route */
5794static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5795				    int idx)
5796{
5797	if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5798		snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5799					 HDA_AMP_MUTE, 0);
5800	} else {
5801		snd_hda_codec_write_cache(codec, cap, 0,
5802					  AC_VERB_SET_CONNECT_SEL, idx);
5803	}
5804}
5805
5806/* set the default connection to that pin */
5807static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
5808{
5809	struct alc_spec *spec = codec->spec;
5810	int i;
5811
5812	if (!pin)
5813		return 0;
5814	for (i = 0; i < spec->num_adc_nids; i++) {
5815		hda_nid_t cap = spec->capsrc_nids ?
5816			spec->capsrc_nids[i] : spec->adc_nids[i];
5817		int idx;
5818
5819		idx = get_connection_index(codec, cap, pin);
5820		if (idx < 0)
5821			continue;
5822		select_or_unmute_capsrc(codec, cap, idx);
5823		return i; /* return the found index */
5824	}
5825	return -1; /* not found */
5826}
5827
5828/* choose the ADC/MUX containing the input pin and initialize the setup */
5829static void fixup_single_adc(struct hda_codec *codec)
5830{
5831	struct alc_spec *spec = codec->spec;
5832	struct auto_pin_cfg *cfg = &spec->autocfg;
5833	int i;
5834
5835	/* search for the input pin; there must be only one */
5836	if (cfg->num_inputs != 1)
5837		return;
5838	i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
5839	if (i >= 0) {
5840		/* use only this ADC */
5841		if (spec->capsrc_nids)
5842			spec->capsrc_nids += i;
5843		spec->adc_nids += i;
5844		spec->num_adc_nids = 1;
5845		spec->single_input_src = 1;
5846	}
5847}
5848
5849/* initialize dual adcs */
5850static void fixup_dual_adc_switch(struct hda_codec *codec)
5851{
5852	struct alc_spec *spec = codec->spec;
5853	init_capsrc_for_pin(codec, spec->ext_mic.pin);
5854	init_capsrc_for_pin(codec, spec->dock_mic.pin);
5855	init_capsrc_for_pin(codec, spec->int_mic.pin);
5856}
5857
5858/* initialize some special cases for input sources */
5859static void alc_init_special_input_src(struct hda_codec *codec)
5860{
5861	struct alc_spec *spec = codec->spec;
5862	if (spec->dual_adc_switch)
5863		fixup_dual_adc_switch(codec);
5864	else if (spec->single_input_src)
5865		init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin);
5866}
5867
5868static void set_capture_mixer(struct hda_codec *codec)
5869{
5870	struct alc_spec *spec = codec->spec;
5871	static const struct snd_kcontrol_new *caps[2][3] = {
5872		{ alc_capture_mixer_nosrc1,
5873		  alc_capture_mixer_nosrc2,
5874		  alc_capture_mixer_nosrc3 },
5875		{ alc_capture_mixer1,
5876		  alc_capture_mixer2,
5877		  alc_capture_mixer3 },
5878	};
5879	if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
5880		int mux = 0;
5881		int num_adcs = spec->num_adc_nids;
5882		if (spec->dual_adc_switch)
5883			num_adcs = 1;
5884		else if (spec->auto_mic)
5885			fixup_automic_adc(codec);
5886		else if (spec->input_mux) {
5887			if (spec->input_mux->num_items > 1)
5888				mux = 1;
5889			else if (spec->input_mux->num_items == 1)
5890				fixup_single_adc(codec);
5891		}
5892		spec->cap_mixer = caps[mux][num_adcs - 1];
5893	}
5894}
5895
5896/* fill adc_nids (and capsrc_nids) containing all active input pins */
5897static void fillup_priv_adc_nids(struct hda_codec *codec, const hda_nid_t *nids,
5898				 int num_nids)
5899{
5900	struct alc_spec *spec = codec->spec;
5901	struct auto_pin_cfg *cfg = &spec->autocfg;
5902	int n;
5903	hda_nid_t fallback_adc = 0, fallback_cap = 0;
5904
5905	for (n = 0; n < num_nids; n++) {
5906		hda_nid_t adc, cap;
5907		hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5908		int nconns, i, j;
5909
5910		adc = nids[n];
5911		if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5912			continue;
5913		cap = adc;
5914		nconns = snd_hda_get_connections(codec, cap, conn,
5915						 ARRAY_SIZE(conn));
5916		if (nconns == 1) {
5917			cap = conn[0];
5918			nconns = snd_hda_get_connections(codec, cap, conn,
5919							 ARRAY_SIZE(conn));
5920		}
5921		if (nconns <= 0)
5922			continue;
5923		if (!fallback_adc) {
5924			fallback_adc = adc;
5925			fallback_cap = cap;
5926		}
5927		for (i = 0; i < cfg->num_inputs; i++) {
5928			hda_nid_t nid = cfg->inputs[i].pin;
5929			for (j = 0; j < nconns; j++) {
5930				if (conn[j] == nid)
5931					break;
5932			}
5933			if (j >= nconns)
5934				break;
5935		}
5936		if (i >= cfg->num_inputs) {
5937			int num_adcs = spec->num_adc_nids;
5938			spec->private_adc_nids[num_adcs] = adc;
5939			spec->private_capsrc_nids[num_adcs] = cap;
5940			spec->num_adc_nids++;
5941			spec->adc_nids = spec->private_adc_nids;
5942			if (adc != cap)
5943				spec->capsrc_nids = spec->private_capsrc_nids;
5944		}
5945	}
5946	if (!spec->num_adc_nids) {
5947		printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
5948		       " using fallback 0x%x\n",
5949		       codec->chip_name, fallback_adc);
5950		spec->private_adc_nids[0] = fallback_adc;
5951		spec->adc_nids = spec->private_adc_nids;
5952		if (fallback_adc != fallback_cap) {
5953			spec->private_capsrc_nids[0] = fallback_cap;
5954			spec->capsrc_nids = spec->private_adc_nids;
5955		}
5956	}
5957}
5958
5959#ifdef CONFIG_SND_HDA_INPUT_BEEP
5960#define set_beep_amp(spec, nid, idx, dir) \
5961	((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
5962
5963static const struct snd_pci_quirk beep_white_list[] = {
5964	SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
5965	SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
5966	SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
5967	SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
5968	SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
5969	{}
5970};
5971
5972static inline int has_cdefine_beep(struct hda_codec *codec)
5973{
5974	struct alc_spec *spec = codec->spec;
5975	const struct snd_pci_quirk *q;
5976	q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5977	if (q)
5978		return q->value;
5979	return spec->cdefine.enable_pcbeep;
5980}
5981#else
5982#define set_beep_amp(spec, nid, idx, dir) /* NOP */
5983#define has_cdefine_beep(codec)		0
5984#endif
5985
5986/*
5987 * OK, here we have finally the patch for ALC880
5988 */
5989
5990static int patch_alc880(struct hda_codec *codec)
5991{
5992	struct alc_spec *spec;
5993	int board_config;
5994	int err;
5995
5996	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5997	if (spec == NULL)
5998		return -ENOMEM;
5999
6000	codec->spec = spec;
6001
6002	board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
6003						  alc880_models,
6004						  alc880_cfg_tbl);
6005	if (board_config < 0) {
6006		printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6007		       codec->chip_name);
6008		board_config = ALC880_AUTO;
6009	}
6010
6011	if (board_config == ALC880_AUTO) {
6012		/* automatic parse from the BIOS config */
6013		err = alc880_parse_auto_config(codec);
6014		if (err < 0) {
6015			alc_free(codec);
6016			return err;
6017		} else if (!err) {
6018			printk(KERN_INFO
6019			       "hda_codec: Cannot set up configuration "
6020			       "from BIOS.  Using 3-stack mode...\n");
6021			board_config = ALC880_3ST;
6022		}
6023	}
6024
6025	err = snd_hda_attach_beep_device(codec, 0x1);
6026	if (err < 0) {
6027		alc_free(codec);
6028		return err;
6029	}
6030
6031	if (board_config != ALC880_AUTO)
6032		setup_preset(codec, &alc880_presets[board_config]);
6033
6034	spec->stream_analog_playback = &alc880_pcm_analog_playback;
6035	spec->stream_analog_capture = &alc880_pcm_analog_capture;
6036	spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
6037
6038	spec->stream_digital_playback = &alc880_pcm_digital_playback;
6039	spec->stream_digital_capture = &alc880_pcm_digital_capture;
6040
6041	if (!spec->adc_nids && spec->input_mux) {
6042		/* check whether NID 0x07 is valid */
6043		unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
6044		/* get type */
6045		wcap = get_wcaps_type(wcap);
6046		if (wcap != AC_WID_AUD_IN) {
6047			spec->adc_nids = alc880_adc_nids_alt;
6048			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
6049		} else {
6050			spec->adc_nids = alc880_adc_nids;
6051			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
6052		}
6053	}
6054	set_capture_mixer(codec);
6055	set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
6056
6057	spec->vmaster_nid = 0x0c;
6058
6059	codec->patch_ops = alc_patch_ops;
6060	if (board_config == ALC880_AUTO)
6061		spec->init_hook = alc880_auto_init;
6062#ifdef CONFIG_SND_HDA_POWER_SAVE
6063	if (!spec->loopback.amplist)
6064		spec->loopback.amplist = alc880_loopbacks;
6065#endif
6066
6067	return 0;
6068}
6069
6070
6071/*
6072 * ALC260 support
6073 */
6074
6075static const hda_nid_t alc260_dac_nids[1] = {
6076	/* front */
6077	0x02,
6078};
6079
6080static const hda_nid_t alc260_adc_nids[1] = {
6081	/* ADC0 */
6082	0x04,
6083};
6084
6085static const hda_nid_t alc260_adc_nids_alt[1] = {
6086	/* ADC1 */
6087	0x05,
6088};
6089
6090/* NIDs used when simultaneous access to both ADCs makes sense.  Note that
6091 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
6092 */
6093static const hda_nid_t alc260_dual_adc_nids[2] = {
6094	/* ADC0, ADC1 */
6095	0x04, 0x05
6096};
6097
6098#define ALC260_DIGOUT_NID	0x03
6099#define ALC260_DIGIN_NID	0x06
6100
6101static const struct hda_input_mux alc260_capture_source = {
6102	.num_items = 4,
6103	.items = {
6104		{ "Mic", 0x0 },
6105		{ "Front Mic", 0x1 },
6106		{ "Line", 0x2 },
6107		{ "CD", 0x4 },
6108	},
6109};
6110
6111/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
6112 * headphone jack and the internal CD lines since these are the only pins at
6113 * which audio can appear.  For flexibility, also allow the option of
6114 * recording the mixer output on the second ADC (ADC0 doesn't have a
6115 * connection to the mixer output).
6116 */
6117static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
6118	{
6119		.num_items = 3,
6120		.items = {
6121			{ "Mic/Line", 0x0 },
6122			{ "CD", 0x4 },
6123			{ "Headphone", 0x2 },
6124		},
6125	},
6126	{
6127		.num_items = 4,
6128		.items = {
6129			{ "Mic/Line", 0x0 },
6130			{ "CD", 0x4 },
6131			{ "Headphone", 0x2 },
6132			{ "Mixer", 0x5 },
6133		},
6134	},
6135
6136};
6137
6138/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
6139 * the Fujitsu S702x, but jacks are marked differently.
6140 */
6141static const struct hda_input_mux alc260_acer_capture_sources[2] = {
6142	{
6143		.num_items = 4,
6144		.items = {
6145			{ "Mic", 0x0 },
6146			{ "Line", 0x2 },
6147			{ "CD", 0x4 },
6148			{ "Headphone", 0x5 },
6149		},
6150	},
6151	{
6152		.num_items = 5,
6153		.items = {
6154			{ "Mic", 0x0 },
6155			{ "Line", 0x2 },
6156			{ "CD", 0x4 },
6157			{ "Headphone", 0x6 },
6158			{ "Mixer", 0x5 },
6159		},
6160	},
6161};
6162
6163/* Maxdata Favorit 100XS */
6164static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
6165	{
6166		.num_items = 2,
6167		.items = {
6168			{ "Line/Mic", 0x0 },
6169			{ "CD", 0x4 },
6170		},
6171	},
6172	{
6173		.num_items = 3,
6174		.items = {
6175			{ "Line/Mic", 0x0 },
6176			{ "CD", 0x4 },
6177			{ "Mixer", 0x5 },
6178		},
6179	},
6180};
6181
6182/*
6183 * This is just place-holder, so there's something for alc_build_pcms to look
6184 * at when it calculates the maximum number of channels. ALC260 has no mixer
6185 * element which allows changing the channel mode, so the verb list is
6186 * never used.
6187 */
6188static const struct hda_channel_mode alc260_modes[1] = {
6189	{ 2, NULL },
6190};
6191
6192
6193/* Mixer combinations
6194 *
6195 * basic: base_output + input + pc_beep + capture
6196 * HP: base_output + input + capture_alt
6197 * HP_3013: hp_3013 + input + capture
6198 * fujitsu: fujitsu + capture
6199 * acer: acer + capture
6200 */
6201
6202static const struct snd_kcontrol_new alc260_base_output_mixer[] = {
6203	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6204	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6205	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6206	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6207	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6208	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6209	{ } /* end */
6210};
6211
6212static const struct snd_kcontrol_new alc260_input_mixer[] = {
6213	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6214	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6215	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6216	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6217	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6218	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6219	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
6220	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
6221	{ } /* end */
6222};
6223
6224/* update HP, line and mono out pins according to the master switch */
6225static void alc260_hp_master_update(struct hda_codec *codec)
6226{
6227	update_speakers(codec);
6228}
6229
6230static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
6231				   struct snd_ctl_elem_value *ucontrol)
6232{
6233	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6234	struct alc_spec *spec = codec->spec;
6235	*ucontrol->value.integer.value = !spec->master_mute;
6236	return 0;
6237}
6238
6239static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
6240				   struct snd_ctl_elem_value *ucontrol)
6241{
6242	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6243	struct alc_spec *spec = codec->spec;
6244	int val = !*ucontrol->value.integer.value;
6245
6246	if (val == spec->master_mute)
6247		return 0;
6248	spec->master_mute = val;
6249	alc260_hp_master_update(codec);
6250	return 1;
6251}
6252
6253static const struct snd_kcontrol_new alc260_hp_output_mixer[] = {
6254	{
6255		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6256		.name = "Master Playback Switch",
6257		.subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
6258		.info = snd_ctl_boolean_mono_info,
6259		.get = alc260_hp_master_sw_get,
6260		.put = alc260_hp_master_sw_put,
6261	},
6262	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6263	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6264	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6265	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6266	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6267			      HDA_OUTPUT),
6268	HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6269	{ } /* end */
6270};
6271
6272static const struct hda_verb alc260_hp_unsol_verbs[] = {
6273	{0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6274	{},
6275};
6276
6277static void alc260_hp_setup(struct hda_codec *codec)
6278{
6279	struct alc_spec *spec = codec->spec;
6280
6281	spec->autocfg.hp_pins[0] = 0x0f;
6282	spec->autocfg.speaker_pins[0] = 0x10;
6283	spec->autocfg.speaker_pins[1] = 0x11;
6284	spec->automute = 1;
6285	spec->automute_mode = ALC_AUTOMUTE_PIN;
6286}
6287
6288static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
6289	{
6290		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6291		.name = "Master Playback Switch",
6292		.subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
6293		.info = snd_ctl_boolean_mono_info,
6294		.get = alc260_hp_master_sw_get,
6295		.put = alc260_hp_master_sw_put,
6296	},
6297	HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6298	HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6299	HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
6300	HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
6301	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6302	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6303	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6304	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
6305	{ } /* end */
6306};
6307
6308static void alc260_hp_3013_setup(struct hda_codec *codec)
6309{
6310	struct alc_spec *spec = codec->spec;
6311
6312	spec->autocfg.hp_pins[0] = 0x15;
6313	spec->autocfg.speaker_pins[0] = 0x10;
6314	spec->autocfg.speaker_pins[1] = 0x11;
6315	spec->automute = 1;
6316	spec->automute_mode = ALC_AUTOMUTE_PIN;
6317}
6318
6319static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
6320	.ops = &snd_hda_bind_vol,
6321	.values = {
6322		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
6323		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
6324		HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6325		0
6326	},
6327};
6328
6329static const struct hda_bind_ctls alc260_dc7600_bind_switch = {
6330	.ops = &snd_hda_bind_sw,
6331	.values = {
6332		HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6333		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6334		0
6335	},
6336};
6337
6338static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
6339	HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6340	HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6341	HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6342	HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6343	{ } /* end */
6344};
6345
6346static const struct hda_verb alc260_hp_3013_unsol_verbs[] = {
6347	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6348	{},
6349};
6350
6351static void alc260_hp_3012_setup(struct hda_codec *codec)
6352{
6353	struct alc_spec *spec = codec->spec;
6354
6355	spec->autocfg.hp_pins[0] = 0x10;
6356	spec->autocfg.speaker_pins[0] = 0x0f;
6357	spec->autocfg.speaker_pins[1] = 0x11;
6358	spec->autocfg.speaker_pins[2] = 0x15;
6359	spec->automute = 1;
6360	spec->automute_mode = ALC_AUTOMUTE_PIN;
6361}
6362
6363/* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12,
6364 * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
6365 */
6366static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
6367	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6368	HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
6369	ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6370	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6371	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6372	HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6373	HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
6374	ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
6375	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6376	HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
6377	{ } /* end */
6378};
6379
6380/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
6381 * versions of the ALC260 don't act on requests to enable mic bias from NID
6382 * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
6383 * datasheet doesn't mention this restriction.  At this stage it's not clear
6384 * whether this behaviour is intentional or is a hardware bug in chip
6385 * revisions available in early 2006.  Therefore for now allow the
6386 * "Headphone Jack Mode" control to span all choices, but if it turns out
6387 * that the lack of mic bias for this NID is intentional we could change the
6388 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6389 *
6390 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6391 * don't appear to make the mic bias available from the "line" jack, even
6392 * though the NID used for this jack (0x14) can supply it.  The theory is
6393 * that perhaps Acer have included blocking capacitors between the ALC260
6394 * and the output jack.  If this turns out to be the case for all such
6395 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6396 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
6397 *
6398 * The C20x Tablet series have a mono internal speaker which is controlled
6399 * via the chip's Mono sum widget and pin complex, so include the necessary
6400 * controls for such models.  On models without a "mono speaker" the control
6401 * won't do anything.
6402 */
6403static const struct snd_kcontrol_new alc260_acer_mixer[] = {
6404	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6405	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6406	ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6407	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6408			      HDA_OUTPUT),
6409	HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
6410			   HDA_INPUT),
6411	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6412	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6413	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6414	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6415	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6416	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6417	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6418	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6419	{ } /* end */
6420};
6421
6422/* Maxdata Favorit 100XS: one output and one input (0x12) jack
6423 */
6424static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
6425	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6426	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6427	ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6428	HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6429	HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6430	ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6431	{ } /* end */
6432};
6433
6434/* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6435 * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
6436 */
6437static const struct snd_kcontrol_new alc260_will_mixer[] = {
6438	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6439	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6440	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6441	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6442	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6443	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6444	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6445	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6446	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6447	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6448	{ } /* end */
6449};
6450
6451/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6452 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6453 */
6454static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6455	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6456	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6457	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6458	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6459	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6460	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6461	HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6462	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6463	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6464	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6465	{ } /* end */
6466};
6467
6468/*
6469 * initialization verbs
6470 */
6471static const struct hda_verb alc260_init_verbs[] = {
6472	/* Line In pin widget for input */
6473	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6474	/* CD pin widget for input */
6475	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6476	/* Mic1 (rear panel) pin widget for input and vref at 80% */
6477	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6478	/* Mic2 (front panel) pin widget for input and vref at 80% */
6479	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6480	/* LINE-2 is used for line-out in rear */
6481	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6482	/* select line-out */
6483	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
6484	/* LINE-OUT pin */
6485	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6486	/* enable HP */
6487	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6488	/* enable Mono */
6489	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6490	/* mute capture amp left and right */
6491	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6492	/* set connection select to line in (default select for this ADC) */
6493	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6494	/* mute capture amp left and right */
6495	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6496	/* set connection select to line in (default select for this ADC) */
6497	{0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
6498	/* set vol=0 Line-Out mixer amp left and right */
6499	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6500	/* unmute pin widget amp left and right (no gain on this amp) */
6501	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6502	/* set vol=0 HP mixer amp left and right */
6503	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6504	/* unmute pin widget amp left and right (no gain on this amp) */
6505	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6506	/* set vol=0 Mono mixer amp left and right */
6507	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6508	/* unmute pin widget amp left and right (no gain on this amp) */
6509	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6510	/* unmute LINE-2 out pin */
6511	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6512	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6513	 * Line In 2 = 0x03
6514	 */
6515	/* mute analog inputs */
6516	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6517	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6518	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6519	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6520	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6521	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6522	/* mute Front out path */
6523	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6524	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6525	/* mute Headphone out path */
6526	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6527	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6528	/* mute Mono out path */
6529	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6530	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6531	{ }
6532};
6533
6534#if 0 /* should be identical with alc260_init_verbs? */
6535static const struct hda_verb alc260_hp_init_verbs[] = {
6536	/* Headphone and output */
6537	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6538	/* mono output */
6539	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6540	/* Mic1 (rear panel) pin widget for input and vref at 80% */
6541	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6542	/* Mic2 (front panel) pin widget for input and vref at 80% */
6543	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6544	/* Line In pin widget for input */
6545	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6546	/* Line-2 pin widget for output */
6547	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6548	/* CD pin widget for input */
6549	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6550	/* unmute amp left and right */
6551	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6552	/* set connection select to line in (default select for this ADC) */
6553	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6554	/* unmute Line-Out mixer amp left and right (volume = 0) */
6555	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6556	/* mute pin widget amp left and right (no gain on this amp) */
6557	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6558	/* unmute HP mixer amp left and right (volume = 0) */
6559	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6560	/* mute pin widget amp left and right (no gain on this amp) */
6561	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6562	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6563	 * Line In 2 = 0x03
6564	 */
6565	/* mute analog inputs */
6566	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6567	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6568	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6569	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6570	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6571	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6572	/* Unmute Front out path */
6573	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6574	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6575	/* Unmute Headphone out path */
6576	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6577	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6578	/* Unmute Mono out path */
6579	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6580	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6581	{ }
6582};
6583#endif
6584
6585static const struct hda_verb alc260_hp_3013_init_verbs[] = {
6586	/* Line out and output */
6587	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6588	/* mono output */
6589	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6590	/* Mic1 (rear panel) pin widget for input and vref at 80% */
6591	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6592	/* Mic2 (front panel) pin widget for input and vref at 80% */
6593	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6594	/* Line In pin widget for input */
6595	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6596	/* Headphone pin widget for output */
6597	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6598	/* CD pin widget for input */
6599	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6600	/* unmute amp left and right */
6601	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6602	/* set connection select to line in (default select for this ADC) */
6603	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6604	/* unmute Line-Out mixer amp left and right (volume = 0) */
6605	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6606	/* mute pin widget amp left and right (no gain on this amp) */
6607	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6608	/* unmute HP mixer amp left and right (volume = 0) */
6609	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6610	/* mute pin widget amp left and right (no gain on this amp) */
6611	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6612	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6613	 * Line In 2 = 0x03
6614	 */
6615	/* mute analog inputs */
6616	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6617	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6618	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6619	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6620	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6621	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6622	/* Unmute Front out path */
6623	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6624	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6625	/* Unmute Headphone out path */
6626	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6627	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6628	/* Unmute Mono out path */
6629	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6630	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6631	{ }
6632};
6633
6634/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
6635 * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6636 * audio = 0x16, internal speaker = 0x10.
6637 */
6638static const struct hda_verb alc260_fujitsu_init_verbs[] = {
6639	/* Disable all GPIOs */
6640	{0x01, AC_VERB_SET_GPIO_MASK, 0},
6641	/* Internal speaker is connected to headphone pin */
6642	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6643	/* Headphone/Line-out jack connects to Line1 pin; make it an output */
6644	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6645	/* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6646	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6647	/* Ensure all other unused pins are disabled and muted. */
6648	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6649	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6650	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6651	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6652	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6653	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6654	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6655	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6656
6657	/* Disable digital (SPDIF) pins */
6658	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6659	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6660
6661	/* Ensure Line1 pin widget takes its input from the OUT1 sum bus
6662	 * when acting as an output.
6663	 */
6664	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6665
6666	/* Start with output sum widgets muted and their output gains at min */
6667	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6668	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6669	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6670	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6671	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6672	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6673	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6674	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6675	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6676
6677	/* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6678	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6679	/* Unmute Line1 pin widget output buffer since it starts as an output.
6680	 * If the pin mode is changed by the user the pin mode control will
6681	 * take care of enabling the pin's input/output buffers as needed.
6682	 * Therefore there's no need to enable the input buffer at this
6683	 * stage.
6684	 */
6685	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6686	/* Unmute input buffer of pin widget used for Line-in (no equiv
6687	 * mixer ctrl)
6688	 */
6689	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6690
6691	/* Mute capture amp left and right */
6692	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6693	/* Set ADC connection select to match default mixer setting - line
6694	 * in (on mic1 pin)
6695	 */
6696	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6697
6698	/* Do the same for the second ADC: mute capture input amp and
6699	 * set ADC connection to line in (on mic1 pin)
6700	 */
6701	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6702	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6703
6704	/* Mute all inputs to mixer widget (even unconnected ones) */
6705	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6706	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6707	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6708	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6709	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6710	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6711	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6712	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6713
6714	{ }
6715};
6716
6717/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6718 * similar laptops (adapted from Fujitsu init verbs).
6719 */
6720static const struct hda_verb alc260_acer_init_verbs[] = {
6721	/* On TravelMate laptops, GPIO 0 enables the internal speaker and
6722	 * the headphone jack.  Turn this on and rely on the standard mute
6723	 * methods whenever the user wants to turn these outputs off.
6724	 */
6725	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6726	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6727	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6728	/* Internal speaker/Headphone jack is connected to Line-out pin */
6729	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6730	/* Internal microphone/Mic jack is connected to Mic1 pin */
6731	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6732	/* Line In jack is connected to Line1 pin */
6733	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6734	/* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6735	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6736	/* Ensure all other unused pins are disabled and muted. */
6737	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6738	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6739	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6740	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6741	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6742	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6743	/* Disable digital (SPDIF) pins */
6744	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6745	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6746
6747	/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6748	 * bus when acting as outputs.
6749	 */
6750	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6751	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6752
6753	/* Start with output sum widgets muted and their output gains at min */
6754	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6755	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6756	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6757	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6758	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6759	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6760	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6761	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6762	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6763
6764	/* Unmute Line-out pin widget amp left and right
6765	 * (no equiv mixer ctrl)
6766	 */
6767	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6768	/* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6769	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6770	/* Unmute Mic1 and Line1 pin widget input buffers since they start as
6771	 * inputs. If the pin mode is changed by the user the pin mode control
6772	 * will take care of enabling the pin's input/output buffers as needed.
6773	 * Therefore there's no need to enable the input buffer at this
6774	 * stage.
6775	 */
6776	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6777	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6778
6779	/* Mute capture amp left and right */
6780	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6781	/* Set ADC connection select to match default mixer setting - mic
6782	 * (on mic1 pin)
6783	 */
6784	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6785
6786	/* Do similar with the second ADC: mute capture input amp and
6787	 * set ADC connection to mic to match ALSA's default state.
6788	 */
6789	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6790	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6791
6792	/* Mute all inputs to mixer widget (even unconnected ones) */
6793	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6794	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6795	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6796	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6797	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6798	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6799	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6800	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6801
6802	{ }
6803};
6804
6805/* Initialisation sequence for Maxdata Favorit 100XS
6806 * (adapted from Acer init verbs).
6807 */
6808static const struct hda_verb alc260_favorit100_init_verbs[] = {
6809	/* GPIO 0 enables the output jack.
6810	 * Turn this on and rely on the standard mute
6811	 * methods whenever the user wants to turn these outputs off.
6812	 */
6813	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6814	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6815	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6816	/* Line/Mic input jack is connected to Mic1 pin */
6817	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6818	/* Ensure all other unused pins are disabled and muted. */
6819	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6820	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6821	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6822	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6823	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6824	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6825	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6826	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6827	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6828	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6829	/* Disable digital (SPDIF) pins */
6830	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6831	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6832
6833	/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6834	 * bus when acting as outputs.
6835	 */
6836	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6837	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6838
6839	/* Start with output sum widgets muted and their output gains at min */
6840	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6841	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6842	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6843	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6844	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6845	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6846	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6847	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6848	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6849
6850	/* Unmute Line-out pin widget amp left and right
6851	 * (no equiv mixer ctrl)
6852	 */
6853	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6854	/* Unmute Mic1 and Line1 pin widget input buffers since they start as
6855	 * inputs. If the pin mode is changed by the user the pin mode control
6856	 * will take care of enabling the pin's input/output buffers as needed.
6857	 * Therefore there's no need to enable the input buffer at this
6858	 * stage.
6859	 */
6860	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6861
6862	/* Mute capture amp left and right */
6863	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6864	/* Set ADC connection select to match default mixer setting - mic
6865	 * (on mic1 pin)
6866	 */
6867	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6868
6869	/* Do similar with the second ADC: mute capture input amp and
6870	 * set ADC connection to mic to match ALSA's default state.
6871	 */
6872	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6873	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6874
6875	/* Mute all inputs to mixer widget (even unconnected ones) */
6876	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6877	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6878	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6879	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6880	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6881	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6882	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6883	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6884
6885	{ }
6886};
6887
6888static const struct hda_verb alc260_will_verbs[] = {
6889	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6890	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6891	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6892	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6893	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6894	{0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6895	{}
6896};
6897
6898static const struct hda_verb alc260_replacer_672v_verbs[] = {
6899	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6900	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6901	{0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6902
6903	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6904	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6905	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6906
6907	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6908	{}
6909};
6910
6911/* toggle speaker-output according to the hp-jack state */
6912static void alc260_replacer_672v_automute(struct hda_codec *codec)
6913{
6914        unsigned int present;
6915
6916	/* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
6917	present = snd_hda_jack_detect(codec, 0x0f);
6918	if (present) {
6919		snd_hda_codec_write_cache(codec, 0x01, 0,
6920					  AC_VERB_SET_GPIO_DATA, 1);
6921		snd_hda_codec_write_cache(codec, 0x0f, 0,
6922					  AC_VERB_SET_PIN_WIDGET_CONTROL,
6923					  PIN_HP);
6924	} else {
6925		snd_hda_codec_write_cache(codec, 0x01, 0,
6926					  AC_VERB_SET_GPIO_DATA, 0);
6927		snd_hda_codec_write_cache(codec, 0x0f, 0,
6928					  AC_VERB_SET_PIN_WIDGET_CONTROL,
6929					  PIN_OUT);
6930	}
6931}
6932
6933static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6934                                       unsigned int res)
6935{
6936        if ((res >> 26) == ALC880_HP_EVENT)
6937                alc260_replacer_672v_automute(codec);
6938}
6939
6940static const struct hda_verb alc260_hp_dc7600_verbs[] = {
6941	{0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6942	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6943	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6944	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6945	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6946	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6947	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6948	{0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6949	{0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6950	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6951	{}
6952};
6953
6954/* Test configuration for debugging, modelled after the ALC880 test
6955 * configuration.
6956 */
6957#ifdef CONFIG_SND_DEBUG
6958static const hda_nid_t alc260_test_dac_nids[1] = {
6959	0x02,
6960};
6961static const hda_nid_t alc260_test_adc_nids[2] = {
6962	0x04, 0x05,
6963};
6964/* For testing the ALC260, each input MUX needs its own definition since
6965 * the signal assignments are different.  This assumes that the first ADC
6966 * is NID 0x04.
6967 */
6968static const struct hda_input_mux alc260_test_capture_sources[2] = {
6969	{
6970		.num_items = 7,
6971		.items = {
6972			{ "MIC1 pin", 0x0 },
6973			{ "MIC2 pin", 0x1 },
6974			{ "LINE1 pin", 0x2 },
6975			{ "LINE2 pin", 0x3 },
6976			{ "CD pin", 0x4 },
6977			{ "LINE-OUT pin", 0x5 },
6978			{ "HP-OUT pin", 0x6 },
6979		},
6980        },
6981	{
6982		.num_items = 8,
6983		.items = {
6984			{ "MIC1 pin", 0x0 },
6985			{ "MIC2 pin", 0x1 },
6986			{ "LINE1 pin", 0x2 },
6987			{ "LINE2 pin", 0x3 },
6988			{ "CD pin", 0x4 },
6989			{ "Mixer", 0x5 },
6990			{ "LINE-OUT pin", 0x6 },
6991			{ "HP-OUT pin", 0x7 },
6992		},
6993        },
6994};
6995static const struct snd_kcontrol_new alc260_test_mixer[] = {
6996	/* Output driver widgets */
6997	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6998	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6999	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
7000	HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
7001	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
7002	HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
7003
7004	/* Modes for retasking pin widgets
7005	 * Note: the ALC260 doesn't seem to act on requests to enable mic
7006         * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
7007         * mention this restriction.  At this stage it's not clear whether
7008         * this behaviour is intentional or is a hardware bug in chip
7009         * revisions available at least up until early 2006.  Therefore for
7010         * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
7011         * choices, but if it turns out that the lack of mic bias for these
7012         * NIDs is intentional we could change their modes from
7013         * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
7014	 */
7015	ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
7016	ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
7017	ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
7018	ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
7019	ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
7020	ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
7021
7022	/* Loopback mixer controls */
7023	HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
7024	HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
7025	HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
7026	HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
7027	HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
7028	HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
7029	HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
7030	HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
7031	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
7032	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7033	HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
7034	HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
7035	HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
7036	HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
7037
7038	/* Controls for GPIO pins, assuming they are configured as outputs */
7039	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
7040	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
7041	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
7042	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
7043
7044	/* Switches to allow the digital IO pins to be enabled.  The datasheet
7045	 * is ambigious as to which NID is which; testing on laptops which
7046	 * make this output available should provide clarification.
7047	 */
7048	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
7049	ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
7050
7051	/* A switch allowing EAPD to be enabled.  Some laptops seem to use
7052	 * this output to turn on an external amplifier.
7053	 */
7054	ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
7055	ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
7056
7057	{ } /* end */
7058};
7059static const struct hda_verb alc260_test_init_verbs[] = {
7060	/* Enable all GPIOs as outputs with an initial value of 0 */
7061	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
7062	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
7063	{0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
7064
7065	/* Enable retasking pins as output, initially without power amp */
7066	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7067	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7068	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7069	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7070	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7071	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7072
7073	/* Disable digital (SPDIF) pins initially, but users can enable
7074	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
7075	 * payload also sets the generation to 0, output to be in "consumer"
7076	 * PCM format, copyright asserted, no pre-emphasis and no validity
7077	 * control.
7078	 */
7079	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
7080	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
7081
7082	/* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7083	 * OUT1 sum bus when acting as an output.
7084	 */
7085	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
7086	{0x0c, AC_VERB_SET_CONNECT_SEL, 0},
7087	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
7088	{0x0e, AC_VERB_SET_CONNECT_SEL, 0},
7089
7090	/* Start with output sum widgets muted and their output gains at min */
7091	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7092	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7093	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7094	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7095	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7096	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7097	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7098	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7099	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7100
7101	/* Unmute retasking pin widget output buffers since the default
7102	 * state appears to be output.  As the pin mode is changed by the
7103	 * user the pin mode control will take care of enabling the pin's
7104	 * input/output buffers as needed.
7105	 */
7106	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7107	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7108	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7109	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7110	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7111	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7112	/* Also unmute the mono-out pin widget */
7113	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7114
7115	/* Mute capture amp left and right */
7116	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7117	/* Set ADC connection select to match default mixer setting (mic1
7118	 * pin)
7119	 */
7120	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7121
7122	/* Do the same for the second ADC: mute capture input amp and
7123	 * set ADC connection to mic1 pin
7124	 */
7125	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7126	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7127
7128	/* Mute all inputs to mixer widget (even unconnected ones) */
7129	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
7130	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
7131	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
7132	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
7133	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
7134	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
7135	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
7136	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
7137
7138	{ }
7139};
7140#endif
7141
7142#define alc260_pcm_analog_playback	alc880_pcm_analog_alt_playback
7143#define alc260_pcm_analog_capture	alc880_pcm_analog_capture
7144
7145#define alc260_pcm_digital_playback	alc880_pcm_digital_playback
7146#define alc260_pcm_digital_capture	alc880_pcm_digital_capture
7147
7148/*
7149 * for BIOS auto-configuration
7150 */
7151
7152static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
7153					const char *pfx, int *vol_bits)
7154{
7155	hda_nid_t nid_vol;
7156	unsigned long vol_val, sw_val;
7157	int err;
7158
7159	if (nid >= 0x0f && nid < 0x11) {
7160		nid_vol = nid - 0x7;
7161		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
7162		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
7163	} else if (nid == 0x11) {
7164		nid_vol = nid - 0x7;
7165		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
7166		sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
7167	} else if (nid >= 0x12 && nid <= 0x15) {
7168		nid_vol = 0x08;
7169		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
7170		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
7171	} else
7172		return 0; /* N/A */
7173
7174	if (!(*vol_bits & (1 << nid_vol))) {
7175		/* first control for the volume widget */
7176		err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
7177		if (err < 0)
7178			return err;
7179		*vol_bits |= (1 << nid_vol);
7180	}
7181	err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
7182	if (err < 0)
7183		return err;
7184	return 1;
7185}
7186
7187/* add playback controls from the parsed DAC table */
7188static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
7189					     const struct auto_pin_cfg *cfg)
7190{
7191	hda_nid_t nid;
7192	int err;
7193	int vols = 0;
7194
7195	spec->multiout.num_dacs = 1;
7196	spec->multiout.dac_nids = spec->private_dac_nids;
7197	spec->private_dac_nids[0] = 0x02;
7198
7199	nid = cfg->line_out_pins[0];
7200	if (nid) {
7201		const char *pfx;
7202		if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
7203			pfx = "Master";
7204		else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
7205			pfx = "Speaker";
7206		else
7207			pfx = "Front";
7208		err = alc260_add_playback_controls(spec, nid, pfx, &vols);
7209		if (err < 0)
7210			return err;
7211	}
7212
7213	nid = cfg->speaker_pins[0];
7214	if (nid) {
7215		err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
7216		if (err < 0)
7217			return err;
7218	}
7219
7220	nid = cfg->hp_pins[0];
7221	if (nid) {
7222		err = alc260_add_playback_controls(spec, nid, "Headphone",
7223						   &vols);
7224		if (err < 0)
7225			return err;
7226	}
7227	return 0;
7228}
7229
7230/* create playback/capture controls for input pins */
7231static int alc260_auto_create_input_ctls(struct hda_codec *codec,
7232						const struct auto_pin_cfg *cfg)
7233{
7234	return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
7235}
7236
7237static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
7238					      hda_nid_t nid, int pin_type,
7239					      int sel_idx)
7240{
7241	alc_set_pin_output(codec, nid, pin_type);
7242	/* need the manual connection? */
7243	if (nid >= 0x12) {
7244		int idx = nid - 0x12;
7245		snd_hda_codec_write(codec, idx + 0x0b, 0,
7246				    AC_VERB_SET_CONNECT_SEL, sel_idx);
7247	}
7248}
7249
7250static void alc260_auto_init_multi_out(struct hda_codec *codec)
7251{
7252	struct alc_spec *spec = codec->spec;
7253	hda_nid_t nid;
7254
7255	nid = spec->autocfg.line_out_pins[0];
7256	if (nid) {
7257		int pin_type = get_pin_type(spec->autocfg.line_out_type);
7258		alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
7259	}
7260
7261	nid = spec->autocfg.speaker_pins[0];
7262	if (nid)
7263		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
7264
7265	nid = spec->autocfg.hp_pins[0];
7266	if (nid)
7267		alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
7268}
7269
7270#define ALC260_PIN_CD_NID		0x16
7271static void alc260_auto_init_analog_input(struct hda_codec *codec)
7272{
7273	struct alc_spec *spec = codec->spec;
7274	struct auto_pin_cfg *cfg = &spec->autocfg;
7275	int i;
7276
7277	for (i = 0; i < cfg->num_inputs; i++) {
7278		hda_nid_t nid = cfg->inputs[i].pin;
7279		if (nid >= 0x12) {
7280			alc_set_input_pin(codec, nid, cfg->inputs[i].type);
7281			if (nid != ALC260_PIN_CD_NID &&
7282			    (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
7283				snd_hda_codec_write(codec, nid, 0,
7284						    AC_VERB_SET_AMP_GAIN_MUTE,
7285						    AMP_OUT_MUTE);
7286		}
7287	}
7288}
7289
7290#define alc260_auto_init_input_src	alc880_auto_init_input_src
7291
7292/*
7293 * generic initialization of ADC, input mixers and output mixers
7294 */
7295static const struct hda_verb alc260_volume_init_verbs[] = {
7296	/*
7297	 * Unmute ADC0-1 and set the default input to mic-in
7298	 */
7299	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7300	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7301	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7302	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7303
7304	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7305	 * mixer widget
7306	 * Note: PASD motherboards uses the Line In 2 as the input for
7307	 * front panel mic (mic 2)
7308	 */
7309	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7310	/* mute analog inputs */
7311	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7312	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7313	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7314	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7315	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7316
7317	/*
7318	 * Set up output mixers (0x08 - 0x0a)
7319	 */
7320	/* set vol=0 to output mixers */
7321	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7322	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7323	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7324	/* set up input amps for analog loopback */
7325	/* Amp Indices: DAC = 0, mixer = 1 */
7326	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7327	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7328	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7329	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7330	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7331	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7332
7333	{ }
7334};
7335
7336static int alc260_parse_auto_config(struct hda_codec *codec)
7337{
7338	struct alc_spec *spec = codec->spec;
7339	int err;
7340	static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
7341
7342	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7343					   alc260_ignore);
7344	if (err < 0)
7345		return err;
7346	err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7347	if (err < 0)
7348		return err;
7349	if (!spec->kctls.list)
7350		return 0; /* can't find valid BIOS pin config */
7351	err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
7352	if (err < 0)
7353		return err;
7354
7355	spec->multiout.max_channels = 2;
7356
7357	if (spec->autocfg.dig_outs)
7358		spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
7359	if (spec->kctls.list)
7360		add_mixer(spec, spec->kctls.list);
7361
7362	add_verb(spec, alc260_volume_init_verbs);
7363
7364	spec->num_mux_defs = 1;
7365	spec->input_mux = &spec->private_imux[0];
7366
7367	alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
7368
7369	return 1;
7370}
7371
7372/* additional initialization for auto-configuration model */
7373static void alc260_auto_init(struct hda_codec *codec)
7374{
7375	struct alc_spec *spec = codec->spec;
7376	alc260_auto_init_multi_out(codec);
7377	alc260_auto_init_analog_input(codec);
7378	alc260_auto_init_input_src(codec);
7379	alc_auto_init_digital(codec);
7380	if (spec->unsol_event)
7381		alc_inithook(codec);
7382}
7383
7384#ifdef CONFIG_SND_HDA_POWER_SAVE
7385static const struct hda_amp_list alc260_loopbacks[] = {
7386	{ 0x07, HDA_INPUT, 0 },
7387	{ 0x07, HDA_INPUT, 1 },
7388	{ 0x07, HDA_INPUT, 2 },
7389	{ 0x07, HDA_INPUT, 3 },
7390	{ 0x07, HDA_INPUT, 4 },
7391	{ } /* end */
7392};
7393#endif
7394
7395/*
7396 * Pin config fixes
7397 */
7398enum {
7399	PINFIX_HP_DC5750,
7400};
7401
7402static const struct alc_fixup alc260_fixups[] = {
7403	[PINFIX_HP_DC5750] = {
7404		.type = ALC_FIXUP_PINS,
7405		.v.pins = (const struct alc_pincfg[]) {
7406			{ 0x11, 0x90130110 }, /* speaker */
7407			{ }
7408		}
7409	},
7410};
7411
7412static const struct snd_pci_quirk alc260_fixup_tbl[] = {
7413	SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7414	{}
7415};
7416
7417/*
7418 * ALC260 configurations
7419 */
7420static const char * const alc260_models[ALC260_MODEL_LAST] = {
7421	[ALC260_BASIC]		= "basic",
7422	[ALC260_HP]		= "hp",
7423	[ALC260_HP_3013]	= "hp-3013",
7424	[ALC260_HP_DC7600]	= "hp-dc7600",
7425	[ALC260_FUJITSU_S702X]	= "fujitsu",
7426	[ALC260_ACER]		= "acer",
7427	[ALC260_WILL]		= "will",
7428	[ALC260_REPLACER_672V]	= "replacer",
7429	[ALC260_FAVORIT100]	= "favorit100",
7430#ifdef CONFIG_SND_DEBUG
7431	[ALC260_TEST]		= "test",
7432#endif
7433	[ALC260_AUTO]		= "auto",
7434};
7435
7436static const struct snd_pci_quirk alc260_cfg_tbl[] = {
7437	SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
7438	SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
7439	SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
7440	SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
7441	SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
7442	SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
7443	SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
7444	SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
7445	SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
7446	SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7447	SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7448	SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7449	SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7450	SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7451	SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7452	SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7453	SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7454	SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
7455	SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
7456	SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
7457	{}
7458};
7459
7460static const struct alc_config_preset alc260_presets[] = {
7461	[ALC260_BASIC] = {
7462		.mixers = { alc260_base_output_mixer,
7463			    alc260_input_mixer },
7464		.init_verbs = { alc260_init_verbs },
7465		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
7466		.dac_nids = alc260_dac_nids,
7467		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7468		.adc_nids = alc260_dual_adc_nids,
7469		.num_channel_mode = ARRAY_SIZE(alc260_modes),
7470		.channel_mode = alc260_modes,
7471		.input_mux = &alc260_capture_source,
7472	},
7473	[ALC260_HP] = {
7474		.mixers = { alc260_hp_output_mixer,
7475			    alc260_input_mixer },
7476		.init_verbs = { alc260_init_verbs,
7477				alc260_hp_unsol_verbs },
7478		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
7479		.dac_nids = alc260_dac_nids,
7480		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7481		.adc_nids = alc260_adc_nids_alt,
7482		.num_channel_mode = ARRAY_SIZE(alc260_modes),
7483		.channel_mode = alc260_modes,
7484		.input_mux = &alc260_capture_source,
7485		.unsol_event = alc_sku_unsol_event,
7486		.setup = alc260_hp_setup,
7487		.init_hook = alc_inithook,
7488	},
7489	[ALC260_HP_DC7600] = {
7490		.mixers = { alc260_hp_dc7600_mixer,
7491			    alc260_input_mixer },
7492		.init_verbs = { alc260_init_verbs,
7493				alc260_hp_dc7600_verbs },
7494		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
7495		.dac_nids = alc260_dac_nids,
7496		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7497		.adc_nids = alc260_adc_nids_alt,
7498		.num_channel_mode = ARRAY_SIZE(alc260_modes),
7499		.channel_mode = alc260_modes,
7500		.input_mux = &alc260_capture_source,
7501		.unsol_event = alc_sku_unsol_event,
7502		.setup = alc260_hp_3012_setup,
7503		.init_hook = alc_inithook,
7504	},
7505	[ALC260_HP_3013] = {
7506		.mixers = { alc260_hp_3013_mixer,
7507			    alc260_input_mixer },
7508		.init_verbs = { alc260_hp_3013_init_verbs,
7509				alc260_hp_3013_unsol_verbs },
7510		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
7511		.dac_nids = alc260_dac_nids,
7512		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7513		.adc_nids = alc260_adc_nids_alt,
7514		.num_channel_mode = ARRAY_SIZE(alc260_modes),
7515		.channel_mode = alc260_modes,
7516		.input_mux = &alc260_capture_source,
7517		.unsol_event = alc_sku_unsol_event,
7518		.setup = alc260_hp_3013_setup,
7519		.init_hook = alc_inithook,
7520	},
7521	[ALC260_FUJITSU_S702X] = {
7522		.mixers = { alc260_fujitsu_mixer },
7523		.init_verbs = { alc260_fujitsu_init_verbs },
7524		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
7525		.dac_nids = alc260_dac_nids,
7526		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7527		.adc_nids = alc260_dual_adc_nids,
7528		.num_channel_mode = ARRAY_SIZE(alc260_modes),
7529		.channel_mode = alc260_modes,
7530		.num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7531		.input_mux = alc260_fujitsu_capture_sources,
7532	},
7533	[ALC260_ACER] = {
7534		.mixers = { alc260_acer_mixer },
7535		.init_verbs = { alc260_acer_init_verbs },
7536		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
7537		.dac_nids = alc260_dac_nids,
7538		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7539		.adc_nids = alc260_dual_adc_nids,
7540		.num_channel_mode = ARRAY_SIZE(alc260_modes),
7541		.channel_mode = alc260_modes,
7542		.num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7543		.input_mux = alc260_acer_capture_sources,
7544	},
7545	[ALC260_FAVORIT100] = {
7546		.mixers = { alc260_favorit100_mixer },
7547		.init_verbs = { alc260_favorit100_init_verbs },
7548		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
7549		.dac_nids = alc260_dac_nids,
7550		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7551		.adc_nids = alc260_dual_adc_nids,
7552		.num_channel_mode = ARRAY_SIZE(alc260_modes),
7553		.channel_mode = alc260_modes,
7554		.num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7555		.input_mux = alc260_favorit100_capture_sources,
7556	},
7557	[ALC260_WILL] = {
7558		.mixers = { alc260_will_mixer },
7559		.init_verbs = { alc260_init_verbs, alc260_will_verbs },
7560		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
7561		.dac_nids = alc260_dac_nids,
7562		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7563		.adc_nids = alc260_adc_nids,
7564		.dig_out_nid = ALC260_DIGOUT_NID,
7565		.num_channel_mode = ARRAY_SIZE(alc260_modes),
7566		.channel_mode = alc260_modes,
7567		.input_mux = &alc260_capture_source,
7568	},
7569	[ALC260_REPLACER_672V] = {
7570		.mixers = { alc260_replacer_672v_mixer },
7571		.init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7572		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
7573		.dac_nids = alc260_dac_nids,
7574		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7575		.adc_nids = alc260_adc_nids,
7576		.dig_out_nid = ALC260_DIGOUT_NID,
7577		.num_channel_mode = ARRAY_SIZE(alc260_modes),
7578		.channel_mode = alc260_modes,
7579		.input_mux = &alc260_capture_source,
7580		.unsol_event = alc260_replacer_672v_unsol_event,
7581		.init_hook = alc260_replacer_672v_automute,
7582	},
7583#ifdef CONFIG_SND_DEBUG
7584	[ALC260_TEST] = {
7585		.mixers = { alc260_test_mixer },
7586		.init_verbs = { alc260_test_init_verbs },
7587		.num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7588		.dac_nids = alc260_test_dac_nids,
7589		.num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7590		.adc_nids = alc260_test_adc_nids,
7591		.num_channel_mode = ARRAY_SIZE(alc260_modes),
7592		.channel_mode = alc260_modes,
7593		.num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7594		.input_mux = alc260_test_capture_sources,
7595	},
7596#endif
7597};
7598
7599static int patch_alc260(struct hda_codec *codec)
7600{
7601	struct alc_spec *spec;
7602	int err, board_config;
7603
7604	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7605	if (spec == NULL)
7606		return -ENOMEM;
7607
7608	codec->spec = spec;
7609
7610	board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7611						  alc260_models,
7612						  alc260_cfg_tbl);
7613	if (board_config < 0) {
7614		snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
7615			   codec->chip_name);
7616		board_config = ALC260_AUTO;
7617	}
7618
7619	if (board_config == ALC260_AUTO) {
7620		alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7621		alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7622	}
7623
7624	if (board_config == ALC260_AUTO) {
7625		/* automatic parse from the BIOS config */
7626		err = alc260_parse_auto_config(codec);
7627		if (err < 0) {
7628			alc_free(codec);
7629			return err;
7630		} else if (!err) {
7631			printk(KERN_INFO
7632			       "hda_codec: Cannot set up configuration "
7633			       "from BIOS.  Using base mode...\n");
7634			board_config = ALC260_BASIC;
7635		}
7636	}
7637
7638	err = snd_hda_attach_beep_device(codec, 0x1);
7639	if (err < 0) {
7640		alc_free(codec);
7641		return err;
7642	}
7643
7644	if (board_config != ALC260_AUTO)
7645		setup_preset(codec, &alc260_presets[board_config]);
7646
7647	spec->stream_analog_playback = &alc260_pcm_analog_playback;
7648	spec->stream_analog_capture = &alc260_pcm_analog_capture;
7649	spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
7650
7651	spec->stream_digital_playback = &alc260_pcm_digital_playback;
7652	spec->stream_digital_capture = &alc260_pcm_digital_capture;
7653
7654	if (!spec->adc_nids && spec->input_mux) {
7655		/* check whether NID 0x04 is valid */
7656		unsigned int wcap = get_wcaps(codec, 0x04);
7657		wcap = get_wcaps_type(wcap);
7658		/* get type */
7659		if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7660			spec->adc_nids = alc260_adc_nids_alt;
7661			spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7662		} else {
7663			spec->adc_nids = alc260_adc_nids;
7664			spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7665		}
7666	}
7667	set_capture_mixer(codec);
7668	set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
7669
7670	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7671
7672	spec->vmaster_nid = 0x08;
7673
7674	codec->patch_ops = alc_patch_ops;
7675	if (board_config == ALC260_AUTO)
7676		spec->init_hook = alc260_auto_init;
7677	spec->shutup = alc_eapd_shutup;
7678#ifdef CONFIG_SND_HDA_POWER_SAVE
7679	if (!spec->loopback.amplist)
7680		spec->loopback.amplist = alc260_loopbacks;
7681#endif
7682
7683	return 0;
7684}
7685
7686
7687/*
7688 * ALC882/883/885/888/889 support
7689 *
7690 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7691 * configuration.  Each pin widget can choose any input DACs and a mixer.
7692 * Each ADC is connected from a mixer of all inputs.  This makes possible
7693 * 6-channel independent captures.
7694 *
7695 * In addition, an independent DAC for the multi-playback (not used in this
7696 * driver yet).
7697 */
7698#define ALC882_DIGOUT_NID	0x06
7699#define ALC882_DIGIN_NID	0x0a
7700#define ALC883_DIGOUT_NID	ALC882_DIGOUT_NID
7701#define ALC883_DIGIN_NID	ALC882_DIGIN_NID
7702#define ALC1200_DIGOUT_NID	0x10
7703
7704
7705static const struct hda_channel_mode alc882_ch_modes[1] = {
7706	{ 8, NULL }
7707};
7708
7709/* DACs */
7710static const hda_nid_t alc882_dac_nids[4] = {
7711	/* front, rear, clfe, rear_surr */
7712	0x02, 0x03, 0x04, 0x05
7713};
7714#define alc883_dac_nids		alc882_dac_nids
7715
7716/* ADCs */
7717#define alc882_adc_nids		alc880_adc_nids
7718#define alc882_adc_nids_alt	alc880_adc_nids_alt
7719#define alc883_adc_nids		alc882_adc_nids_alt
7720static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7721static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7722#define alc889_adc_nids		alc880_adc_nids
7723
7724static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7725static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
7726#define alc883_capsrc_nids	alc882_capsrc_nids_alt
7727static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7728#define alc889_capsrc_nids	alc882_capsrc_nids
7729
7730/* input MUX */
7731/* FIXME: should be a matrix-type input source selection */
7732
7733static const struct hda_input_mux alc882_capture_source = {
7734	.num_items = 4,
7735	.items = {
7736		{ "Mic", 0x0 },
7737		{ "Front Mic", 0x1 },
7738		{ "Line", 0x2 },
7739		{ "CD", 0x4 },
7740	},
7741};
7742
7743#define alc883_capture_source	alc882_capture_source
7744
7745static const struct hda_input_mux alc889_capture_source = {
7746	.num_items = 3,
7747	.items = {
7748		{ "Front Mic", 0x0 },
7749		{ "Mic", 0x3 },
7750		{ "Line", 0x2 },
7751	},
7752};
7753
7754static const struct hda_input_mux mb5_capture_source = {
7755	.num_items = 3,
7756	.items = {
7757		{ "Mic", 0x1 },
7758		{ "Line", 0x7 },
7759		{ "CD", 0x4 },
7760	},
7761};
7762
7763static const struct hda_input_mux macmini3_capture_source = {
7764	.num_items = 2,
7765	.items = {
7766		{ "Line", 0x2 },
7767		{ "CD", 0x4 },
7768	},
7769};
7770
7771static const struct hda_input_mux alc883_3stack_6ch_intel = {
7772	.num_items = 4,
7773	.items = {
7774		{ "Mic", 0x1 },
7775		{ "Front Mic", 0x0 },
7776		{ "Line", 0x2 },
7777		{ "CD", 0x4 },
7778	},
7779};
7780
7781static const struct hda_input_mux alc883_lenovo_101e_capture_source = {
7782	.num_items = 2,
7783	.items = {
7784		{ "Mic", 0x1 },
7785		{ "Line", 0x2 },
7786	},
7787};
7788
7789static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7790	.num_items = 4,
7791	.items = {
7792		{ "Mic", 0x0 },
7793		{ "Internal Mic", 0x1 },
7794		{ "Line", 0x2 },
7795		{ "CD", 0x4 },
7796	},
7797};
7798
7799static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7800	.num_items = 2,
7801	.items = {
7802		{ "Mic", 0x0 },
7803		{ "Internal Mic", 0x1 },
7804	},
7805};
7806
7807static const struct hda_input_mux alc883_lenovo_sky_capture_source = {
7808	.num_items = 3,
7809	.items = {
7810		{ "Mic", 0x0 },
7811		{ "Front Mic", 0x1 },
7812		{ "Line", 0x4 },
7813	},
7814};
7815
7816static const struct hda_input_mux alc883_asus_eee1601_capture_source = {
7817	.num_items = 2,
7818	.items = {
7819		{ "Mic", 0x0 },
7820		{ "Line", 0x2 },
7821	},
7822};
7823
7824static const struct hda_input_mux alc889A_mb31_capture_source = {
7825	.num_items = 2,
7826	.items = {
7827		{ "Mic", 0x0 },
7828		/* Front Mic (0x01) unused */
7829		{ "Line", 0x2 },
7830		/* Line 2 (0x03) unused */
7831		/* CD (0x04) unused? */
7832	},
7833};
7834
7835static const struct hda_input_mux alc889A_imac91_capture_source = {
7836	.num_items = 2,
7837	.items = {
7838		{ "Mic", 0x01 },
7839		{ "Line", 0x2 }, /* Not sure! */
7840	},
7841};
7842
7843/*
7844 * 2ch mode
7845 */
7846static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7847	{ 2, NULL }
7848};
7849
7850/*
7851 * 2ch mode
7852 */
7853static const struct hda_verb alc882_3ST_ch2_init[] = {
7854	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7855	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7856	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7857	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7858	{ } /* end */
7859};
7860
7861/*
7862 * 4ch mode
7863 */
7864static const struct hda_verb alc882_3ST_ch4_init[] = {
7865	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7866	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7867	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7868	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7869	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7870	{ } /* end */
7871};
7872
7873/*
7874 * 6ch mode
7875 */
7876static const struct hda_verb alc882_3ST_ch6_init[] = {
7877	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7878	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7879	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7880	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7881	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7882	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7883	{ } /* end */
7884};
7885
7886static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
7887	{ 2, alc882_3ST_ch2_init },
7888	{ 4, alc882_3ST_ch4_init },
7889	{ 6, alc882_3ST_ch6_init },
7890};
7891
7892#define alc883_3ST_6ch_modes	alc882_3ST_6ch_modes
7893
7894/*
7895 * 2ch mode
7896 */
7897static const struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7898	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7899	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7900	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7901	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7902	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7903	{ } /* end */
7904};
7905
7906/*
7907 * 4ch mode
7908 */
7909static const struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7910	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7911	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7912	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7913	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7914	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7915	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7916	{ } /* end */
7917};
7918
7919/*
7920 * 6ch mode
7921 */
7922static const struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7923	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7924	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7925	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7926	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7927	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7928	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7929	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7930	{ } /* end */
7931};
7932
7933static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7934	{ 2, alc883_3ST_ch2_clevo_init },
7935	{ 4, alc883_3ST_ch4_clevo_init },
7936	{ 6, alc883_3ST_ch6_clevo_init },
7937};
7938
7939
7940/*
7941 * 6ch mode
7942 */
7943static const struct hda_verb alc882_sixstack_ch6_init[] = {
7944	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7945	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7946	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7947	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7948	{ } /* end */
7949};
7950
7951/*
7952 * 8ch mode
7953 */
7954static const struct hda_verb alc882_sixstack_ch8_init[] = {
7955	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7956	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7957	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7958	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7959	{ } /* end */
7960};
7961
7962static const struct hda_channel_mode alc882_sixstack_modes[2] = {
7963	{ 6, alc882_sixstack_ch6_init },
7964	{ 8, alc882_sixstack_ch8_init },
7965};
7966
7967
7968/* Macbook Air 2,1 */
7969
7970static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7971      { 2, NULL },
7972};
7973
7974/*
7975 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
7976 */
7977
7978/*
7979 * 2ch mode
7980 */
7981static const struct hda_verb alc885_mbp_ch2_init[] = {
7982	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7983	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7984	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7985	{ } /* end */
7986};
7987
7988/*
7989 * 4ch mode
7990 */
7991static const struct hda_verb alc885_mbp_ch4_init[] = {
7992	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7993	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7994	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7995	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7996	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7997	{ } /* end */
7998};
7999
8000static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
8001	{ 2, alc885_mbp_ch2_init },
8002	{ 4, alc885_mbp_ch4_init },
8003};
8004
8005/*
8006 * 2ch
8007 * Speakers/Woofer/HP = Front
8008 * LineIn = Input
8009 */
8010static const struct hda_verb alc885_mb5_ch2_init[] = {
8011	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8012	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8013	{ } /* end */
8014};
8015
8016/*
8017 * 6ch mode
8018 * Speakers/HP = Front
8019 * Woofer = LFE
8020 * LineIn = Surround
8021 */
8022static const struct hda_verb alc885_mb5_ch6_init[] = {
8023	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8024	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8025	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8026	{ } /* end */
8027};
8028
8029static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
8030	{ 2, alc885_mb5_ch2_init },
8031	{ 6, alc885_mb5_ch6_init },
8032};
8033
8034#define alc885_macmini3_6ch_modes	alc885_mb5_6ch_modes
8035
8036/*
8037 * 2ch mode
8038 */
8039static const struct hda_verb alc883_4ST_ch2_init[] = {
8040	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8041	{ 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8042	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8043	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8044	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8045	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8046	{ } /* end */
8047};
8048
8049/*
8050 * 4ch mode
8051 */
8052static const struct hda_verb alc883_4ST_ch4_init[] = {
8053	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8054	{ 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8055	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8056	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8057	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8058	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8059	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8060	{ } /* end */
8061};
8062
8063/*
8064 * 6ch mode
8065 */
8066static const struct hda_verb alc883_4ST_ch6_init[] = {
8067	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8068	{ 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8069	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8070	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8071	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8072	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8073	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8074	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8075	{ } /* end */
8076};
8077
8078/*
8079 * 8ch mode
8080 */
8081static const struct hda_verb alc883_4ST_ch8_init[] = {
8082	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8083	{ 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8084	{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8085	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8086	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8087	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8088	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8089	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8090	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8091	{ } /* end */
8092};
8093
8094static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
8095	{ 2, alc883_4ST_ch2_init },
8096	{ 4, alc883_4ST_ch4_init },
8097	{ 6, alc883_4ST_ch6_init },
8098	{ 8, alc883_4ST_ch8_init },
8099};
8100
8101
8102/*
8103 * 2ch mode
8104 */
8105static const struct hda_verb alc883_3ST_ch2_intel_init[] = {
8106	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8107	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8108	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8109	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8110	{ } /* end */
8111};
8112
8113/*
8114 * 4ch mode
8115 */
8116static const struct hda_verb alc883_3ST_ch4_intel_init[] = {
8117	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8118	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8119	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8120	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8121	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8122	{ } /* end */
8123};
8124
8125/*
8126 * 6ch mode
8127 */
8128static const struct hda_verb alc883_3ST_ch6_intel_init[] = {
8129	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8130	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8131	{ 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
8132	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8133	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8134	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8135	{ } /* end */
8136};
8137
8138static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
8139	{ 2, alc883_3ST_ch2_intel_init },
8140	{ 4, alc883_3ST_ch4_intel_init },
8141	{ 6, alc883_3ST_ch6_intel_init },
8142};
8143
8144/*
8145 * 2ch mode
8146 */
8147static const struct hda_verb alc889_ch2_intel_init[] = {
8148	{ 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8149	{ 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
8150	{ 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
8151	{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
8152	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8153	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8154	{ } /* end */
8155};
8156
8157/*
8158 * 6ch mode
8159 */
8160static const struct hda_verb alc889_ch6_intel_init[] = {
8161	{ 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8162	{ 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8163	{ 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8164	{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8165	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8166	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8167	{ } /* end */
8168};
8169
8170/*
8171 * 8ch mode
8172 */
8173static const struct hda_verb alc889_ch8_intel_init[] = {
8174	{ 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8175	{ 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8176	{ 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8177	{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8178	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
8179	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8180	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8181	{ } /* end */
8182};
8183
8184static const struct hda_channel_mode alc889_8ch_intel_modes[3] = {
8185	{ 2, alc889_ch2_intel_init },
8186	{ 6, alc889_ch6_intel_init },
8187	{ 8, alc889_ch8_intel_init },
8188};
8189
8190/*
8191 * 6ch mode
8192 */
8193static const struct hda_verb alc883_sixstack_ch6_init[] = {
8194	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8195	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8196	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8197	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8198	{ } /* end */
8199};
8200
8201/*
8202 * 8ch mode
8203 */
8204static const struct hda_verb alc883_sixstack_ch8_init[] = {
8205	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8206	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8207	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8208	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8209	{ } /* end */
8210};
8211
8212static const struct hda_channel_mode alc883_sixstack_modes[2] = {
8213	{ 6, alc883_sixstack_ch6_init },
8214	{ 8, alc883_sixstack_ch8_init },
8215};
8216
8217
8218/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
8219 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
8220 */
8221static const struct snd_kcontrol_new alc882_base_mixer[] = {
8222	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8223	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8224	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8225	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8226	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8227	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8228	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8229	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8230	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8231	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8232	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8233	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8234	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8235	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8236	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8237	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8238	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8239	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8240	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8241	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8242	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8243	{ } /* end */
8244};
8245
8246/* Macbook Air 2,1 same control for HP and internal Speaker */
8247
8248static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
8249      HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8250      HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
8251     { }
8252};
8253
8254
8255static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
8256	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8257	HDA_BIND_MUTE   ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8258	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8259	HDA_BIND_MUTE   ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
8260	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8261	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8262	HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8263	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8264	HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8265	HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
8266	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
8267	{ } /* end */
8268};
8269
8270static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
8271	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8272	HDA_BIND_MUTE   ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8273	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8274	HDA_BIND_MUTE   ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8275	HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8276	HDA_BIND_MUTE   ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8277	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8278	HDA_BIND_MUTE   ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8279	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8280	HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8281	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8282	HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8283	HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8284	HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
8285	{ } /* end */
8286};
8287
8288static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
8289	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8290	HDA_BIND_MUTE   ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8291	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8292	HDA_BIND_MUTE   ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8293	HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8294	HDA_BIND_MUTE   ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8295	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8296	HDA_BIND_MUTE   ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8297	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8298	HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8299	HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8300	{ } /* end */
8301};
8302
8303static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
8304	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8305	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8306	{ } /* end */
8307};
8308
8309
8310static const struct snd_kcontrol_new alc882_w2jc_mixer[] = {
8311	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8312	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8313	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8314	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8315	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8316	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8317	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8318	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8319	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8320	{ } /* end */
8321};
8322
8323static const struct snd_kcontrol_new alc882_targa_mixer[] = {
8324	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8325	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8326	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8327	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8328	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8329	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8330	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8331	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8332	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8333	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8334	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8335	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8336	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8337	{ } /* end */
8338};
8339
8340/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8341 *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8342 */
8343static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
8344	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8345	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8346	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8347	HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8348	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8349	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8350	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8351	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8352	HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8353	HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8354	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8355	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8356	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8357	{ } /* end */
8358};
8359
8360static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
8361	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8362	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8363	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8364	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8365	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8366	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8367	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8368	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8369	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8370	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8371	{ } /* end */
8372};
8373
8374static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
8375	{
8376		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8377		.name = "Channel Mode",
8378		.info = alc_ch_mode_info,
8379		.get = alc_ch_mode_get,
8380		.put = alc_ch_mode_put,
8381	},
8382	{ } /* end */
8383};
8384
8385static const struct hda_verb alc882_base_init_verbs[] = {
8386	/* Front mixer: unmute input/output amp left and right (volume = 0) */
8387	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8388	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8389	/* Rear mixer */
8390	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8391	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8392	/* CLFE mixer */
8393	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8394	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8395	/* Side mixer */
8396	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8397	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8398
8399	/* Front Pin: output 0 (0x0c) */
8400	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8401	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8402	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8403	/* Rear Pin: output 1 (0x0d) */
8404	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8405	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8406	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8407	/* CLFE Pin: output 2 (0x0e) */
8408	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8409	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8410	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8411	/* Side Pin: output 3 (0x0f) */
8412	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8413	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8414	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8415	/* Mic (rear) pin: input vref at 80% */
8416	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8417	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8418	/* Front Mic pin: input vref at 80% */
8419	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8420	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8421	/* Line In pin: input */
8422	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8423	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8424	/* Line-2 In: Headphone output (output 0 - 0x0c) */
8425	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8426	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8427	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8428	/* CD pin widget for input */
8429	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8430
8431	/* FIXME: use matrix-type input source selection */
8432	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8433	/* Input mixer2 */
8434	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8435	/* Input mixer3 */
8436	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8437	/* ADC2: mute amp left and right */
8438	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8439	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8440	/* ADC3: mute amp left and right */
8441	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8442	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8443
8444	{ }
8445};
8446
8447static const struct hda_verb alc882_adc1_init_verbs[] = {
8448	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8449	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8450	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8451	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8452	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8453	/* ADC1: mute amp left and right */
8454	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8455	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8456	{ }
8457};
8458
8459static const struct hda_verb alc882_eapd_verbs[] = {
8460	/* change to EAPD mode */
8461	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8462	{0x20, AC_VERB_SET_PROC_COEF, 0x3060},
8463	{ }
8464};
8465
8466static const struct hda_verb alc889_eapd_verbs[] = {
8467	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8468	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8469	{ }
8470};
8471
8472static const struct hda_verb alc_hp15_unsol_verbs[] = {
8473	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8474	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8475	{}
8476};
8477
8478static const struct hda_verb alc885_init_verbs[] = {
8479	/* Front mixer: unmute input/output amp left and right (volume = 0) */
8480	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8481	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8482	/* Rear mixer */
8483	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8484	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8485	/* CLFE mixer */
8486	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8487	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8488	/* Side mixer */
8489	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8490	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8491
8492	/* Front HP Pin: output 0 (0x0c) */
8493	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8494	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8495	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8496	/* Front Pin: output 0 (0x0c) */
8497	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8498	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8499	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8500	/* Rear Pin: output 1 (0x0d) */
8501	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8502	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8503	{0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8504	/* CLFE Pin: output 2 (0x0e) */
8505	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8506	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8507	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8508	/* Side Pin: output 3 (0x0f) */
8509	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8510	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8511	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8512	/* Mic (rear) pin: input vref at 80% */
8513	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8514	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8515	/* Front Mic pin: input vref at 80% */
8516	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8517	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8518	/* Line In pin: input */
8519	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8520	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8521
8522	/* Mixer elements: 0x18, , 0x1a, 0x1b */
8523	/* Input mixer1 */
8524	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8525	/* Input mixer2 */
8526	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8527	/* Input mixer3 */
8528	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8529	/* ADC2: mute amp left and right */
8530	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8531	/* ADC3: mute amp left and right */
8532	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8533
8534	{ }
8535};
8536
8537static const struct hda_verb alc885_init_input_verbs[] = {
8538	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8539	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8540	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8541	{ }
8542};
8543
8544
8545/* Unmute Selector 24h and set the default input to front mic */
8546static const struct hda_verb alc889_init_input_verbs[] = {
8547	{0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8548	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8549	{ }
8550};
8551
8552
8553#define alc883_init_verbs	alc882_base_init_verbs
8554
8555/* Mac Pro test */
8556static const struct snd_kcontrol_new alc882_macpro_mixer[] = {
8557	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8558	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8559	HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8560	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8561	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8562	/* FIXME: this looks suspicious...
8563	HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8564	HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
8565	*/
8566	{ } /* end */
8567};
8568
8569static const struct hda_verb alc882_macpro_init_verbs[] = {
8570	/* Front mixer: unmute input/output amp left and right (volume = 0) */
8571	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8572	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8573	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8574	/* Front Pin: output 0 (0x0c) */
8575	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8576	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8577	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8578	/* Front Mic pin: input vref at 80% */
8579	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8580	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8581	/* Speaker:  output */
8582	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8583	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8584	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8585	/* Headphone output (output 0 - 0x0c) */
8586	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8587	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8588	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8589
8590	/* FIXME: use matrix-type input source selection */
8591	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8592	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8593	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8594	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8595	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8596	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8597	/* Input mixer2 */
8598	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8599	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8600	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8601	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8602	/* Input mixer3 */
8603	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8604	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8605	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8606	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8607	/* ADC1: mute amp left and right */
8608	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8609	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8610	/* ADC2: mute amp left and right */
8611	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8612	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8613	/* ADC3: mute amp left and right */
8614	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8615	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8616
8617	{ }
8618};
8619
8620/* Macbook 5,1 */
8621static const struct hda_verb alc885_mb5_init_verbs[] = {
8622	/* DACs */
8623	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8624	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8625	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8626	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8627	/* Front mixer */
8628	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8629	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8630	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8631	/* Surround mixer */
8632	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8633	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8634	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8635	/* LFE mixer */
8636	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8637	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8638	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8639	/* HP mixer */
8640	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8641	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8642	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8643	/* Front Pin (0x0c) */
8644	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8645	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8646	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8647	/* LFE Pin (0x0e) */
8648	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8649	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8650	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8651	/* HP Pin (0x0f) */
8652	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8653	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8654	{0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8655	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8656	/* Front Mic pin: input vref at 80% */
8657	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8658	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8659	/* Line In pin */
8660	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8661	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8662
8663	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8664	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8665	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
8666	{ }
8667};
8668
8669/* Macmini 3,1 */
8670static const struct hda_verb alc885_macmini3_init_verbs[] = {
8671	/* DACs */
8672	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8673	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8674	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8675	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8676	/* Front mixer */
8677	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8678	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8679	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8680	/* Surround mixer */
8681	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8682	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8683	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8684	/* LFE mixer */
8685	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8686	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8687	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8688	/* HP mixer */
8689	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8690	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8691	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8692	/* Front Pin (0x0c) */
8693	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8694	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8695	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8696	/* LFE Pin (0x0e) */
8697	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8698	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8699	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8700	/* HP Pin (0x0f) */
8701	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8702	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8703	{0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8704	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8705	/* Line In pin */
8706	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8707	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8708
8709	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8710	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8711	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8712	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8713	{ }
8714};
8715
8716
8717static const struct hda_verb alc885_mba21_init_verbs[] = {
8718	/*Internal and HP Speaker Mixer*/
8719	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8720	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8721	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8722	/*Internal Speaker Pin (0x0c)*/
8723	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8724	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8725	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8726	/* HP Pin: output 0 (0x0e) */
8727	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8728	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8729	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8730	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8731	/* Line in (is hp when jack connected)*/
8732	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8733	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8734
8735	{ }
8736 };
8737
8738
8739/* Macbook Pro rev3 */
8740static const struct hda_verb alc885_mbp3_init_verbs[] = {
8741	/* Front mixer: unmute input/output amp left and right (volume = 0) */
8742	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8743	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8744	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8745	/* Rear mixer */
8746	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8747	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8748	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8749	/* HP mixer */
8750	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8751	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8752	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8753	/* Front Pin: output 0 (0x0c) */
8754	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8755	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8756	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8757	/* HP Pin: output 0 (0x0e) */
8758	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8759	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8760	{0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
8761	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8762	/* Mic (rear) pin: input vref at 80% */
8763	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8764	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8765	/* Front Mic pin: input vref at 80% */
8766	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8767	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8768	/* Line In pin: use output 1 when in LineOut mode */
8769	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8770	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8771	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8772
8773	/* FIXME: use matrix-type input source selection */
8774	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8775	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8776	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8777	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8778	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8779	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8780	/* Input mixer2 */
8781	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8782	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8783	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8784	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8785	/* Input mixer3 */
8786	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8787	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8788	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8789	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8790	/* ADC1: mute amp left and right */
8791	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8792	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8793	/* ADC2: mute amp left and right */
8794	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8795	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8796	/* ADC3: mute amp left and right */
8797	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8798	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8799
8800	{ }
8801};
8802
8803/* iMac 9,1 */
8804static const struct hda_verb alc885_imac91_init_verbs[] = {
8805	/* Internal Speaker Pin (0x0c) */
8806	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8807	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8808	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8809	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8810	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8811	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8812	/* HP Pin: Rear */
8813	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8814	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8815	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8816	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8817	/* Line in Rear */
8818	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8819	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8820	/* Front Mic pin: input vref at 80% */
8821	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8822	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8823	/* Rear mixer */
8824	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8825	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8826	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8827	/* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8828	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8829	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8830	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8831	/* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8832	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8833	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8834	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8835	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8836	/* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8837	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8838	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8839	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8840	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8841	/* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8842	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8843	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8844	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8845	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8846	/* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8847	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8848	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8849	/* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8850	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8851	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8852	/* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8853	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8854	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8855	{ }
8856};
8857
8858/* iMac 24 mixer. */
8859static const struct snd_kcontrol_new alc885_imac24_mixer[] = {
8860	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8861	HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8862	{ } /* end */
8863};
8864
8865/* iMac 24 init verbs. */
8866static const struct hda_verb alc885_imac24_init_verbs[] = {
8867	/* Internal speakers: output 0 (0x0c) */
8868	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8869	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8870	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8871	/* Internal speakers: output 0 (0x0c) */
8872	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8873	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8874	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8875	/* Headphone: output 0 (0x0c) */
8876	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8877	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8878	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8879	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8880	/* Front Mic: input vref at 80% */
8881	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8882	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8883	{ }
8884};
8885
8886/* Toggle speaker-output according to the hp-jack state */
8887static void alc885_imac24_setup(struct hda_codec *codec)
8888{
8889	struct alc_spec *spec = codec->spec;
8890
8891	spec->autocfg.hp_pins[0] = 0x14;
8892	spec->autocfg.speaker_pins[0] = 0x18;
8893	spec->autocfg.speaker_pins[1] = 0x1a;
8894	spec->automute = 1;
8895	spec->automute_mode = ALC_AUTOMUTE_AMP;
8896}
8897
8898#define alc885_mb5_setup	alc885_imac24_setup
8899#define alc885_macmini3_setup	alc885_imac24_setup
8900
8901/* Macbook Air 2,1 */
8902static void alc885_mba21_setup(struct hda_codec *codec)
8903{
8904       struct alc_spec *spec = codec->spec;
8905
8906       spec->autocfg.hp_pins[0] = 0x14;
8907       spec->autocfg.speaker_pins[0] = 0x18;
8908	spec->automute = 1;
8909	spec->automute_mode = ALC_AUTOMUTE_AMP;
8910}
8911
8912
8913
8914static void alc885_mbp3_setup(struct hda_codec *codec)
8915{
8916	struct alc_spec *spec = codec->spec;
8917
8918	spec->autocfg.hp_pins[0] = 0x15;
8919	spec->autocfg.speaker_pins[0] = 0x14;
8920	spec->automute = 1;
8921	spec->automute_mode = ALC_AUTOMUTE_AMP;
8922}
8923
8924static void alc885_imac91_setup(struct hda_codec *codec)
8925{
8926	struct alc_spec *spec = codec->spec;
8927
8928	spec->autocfg.hp_pins[0] = 0x14;
8929	spec->autocfg.speaker_pins[0] = 0x18;
8930	spec->autocfg.speaker_pins[1] = 0x1a;
8931	spec->automute = 1;
8932	spec->automute_mode = ALC_AUTOMUTE_AMP;
8933}
8934
8935static const struct hda_verb alc882_targa_verbs[] = {
8936	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8937	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8938
8939	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8940	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8941
8942	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8943	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8944	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8945
8946	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8947	{ } /* end */
8948};
8949
8950/* toggle speaker-output according to the hp-jack state */
8951static void alc882_targa_automute(struct hda_codec *codec)
8952{
8953	struct alc_spec *spec = codec->spec;
8954	alc_hp_automute(codec);
8955	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8956				  spec->jack_present ? 1 : 3);
8957}
8958
8959static void alc882_targa_setup(struct hda_codec *codec)
8960{
8961	struct alc_spec *spec = codec->spec;
8962
8963	spec->autocfg.hp_pins[0] = 0x14;
8964	spec->autocfg.speaker_pins[0] = 0x1b;
8965	spec->automute = 1;
8966	spec->automute_mode = ALC_AUTOMUTE_AMP;
8967}
8968
8969static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8970{
8971	if ((res >> 26) == ALC880_HP_EVENT)
8972		alc882_targa_automute(codec);
8973}
8974
8975static const struct hda_verb alc882_asus_a7j_verbs[] = {
8976	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8977	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8978
8979	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8980	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8981	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8982
8983	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8984	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8985	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8986
8987	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8988	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8989	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8990	{ } /* end */
8991};
8992
8993static const struct hda_verb alc882_asus_a7m_verbs[] = {
8994	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8995	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8996
8997	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8998	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8999	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9000
9001	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
9002	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
9003	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
9004
9005	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
9006	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
9007	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
9008 	{ } /* end */
9009};
9010
9011static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
9012{
9013	unsigned int gpiostate, gpiomask, gpiodir;
9014
9015	gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
9016				       AC_VERB_GET_GPIO_DATA, 0);
9017
9018	if (!muted)
9019		gpiostate |= (1 << pin);
9020	else
9021		gpiostate &= ~(1 << pin);
9022
9023	gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
9024				      AC_VERB_GET_GPIO_MASK, 0);
9025	gpiomask |= (1 << pin);
9026
9027	gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
9028				     AC_VERB_GET_GPIO_DIRECTION, 0);
9029	gpiodir |= (1 << pin);
9030
9031
9032	snd_hda_codec_write(codec, codec->afg, 0,
9033			    AC_VERB_SET_GPIO_MASK, gpiomask);
9034	snd_hda_codec_write(codec, codec->afg, 0,
9035			    AC_VERB_SET_GPIO_DIRECTION, gpiodir);
9036
9037	msleep(1);
9038
9039	snd_hda_codec_write(codec, codec->afg, 0,
9040			    AC_VERB_SET_GPIO_DATA, gpiostate);
9041}
9042
9043/* set up GPIO at initialization */
9044static void alc885_macpro_init_hook(struct hda_codec *codec)
9045{
9046	alc882_gpio_mute(codec, 0, 0);
9047	alc882_gpio_mute(codec, 1, 0);
9048}
9049
9050/* set up GPIO and update auto-muting at initialization */
9051static void alc885_imac24_init_hook(struct hda_codec *codec)
9052{
9053	alc885_macpro_init_hook(codec);
9054	alc_hp_automute(codec);
9055}
9056
9057/*
9058 * generic initialization of ADC, input mixers and output mixers
9059 */
9060static const struct hda_verb alc883_auto_init_verbs[] = {
9061	/*
9062	 * Unmute ADC0-2 and set the default input to mic-in
9063	 */
9064	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9065	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9066	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9067	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9068
9069	/*
9070	 * Set up output mixers (0x0c - 0x0f)
9071	 */
9072	/* set vol=0 to output mixers */
9073	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9074	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9075	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9076	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9077	/* set up input amps for analog loopback */
9078	/* Amp Indices: DAC = 0, mixer = 1 */
9079	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9080	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9081	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9082	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9083	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9084	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9085	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9086	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9087	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9088	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9089
9090	/* FIXME: use matrix-type input source selection */
9091	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9092	/* Input mixer2 */
9093	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9094	/* Input mixer3 */
9095	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9096	{ }
9097};
9098
9099/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
9100static const struct hda_verb alc889A_mb31_ch2_init[] = {
9101	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},             /* HP as front */
9102	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9103	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},    /* Line as input */
9104	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},   /* Line off */
9105	{ } /* end */
9106};
9107
9108/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
9109static const struct hda_verb alc889A_mb31_ch4_init[] = {
9110	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},             /* HP as front */
9111	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9112	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},   /* Line as output */
9113	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9114	{ } /* end */
9115};
9116
9117/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
9118static const struct hda_verb alc889A_mb31_ch5_init[] = {
9119	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},             /* HP as rear */
9120	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9121	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},    /* Line as input */
9122	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},   /* Line off */
9123	{ } /* end */
9124};
9125
9126/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
9127static const struct hda_verb alc889A_mb31_ch6_init[] = {
9128	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},             /* HP as front */
9129	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},   /* Subwoofer off */
9130	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},   /* Line as output */
9131	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9132	{ } /* end */
9133};
9134
9135static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
9136	{ 2, alc889A_mb31_ch2_init },
9137	{ 4, alc889A_mb31_ch4_init },
9138	{ 5, alc889A_mb31_ch5_init },
9139	{ 6, alc889A_mb31_ch6_init },
9140};
9141
9142static const struct hda_verb alc883_medion_eapd_verbs[] = {
9143        /* eanable EAPD on medion laptop */
9144	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9145	{0x20, AC_VERB_SET_PROC_COEF, 0x3070},
9146	{ }
9147};
9148
9149#define alc883_base_mixer	alc882_base_mixer
9150
9151static const struct snd_kcontrol_new alc883_mitac_mixer[] = {
9152	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9153	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9154	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9155	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9156	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9157	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9158	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9159	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9160	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9161	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9162	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9163	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9164	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9165	{ } /* end */
9166};
9167
9168static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
9169	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9170	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9171	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9172	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9173	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9174	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9175	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9176	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9177	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9178	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9179	{ } /* end */
9180};
9181
9182static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
9183	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9184	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9185	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9186	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9187	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9188	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9189	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9190	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9191	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9192	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9193	{ } /* end */
9194};
9195
9196static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
9197	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9198	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9199	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9200	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9201	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9202	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9203	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9204	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9205	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9206	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9207	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9208	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9209	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9210	{ } /* end */
9211};
9212
9213static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
9214	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9215	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9216	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9217	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9218	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9219	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9220	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9221	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9222	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9223	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9224	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9225	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9226	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9227	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9228	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9229	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9230	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9231	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9232	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9233	{ } /* end */
9234};
9235
9236static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
9237	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9238	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9239	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9240	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9241	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9242			      HDA_OUTPUT),
9243	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9244	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9245	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9246	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9247	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9248	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9249	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9250	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9251	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9252	HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
9253	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9254	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9255	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
9256	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9257	{ } /* end */
9258};
9259
9260static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
9261	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9262	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9263	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9264	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9265	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9266			      HDA_OUTPUT),
9267	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9268	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9269	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9270	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9271	HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
9272	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9273	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9274	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9275	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
9276	HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
9277	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
9278	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9279	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
9280	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9281	{ } /* end */
9282};
9283
9284static const struct snd_kcontrol_new alc883_fivestack_mixer[] = {
9285	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9286	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9287	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9288	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9289	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9290	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9291	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9292	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9293	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9294	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9295	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9296	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9297	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9298	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9299	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9300	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9301	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9302	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9303	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9304	{ } /* end */
9305};
9306
9307static const struct snd_kcontrol_new alc883_targa_mixer[] = {
9308	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9309	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9310	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9311	HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9312	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9313	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9314	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9315	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9316	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9317	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9318	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9319	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9320	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9321	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9322	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9323	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9324	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9325	{ } /* end */
9326};
9327
9328static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
9329	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9330	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9331	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9332	HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9333	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9334	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9335	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9336	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9337	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9338	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9339	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9340	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9341	{ } /* end */
9342};
9343
9344static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
9345	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9346	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9347	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9348	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9349	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9350	{ } /* end */
9351};
9352
9353static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
9354	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9355	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9356	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9357	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9358	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9359	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9360	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9361	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9362	{ } /* end */
9363};
9364
9365static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
9366	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9367	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9368	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9369	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9370	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9371	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9372	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9373	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9374	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9375	{ } /* end */
9376};
9377
9378static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
9379	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9380	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9381	HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9382	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9383	HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9384	HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9385	{ } /* end */
9386};
9387
9388static const struct hda_verb alc883_medion_wim2160_verbs[] = {
9389	/* Unmute front mixer */
9390	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9391	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9392
9393	/* Set speaker pin to front mixer */
9394	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9395
9396	/* Init headphone pin */
9397	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9398	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9399	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9400	{0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9401
9402	{ } /* end */
9403};
9404
9405/* toggle speaker-output according to the hp-jack state */
9406static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9407{
9408	struct alc_spec *spec = codec->spec;
9409
9410	spec->autocfg.hp_pins[0] = 0x1a;
9411	spec->autocfg.speaker_pins[0] = 0x15;
9412	spec->automute = 1;
9413	spec->automute_mode = ALC_AUTOMUTE_AMP;
9414}
9415
9416static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
9417	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9418	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9419	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9420	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9421	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9422	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9423	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9424	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9425	{ } /* end */
9426};
9427
9428static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9429	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9430	HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9431	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9432	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9433	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9434	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9435	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9436	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9437	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9438	{ } /* end */
9439};
9440
9441static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9442	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9443	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9444	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9445	HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9446	HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9447						0x0d, 1, 0x0, HDA_OUTPUT),
9448	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9449	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9450	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9451	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9452	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9453	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9454	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9455	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9456	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9457	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9458	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9459	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9460	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9461	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9462	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9463	{ } /* end */
9464};
9465
9466static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9467	/* Output mixers */
9468	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9469	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9470	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9471	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9472	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9473		HDA_OUTPUT),
9474	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9475	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9476	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9477	/* Output switches */
9478	HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9479	HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9480	HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9481	/* Boost mixers */
9482	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9483	HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
9484	/* Input mixers */
9485	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9486	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9487	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9488	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9489	{ } /* end */
9490};
9491
9492static const struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9493	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9494	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9495	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9496	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9497	HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
9498	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9499	{ } /* end */
9500};
9501
9502static const struct hda_bind_ctls alc883_bind_cap_vol = {
9503	.ops = &snd_hda_bind_vol,
9504	.values = {
9505		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9506		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9507		0
9508	},
9509};
9510
9511static const struct hda_bind_ctls alc883_bind_cap_switch = {
9512	.ops = &snd_hda_bind_sw,
9513	.values = {
9514		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9515		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9516		0
9517	},
9518};
9519
9520static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9521	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9522	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9523	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9524	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9525	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9526	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9527	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9528	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9529	{ } /* end */
9530};
9531
9532static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9533	HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9534	HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9535	{
9536		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9537		/* .name = "Capture Source", */
9538		.name = "Input Source",
9539		.count = 1,
9540		.info = alc_mux_enum_info,
9541		.get = alc_mux_enum_get,
9542		.put = alc_mux_enum_put,
9543	},
9544	{ } /* end */
9545};
9546
9547static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
9548	{
9549		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9550		.name = "Channel Mode",
9551		.info = alc_ch_mode_info,
9552		.get = alc_ch_mode_get,
9553		.put = alc_ch_mode_put,
9554	},
9555	{ } /* end */
9556};
9557
9558/* toggle speaker-output according to the hp-jack state */
9559static void alc883_mitac_setup(struct hda_codec *codec)
9560{
9561	struct alc_spec *spec = codec->spec;
9562
9563	spec->autocfg.hp_pins[0] = 0x15;
9564	spec->autocfg.speaker_pins[0] = 0x14;
9565	spec->autocfg.speaker_pins[1] = 0x17;
9566	spec->automute = 1;
9567	spec->automute_mode = ALC_AUTOMUTE_AMP;
9568}
9569
9570static const struct hda_verb alc883_mitac_verbs[] = {
9571	/* HP */
9572	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9573	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9574	/* Subwoofer */
9575	{0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9576	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9577
9578	/* enable unsolicited event */
9579	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9580	/* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9581
9582	{ } /* end */
9583};
9584
9585static const struct hda_verb alc883_clevo_m540r_verbs[] = {
9586	/* HP */
9587	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9588	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9589	/* Int speaker */
9590	/*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9591
9592	/* enable unsolicited event */
9593	/*
9594	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9595	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9596	*/
9597
9598	{ } /* end */
9599};
9600
9601static const struct hda_verb alc883_clevo_m720_verbs[] = {
9602	/* HP */
9603	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9604	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9605	/* Int speaker */
9606	{0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9607	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9608
9609	/* enable unsolicited event */
9610	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9611	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9612
9613	{ } /* end */
9614};
9615
9616static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9617	/* HP */
9618	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9619	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9620	/* Subwoofer */
9621	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9622	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9623
9624	/* enable unsolicited event */
9625	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9626
9627	{ } /* end */
9628};
9629
9630static const struct hda_verb alc883_targa_verbs[] = {
9631	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9632	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9633
9634	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9635	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9636
9637/* Connect Line-Out side jack (SPDIF) to Side */
9638	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9639	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9640	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9641/* Connect Mic jack to CLFE */
9642	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9643	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9644	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9645/* Connect Line-in jack to Surround */
9646	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9647	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9648	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9649/* Connect HP out jack to Front */
9650	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9651	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9652	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9653
9654	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9655
9656	{ } /* end */
9657};
9658
9659static const struct hda_verb alc883_lenovo_101e_verbs[] = {
9660	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9661	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9662        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9663	{ } /* end */
9664};
9665
9666static const struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9667        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9668	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9669        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9670        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9671	{ } /* end */
9672};
9673
9674static const struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9675	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9676	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9677	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9678	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9679	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
9680	{ } /* end */
9681};
9682
9683static const struct hda_verb alc883_haier_w66_verbs[] = {
9684	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9685	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9686
9687	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9688
9689	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9690	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9691	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9692	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9693	{ } /* end */
9694};
9695
9696static const struct hda_verb alc888_lenovo_sky_verbs[] = {
9697	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9698	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9699	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9700	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9701	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9702	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9703	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9704	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9705	{ } /* end */
9706};
9707
9708static const struct hda_verb alc888_6st_dell_verbs[] = {
9709	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9710	{ }
9711};
9712
9713static const struct hda_verb alc883_vaiott_verbs[] = {
9714	/* HP */
9715	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9716	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9717
9718	/* enable unsolicited event */
9719	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9720
9721	{ } /* end */
9722};
9723
9724static void alc888_3st_hp_setup(struct hda_codec *codec)
9725{
9726	struct alc_spec *spec = codec->spec;
9727
9728	spec->autocfg.hp_pins[0] = 0x1b;
9729	spec->autocfg.speaker_pins[0] = 0x14;
9730	spec->autocfg.speaker_pins[1] = 0x16;
9731	spec->autocfg.speaker_pins[2] = 0x18;
9732	spec->automute = 1;
9733	spec->automute_mode = ALC_AUTOMUTE_AMP;
9734}
9735
9736static const struct hda_verb alc888_3st_hp_verbs[] = {
9737	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Front: output 0 (0x0c) */
9738	{0x16, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Rear : output 1 (0x0d) */
9739	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02},	/* CLFE : output 2 (0x0e) */
9740	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9741	{ } /* end */
9742};
9743
9744/*
9745 * 2ch mode
9746 */
9747static const struct hda_verb alc888_3st_hp_2ch_init[] = {
9748	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9749	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9750	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9751	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9752	{ } /* end */
9753};
9754
9755/*
9756 * 4ch mode
9757 */
9758static const struct hda_verb alc888_3st_hp_4ch_init[] = {
9759	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9760	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9761	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9762	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9763	{ 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9764	{ } /* end */
9765};
9766
9767/*
9768 * 6ch mode
9769 */
9770static const struct hda_verb alc888_3st_hp_6ch_init[] = {
9771	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9772	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9773	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
9774	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9775	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9776	{ 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9777	{ } /* end */
9778};
9779
9780static const struct hda_channel_mode alc888_3st_hp_modes[3] = {
9781	{ 2, alc888_3st_hp_2ch_init },
9782	{ 4, alc888_3st_hp_4ch_init },
9783	{ 6, alc888_3st_hp_6ch_init },
9784};
9785
9786static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)
9787{
9788	struct alc_spec *spec = codec->spec;
9789
9790	spec->autocfg.hp_pins[0] = 0x1b;
9791	spec->autocfg.line_out_pins[0] = 0x14;
9792	spec->autocfg.speaker_pins[0] = 0x15;
9793	spec->automute = 1;
9794	spec->automute_mode = ALC_AUTOMUTE_AMP;
9795}
9796
9797/* toggle speaker-output according to the hp-jack state */
9798static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
9799{
9800	struct alc_spec *spec = codec->spec;
9801
9802	spec->autocfg.hp_pins[0] = 0x14;
9803	spec->autocfg.speaker_pins[0] = 0x15;
9804	spec->automute = 1;
9805	spec->automute_mode = ALC_AUTOMUTE_AMP;
9806}
9807
9808/* toggle speaker-output according to the hp-jack state */
9809#define alc883_targa_init_hook		alc882_targa_init_hook
9810#define alc883_targa_unsol_event	alc882_targa_unsol_event
9811
9812static void alc883_clevo_m720_setup(struct hda_codec *codec)
9813{
9814	struct alc_spec *spec = codec->spec;
9815
9816	spec->autocfg.hp_pins[0] = 0x15;
9817	spec->autocfg.speaker_pins[0] = 0x14;
9818	spec->automute = 1;
9819	spec->automute_mode = ALC_AUTOMUTE_AMP;
9820}
9821
9822static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9823{
9824	alc_hp_automute(codec);
9825	alc88x_simple_mic_automute(codec);
9826}
9827
9828static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
9829					   unsigned int res)
9830{
9831	switch (res >> 26) {
9832	case ALC880_MIC_EVENT:
9833		alc88x_simple_mic_automute(codec);
9834		break;
9835	default:
9836		alc_sku_unsol_event(codec, res);
9837		break;
9838	}
9839}
9840
9841/* toggle speaker-output according to the hp-jack state */
9842static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
9843{
9844	struct alc_spec *spec = codec->spec;
9845
9846	spec->autocfg.hp_pins[0] = 0x14;
9847	spec->autocfg.speaker_pins[0] = 0x15;
9848	spec->automute = 1;
9849	spec->automute_mode = ALC_AUTOMUTE_AMP;
9850}
9851
9852static void alc883_haier_w66_setup(struct hda_codec *codec)
9853{
9854	struct alc_spec *spec = codec->spec;
9855
9856	spec->autocfg.hp_pins[0] = 0x1b;
9857	spec->autocfg.speaker_pins[0] = 0x14;
9858	spec->automute = 1;
9859	spec->automute_mode = ALC_AUTOMUTE_AMP;
9860}
9861
9862static void alc883_lenovo_101e_setup(struct hda_codec *codec)
9863{
9864	struct alc_spec *spec = codec->spec;
9865
9866	spec->autocfg.hp_pins[0] = 0x1b;
9867	spec->autocfg.line_out_pins[0] = 0x14;
9868	spec->autocfg.speaker_pins[0] = 0x15;
9869	spec->automute = 1;
9870	spec->detect_line = 1;
9871	spec->automute_lines = 1;
9872	spec->automute_mode = ALC_AUTOMUTE_AMP;
9873}
9874
9875/* toggle speaker-output according to the hp-jack state */
9876static void alc883_acer_aspire_setup(struct hda_codec *codec)
9877{
9878	struct alc_spec *spec = codec->spec;
9879
9880	spec->autocfg.hp_pins[0] = 0x14;
9881	spec->autocfg.speaker_pins[0] = 0x15;
9882	spec->autocfg.speaker_pins[1] = 0x16;
9883	spec->automute = 1;
9884	spec->automute_mode = ALC_AUTOMUTE_AMP;
9885}
9886
9887static const struct hda_verb alc883_acer_eapd_verbs[] = {
9888	/* HP Pin: output 0 (0x0c) */
9889	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9890	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9891	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9892	/* Front Pin: output 0 (0x0c) */
9893	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9894	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9895	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9896	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9897        /* eanable EAPD on medion laptop */
9898	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9899	{0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9900	/* enable unsolicited event */
9901	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9902	{ }
9903};
9904
9905static void alc888_6st_dell_setup(struct hda_codec *codec)
9906{
9907	struct alc_spec *spec = codec->spec;
9908
9909	spec->autocfg.hp_pins[0] = 0x1b;
9910	spec->autocfg.speaker_pins[0] = 0x14;
9911	spec->autocfg.speaker_pins[1] = 0x15;
9912	spec->autocfg.speaker_pins[2] = 0x16;
9913	spec->autocfg.speaker_pins[3] = 0x17;
9914	spec->automute = 1;
9915	spec->automute_mode = ALC_AUTOMUTE_AMP;
9916}
9917
9918static void alc888_lenovo_sky_setup(struct hda_codec *codec)
9919{
9920	struct alc_spec *spec = codec->spec;
9921
9922	spec->autocfg.hp_pins[0] = 0x1b;
9923	spec->autocfg.speaker_pins[0] = 0x14;
9924	spec->autocfg.speaker_pins[1] = 0x15;
9925	spec->autocfg.speaker_pins[2] = 0x16;
9926	spec->autocfg.speaker_pins[3] = 0x17;
9927	spec->autocfg.speaker_pins[4] = 0x1a;
9928	spec->automute = 1;
9929	spec->automute_mode = ALC_AUTOMUTE_AMP;
9930}
9931
9932static void alc883_vaiott_setup(struct hda_codec *codec)
9933{
9934	struct alc_spec *spec = codec->spec;
9935
9936	spec->autocfg.hp_pins[0] = 0x15;
9937	spec->autocfg.speaker_pins[0] = 0x14;
9938	spec->autocfg.speaker_pins[1] = 0x17;
9939	spec->automute = 1;
9940	spec->automute_mode = ALC_AUTOMUTE_AMP;
9941}
9942
9943static const struct hda_verb alc888_asus_m90v_verbs[] = {
9944	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9945	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9946	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9947	/* enable unsolicited event */
9948	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9949	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9950	{ } /* end */
9951};
9952
9953static void alc883_mode2_setup(struct hda_codec *codec)
9954{
9955	struct alc_spec *spec = codec->spec;
9956
9957	spec->autocfg.hp_pins[0] = 0x1b;
9958	spec->autocfg.speaker_pins[0] = 0x14;
9959	spec->autocfg.speaker_pins[1] = 0x15;
9960	spec->autocfg.speaker_pins[2] = 0x16;
9961	spec->ext_mic.pin = 0x18;
9962	spec->int_mic.pin = 0x19;
9963	spec->ext_mic.mux_idx = 0;
9964	spec->int_mic.mux_idx = 1;
9965	spec->auto_mic = 1;
9966	spec->automute = 1;
9967	spec->automute_mode = ALC_AUTOMUTE_AMP;
9968}
9969
9970static const struct hda_verb alc888_asus_eee1601_verbs[] = {
9971	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9972	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9973	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9974	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9975	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9976	{0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9977	{0x20, AC_VERB_SET_PROC_COEF,  0x0838},
9978	/* enable unsolicited event */
9979	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9980	{ } /* end */
9981};
9982
9983static void alc883_eee1601_inithook(struct hda_codec *codec)
9984{
9985	struct alc_spec *spec = codec->spec;
9986
9987	spec->autocfg.hp_pins[0] = 0x14;
9988	spec->autocfg.speaker_pins[0] = 0x1b;
9989	alc_hp_automute(codec);
9990}
9991
9992static const struct hda_verb alc889A_mb31_verbs[] = {
9993	/* Init rear pin (used as headphone output) */
9994	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},    /* Apple Headphones */
9995	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},           /* Connect to front */
9996	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9997	/* Init line pin (used as output in 4ch and 6ch mode) */
9998	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},           /* Connect to CLFE */
9999	/* Init line 2 pin (used as headphone out by default) */
10000	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},  /* Use as input */
10001	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
10002	{ } /* end */
10003};
10004
10005/* Mute speakers according to the headphone jack state */
10006static void alc889A_mb31_automute(struct hda_codec *codec)
10007{
10008	unsigned int present;
10009
10010	/* Mute only in 2ch or 4ch mode */
10011	if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
10012	    == 0x00) {
10013		present = snd_hda_jack_detect(codec, 0x15);
10014		snd_hda_codec_amp_stereo(codec, 0x14,  HDA_OUTPUT, 0,
10015			HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
10016		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10017			HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
10018	}
10019}
10020
10021static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
10022{
10023	if ((res >> 26) == ALC880_HP_EVENT)
10024		alc889A_mb31_automute(codec);
10025}
10026
10027
10028#ifdef CONFIG_SND_HDA_POWER_SAVE
10029#define alc882_loopbacks	alc880_loopbacks
10030#endif
10031
10032/* pcm configuration: identical with ALC880 */
10033#define alc882_pcm_analog_playback	alc880_pcm_analog_playback
10034#define alc882_pcm_analog_capture	alc880_pcm_analog_capture
10035#define alc882_pcm_digital_playback	alc880_pcm_digital_playback
10036#define alc882_pcm_digital_capture	alc880_pcm_digital_capture
10037
10038static const hda_nid_t alc883_slave_dig_outs[] = {
10039	ALC1200_DIGOUT_NID, 0,
10040};
10041
10042static const hda_nid_t alc1200_slave_dig_outs[] = {
10043	ALC883_DIGOUT_NID, 0,
10044};
10045
10046/*
10047 * configuration and preset
10048 */
10049static const char * const alc882_models[ALC882_MODEL_LAST] = {
10050	[ALC882_3ST_DIG]	= "3stack-dig",
10051	[ALC882_6ST_DIG]	= "6stack-dig",
10052	[ALC882_ARIMA]		= "arima",
10053	[ALC882_W2JC]		= "w2jc",
10054	[ALC882_TARGA]		= "targa",
10055	[ALC882_ASUS_A7J]	= "asus-a7j",
10056	[ALC882_ASUS_A7M]	= "asus-a7m",
10057	[ALC885_MACPRO]		= "macpro",
10058	[ALC885_MB5]		= "mb5",
10059	[ALC885_MACMINI3]	= "macmini3",
10060	[ALC885_MBA21]		= "mba21",
10061	[ALC885_MBP3]		= "mbp3",
10062	[ALC885_IMAC24]		= "imac24",
10063	[ALC885_IMAC91]		= "imac91",
10064	[ALC883_3ST_2ch_DIG]	= "3stack-2ch-dig",
10065	[ALC883_3ST_6ch_DIG]	= "3stack-6ch-dig",
10066	[ALC883_3ST_6ch]	= "3stack-6ch",
10067	[ALC883_6ST_DIG]	= "alc883-6stack-dig",
10068	[ALC883_TARGA_DIG]	= "targa-dig",
10069	[ALC883_TARGA_2ch_DIG]	= "targa-2ch-dig",
10070	[ALC883_TARGA_8ch_DIG]	= "targa-8ch-dig",
10071	[ALC883_ACER]		= "acer",
10072	[ALC883_ACER_ASPIRE]	= "acer-aspire",
10073	[ALC888_ACER_ASPIRE_4930G]	= "acer-aspire-4930g",
10074	[ALC888_ACER_ASPIRE_6530G]	= "acer-aspire-6530g",
10075	[ALC888_ACER_ASPIRE_8930G]	= "acer-aspire-8930g",
10076	[ALC888_ACER_ASPIRE_7730G]	= "acer-aspire-7730g",
10077	[ALC883_MEDION]		= "medion",
10078	[ALC883_MEDION_WIM2160]	= "medion-wim2160",
10079	[ALC883_LAPTOP_EAPD]	= "laptop-eapd",
10080	[ALC883_LENOVO_101E_2ch] = "lenovo-101e",
10081	[ALC883_LENOVO_NB0763]	= "lenovo-nb0763",
10082	[ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
10083	[ALC888_LENOVO_SKY] = "lenovo-sky",
10084	[ALC883_HAIER_W66] 	= "haier-w66",
10085	[ALC888_3ST_HP]		= "3stack-hp",
10086	[ALC888_6ST_DELL]	= "6stack-dell",
10087	[ALC883_MITAC]		= "mitac",
10088	[ALC883_CLEVO_M540R]	= "clevo-m540r",
10089	[ALC883_CLEVO_M720]	= "clevo-m720",
10090	[ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
10091	[ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
10092	[ALC883_3ST_6ch_INTEL]	= "3stack-6ch-intel",
10093	[ALC889A_INTEL]		= "intel-alc889a",
10094	[ALC889_INTEL]		= "intel-x58",
10095	[ALC1200_ASUS_P5Q]	= "asus-p5q",
10096	[ALC889A_MB31]		= "mb31",
10097	[ALC883_SONY_VAIO_TT]	= "sony-vaio-tt",
10098	[ALC882_AUTO]		= "auto",
10099};
10100
10101static const struct snd_pci_quirk alc882_cfg_tbl[] = {
10102	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
10103
10104	SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
10105	SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
10106	SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
10107	SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
10108	SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
10109	SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
10110	SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
10111		ALC888_ACER_ASPIRE_4930G),
10112	SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
10113		ALC888_ACER_ASPIRE_4930G),
10114	SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
10115		ALC888_ACER_ASPIRE_8930G),
10116	SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
10117		ALC888_ACER_ASPIRE_8930G),
10118	SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
10119	SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
10120	SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
10121		ALC888_ACER_ASPIRE_6530G),
10122	SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
10123		ALC888_ACER_ASPIRE_6530G),
10124	SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
10125		ALC888_ACER_ASPIRE_7730G),
10126	/* default Acer -- disabled as it causes more problems.
10127	 *    model=auto should work fine now
10128	 */
10129	/* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
10130
10131	SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
10132
10133	SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG),
10134	SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
10135	SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
10136	SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
10137	SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
10138	SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
10139
10140	SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
10141	SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
10142	SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
10143	SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
10144	SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
10145	SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
10146	SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
10147	SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
10148	SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
10149	SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
10150	SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
10151
10152	SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
10153	SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
10154	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
10155	SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
10156	SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
10157	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
10158	SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
10159	SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
10160	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
10161
10162	SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
10163	SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
10164	SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
10165	SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
10166	SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
10167	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
10168	SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
10169	SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
10170	SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
10171	SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
10172	SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
10173	SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
10174	SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
10175	SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
10176	SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
10177	SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
10178	SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
10179	SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
10180	SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
10181	SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
10182	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
10183	SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
10184	SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
10185	SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
10186	SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
10187	SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
10188	SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
10189	SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
10190	SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
10191	SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
10192	SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
10193
10194	SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
10195	SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
10196	SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
10197	SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
10198	SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
10199	SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
10200	SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
10201	/* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
10202	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
10203	SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
10204		      ALC883_FUJITSU_PI2515),
10205	SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
10206		ALC888_FUJITSU_XA3530),
10207	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
10208	SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10209	SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10210	SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10211	SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
10212	SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
10213	SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
10214	SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
10215
10216	SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
10217	SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
10218	SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
10219	SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
10220	SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
10221	SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
10222	SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
10223
10224	{}
10225};
10226
10227/* codec SSID table for Intel Mac */
10228static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
10229	SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
10230	SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
10231	SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
10232	SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
10233	SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
10234	SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
10235	SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
10236	SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
10237	SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
10238	SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
10239	SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
10240	SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
10241	SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
10242	SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
10243	SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
10244	SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
10245	SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
10246	/* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
10247	 * so apparently no perfect solution yet
10248	 */
10249	SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
10250	SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
10251	SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
10252	{} /* terminator */
10253};
10254
10255static const struct alc_config_preset alc882_presets[] = {
10256	[ALC882_3ST_DIG] = {
10257		.mixers = { alc882_base_mixer },
10258		.init_verbs = { alc882_base_init_verbs,
10259				alc882_adc1_init_verbs },
10260		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10261		.dac_nids = alc882_dac_nids,
10262		.dig_out_nid = ALC882_DIGOUT_NID,
10263		.dig_in_nid = ALC882_DIGIN_NID,
10264		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10265		.channel_mode = alc882_ch_modes,
10266		.need_dac_fix = 1,
10267		.input_mux = &alc882_capture_source,
10268	},
10269	[ALC882_6ST_DIG] = {
10270		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
10271		.init_verbs = { alc882_base_init_verbs,
10272				alc882_adc1_init_verbs },
10273		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10274		.dac_nids = alc882_dac_nids,
10275		.dig_out_nid = ALC882_DIGOUT_NID,
10276		.dig_in_nid = ALC882_DIGIN_NID,
10277		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10278		.channel_mode = alc882_sixstack_modes,
10279		.input_mux = &alc882_capture_source,
10280	},
10281	[ALC882_ARIMA] = {
10282		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
10283		.init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10284				alc882_eapd_verbs },
10285		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10286		.dac_nids = alc882_dac_nids,
10287		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10288		.channel_mode = alc882_sixstack_modes,
10289		.input_mux = &alc882_capture_source,
10290	},
10291	[ALC882_W2JC] = {
10292		.mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
10293		.init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10294				alc882_eapd_verbs, alc880_gpio1_init_verbs },
10295		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10296		.dac_nids = alc882_dac_nids,
10297		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10298		.channel_mode = alc880_threestack_modes,
10299		.need_dac_fix = 1,
10300		.input_mux = &alc882_capture_source,
10301		.dig_out_nid = ALC882_DIGOUT_NID,
10302	},
10303	   [ALC885_MBA21] = {
10304			.mixers = { alc885_mba21_mixer },
10305			.init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
10306			.num_dacs = 2,
10307			.dac_nids = alc882_dac_nids,
10308			.channel_mode = alc885_mba21_ch_modes,
10309			.num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10310			.input_mux = &alc882_capture_source,
10311			.unsol_event = alc_sku_unsol_event,
10312			.setup = alc885_mba21_setup,
10313			.init_hook = alc_hp_automute,
10314       },
10315	[ALC885_MBP3] = {
10316		.mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10317		.init_verbs = { alc885_mbp3_init_verbs,
10318				alc880_gpio1_init_verbs },
10319		.num_dacs = 2,
10320		.dac_nids = alc882_dac_nids,
10321		.hp_nid = 0x04,
10322		.channel_mode = alc885_mbp_4ch_modes,
10323		.num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
10324		.input_mux = &alc882_capture_source,
10325		.dig_out_nid = ALC882_DIGOUT_NID,
10326		.dig_in_nid = ALC882_DIGIN_NID,
10327		.unsol_event = alc_sku_unsol_event,
10328		.setup = alc885_mbp3_setup,
10329		.init_hook = alc_hp_automute,
10330	},
10331	[ALC885_MB5] = {
10332		.mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10333		.init_verbs = { alc885_mb5_init_verbs,
10334				alc880_gpio1_init_verbs },
10335		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10336		.dac_nids = alc882_dac_nids,
10337		.channel_mode = alc885_mb5_6ch_modes,
10338		.num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10339		.input_mux = &mb5_capture_source,
10340		.dig_out_nid = ALC882_DIGOUT_NID,
10341		.dig_in_nid = ALC882_DIGIN_NID,
10342		.unsol_event = alc_sku_unsol_event,
10343		.setup = alc885_mb5_setup,
10344		.init_hook = alc_hp_automute,
10345	},
10346	[ALC885_MACMINI3] = {
10347		.mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10348		.init_verbs = { alc885_macmini3_init_verbs,
10349				alc880_gpio1_init_verbs },
10350		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10351		.dac_nids = alc882_dac_nids,
10352		.channel_mode = alc885_macmini3_6ch_modes,
10353		.num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10354		.input_mux = &macmini3_capture_source,
10355		.dig_out_nid = ALC882_DIGOUT_NID,
10356		.dig_in_nid = ALC882_DIGIN_NID,
10357		.unsol_event = alc_sku_unsol_event,
10358		.setup = alc885_macmini3_setup,
10359		.init_hook = alc_hp_automute,
10360	},
10361	[ALC885_MACPRO] = {
10362		.mixers = { alc882_macpro_mixer },
10363		.init_verbs = { alc882_macpro_init_verbs },
10364		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10365		.dac_nids = alc882_dac_nids,
10366		.dig_out_nid = ALC882_DIGOUT_NID,
10367		.dig_in_nid = ALC882_DIGIN_NID,
10368		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10369		.channel_mode = alc882_ch_modes,
10370		.input_mux = &alc882_capture_source,
10371		.init_hook = alc885_macpro_init_hook,
10372	},
10373	[ALC885_IMAC24] = {
10374		.mixers = { alc885_imac24_mixer },
10375		.init_verbs = { alc885_imac24_init_verbs },
10376		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10377		.dac_nids = alc882_dac_nids,
10378		.dig_out_nid = ALC882_DIGOUT_NID,
10379		.dig_in_nid = ALC882_DIGIN_NID,
10380		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10381		.channel_mode = alc882_ch_modes,
10382		.input_mux = &alc882_capture_source,
10383		.unsol_event = alc_sku_unsol_event,
10384		.setup = alc885_imac24_setup,
10385		.init_hook = alc885_imac24_init_hook,
10386	},
10387	[ALC885_IMAC91] = {
10388		.mixers = {alc885_imac91_mixer},
10389		.init_verbs = { alc885_imac91_init_verbs,
10390				alc880_gpio1_init_verbs },
10391		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10392		.dac_nids = alc882_dac_nids,
10393		.channel_mode = alc885_mba21_ch_modes,
10394		.num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10395		.input_mux = &alc889A_imac91_capture_source,
10396		.dig_out_nid = ALC882_DIGOUT_NID,
10397		.dig_in_nid = ALC882_DIGIN_NID,
10398		.unsol_event = alc_sku_unsol_event,
10399		.setup = alc885_imac91_setup,
10400		.init_hook = alc_hp_automute,
10401	},
10402	[ALC882_TARGA] = {
10403		.mixers = { alc882_targa_mixer, alc882_chmode_mixer },
10404		.init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10405				alc880_gpio3_init_verbs, alc882_targa_verbs},
10406		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10407		.dac_nids = alc882_dac_nids,
10408		.dig_out_nid = ALC882_DIGOUT_NID,
10409		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10410		.adc_nids = alc882_adc_nids,
10411		.capsrc_nids = alc882_capsrc_nids,
10412		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10413		.channel_mode = alc882_3ST_6ch_modes,
10414		.need_dac_fix = 1,
10415		.input_mux = &alc882_capture_source,
10416		.unsol_event = alc_sku_unsol_event,
10417		.setup = alc882_targa_setup,
10418		.init_hook = alc882_targa_automute,
10419	},
10420	[ALC882_ASUS_A7J] = {
10421		.mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
10422		.init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10423				alc882_asus_a7j_verbs},
10424		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10425		.dac_nids = alc882_dac_nids,
10426		.dig_out_nid = ALC882_DIGOUT_NID,
10427		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10428		.adc_nids = alc882_adc_nids,
10429		.capsrc_nids = alc882_capsrc_nids,
10430		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10431		.channel_mode = alc882_3ST_6ch_modes,
10432		.need_dac_fix = 1,
10433		.input_mux = &alc882_capture_source,
10434	},
10435	[ALC882_ASUS_A7M] = {
10436		.mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
10437		.init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10438				alc882_eapd_verbs, alc880_gpio1_init_verbs,
10439				alc882_asus_a7m_verbs },
10440		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
10441		.dac_nids = alc882_dac_nids,
10442		.dig_out_nid = ALC882_DIGOUT_NID,
10443		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10444		.channel_mode = alc880_threestack_modes,
10445		.need_dac_fix = 1,
10446		.input_mux = &alc882_capture_source,
10447	},
10448	[ALC883_3ST_2ch_DIG] = {
10449		.mixers = { alc883_3ST_2ch_mixer },
10450		.init_verbs = { alc883_init_verbs },
10451		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10452		.dac_nids = alc883_dac_nids,
10453		.dig_out_nid = ALC883_DIGOUT_NID,
10454		.dig_in_nid = ALC883_DIGIN_NID,
10455		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10456		.channel_mode = alc883_3ST_2ch_modes,
10457		.input_mux = &alc883_capture_source,
10458	},
10459	[ALC883_3ST_6ch_DIG] = {
10460		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10461		.init_verbs = { alc883_init_verbs },
10462		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10463		.dac_nids = alc883_dac_nids,
10464		.dig_out_nid = ALC883_DIGOUT_NID,
10465		.dig_in_nid = ALC883_DIGIN_NID,
10466		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10467		.channel_mode = alc883_3ST_6ch_modes,
10468		.need_dac_fix = 1,
10469		.input_mux = &alc883_capture_source,
10470	},
10471	[ALC883_3ST_6ch] = {
10472		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10473		.init_verbs = { alc883_init_verbs },
10474		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10475		.dac_nids = alc883_dac_nids,
10476		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10477		.channel_mode = alc883_3ST_6ch_modes,
10478		.need_dac_fix = 1,
10479		.input_mux = &alc883_capture_source,
10480	},
10481	[ALC883_3ST_6ch_INTEL] = {
10482		.mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10483		.init_verbs = { alc883_init_verbs },
10484		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10485		.dac_nids = alc883_dac_nids,
10486		.dig_out_nid = ALC883_DIGOUT_NID,
10487		.dig_in_nid = ALC883_DIGIN_NID,
10488		.slave_dig_outs = alc883_slave_dig_outs,
10489		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10490		.channel_mode = alc883_3ST_6ch_intel_modes,
10491		.need_dac_fix = 1,
10492		.input_mux = &alc883_3stack_6ch_intel,
10493	},
10494	[ALC889A_INTEL] = {
10495		.mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10496		.init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10497				alc_hp15_unsol_verbs },
10498		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10499		.dac_nids = alc883_dac_nids,
10500		.num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10501		.adc_nids = alc889_adc_nids,
10502		.dig_out_nid = ALC883_DIGOUT_NID,
10503		.dig_in_nid = ALC883_DIGIN_NID,
10504		.slave_dig_outs = alc883_slave_dig_outs,
10505		.num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10506		.channel_mode = alc889_8ch_intel_modes,
10507		.capsrc_nids = alc889_capsrc_nids,
10508		.input_mux = &alc889_capture_source,
10509		.setup = alc889_automute_setup,
10510		.init_hook = alc_hp_automute,
10511		.unsol_event = alc_sku_unsol_event,
10512		.need_dac_fix = 1,
10513	},
10514	[ALC889_INTEL] = {
10515		.mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10516		.init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
10517				alc889_eapd_verbs, alc_hp15_unsol_verbs},
10518		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10519		.dac_nids = alc883_dac_nids,
10520		.num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10521		.adc_nids = alc889_adc_nids,
10522		.dig_out_nid = ALC883_DIGOUT_NID,
10523		.dig_in_nid = ALC883_DIGIN_NID,
10524		.slave_dig_outs = alc883_slave_dig_outs,
10525		.num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10526		.channel_mode = alc889_8ch_intel_modes,
10527		.capsrc_nids = alc889_capsrc_nids,
10528		.input_mux = &alc889_capture_source,
10529		.setup = alc889_automute_setup,
10530		.init_hook = alc889_intel_init_hook,
10531		.unsol_event = alc_sku_unsol_event,
10532		.need_dac_fix = 1,
10533	},
10534	[ALC883_6ST_DIG] = {
10535		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
10536		.init_verbs = { alc883_init_verbs },
10537		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10538		.dac_nids = alc883_dac_nids,
10539		.dig_out_nid = ALC883_DIGOUT_NID,
10540		.dig_in_nid = ALC883_DIGIN_NID,
10541		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10542		.channel_mode = alc883_sixstack_modes,
10543		.input_mux = &alc883_capture_source,
10544	},
10545	[ALC883_TARGA_DIG] = {
10546		.mixers = { alc883_targa_mixer, alc883_chmode_mixer },
10547		.init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10548				alc883_targa_verbs},
10549		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10550		.dac_nids = alc883_dac_nids,
10551		.dig_out_nid = ALC883_DIGOUT_NID,
10552		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10553		.channel_mode = alc883_3ST_6ch_modes,
10554		.need_dac_fix = 1,
10555		.input_mux = &alc883_capture_source,
10556		.unsol_event = alc883_targa_unsol_event,
10557		.setup = alc882_targa_setup,
10558		.init_hook = alc882_targa_automute,
10559	},
10560	[ALC883_TARGA_2ch_DIG] = {
10561		.mixers = { alc883_targa_2ch_mixer},
10562		.init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10563				alc883_targa_verbs},
10564		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10565		.dac_nids = alc883_dac_nids,
10566		.adc_nids = alc883_adc_nids_alt,
10567		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10568		.capsrc_nids = alc883_capsrc_nids,
10569		.dig_out_nid = ALC883_DIGOUT_NID,
10570		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10571		.channel_mode = alc883_3ST_2ch_modes,
10572		.input_mux = &alc883_capture_source,
10573		.unsol_event = alc883_targa_unsol_event,
10574		.setup = alc882_targa_setup,
10575		.init_hook = alc882_targa_automute,
10576	},
10577	[ALC883_TARGA_8ch_DIG] = {
10578		.mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10579			    alc883_chmode_mixer },
10580		.init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10581				alc883_targa_verbs },
10582		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10583		.dac_nids = alc883_dac_nids,
10584		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10585		.adc_nids = alc883_adc_nids_rev,
10586		.capsrc_nids = alc883_capsrc_nids_rev,
10587		.dig_out_nid = ALC883_DIGOUT_NID,
10588		.dig_in_nid = ALC883_DIGIN_NID,
10589		.num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10590		.channel_mode = alc883_4ST_8ch_modes,
10591		.need_dac_fix = 1,
10592		.input_mux = &alc883_capture_source,
10593		.unsol_event = alc883_targa_unsol_event,
10594		.setup = alc882_targa_setup,
10595		.init_hook = alc882_targa_automute,
10596	},
10597	[ALC883_ACER] = {
10598		.mixers = { alc883_base_mixer },
10599		/* On TravelMate laptops, GPIO 0 enables the internal speaker
10600		 * and the headphone jack.  Turn this on and rely on the
10601		 * standard mute methods whenever the user wants to turn
10602		 * these outputs off.
10603		 */
10604		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10605		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10606		.dac_nids = alc883_dac_nids,
10607		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10608		.channel_mode = alc883_3ST_2ch_modes,
10609		.input_mux = &alc883_capture_source,
10610	},
10611	[ALC883_ACER_ASPIRE] = {
10612		.mixers = { alc883_acer_aspire_mixer },
10613		.init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
10614		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10615		.dac_nids = alc883_dac_nids,
10616		.dig_out_nid = ALC883_DIGOUT_NID,
10617		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10618		.channel_mode = alc883_3ST_2ch_modes,
10619		.input_mux = &alc883_capture_source,
10620		.unsol_event = alc_sku_unsol_event,
10621		.setup = alc883_acer_aspire_setup,
10622		.init_hook = alc_hp_automute,
10623	},
10624	[ALC888_ACER_ASPIRE_4930G] = {
10625		.mixers = { alc888_acer_aspire_4930g_mixer,
10626				alc883_chmode_mixer },
10627		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10628				alc888_acer_aspire_4930g_verbs },
10629		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10630		.dac_nids = alc883_dac_nids,
10631		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10632		.adc_nids = alc883_adc_nids_rev,
10633		.capsrc_nids = alc883_capsrc_nids_rev,
10634		.dig_out_nid = ALC883_DIGOUT_NID,
10635		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10636		.channel_mode = alc883_3ST_6ch_modes,
10637		.need_dac_fix = 1,
10638		.const_channel_count = 6,
10639		.num_mux_defs =
10640			ARRAY_SIZE(alc888_2_capture_sources),
10641		.input_mux = alc888_2_capture_sources,
10642		.unsol_event = alc_sku_unsol_event,
10643		.setup = alc888_acer_aspire_4930g_setup,
10644		.init_hook = alc_hp_automute,
10645	},
10646	[ALC888_ACER_ASPIRE_6530G] = {
10647		.mixers = { alc888_acer_aspire_6530_mixer },
10648		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10649				alc888_acer_aspire_6530g_verbs },
10650		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10651		.dac_nids = alc883_dac_nids,
10652		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10653		.adc_nids = alc883_adc_nids_rev,
10654		.capsrc_nids = alc883_capsrc_nids_rev,
10655		.dig_out_nid = ALC883_DIGOUT_NID,
10656		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10657		.channel_mode = alc883_3ST_2ch_modes,
10658		.num_mux_defs =
10659			ARRAY_SIZE(alc888_2_capture_sources),
10660		.input_mux = alc888_acer_aspire_6530_sources,
10661		.unsol_event = alc_sku_unsol_event,
10662		.setup = alc888_acer_aspire_6530g_setup,
10663		.init_hook = alc_hp_automute,
10664	},
10665	[ALC888_ACER_ASPIRE_8930G] = {
10666		.mixers = { alc889_acer_aspire_8930g_mixer,
10667				alc883_chmode_mixer },
10668		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10669				alc889_acer_aspire_8930g_verbs,
10670				alc889_eapd_verbs},
10671		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10672		.dac_nids = alc883_dac_nids,
10673		.num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10674		.adc_nids = alc889_adc_nids,
10675		.capsrc_nids = alc889_capsrc_nids,
10676		.dig_out_nid = ALC883_DIGOUT_NID,
10677		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10678		.channel_mode = alc883_3ST_6ch_modes,
10679		.need_dac_fix = 1,
10680		.const_channel_count = 6,
10681		.num_mux_defs =
10682			ARRAY_SIZE(alc889_capture_sources),
10683		.input_mux = alc889_capture_sources,
10684		.unsol_event = alc_sku_unsol_event,
10685		.setup = alc889_acer_aspire_8930g_setup,
10686		.init_hook = alc_hp_automute,
10687#ifdef CONFIG_SND_HDA_POWER_SAVE
10688		.power_hook = alc_power_eapd,
10689#endif
10690	},
10691	[ALC888_ACER_ASPIRE_7730G] = {
10692		.mixers = { alc883_3ST_6ch_mixer,
10693				alc883_chmode_mixer },
10694		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10695				alc888_acer_aspire_7730G_verbs },
10696		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10697		.dac_nids = alc883_dac_nids,
10698		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10699		.adc_nids = alc883_adc_nids_rev,
10700		.capsrc_nids = alc883_capsrc_nids_rev,
10701		.dig_out_nid = ALC883_DIGOUT_NID,
10702		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10703		.channel_mode = alc883_3ST_6ch_modes,
10704		.need_dac_fix = 1,
10705		.const_channel_count = 6,
10706		.input_mux = &alc883_capture_source,
10707		.unsol_event = alc_sku_unsol_event,
10708		.setup = alc888_acer_aspire_7730g_setup,
10709		.init_hook = alc_hp_automute,
10710	},
10711	[ALC883_MEDION] = {
10712		.mixers = { alc883_fivestack_mixer,
10713			    alc883_chmode_mixer },
10714		.init_verbs = { alc883_init_verbs,
10715				alc883_medion_eapd_verbs },
10716		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10717		.dac_nids = alc883_dac_nids,
10718		.adc_nids = alc883_adc_nids_alt,
10719		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10720		.capsrc_nids = alc883_capsrc_nids,
10721		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10722		.channel_mode = alc883_sixstack_modes,
10723		.input_mux = &alc883_capture_source,
10724	},
10725	[ALC883_MEDION_WIM2160] = {
10726		.mixers = { alc883_medion_wim2160_mixer },
10727		.init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10728		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10729		.dac_nids = alc883_dac_nids,
10730		.dig_out_nid = ALC883_DIGOUT_NID,
10731		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10732		.adc_nids = alc883_adc_nids,
10733		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10734		.channel_mode = alc883_3ST_2ch_modes,
10735		.input_mux = &alc883_capture_source,
10736		.unsol_event = alc_sku_unsol_event,
10737		.setup = alc883_medion_wim2160_setup,
10738		.init_hook = alc_hp_automute,
10739	},
10740	[ALC883_LAPTOP_EAPD] = {
10741		.mixers = { alc883_base_mixer },
10742		.init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10743		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10744		.dac_nids = alc883_dac_nids,
10745		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10746		.channel_mode = alc883_3ST_2ch_modes,
10747		.input_mux = &alc883_capture_source,
10748	},
10749	[ALC883_CLEVO_M540R] = {
10750		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10751		.init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10752		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10753		.dac_nids = alc883_dac_nids,
10754		.dig_out_nid = ALC883_DIGOUT_NID,
10755		.dig_in_nid = ALC883_DIGIN_NID,
10756		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10757		.channel_mode = alc883_3ST_6ch_clevo_modes,
10758		.need_dac_fix = 1,
10759		.input_mux = &alc883_capture_source,
10760		/* This machine has the hardware HP auto-muting, thus
10761		 * we need no software mute via unsol event
10762		 */
10763	},
10764	[ALC883_CLEVO_M720] = {
10765		.mixers = { alc883_clevo_m720_mixer },
10766		.init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
10767		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10768		.dac_nids = alc883_dac_nids,
10769		.dig_out_nid = ALC883_DIGOUT_NID,
10770		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10771		.channel_mode = alc883_3ST_2ch_modes,
10772		.input_mux = &alc883_capture_source,
10773		.unsol_event = alc883_clevo_m720_unsol_event,
10774		.setup = alc883_clevo_m720_setup,
10775		.init_hook = alc883_clevo_m720_init_hook,
10776	},
10777	[ALC883_LENOVO_101E_2ch] = {
10778		.mixers = { alc883_lenovo_101e_2ch_mixer},
10779		.init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10780		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10781		.dac_nids = alc883_dac_nids,
10782		.adc_nids = alc883_adc_nids_alt,
10783		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10784		.capsrc_nids = alc883_capsrc_nids,
10785		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10786		.channel_mode = alc883_3ST_2ch_modes,
10787		.input_mux = &alc883_lenovo_101e_capture_source,
10788		.setup = alc883_lenovo_101e_setup,
10789		.unsol_event = alc_sku_unsol_event,
10790		.init_hook = alc_inithook,
10791	},
10792	[ALC883_LENOVO_NB0763] = {
10793		.mixers = { alc883_lenovo_nb0763_mixer },
10794		.init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10795		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10796		.dac_nids = alc883_dac_nids,
10797		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10798		.channel_mode = alc883_3ST_2ch_modes,
10799		.need_dac_fix = 1,
10800		.input_mux = &alc883_lenovo_nb0763_capture_source,
10801		.unsol_event = alc_sku_unsol_event,
10802		.setup = alc883_lenovo_nb0763_setup,
10803		.init_hook = alc_hp_automute,
10804	},
10805	[ALC888_LENOVO_MS7195_DIG] = {
10806		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10807		.init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10808		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10809		.dac_nids = alc883_dac_nids,
10810		.dig_out_nid = ALC883_DIGOUT_NID,
10811		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10812		.channel_mode = alc883_3ST_6ch_modes,
10813		.need_dac_fix = 1,
10814		.input_mux = &alc883_capture_source,
10815		.unsol_event = alc_sku_unsol_event,
10816		.setup = alc888_lenovo_ms7195_setup,
10817		.init_hook = alc_inithook,
10818	},
10819	[ALC883_HAIER_W66] = {
10820		.mixers = { alc883_targa_2ch_mixer},
10821		.init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10822		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10823		.dac_nids = alc883_dac_nids,
10824		.dig_out_nid = ALC883_DIGOUT_NID,
10825		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10826		.channel_mode = alc883_3ST_2ch_modes,
10827		.input_mux = &alc883_capture_source,
10828		.unsol_event = alc_sku_unsol_event,
10829		.setup = alc883_haier_w66_setup,
10830		.init_hook = alc_hp_automute,
10831	},
10832	[ALC888_3ST_HP] = {
10833		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10834		.init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
10835		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10836		.dac_nids = alc883_dac_nids,
10837		.num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10838		.channel_mode = alc888_3st_hp_modes,
10839		.need_dac_fix = 1,
10840		.input_mux = &alc883_capture_source,
10841		.unsol_event = alc_sku_unsol_event,
10842		.setup = alc888_3st_hp_setup,
10843		.init_hook = alc_hp_automute,
10844	},
10845	[ALC888_6ST_DELL] = {
10846		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
10847		.init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10848		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10849		.dac_nids = alc883_dac_nids,
10850		.dig_out_nid = ALC883_DIGOUT_NID,
10851		.dig_in_nid = ALC883_DIGIN_NID,
10852		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10853		.channel_mode = alc883_sixstack_modes,
10854		.input_mux = &alc883_capture_source,
10855		.unsol_event = alc_sku_unsol_event,
10856		.setup = alc888_6st_dell_setup,
10857		.init_hook = alc_hp_automute,
10858	},
10859	[ALC883_MITAC] = {
10860		.mixers = { alc883_mitac_mixer },
10861		.init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10862		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10863		.dac_nids = alc883_dac_nids,
10864		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10865		.channel_mode = alc883_3ST_2ch_modes,
10866		.input_mux = &alc883_capture_source,
10867		.unsol_event = alc_sku_unsol_event,
10868		.setup = alc883_mitac_setup,
10869		.init_hook = alc_hp_automute,
10870	},
10871	[ALC883_FUJITSU_PI2515] = {
10872		.mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10873		.init_verbs = { alc883_init_verbs,
10874				alc883_2ch_fujitsu_pi2515_verbs},
10875		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10876		.dac_nids = alc883_dac_nids,
10877		.dig_out_nid = ALC883_DIGOUT_NID,
10878		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10879		.channel_mode = alc883_3ST_2ch_modes,
10880		.input_mux = &alc883_fujitsu_pi2515_capture_source,
10881		.unsol_event = alc_sku_unsol_event,
10882		.setup = alc883_2ch_fujitsu_pi2515_setup,
10883		.init_hook = alc_hp_automute,
10884	},
10885	[ALC888_FUJITSU_XA3530] = {
10886		.mixers = { alc888_base_mixer, alc883_chmode_mixer },
10887		.init_verbs = { alc883_init_verbs,
10888			alc888_fujitsu_xa3530_verbs },
10889		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10890		.dac_nids = alc883_dac_nids,
10891		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10892		.adc_nids = alc883_adc_nids_rev,
10893		.capsrc_nids = alc883_capsrc_nids_rev,
10894		.dig_out_nid = ALC883_DIGOUT_NID,
10895		.num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10896		.channel_mode = alc888_4ST_8ch_intel_modes,
10897		.num_mux_defs =
10898			ARRAY_SIZE(alc888_2_capture_sources),
10899		.input_mux = alc888_2_capture_sources,
10900		.unsol_event = alc_sku_unsol_event,
10901		.setup = alc888_fujitsu_xa3530_setup,
10902		.init_hook = alc_hp_automute,
10903	},
10904	[ALC888_LENOVO_SKY] = {
10905		.mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10906		.init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10907		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10908		.dac_nids = alc883_dac_nids,
10909		.dig_out_nid = ALC883_DIGOUT_NID,
10910		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10911		.channel_mode = alc883_sixstack_modes,
10912		.need_dac_fix = 1,
10913		.input_mux = &alc883_lenovo_sky_capture_source,
10914		.unsol_event = alc_sku_unsol_event,
10915		.setup = alc888_lenovo_sky_setup,
10916		.init_hook = alc_hp_automute,
10917	},
10918	[ALC888_ASUS_M90V] = {
10919		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10920		.init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10921		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10922		.dac_nids = alc883_dac_nids,
10923		.dig_out_nid = ALC883_DIGOUT_NID,
10924		.dig_in_nid = ALC883_DIGIN_NID,
10925		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10926		.channel_mode = alc883_3ST_6ch_modes,
10927		.need_dac_fix = 1,
10928		.input_mux = &alc883_fujitsu_pi2515_capture_source,
10929		.unsol_event = alc_sku_unsol_event,
10930		.setup = alc883_mode2_setup,
10931		.init_hook = alc_inithook,
10932	},
10933	[ALC888_ASUS_EEE1601] = {
10934		.mixers = { alc883_asus_eee1601_mixer },
10935		.cap_mixer = alc883_asus_eee1601_cap_mixer,
10936		.init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10937		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10938		.dac_nids = alc883_dac_nids,
10939		.dig_out_nid = ALC883_DIGOUT_NID,
10940		.dig_in_nid = ALC883_DIGIN_NID,
10941		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10942		.channel_mode = alc883_3ST_2ch_modes,
10943		.need_dac_fix = 1,
10944		.input_mux = &alc883_asus_eee1601_capture_source,
10945		.unsol_event = alc_sku_unsol_event,
10946		.init_hook = alc883_eee1601_inithook,
10947	},
10948	[ALC1200_ASUS_P5Q] = {
10949		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
10950		.init_verbs = { alc883_init_verbs },
10951		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10952		.dac_nids = alc883_dac_nids,
10953		.dig_out_nid = ALC1200_DIGOUT_NID,
10954		.dig_in_nid = ALC883_DIGIN_NID,
10955		.slave_dig_outs = alc1200_slave_dig_outs,
10956		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10957		.channel_mode = alc883_sixstack_modes,
10958		.input_mux = &alc883_capture_source,
10959	},
10960	[ALC889A_MB31] = {
10961		.mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10962		.init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10963			alc880_gpio1_init_verbs },
10964		.adc_nids = alc883_adc_nids,
10965		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10966		.capsrc_nids = alc883_capsrc_nids,
10967		.dac_nids = alc883_dac_nids,
10968		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10969		.channel_mode = alc889A_mb31_6ch_modes,
10970		.num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10971		.input_mux = &alc889A_mb31_capture_source,
10972		.dig_out_nid = ALC883_DIGOUT_NID,
10973		.unsol_event = alc889A_mb31_unsol_event,
10974		.init_hook = alc889A_mb31_automute,
10975	},
10976	[ALC883_SONY_VAIO_TT] = {
10977		.mixers = { alc883_vaiott_mixer },
10978		.init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10979		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
10980		.dac_nids = alc883_dac_nids,
10981		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10982		.channel_mode = alc883_3ST_2ch_modes,
10983		.input_mux = &alc883_capture_source,
10984		.unsol_event = alc_sku_unsol_event,
10985		.setup = alc883_vaiott_setup,
10986		.init_hook = alc_hp_automute,
10987	},
10988};
10989
10990
10991/*
10992 * Pin config fixes
10993 */
10994enum {
10995	PINFIX_ABIT_AW9D_MAX,
10996	PINFIX_LENOVO_Y530,
10997	PINFIX_PB_M5210,
10998	PINFIX_ACER_ASPIRE_7736,
10999};
11000
11001static const struct alc_fixup alc882_fixups[] = {
11002	[PINFIX_ABIT_AW9D_MAX] = {
11003		.type = ALC_FIXUP_PINS,
11004		.v.pins = (const struct alc_pincfg[]) {
11005			{ 0x15, 0x01080104 }, /* side */
11006			{ 0x16, 0x01011012 }, /* rear */
11007			{ 0x17, 0x01016011 }, /* clfe */
11008			{ }
11009		}
11010	},
11011	[PINFIX_LENOVO_Y530] = {
11012		.type = ALC_FIXUP_PINS,
11013		.v.pins = (const struct alc_pincfg[]) {
11014			{ 0x15, 0x99130112 }, /* rear int speakers */
11015			{ 0x16, 0x99130111 }, /* subwoofer */
11016			{ }
11017		}
11018	},
11019	[PINFIX_PB_M5210] = {
11020		.type = ALC_FIXUP_VERBS,
11021		.v.verbs = (const struct hda_verb[]) {
11022			{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
11023			{}
11024		}
11025	},
11026	[PINFIX_ACER_ASPIRE_7736] = {
11027		.type = ALC_FIXUP_SKU,
11028		.v.sku = ALC_FIXUP_SKU_IGNORE,
11029	},
11030};
11031
11032static const struct snd_pci_quirk alc882_fixup_tbl[] = {
11033	SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
11034	SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
11035	SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
11036	SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
11037	{}
11038};
11039
11040/*
11041 * BIOS auto configuration
11042 */
11043static int alc882_auto_create_input_ctls(struct hda_codec *codec,
11044						const struct auto_pin_cfg *cfg)
11045{
11046	return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
11047}
11048
11049static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
11050					      hda_nid_t nid, int pin_type,
11051					      hda_nid_t dac)
11052{
11053	int idx;
11054
11055	/* set as output */
11056	alc_set_pin_output(codec, nid, pin_type);
11057
11058	if (dac == 0x25)
11059		idx = 4;
11060	else if (dac >= 0x02 && dac <= 0x05)
11061		idx = dac - 2;
11062	else
11063		return;
11064	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
11065}
11066
11067static void alc882_auto_init_multi_out(struct hda_codec *codec)
11068{
11069	struct alc_spec *spec = codec->spec;
11070	int i;
11071
11072	for (i = 0; i <= HDA_SIDE; i++) {
11073		hda_nid_t nid = spec->autocfg.line_out_pins[i];
11074		int pin_type = get_pin_type(spec->autocfg.line_out_type);
11075		if (nid)
11076			alc882_auto_set_output_and_unmute(codec, nid, pin_type,
11077					spec->multiout.dac_nids[i]);
11078	}
11079}
11080
11081static void alc882_auto_init_hp_out(struct hda_codec *codec)
11082{
11083	struct alc_spec *spec = codec->spec;
11084	hda_nid_t pin, dac;
11085	int i;
11086
11087	if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) {
11088		for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
11089			pin = spec->autocfg.hp_pins[i];
11090			if (!pin)
11091				break;
11092			dac = spec->multiout.hp_nid;
11093			if (!dac)
11094				dac = spec->multiout.dac_nids[0]; /* to front */
11095			alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
11096		}
11097	}
11098
11099	if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) {
11100		for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
11101			pin = spec->autocfg.speaker_pins[i];
11102			if (!pin)
11103				break;
11104			dac = spec->multiout.extra_out_nid[0];
11105			if (!dac)
11106				dac = spec->multiout.dac_nids[0]; /* to front */
11107			alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
11108		}
11109	}
11110}
11111
11112static void alc882_auto_init_analog_input(struct hda_codec *codec)
11113{
11114	struct alc_spec *spec = codec->spec;
11115	struct auto_pin_cfg *cfg = &spec->autocfg;
11116	int i;
11117
11118	for (i = 0; i < cfg->num_inputs; i++) {
11119		hda_nid_t nid = cfg->inputs[i].pin;
11120		alc_set_input_pin(codec, nid, cfg->inputs[i].type);
11121		if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
11122			snd_hda_codec_write(codec, nid, 0,
11123					    AC_VERB_SET_AMP_GAIN_MUTE,
11124					    AMP_OUT_MUTE);
11125	}
11126}
11127
11128static void alc882_auto_init_input_src(struct hda_codec *codec)
11129{
11130	struct alc_spec *spec = codec->spec;
11131	int c;
11132
11133	for (c = 0; c < spec->num_adc_nids; c++) {
11134		hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
11135		hda_nid_t nid = spec->capsrc_nids[c];
11136		unsigned int mux_idx;
11137		const struct hda_input_mux *imux;
11138		int conns, mute, idx, item;
11139
11140		/* mute ADC */
11141		snd_hda_codec_write(codec, spec->adc_nids[c], 0,
11142				    AC_VERB_SET_AMP_GAIN_MUTE,
11143				    AMP_IN_MUTE(0));
11144
11145		conns = snd_hda_get_connections(codec, nid, conn_list,
11146						ARRAY_SIZE(conn_list));
11147		if (conns < 0)
11148			continue;
11149		mux_idx = c >= spec->num_mux_defs ? 0 : c;
11150		imux = &spec->input_mux[mux_idx];
11151		if (!imux->num_items && mux_idx > 0)
11152			imux = &spec->input_mux[0];
11153		for (idx = 0; idx < conns; idx++) {
11154			/* if the current connection is the selected one,
11155			 * unmute it as default - otherwise mute it
11156			 */
11157			mute = AMP_IN_MUTE(idx);
11158			for (item = 0; item < imux->num_items; item++) {
11159				if (imux->items[item].index == idx) {
11160					if (spec->cur_mux[c] == item)
11161						mute = AMP_IN_UNMUTE(idx);
11162					break;
11163				}
11164			}
11165			/* check if we have a selector or mixer
11166			 * we could check for the widget type instead, but
11167			 * just check for Amp-In presence (in case of mixer
11168			 * without amp-in there is something wrong, this
11169			 * function shouldn't be used or capsrc nid is wrong)
11170			 */
11171			if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
11172				snd_hda_codec_write(codec, nid, 0,
11173						    AC_VERB_SET_AMP_GAIN_MUTE,
11174						    mute);
11175			else if (mute != AMP_IN_MUTE(idx))
11176				snd_hda_codec_write(codec, nid, 0,
11177						    AC_VERB_SET_CONNECT_SEL,
11178						    idx);
11179		}
11180	}
11181}
11182
11183/* add mic boosts if needed */
11184static int alc_auto_add_mic_boost(struct hda_codec *codec)
11185{
11186	struct alc_spec *spec = codec->spec;
11187	struct auto_pin_cfg *cfg = &spec->autocfg;
11188	int i, err;
11189	int type_idx = 0;
11190	hda_nid_t nid;
11191	const char *prev_label = NULL;
11192
11193	for (i = 0; i < cfg->num_inputs; i++) {
11194		if (cfg->inputs[i].type > AUTO_PIN_MIC)
11195			break;
11196		nid = cfg->inputs[i].pin;
11197		if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
11198			const char *label;
11199			char boost_label[32];
11200
11201			label = hda_get_autocfg_input_label(codec, cfg, i);
11202			if (prev_label && !strcmp(label, prev_label))
11203				type_idx++;
11204			else
11205				type_idx = 0;
11206			prev_label = label;
11207
11208			snprintf(boost_label, sizeof(boost_label),
11209				 "%s Boost Volume", label);
11210			err = add_control(spec, ALC_CTL_WIDGET_VOL,
11211					  boost_label, type_idx,
11212				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11213			if (err < 0)
11214				return err;
11215		}
11216	}
11217	return 0;
11218}
11219
11220/* almost identical with ALC880 parser... */
11221static int alc882_parse_auto_config(struct hda_codec *codec)
11222{
11223	struct alc_spec *spec = codec->spec;
11224	static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
11225	int err;
11226
11227	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11228					   alc882_ignore);
11229	if (err < 0)
11230		return err;
11231	if (!spec->autocfg.line_outs)
11232		return 0; /* can't find valid BIOS pin config */
11233
11234	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
11235	if (err < 0)
11236		return err;
11237	err = alc_auto_add_multi_channel_mode(codec);
11238	if (err < 0)
11239		return err;
11240	err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
11241	if (err < 0)
11242		return err;
11243	err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
11244					   "Headphone");
11245	if (err < 0)
11246		return err;
11247	err = alc880_auto_create_extra_out(spec,
11248					   spec->autocfg.speaker_pins[0],
11249					   "Speaker");
11250	if (err < 0)
11251		return err;
11252	err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
11253	if (err < 0)
11254		return err;
11255
11256	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11257
11258	alc_auto_parse_digital(codec);
11259
11260	if (spec->kctls.list)
11261		add_mixer(spec, spec->kctls.list);
11262
11263	add_verb(spec, alc883_auto_init_verbs);
11264	/* if ADC 0x07 is available, initialize it, too */
11265	if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
11266		add_verb(spec, alc882_adc1_init_verbs);
11267
11268	spec->num_mux_defs = 1;
11269	spec->input_mux = &spec->private_imux[0];
11270
11271	alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
11272
11273	err = alc_auto_add_mic_boost(codec);
11274	if (err < 0)
11275		return err;
11276
11277	return 1; /* config found */
11278}
11279
11280/* additional initialization for auto-configuration model */
11281static void alc882_auto_init(struct hda_codec *codec)
11282{
11283	struct alc_spec *spec = codec->spec;
11284	alc882_auto_init_multi_out(codec);
11285	alc882_auto_init_hp_out(codec);
11286	alc882_auto_init_analog_input(codec);
11287	alc882_auto_init_input_src(codec);
11288	alc_auto_init_digital(codec);
11289	if (spec->unsol_event)
11290		alc_inithook(codec);
11291}
11292
11293static int patch_alc882(struct hda_codec *codec)
11294{
11295	struct alc_spec *spec;
11296	int err, board_config;
11297
11298	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11299	if (spec == NULL)
11300		return -ENOMEM;
11301
11302	codec->spec = spec;
11303
11304	switch (codec->vendor_id) {
11305	case 0x10ec0882:
11306	case 0x10ec0885:
11307		break;
11308	default:
11309		/* ALC883 and variants */
11310		alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11311		break;
11312	}
11313
11314	board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
11315						  alc882_models,
11316						  alc882_cfg_tbl);
11317
11318	if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
11319		board_config = snd_hda_check_board_codec_sid_config(codec,
11320			ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
11321
11322	if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
11323		printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
11324		       codec->chip_name);
11325		board_config = ALC882_AUTO;
11326	}
11327
11328	if (board_config == ALC882_AUTO) {
11329		alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11330		alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11331	}
11332
11333	alc_auto_parse_customize_define(codec);
11334
11335	if (board_config == ALC882_AUTO) {
11336		/* automatic parse from the BIOS config */
11337		err = alc882_parse_auto_config(codec);
11338		if (err < 0) {
11339			alc_free(codec);
11340			return err;
11341		} else if (!err) {
11342			printk(KERN_INFO
11343			       "hda_codec: Cannot set up configuration "
11344			       "from BIOS.  Using base mode...\n");
11345			board_config = ALC882_3ST_DIG;
11346		}
11347	}
11348
11349	if (has_cdefine_beep(codec)) {
11350		err = snd_hda_attach_beep_device(codec, 0x1);
11351		if (err < 0) {
11352			alc_free(codec);
11353			return err;
11354		}
11355	}
11356
11357	if (board_config != ALC882_AUTO)
11358		setup_preset(codec, &alc882_presets[board_config]);
11359
11360	spec->stream_analog_playback = &alc882_pcm_analog_playback;
11361	spec->stream_analog_capture = &alc882_pcm_analog_capture;
11362	/* FIXME: setup DAC5 */
11363	/*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
11364	spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11365
11366	spec->stream_digital_playback = &alc882_pcm_digital_playback;
11367	spec->stream_digital_capture = &alc882_pcm_digital_capture;
11368
11369	if (!spec->adc_nids && spec->input_mux) {
11370		int i, j;
11371		spec->num_adc_nids = 0;
11372		for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
11373			const struct hda_input_mux *imux = spec->input_mux;
11374			hda_nid_t cap;
11375			hda_nid_t items[16];
11376			hda_nid_t nid = alc882_adc_nids[i];
11377			unsigned int wcap = get_wcaps(codec, nid);
11378			/* get type */
11379			wcap = get_wcaps_type(wcap);
11380			if (wcap != AC_WID_AUD_IN)
11381				continue;
11382			spec->private_adc_nids[spec->num_adc_nids] = nid;
11383			err = snd_hda_get_connections(codec, nid, &cap, 1);
11384			if (err < 0)
11385				continue;
11386			err = snd_hda_get_connections(codec, cap, items,
11387						      ARRAY_SIZE(items));
11388			if (err < 0)
11389				continue;
11390			for (j = 0; j < imux->num_items; j++)
11391				if (imux->items[j].index >= err)
11392					break;
11393			if (j < imux->num_items)
11394				continue;
11395			spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11396			spec->num_adc_nids++;
11397		}
11398		spec->adc_nids = spec->private_adc_nids;
11399		spec->capsrc_nids = spec->private_capsrc_nids;
11400	}
11401
11402	set_capture_mixer(codec);
11403
11404	if (has_cdefine_beep(codec))
11405		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11406
11407	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
11408
11409	spec->vmaster_nid = 0x0c;
11410
11411	codec->patch_ops = alc_patch_ops;
11412	if (board_config == ALC882_AUTO)
11413		spec->init_hook = alc882_auto_init;
11414
11415	alc_init_jacks(codec);
11416#ifdef CONFIG_SND_HDA_POWER_SAVE
11417	if (!spec->loopback.amplist)
11418		spec->loopback.amplist = alc882_loopbacks;
11419#endif
11420
11421	return 0;
11422}
11423
11424
11425/*
11426 * ALC262 support
11427 */
11428
11429#define ALC262_DIGOUT_NID	ALC880_DIGOUT_NID
11430#define ALC262_DIGIN_NID	ALC880_DIGIN_NID
11431
11432#define alc262_dac_nids		alc260_dac_nids
11433#define alc262_adc_nids		alc882_adc_nids
11434#define alc262_adc_nids_alt	alc882_adc_nids_alt
11435#define alc262_capsrc_nids	alc882_capsrc_nids
11436#define alc262_capsrc_nids_alt	alc882_capsrc_nids_alt
11437
11438#define alc262_modes		alc260_modes
11439#define alc262_capture_source	alc882_capture_source
11440
11441static const hda_nid_t alc262_dmic_adc_nids[1] = {
11442	/* ADC0 */
11443	0x09
11444};
11445
11446static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11447
11448static const struct snd_kcontrol_new alc262_base_mixer[] = {
11449	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11450	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11451	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11452	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11453	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11454	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11455	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11456	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11457	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11458	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11459	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11460	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11461	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11462	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11463	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11464	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11465	{ } /* end */
11466};
11467
11468/* update HP, line and mono-out pins according to the master switch */
11469#define alc262_hp_master_update		alc260_hp_master_update
11470
11471static void alc262_hp_bpc_setup(struct hda_codec *codec)
11472{
11473	struct alc_spec *spec = codec->spec;
11474
11475	spec->autocfg.hp_pins[0] = 0x1b;
11476	spec->autocfg.speaker_pins[0] = 0x16;
11477	spec->automute = 1;
11478	spec->automute_mode = ALC_AUTOMUTE_PIN;
11479}
11480
11481static void alc262_hp_wildwest_setup(struct hda_codec *codec)
11482{
11483	struct alc_spec *spec = codec->spec;
11484
11485	spec->autocfg.hp_pins[0] = 0x15;
11486	spec->autocfg.speaker_pins[0] = 0x16;
11487	spec->automute = 1;
11488	spec->automute_mode = ALC_AUTOMUTE_PIN;
11489}
11490
11491#define alc262_hp_master_sw_get		alc260_hp_master_sw_get
11492#define alc262_hp_master_sw_put		alc260_hp_master_sw_put
11493
11494#define ALC262_HP_MASTER_SWITCH					\
11495	{							\
11496		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,		\
11497		.name = "Master Playback Switch",		\
11498		.info = snd_ctl_boolean_mono_info,		\
11499		.get = alc262_hp_master_sw_get,			\
11500		.put = alc262_hp_master_sw_put,			\
11501	}, \
11502	{							\
11503		.iface = NID_MAPPING,				\
11504		.name = "Master Playback Switch",		\
11505		.private_value = 0x15 | (0x16 << 8) | (0x1b << 16),	\
11506	}
11507
11508
11509static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
11510	ALC262_HP_MASTER_SWITCH,
11511	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11512	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11513	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11514	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11515			      HDA_OUTPUT),
11516	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11517			    HDA_OUTPUT),
11518	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11519	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11520	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11521	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11522	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11523	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11524	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11525	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11526	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11527	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11528	HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11529	HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11530	{ } /* end */
11531};
11532
11533static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
11534	ALC262_HP_MASTER_SWITCH,
11535	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11536	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11537	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11538	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11539	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11540			      HDA_OUTPUT),
11541	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11542			    HDA_OUTPUT),
11543	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11544	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
11545	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
11546	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11547	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11548	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11549	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11550	{ } /* end */
11551};
11552
11553static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11554	HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11555	HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11556	HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
11557	{ } /* end */
11558};
11559
11560/* mute/unmute internal speaker according to the hp jack and mute state */
11561static void alc262_hp_t5735_setup(struct hda_codec *codec)
11562{
11563	struct alc_spec *spec = codec->spec;
11564
11565	spec->autocfg.hp_pins[0] = 0x15;
11566	spec->autocfg.speaker_pins[0] = 0x14;
11567	spec->automute = 1;
11568	spec->automute_mode = ALC_AUTOMUTE_PIN;
11569}
11570
11571static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
11572	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11573	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11574	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11575	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11576	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11577	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11578	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11579	{ } /* end */
11580};
11581
11582static const struct hda_verb alc262_hp_t5735_verbs[] = {
11583	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11584	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11585
11586	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11587	{ }
11588};
11589
11590static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
11591	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11592	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11593	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11594	HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
11595	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11596	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11597	{ } /* end */
11598};
11599
11600static const struct hda_verb alc262_hp_rp5700_verbs[] = {
11601	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11602	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11603	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11604	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11605	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11606	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11607	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11608	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11609	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11610	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11611	{}
11612};
11613
11614static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
11615	.num_items = 1,
11616	.items = {
11617		{ "Line", 0x1 },
11618	},
11619};
11620
11621/* bind hp and internal speaker mute (with plug check) as master switch */
11622#define alc262_hippo_master_update	alc262_hp_master_update
11623#define alc262_hippo_master_sw_get	alc262_hp_master_sw_get
11624#define alc262_hippo_master_sw_put	alc262_hp_master_sw_put
11625
11626#define ALC262_HIPPO_MASTER_SWITCH				\
11627	{							\
11628		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,		\
11629		.name = "Master Playback Switch",		\
11630		.info = snd_ctl_boolean_mono_info,		\
11631		.get = alc262_hippo_master_sw_get,		\
11632		.put = alc262_hippo_master_sw_put,		\
11633	},							\
11634	{							\
11635		.iface = NID_MAPPING,				\
11636		.name = "Master Playback Switch",		\
11637		.subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11638			     (SUBDEV_SPEAKER(0) << 16), \
11639	}
11640
11641static const struct snd_kcontrol_new alc262_hippo_mixer[] = {
11642	ALC262_HIPPO_MASTER_SWITCH,
11643	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11644	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11645	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11646	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11647	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11648	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11649	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11650	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11651	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11652	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11653	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11654	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11655	{ } /* end */
11656};
11657
11658static const struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11659	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11660	ALC262_HIPPO_MASTER_SWITCH,
11661	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11662	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11663	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11664	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11665	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11666	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11667	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11668	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11669	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11670	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11671	{ } /* end */
11672};
11673
11674/* mute/unmute internal speaker according to the hp jack and mute state */
11675static void alc262_hippo_setup(struct hda_codec *codec)
11676{
11677	struct alc_spec *spec = codec->spec;
11678
11679	spec->autocfg.hp_pins[0] = 0x15;
11680	spec->autocfg.speaker_pins[0] = 0x14;
11681	spec->automute = 1;
11682	spec->automute_mode = ALC_AUTOMUTE_AMP;
11683}
11684
11685static void alc262_hippo1_setup(struct hda_codec *codec)
11686{
11687	struct alc_spec *spec = codec->spec;
11688
11689	spec->autocfg.hp_pins[0] = 0x1b;
11690	spec->autocfg.speaker_pins[0] = 0x14;
11691	spec->automute = 1;
11692	spec->automute_mode = ALC_AUTOMUTE_AMP;
11693}
11694
11695
11696static const struct snd_kcontrol_new alc262_sony_mixer[] = {
11697	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11698	ALC262_HIPPO_MASTER_SWITCH,
11699	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11700	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11701	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11702	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11703	{ } /* end */
11704};
11705
11706static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
11707	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11708	ALC262_HIPPO_MASTER_SWITCH,
11709	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11710	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11711	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11712	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11713	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11714	{ } /* end */
11715};
11716
11717static const struct snd_kcontrol_new alc262_tyan_mixer[] = {
11718	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11719	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11720	HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11721	HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11722	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11723	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11724	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11725	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11726	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11727	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11728	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11729	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11730	{ } /* end */
11731};
11732
11733static const struct hda_verb alc262_tyan_verbs[] = {
11734	/* Headphone automute */
11735	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11736	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11737	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11738
11739	/* P11 AUX_IN, white 4-pin connector */
11740	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11741	{0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11742	{0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11743	{0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11744
11745	{}
11746};
11747
11748/* unsolicited event for HP jack sensing */
11749static void alc262_tyan_setup(struct hda_codec *codec)
11750{
11751	struct alc_spec *spec = codec->spec;
11752
11753	spec->autocfg.hp_pins[0] = 0x1b;
11754	spec->autocfg.speaker_pins[0] = 0x15;
11755	spec->automute = 1;
11756	spec->automute_mode = ALC_AUTOMUTE_AMP;
11757}
11758
11759
11760#define alc262_capture_mixer		alc882_capture_mixer
11761#define alc262_capture_alt_mixer	alc882_capture_alt_mixer
11762
11763/*
11764 * generic initialization of ADC, input mixers and output mixers
11765 */
11766static const struct hda_verb alc262_init_verbs[] = {
11767	/*
11768	 * Unmute ADC0-2 and set the default input to mic-in
11769	 */
11770	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11771	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11772	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11773	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11774	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11775	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11776
11777	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11778	 * mixer widget
11779	 * Note: PASD motherboards uses the Line In 2 as the input for
11780	 * front panel mic (mic 2)
11781	 */
11782	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11783	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11784	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11785	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11786	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11787	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11788
11789	/*
11790	 * Set up output mixers (0x0c - 0x0e)
11791	 */
11792	/* set vol=0 to output mixers */
11793	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11794	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11795	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11796	/* set up input amps for analog loopback */
11797	/* Amp Indices: DAC = 0, mixer = 1 */
11798	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11799	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11800	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11801	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11802	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11803	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11804
11805	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11806	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11807	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11808	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11809	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11810	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11811
11812	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11813	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11814	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11815	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11816	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11817
11818	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11819	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11820
11821	/* FIXME: use matrix-type input source selection */
11822	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11823	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11824	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11825	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11826	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11827	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11828	/* Input mixer2 */
11829	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11830	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11831	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11832	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11833	/* Input mixer3 */
11834	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11835	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11836	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11837	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11838
11839	{ }
11840};
11841
11842static const struct hda_verb alc262_eapd_verbs[] = {
11843	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11844	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11845	{ }
11846};
11847
11848static const struct hda_verb alc262_hippo1_unsol_verbs[] = {
11849	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11850	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11851	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11852
11853	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11854	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11855	{}
11856};
11857
11858static const struct hda_verb alc262_sony_unsol_verbs[] = {
11859	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11860	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11861	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},	// Front Mic
11862
11863	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11864	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11865	{}
11866};
11867
11868static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11869	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11870	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11871	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11872	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11873	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11874	{ } /* end */
11875};
11876
11877static const struct hda_verb alc262_toshiba_s06_verbs[] = {
11878	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11879	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11880	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11881	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11882	{0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11883	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11884	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11885	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11886	{}
11887};
11888
11889static void alc262_toshiba_s06_setup(struct hda_codec *codec)
11890{
11891	struct alc_spec *spec = codec->spec;
11892
11893	spec->autocfg.hp_pins[0] = 0x15;
11894	spec->autocfg.speaker_pins[0] = 0x14;
11895	spec->ext_mic.pin = 0x18;
11896	spec->ext_mic.mux_idx = 0;
11897	spec->int_mic.pin = 0x12;
11898	spec->int_mic.mux_idx = 9;
11899	spec->auto_mic = 1;
11900	spec->automute = 1;
11901	spec->automute_mode = ALC_AUTOMUTE_PIN;
11902}
11903
11904/*
11905 * nec model
11906 *  0x15 = headphone
11907 *  0x16 = internal speaker
11908 *  0x18 = external mic
11909 */
11910
11911static const struct snd_kcontrol_new alc262_nec_mixer[] = {
11912	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11913	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11914
11915	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11916	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11917	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11918
11919	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11920	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11921	{ } /* end */
11922};
11923
11924static const struct hda_verb alc262_nec_verbs[] = {
11925	/* Unmute Speaker */
11926	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11927
11928	/* Headphone */
11929	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11930	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11931
11932	/* External mic to headphone */
11933	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11934	/* External mic to speaker */
11935	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11936	{}
11937};
11938
11939/*
11940 * fujitsu model
11941 *  0x14 = headphone/spdif-out, 0x15 = internal speaker,
11942 *  0x1b = port replicator headphone out
11943 */
11944
11945#define ALC_HP_EVENT	ALC880_HP_EVENT
11946
11947static const struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11948	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11949	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11950	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11951	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11952	{}
11953};
11954
11955static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
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_init_verbs[] = {
11962	/* Front Mic pin: input vref at 50% */
11963	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11964	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11965	{}
11966};
11967
11968static const struct hda_input_mux alc262_fujitsu_capture_source = {
11969	.num_items = 3,
11970	.items = {
11971		{ "Mic", 0x0 },
11972		{ "Internal Mic", 0x1 },
11973		{ "CD", 0x4 },
11974	},
11975};
11976
11977static const struct hda_input_mux alc262_HP_capture_source = {
11978	.num_items = 5,
11979	.items = {
11980		{ "Mic", 0x0 },
11981		{ "Front Mic", 0x1 },
11982		{ "Line", 0x2 },
11983		{ "CD", 0x4 },
11984		{ "AUX IN", 0x6 },
11985	},
11986};
11987
11988static const struct hda_input_mux alc262_HP_D7000_capture_source = {
11989	.num_items = 4,
11990	.items = {
11991		{ "Mic", 0x0 },
11992		{ "Front Mic", 0x2 },
11993		{ "Line", 0x1 },
11994		{ "CD", 0x4 },
11995	},
11996};
11997
11998static void alc262_fujitsu_setup(struct hda_codec *codec)
11999{
12000	struct alc_spec *spec = codec->spec;
12001
12002	spec->autocfg.hp_pins[0] = 0x14;
12003	spec->autocfg.hp_pins[1] = 0x1b;
12004	spec->autocfg.speaker_pins[0] = 0x15;
12005	spec->automute = 1;
12006	spec->automute_mode = ALC_AUTOMUTE_AMP;
12007}
12008
12009/* bind volumes of both NID 0x0c and 0x0d */
12010static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
12011	.ops = &snd_hda_bind_vol,
12012	.values = {
12013		HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
12014		HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
12015		0
12016	},
12017};
12018
12019static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
12020	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
12021	{
12022		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12023		.name = "Master Playback Switch",
12024		.subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
12025		.info = snd_ctl_boolean_mono_info,
12026		.get = alc262_hp_master_sw_get,
12027		.put = alc262_hp_master_sw_put,
12028	},
12029	{
12030		.iface = NID_MAPPING,
12031		.name = "Master Playback Switch",
12032		.private_value = 0x1b,
12033	},
12034	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12035	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12036	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12037	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12038	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12039	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12040	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12041	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12042	{ } /* end */
12043};
12044
12045static void alc262_lenovo_3000_setup(struct hda_codec *codec)
12046{
12047	struct alc_spec *spec = codec->spec;
12048
12049	spec->autocfg.hp_pins[0] = 0x1b;
12050	spec->autocfg.speaker_pins[0] = 0x14;
12051	spec->autocfg.speaker_pins[1] = 0x16;
12052	spec->automute = 1;
12053	spec->automute_mode = ALC_AUTOMUTE_AMP;
12054}
12055
12056static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
12057	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
12058	{
12059		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12060		.name = "Master Playback Switch",
12061		.subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
12062		.info = snd_ctl_boolean_mono_info,
12063		.get = alc262_hp_master_sw_get,
12064		.put = alc262_hp_master_sw_put,
12065	},
12066	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12067	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12068	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12069	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12070	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12071	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12072	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12073	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12074	{ } /* end */
12075};
12076
12077static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
12078	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
12079	ALC262_HIPPO_MASTER_SWITCH,
12080	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12081	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12082	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12083	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12084	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12085	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
12086	{ } /* end */
12087};
12088
12089/* additional init verbs for Benq laptops */
12090static const struct hda_verb alc262_EAPD_verbs[] = {
12091	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12092	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
12093	{}
12094};
12095
12096static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
12097	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12098	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12099
12100	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12101	{0x20, AC_VERB_SET_PROC_COEF,  0x3050},
12102	{}
12103};
12104
12105/* Samsung Q1 Ultra Vista model setup */
12106static const struct snd_kcontrol_new alc262_ultra_mixer[] = {
12107	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
12108	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
12109	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12110	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12111	HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
12112	HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
12113	{ } /* end */
12114};
12115
12116static const struct hda_verb alc262_ultra_verbs[] = {
12117	/* output mixer */
12118	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12119	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12120	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12121	/* speaker */
12122	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12123	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12124	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12125	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12126	/* HP */
12127	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12128	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12129	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12130	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12131	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12132	/* internal mic */
12133	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12134	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12135	/* ADC, choose mic */
12136	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12137	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12138	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12139	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12140	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12141	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12142	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12143	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12144	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12145	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
12146	{}
12147};
12148
12149/* mute/unmute internal speaker according to the hp jack and mute state */
12150static void alc262_ultra_automute(struct hda_codec *codec)
12151{
12152	struct alc_spec *spec = codec->spec;
12153	unsigned int mute;
12154
12155	mute = 0;
12156	/* auto-mute only when HP is used as HP */
12157	if (!spec->cur_mux[0]) {
12158		spec->jack_present = snd_hda_jack_detect(codec, 0x15);
12159		if (spec->jack_present)
12160			mute = HDA_AMP_MUTE;
12161	}
12162	/* mute/unmute internal speaker */
12163	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12164				 HDA_AMP_MUTE, mute);
12165	/* mute/unmute HP */
12166	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12167				 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
12168}
12169
12170/* unsolicited event for HP jack sensing */
12171static void alc262_ultra_unsol_event(struct hda_codec *codec,
12172				       unsigned int res)
12173{
12174	if ((res >> 26) != ALC880_HP_EVENT)
12175		return;
12176	alc262_ultra_automute(codec);
12177}
12178
12179static const struct hda_input_mux alc262_ultra_capture_source = {
12180	.num_items = 2,
12181	.items = {
12182		{ "Mic", 0x1 },
12183		{ "Headphone", 0x7 },
12184	},
12185};
12186
12187static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12188				     struct snd_ctl_elem_value *ucontrol)
12189{
12190	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12191	struct alc_spec *spec = codec->spec;
12192	int ret;
12193
12194	ret = alc_mux_enum_put(kcontrol, ucontrol);
12195	if (!ret)
12196		return 0;
12197	/* reprogram the HP pin as mic or HP according to the input source */
12198	snd_hda_codec_write_cache(codec, 0x15, 0,
12199				  AC_VERB_SET_PIN_WIDGET_CONTROL,
12200				  spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12201	alc262_ultra_automute(codec); /* mute/unmute HP */
12202	return ret;
12203}
12204
12205static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
12206	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12207	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12208	{
12209		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12210		.name = "Capture Source",
12211		.info = alc_mux_enum_info,
12212		.get = alc_mux_enum_get,
12213		.put = alc262_ultra_mux_enum_put,
12214	},
12215	{
12216		.iface = NID_MAPPING,
12217		.name = "Capture Source",
12218		.private_value = 0x15,
12219	},
12220	{ } /* end */
12221};
12222
12223/* We use two mixers depending on the output pin; 0x16 is a mono output
12224 * and thus it's bound with a different mixer.
12225 * This function returns which mixer amp should be used.
12226 */
12227static int alc262_check_volbit(hda_nid_t nid)
12228{
12229	if (!nid)
12230		return 0;
12231	else if (nid == 0x16)
12232		return 2;
12233	else
12234		return 1;
12235}
12236
12237static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
12238				  const char *pfx, int *vbits, int idx)
12239{
12240	unsigned long val;
12241	int vbit;
12242
12243	vbit = alc262_check_volbit(nid);
12244	if (!vbit)
12245		return 0;
12246	if (*vbits & vbit) /* a volume control for this mixer already there */
12247		return 0;
12248	*vbits |= vbit;
12249	if (vbit == 2)
12250		val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12251	else
12252		val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
12253	return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
12254}
12255
12256static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
12257				 const char *pfx, int idx)
12258{
12259	unsigned long val;
12260
12261	if (!nid)
12262		return 0;
12263	if (nid == 0x16)
12264		val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12265	else
12266		val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
12267	return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
12268}
12269
12270/* add playback controls from the parsed DAC table */
12271static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12272					     const struct auto_pin_cfg *cfg)
12273{
12274	const char *pfx;
12275	int vbits;
12276	int i, err;
12277
12278	spec->multiout.num_dacs = 1;	/* only use one dac */
12279	spec->multiout.dac_nids = spec->private_dac_nids;
12280	spec->private_dac_nids[0] = 2;
12281
12282	pfx = alc_get_line_out_pfx(spec, true);
12283	if (!pfx)
12284		pfx = "Front";
12285	for (i = 0; i < 2; i++) {
12286		err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12287		if (err < 0)
12288			return err;
12289		if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12290			err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12291						    "Speaker", i);
12292			if (err < 0)
12293				return err;
12294		}
12295		if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12296			err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12297						    "Headphone", i);
12298			if (err < 0)
12299				return err;
12300		}
12301	}
12302
12303	vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12304		alc262_check_volbit(cfg->speaker_pins[0]) |
12305		alc262_check_volbit(cfg->hp_pins[0]);
12306	if (vbits == 1 || vbits == 2)
12307		pfx = "Master"; /* only one mixer is used */
12308	vbits = 0;
12309	for (i = 0; i < 2; i++) {
12310		err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12311					     &vbits, i);
12312		if (err < 0)
12313			return err;
12314		if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12315			err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12316						     "Speaker", &vbits, i);
12317			if (err < 0)
12318				return err;
12319		}
12320		if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12321			err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12322						     "Headphone", &vbits, i);
12323			if (err < 0)
12324				return err;
12325		}
12326	}
12327	return 0;
12328}
12329
12330#define alc262_auto_create_input_ctls \
12331	alc882_auto_create_input_ctls
12332
12333/*
12334 * generic initialization of ADC, input mixers and output mixers
12335 */
12336static const struct hda_verb alc262_volume_init_verbs[] = {
12337	/*
12338	 * Unmute ADC0-2 and set the default input to mic-in
12339	 */
12340	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12341	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12342	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12343	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12344	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12345	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12346
12347	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12348	 * mixer widget
12349	 * Note: PASD motherboards uses the Line In 2 as the input for
12350	 * front panel mic (mic 2)
12351	 */
12352	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12353	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12354	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12355	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12356	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12357	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12358
12359	/*
12360	 * Set up output mixers (0x0c - 0x0f)
12361	 */
12362	/* set vol=0 to output mixers */
12363	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12364	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12365	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12366
12367	/* set up input amps for analog loopback */
12368	/* Amp Indices: DAC = 0, mixer = 1 */
12369	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12370	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12371	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12372	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12373	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12374	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12375
12376	/* FIXME: use matrix-type input source selection */
12377	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12378	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12379	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12380	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12381	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12382	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12383	/* Input mixer2 */
12384	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12385	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12386	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12387	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12388	/* Input mixer3 */
12389	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12390	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12391	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12392	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12393
12394	{ }
12395};
12396
12397static const struct hda_verb alc262_HP_BPC_init_verbs[] = {
12398	/*
12399	 * Unmute ADC0-2 and set the default input to mic-in
12400	 */
12401	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12402	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12403	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12404	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12405	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12406	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12407
12408	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12409	 * mixer widget
12410	 * Note: PASD motherboards uses the Line In 2 as the input for
12411	 * front panel mic (mic 2)
12412	 */
12413	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12414	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12415	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12416	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12417	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12418	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12419	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12420        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12421
12422	/*
12423	 * Set up output mixers (0x0c - 0x0e)
12424	 */
12425	/* set vol=0 to output mixers */
12426	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12427	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12428	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12429
12430	/* set up input amps for analog loopback */
12431	/* Amp Indices: DAC = 0, mixer = 1 */
12432	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12433	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12434	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12435	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12436	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12437	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12438
12439	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12440	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12441	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12442
12443	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12444	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12445
12446	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12447	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12448
12449	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12450	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12451        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12452	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12453	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12454
12455	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12456	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12457        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12458	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12459	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12460	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12461
12462
12463	/* FIXME: use matrix-type input source selection */
12464	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12465	/* Input mixer1: only unmute Mic */
12466	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12467	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12468	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12469	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12470	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12471	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12472	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12473	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12474	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12475	/* Input mixer2 */
12476	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12477	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12478	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12479	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12480	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12481	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12482	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12483	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12484	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12485	/* Input mixer3 */
12486	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12487	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12488	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12489	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12490	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12491	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12492	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12493	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12494	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12495
12496	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12497
12498	{ }
12499};
12500
12501static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12502	/*
12503	 * Unmute ADC0-2 and set the default input to mic-in
12504	 */
12505	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12506	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12507	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12508	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12509	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12510	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12511
12512	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12513	 * mixer widget
12514	 * Note: PASD motherboards uses the Line In 2 as the input for front
12515	 * panel mic (mic 2)
12516	 */
12517	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12518	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12519	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12520	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12521	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12522	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12523	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12524	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12525	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12526	/*
12527	 * Set up output mixers (0x0c - 0x0e)
12528	 */
12529	/* set vol=0 to output mixers */
12530	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12531	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12532	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12533
12534	/* set up input amps for analog loopback */
12535	/* Amp Indices: DAC = 0, mixer = 1 */
12536	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12537	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12538	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12539	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12540	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12541	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12542
12543
12544	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },	/* HP */
12545	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Mono */
12546	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* rear MIC */
12547	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* Line in */
12548	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* Front MIC */
12549	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Line out */
12550	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* CD in */
12551
12552	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12553	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12554
12555	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12556	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12557
12558	/* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12559	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12560	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12561	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12562	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12563	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12564
12565	/* FIXME: use matrix-type input source selection */
12566	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12567	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12568	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12569	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12570	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12571	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12572	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12573        /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
12574	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12575	/* Input mixer2 */
12576	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12577	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12578	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12579	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12580	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12581        /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12582	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12583	/* Input mixer3 */
12584	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12585	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12586	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12587	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12588	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12589        /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12590	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12591
12592	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12593
12594	{ }
12595};
12596
12597static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12598
12599	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Front Speaker */
12600	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12601	{0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12602
12603	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* MIC jack */
12604	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* Front MIC */
12605	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12606	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12607
12608	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },	/* HP  jack */
12609	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12610	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12611	{}
12612};
12613
12614/*
12615 * Pin config fixes
12616 */
12617enum {
12618	PINFIX_FSC_H270,
12619	PINFIX_HP_Z200,
12620};
12621
12622static const struct alc_fixup alc262_fixups[] = {
12623	[PINFIX_FSC_H270] = {
12624		.type = ALC_FIXUP_PINS,
12625		.v.pins = (const struct alc_pincfg[]) {
12626			{ 0x14, 0x99130110 }, /* speaker */
12627			{ 0x15, 0x0221142f }, /* front HP */
12628			{ 0x1b, 0x0121141f }, /* rear HP */
12629			{ }
12630		}
12631	},
12632	[PINFIX_HP_Z200] = {
12633		.type = ALC_FIXUP_PINS,
12634		.v.pins = (const struct alc_pincfg[]) {
12635			{ 0x16, 0x99130120 }, /* internal speaker */
12636			{ }
12637		}
12638	},
12639};
12640
12641static const struct snd_pci_quirk alc262_fixup_tbl[] = {
12642	SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", PINFIX_HP_Z200),
12643	SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12644	{}
12645};
12646
12647
12648#ifdef CONFIG_SND_HDA_POWER_SAVE
12649#define alc262_loopbacks	alc880_loopbacks
12650#endif
12651
12652/* pcm configuration: identical with ALC880 */
12653#define alc262_pcm_analog_playback	alc880_pcm_analog_playback
12654#define alc262_pcm_analog_capture	alc880_pcm_analog_capture
12655#define alc262_pcm_digital_playback	alc880_pcm_digital_playback
12656#define alc262_pcm_digital_capture	alc880_pcm_digital_capture
12657
12658/*
12659 * BIOS auto configuration
12660 */
12661static int alc262_parse_auto_config(struct hda_codec *codec)
12662{
12663	struct alc_spec *spec = codec->spec;
12664	int err;
12665	static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12666
12667	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12668					   alc262_ignore);
12669	if (err < 0)
12670		return err;
12671	if (!spec->autocfg.line_outs) {
12672		if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12673			spec->multiout.max_channels = 2;
12674			spec->no_analog = 1;
12675			goto dig_only;
12676		}
12677		return 0; /* can't find valid BIOS pin config */
12678	}
12679	err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12680	if (err < 0)
12681		return err;
12682	err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
12683	if (err < 0)
12684		return err;
12685
12686	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12687
12688 dig_only:
12689	alc_auto_parse_digital(codec);
12690
12691	if (spec->kctls.list)
12692		add_mixer(spec, spec->kctls.list);
12693
12694	add_verb(spec, alc262_volume_init_verbs);
12695	spec->num_mux_defs = 1;
12696	spec->input_mux = &spec->private_imux[0];
12697
12698	err = alc_auto_add_mic_boost(codec);
12699	if (err < 0)
12700		return err;
12701
12702	alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
12703
12704	return 1;
12705}
12706
12707#define alc262_auto_init_multi_out	alc882_auto_init_multi_out
12708#define alc262_auto_init_hp_out		alc882_auto_init_hp_out
12709#define alc262_auto_init_analog_input	alc882_auto_init_analog_input
12710#define alc262_auto_init_input_src	alc882_auto_init_input_src
12711
12712
12713/* init callback for auto-configuration model -- overriding the default init */
12714static void alc262_auto_init(struct hda_codec *codec)
12715{
12716	struct alc_spec *spec = codec->spec;
12717	alc262_auto_init_multi_out(codec);
12718	alc262_auto_init_hp_out(codec);
12719	alc262_auto_init_analog_input(codec);
12720	alc262_auto_init_input_src(codec);
12721	alc_auto_init_digital(codec);
12722	if (spec->unsol_event)
12723		alc_inithook(codec);
12724}
12725
12726/*
12727 * configuration and preset
12728 */
12729static const char * const alc262_models[ALC262_MODEL_LAST] = {
12730	[ALC262_BASIC]		= "basic",
12731	[ALC262_HIPPO]		= "hippo",
12732	[ALC262_HIPPO_1]	= "hippo_1",
12733	[ALC262_FUJITSU]	= "fujitsu",
12734	[ALC262_HP_BPC]		= "hp-bpc",
12735	[ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
12736	[ALC262_HP_TC_T5735]	= "hp-tc-t5735",
12737	[ALC262_HP_RP5700]	= "hp-rp5700",
12738	[ALC262_BENQ_ED8]	= "benq",
12739	[ALC262_BENQ_T31]	= "benq-t31",
12740	[ALC262_SONY_ASSAMD]	= "sony-assamd",
12741	[ALC262_TOSHIBA_S06]	= "toshiba-s06",
12742	[ALC262_TOSHIBA_RX1]	= "toshiba-rx1",
12743	[ALC262_ULTRA]		= "ultra",
12744	[ALC262_LENOVO_3000]	= "lenovo-3000",
12745	[ALC262_NEC]		= "nec",
12746	[ALC262_TYAN]		= "tyan",
12747	[ALC262_AUTO]		= "auto",
12748};
12749
12750static const struct snd_pci_quirk alc262_cfg_tbl[] = {
12751	SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
12752	SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
12753	SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12754			   ALC262_HP_BPC),
12755	SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12756			   ALC262_HP_BPC),
12757	SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12758			   ALC262_HP_BPC),
12759	SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200",
12760			   ALC262_AUTO),
12761	SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12762			   ALC262_HP_BPC),
12763	SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
12764	SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
12765	SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
12766	SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
12767	SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
12768	SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
12769	SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
12770	SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
12771	SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12772	SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12773	SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
12774	SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12775		      ALC262_HP_TC_T5735),
12776	SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
12777	SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12778	SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
12779	SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12780	SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
12781	SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
12782	SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12783	SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
12784#if 0 /* disable the quirk since model=auto works better in recent versions */
12785	SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12786			   ALC262_SONY_ASSAMD),
12787#endif
12788	SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
12789		      ALC262_TOSHIBA_RX1),
12790	SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
12791	SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
12792	SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
12793	SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
12794	SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12795			   ALC262_ULTRA),
12796	SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
12797	SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
12798	SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12799	SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12800	SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
12801	{}
12802};
12803
12804static const struct alc_config_preset alc262_presets[] = {
12805	[ALC262_BASIC] = {
12806		.mixers = { alc262_base_mixer },
12807		.init_verbs = { alc262_init_verbs },
12808		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12809		.dac_nids = alc262_dac_nids,
12810		.hp_nid = 0x03,
12811		.num_channel_mode = ARRAY_SIZE(alc262_modes),
12812		.channel_mode = alc262_modes,
12813		.input_mux = &alc262_capture_source,
12814	},
12815	[ALC262_HIPPO] = {
12816		.mixers = { alc262_hippo_mixer },
12817		.init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
12818		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12819		.dac_nids = alc262_dac_nids,
12820		.hp_nid = 0x03,
12821		.dig_out_nid = ALC262_DIGOUT_NID,
12822		.num_channel_mode = ARRAY_SIZE(alc262_modes),
12823		.channel_mode = alc262_modes,
12824		.input_mux = &alc262_capture_source,
12825		.unsol_event = alc_sku_unsol_event,
12826		.setup = alc262_hippo_setup,
12827		.init_hook = alc_inithook,
12828	},
12829	[ALC262_HIPPO_1] = {
12830		.mixers = { alc262_hippo1_mixer },
12831		.init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12832		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12833		.dac_nids = alc262_dac_nids,
12834		.hp_nid = 0x02,
12835		.dig_out_nid = ALC262_DIGOUT_NID,
12836		.num_channel_mode = ARRAY_SIZE(alc262_modes),
12837		.channel_mode = alc262_modes,
12838		.input_mux = &alc262_capture_source,
12839		.unsol_event = alc_sku_unsol_event,
12840		.setup = alc262_hippo1_setup,
12841		.init_hook = alc_inithook,
12842	},
12843	[ALC262_FUJITSU] = {
12844		.mixers = { alc262_fujitsu_mixer },
12845		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12846				alc262_fujitsu_unsol_verbs },
12847		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12848		.dac_nids = alc262_dac_nids,
12849		.hp_nid = 0x03,
12850		.dig_out_nid = ALC262_DIGOUT_NID,
12851		.num_channel_mode = ARRAY_SIZE(alc262_modes),
12852		.channel_mode = alc262_modes,
12853		.input_mux = &alc262_fujitsu_capture_source,
12854		.unsol_event = alc_sku_unsol_event,
12855		.setup = alc262_fujitsu_setup,
12856		.init_hook = alc_inithook,
12857	},
12858	[ALC262_HP_BPC] = {
12859		.mixers = { alc262_HP_BPC_mixer },
12860		.init_verbs = { alc262_HP_BPC_init_verbs },
12861		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12862		.dac_nids = alc262_dac_nids,
12863		.hp_nid = 0x03,
12864		.num_channel_mode = ARRAY_SIZE(alc262_modes),
12865		.channel_mode = alc262_modes,
12866		.input_mux = &alc262_HP_capture_source,
12867		.unsol_event = alc_sku_unsol_event,
12868		.setup = alc262_hp_bpc_setup,
12869		.init_hook = alc_inithook,
12870	},
12871	[ALC262_HP_BPC_D7000_WF] = {
12872		.mixers = { alc262_HP_BPC_WildWest_mixer },
12873		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12874		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12875		.dac_nids = alc262_dac_nids,
12876		.hp_nid = 0x03,
12877		.num_channel_mode = ARRAY_SIZE(alc262_modes),
12878		.channel_mode = alc262_modes,
12879		.input_mux = &alc262_HP_D7000_capture_source,
12880		.unsol_event = alc_sku_unsol_event,
12881		.setup = alc262_hp_wildwest_setup,
12882		.init_hook = alc_inithook,
12883	},
12884	[ALC262_HP_BPC_D7000_WL] = {
12885		.mixers = { alc262_HP_BPC_WildWest_mixer,
12886			    alc262_HP_BPC_WildWest_option_mixer },
12887		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12888		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12889		.dac_nids = alc262_dac_nids,
12890		.hp_nid = 0x03,
12891		.num_channel_mode = ARRAY_SIZE(alc262_modes),
12892		.channel_mode = alc262_modes,
12893		.input_mux = &alc262_HP_D7000_capture_source,
12894		.unsol_event = alc_sku_unsol_event,
12895		.setup = alc262_hp_wildwest_setup,
12896		.init_hook = alc_inithook,
12897	},
12898	[ALC262_HP_TC_T5735] = {
12899		.mixers = { alc262_hp_t5735_mixer },
12900		.init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12901		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12902		.dac_nids = alc262_dac_nids,
12903		.hp_nid = 0x03,
12904		.num_channel_mode = ARRAY_SIZE(alc262_modes),
12905		.channel_mode = alc262_modes,
12906		.input_mux = &alc262_capture_source,
12907		.unsol_event = alc_sku_unsol_event,
12908		.setup = alc262_hp_t5735_setup,
12909		.init_hook = alc_inithook,
12910	},
12911	[ALC262_HP_RP5700] = {
12912		.mixers = { alc262_hp_rp5700_mixer },
12913		.init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12914		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12915		.dac_nids = alc262_dac_nids,
12916		.num_channel_mode = ARRAY_SIZE(alc262_modes),
12917		.channel_mode = alc262_modes,
12918		.input_mux = &alc262_hp_rp5700_capture_source,
12919        },
12920	[ALC262_BENQ_ED8] = {
12921		.mixers = { alc262_base_mixer },
12922		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12923		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12924		.dac_nids = alc262_dac_nids,
12925		.hp_nid = 0x03,
12926		.num_channel_mode = ARRAY_SIZE(alc262_modes),
12927		.channel_mode = alc262_modes,
12928		.input_mux = &alc262_capture_source,
12929	},
12930	[ALC262_SONY_ASSAMD] = {
12931		.mixers = { alc262_sony_mixer },
12932		.init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12933		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12934		.dac_nids = alc262_dac_nids,
12935		.hp_nid = 0x02,
12936		.num_channel_mode = ARRAY_SIZE(alc262_modes),
12937		.channel_mode = alc262_modes,
12938		.input_mux = &alc262_capture_source,
12939		.unsol_event = alc_sku_unsol_event,
12940		.setup = alc262_hippo_setup,
12941		.init_hook = alc_inithook,
12942	},
12943	[ALC262_BENQ_T31] = {
12944		.mixers = { alc262_benq_t31_mixer },
12945		.init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12946				alc_hp15_unsol_verbs },
12947		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12948		.dac_nids = alc262_dac_nids,
12949		.hp_nid = 0x03,
12950		.num_channel_mode = ARRAY_SIZE(alc262_modes),
12951		.channel_mode = alc262_modes,
12952		.input_mux = &alc262_capture_source,
12953		.unsol_event = alc_sku_unsol_event,
12954		.setup = alc262_hippo_setup,
12955		.init_hook = alc_inithook,
12956	},
12957	[ALC262_ULTRA] = {
12958		.mixers = { alc262_ultra_mixer },
12959		.cap_mixer = alc262_ultra_capture_mixer,
12960		.init_verbs = { alc262_ultra_verbs },
12961		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12962		.dac_nids = alc262_dac_nids,
12963		.num_channel_mode = ARRAY_SIZE(alc262_modes),
12964		.channel_mode = alc262_modes,
12965		.input_mux = &alc262_ultra_capture_source,
12966		.adc_nids = alc262_adc_nids, /* ADC0 */
12967		.capsrc_nids = alc262_capsrc_nids,
12968		.num_adc_nids = 1, /* single ADC */
12969		.unsol_event = alc262_ultra_unsol_event,
12970		.init_hook = alc262_ultra_automute,
12971	},
12972	[ALC262_LENOVO_3000] = {
12973		.mixers = { alc262_lenovo_3000_mixer },
12974		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12975				alc262_lenovo_3000_unsol_verbs,
12976				alc262_lenovo_3000_init_verbs },
12977		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12978		.dac_nids = alc262_dac_nids,
12979		.hp_nid = 0x03,
12980		.dig_out_nid = ALC262_DIGOUT_NID,
12981		.num_channel_mode = ARRAY_SIZE(alc262_modes),
12982		.channel_mode = alc262_modes,
12983		.input_mux = &alc262_fujitsu_capture_source,
12984		.unsol_event = alc_sku_unsol_event,
12985		.setup = alc262_lenovo_3000_setup,
12986		.init_hook = alc_inithook,
12987	},
12988	[ALC262_NEC] = {
12989		.mixers = { alc262_nec_mixer },
12990		.init_verbs = { alc262_nec_verbs },
12991		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
12992		.dac_nids = alc262_dac_nids,
12993		.hp_nid = 0x03,
12994		.num_channel_mode = ARRAY_SIZE(alc262_modes),
12995		.channel_mode = alc262_modes,
12996		.input_mux = &alc262_capture_source,
12997	},
12998	[ALC262_TOSHIBA_S06] = {
12999		.mixers = { alc262_toshiba_s06_mixer },
13000		.init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
13001							alc262_eapd_verbs },
13002		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
13003		.capsrc_nids = alc262_dmic_capsrc_nids,
13004		.dac_nids = alc262_dac_nids,
13005		.adc_nids = alc262_dmic_adc_nids, /* ADC0 */
13006		.num_adc_nids = 1, /* single ADC */
13007		.dig_out_nid = ALC262_DIGOUT_NID,
13008		.num_channel_mode = ARRAY_SIZE(alc262_modes),
13009		.channel_mode = alc262_modes,
13010		.unsol_event = alc_sku_unsol_event,
13011		.setup = alc262_toshiba_s06_setup,
13012		.init_hook = alc_inithook,
13013	},
13014	[ALC262_TOSHIBA_RX1] = {
13015		.mixers = { alc262_toshiba_rx1_mixer },
13016		.init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
13017		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
13018		.dac_nids = alc262_dac_nids,
13019		.hp_nid = 0x03,
13020		.num_channel_mode = ARRAY_SIZE(alc262_modes),
13021		.channel_mode = alc262_modes,
13022		.input_mux = &alc262_capture_source,
13023		.unsol_event = alc_sku_unsol_event,
13024		.setup = alc262_hippo_setup,
13025		.init_hook = alc_inithook,
13026	},
13027	[ALC262_TYAN] = {
13028		.mixers = { alc262_tyan_mixer },
13029		.init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
13030		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
13031		.dac_nids = alc262_dac_nids,
13032		.hp_nid = 0x02,
13033		.dig_out_nid = ALC262_DIGOUT_NID,
13034		.num_channel_mode = ARRAY_SIZE(alc262_modes),
13035		.channel_mode = alc262_modes,
13036		.input_mux = &alc262_capture_source,
13037		.unsol_event = alc_sku_unsol_event,
13038		.setup = alc262_tyan_setup,
13039		.init_hook = alc_hp_automute,
13040	},
13041};
13042
13043static int patch_alc262(struct hda_codec *codec)
13044{
13045	struct alc_spec *spec;
13046	int board_config;
13047	int err;
13048
13049	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13050	if (spec == NULL)
13051		return -ENOMEM;
13052
13053	codec->spec = spec;
13054#if 0
13055	/* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
13056	 * under-run
13057	 */
13058	{
13059	int tmp;
13060	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
13061	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
13062	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
13063	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
13064	}
13065#endif
13066	alc_auto_parse_customize_define(codec);
13067
13068	alc_fix_pll_init(codec, 0x20, 0x0a, 10);
13069
13070	board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
13071						  alc262_models,
13072						  alc262_cfg_tbl);
13073
13074	if (board_config < 0) {
13075		printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13076		       codec->chip_name);
13077		board_config = ALC262_AUTO;
13078	}
13079
13080	if (board_config == ALC262_AUTO) {
13081		alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
13082		alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
13083	}
13084
13085	if (board_config == ALC262_AUTO) {
13086		/* automatic parse from the BIOS config */
13087		err = alc262_parse_auto_config(codec);
13088		if (err < 0) {
13089			alc_free(codec);
13090			return err;
13091		} else if (!err) {
13092			printk(KERN_INFO
13093			       "hda_codec: Cannot set up configuration "
13094			       "from BIOS.  Using base mode...\n");
13095			board_config = ALC262_BASIC;
13096		}
13097	}
13098
13099	if (!spec->no_analog && has_cdefine_beep(codec)) {
13100		err = snd_hda_attach_beep_device(codec, 0x1);
13101		if (err < 0) {
13102			alc_free(codec);
13103			return err;
13104		}
13105	}
13106
13107	if (board_config != ALC262_AUTO)
13108		setup_preset(codec, &alc262_presets[board_config]);
13109
13110	spec->stream_analog_playback = &alc262_pcm_analog_playback;
13111	spec->stream_analog_capture = &alc262_pcm_analog_capture;
13112
13113	spec->stream_digital_playback = &alc262_pcm_digital_playback;
13114	spec->stream_digital_capture = &alc262_pcm_digital_capture;
13115
13116	if (!spec->adc_nids && spec->input_mux) {
13117		int i;
13118		/* check whether the digital-mic has to be supported */
13119		for (i = 0; i < spec->input_mux->num_items; i++) {
13120			if (spec->input_mux->items[i].index >= 9)
13121				break;
13122		}
13123		if (i < spec->input_mux->num_items) {
13124			/* use only ADC0 */
13125			spec->adc_nids = alc262_dmic_adc_nids;
13126			spec->num_adc_nids = 1;
13127			spec->capsrc_nids = alc262_dmic_capsrc_nids;
13128		} else {
13129			/* all analog inputs */
13130			/* check whether NID 0x07 is valid */
13131			unsigned int wcap = get_wcaps(codec, 0x07);
13132
13133			/* get type */
13134			wcap = get_wcaps_type(wcap);
13135			if (wcap != AC_WID_AUD_IN) {
13136				spec->adc_nids = alc262_adc_nids_alt;
13137				spec->num_adc_nids =
13138					ARRAY_SIZE(alc262_adc_nids_alt);
13139				spec->capsrc_nids = alc262_capsrc_nids_alt;
13140			} else {
13141				spec->adc_nids = alc262_adc_nids;
13142				spec->num_adc_nids =
13143					ARRAY_SIZE(alc262_adc_nids);
13144				spec->capsrc_nids = alc262_capsrc_nids;
13145			}
13146		}
13147	}
13148	if (!spec->cap_mixer && !spec->no_analog)
13149		set_capture_mixer(codec);
13150	if (!spec->no_analog && has_cdefine_beep(codec))
13151		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
13152
13153	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
13154
13155	spec->vmaster_nid = 0x0c;
13156
13157	codec->patch_ops = alc_patch_ops;
13158	if (board_config == ALC262_AUTO)
13159		spec->init_hook = alc262_auto_init;
13160	spec->shutup = alc_eapd_shutup;
13161
13162	alc_init_jacks(codec);
13163#ifdef CONFIG_SND_HDA_POWER_SAVE
13164	if (!spec->loopback.amplist)
13165		spec->loopback.amplist = alc262_loopbacks;
13166#endif
13167
13168	return 0;
13169}
13170
13171/*
13172 *  ALC268 channel source setting (2 channel)
13173 */
13174#define ALC268_DIGOUT_NID	ALC880_DIGOUT_NID
13175#define alc268_modes		alc260_modes
13176
13177static const hda_nid_t alc268_dac_nids[2] = {
13178	/* front, hp */
13179	0x02, 0x03
13180};
13181
13182static const hda_nid_t alc268_adc_nids[2] = {
13183	/* ADC0-1 */
13184	0x08, 0x07
13185};
13186
13187static const hda_nid_t alc268_adc_nids_alt[1] = {
13188	/* ADC0 */
13189	0x08
13190};
13191
13192static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
13193
13194static const struct snd_kcontrol_new alc268_base_mixer[] = {
13195	/* output mixer control */
13196	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13197	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13198	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13199	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13200	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13201	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13202	HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13203	{ }
13204};
13205
13206static const struct snd_kcontrol_new alc268_toshiba_mixer[] = {
13207	/* output mixer control */
13208	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13209	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13210	ALC262_HIPPO_MASTER_SWITCH,
13211	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13212	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13213	HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13214	{ }
13215};
13216
13217/* bind Beep switches of both NID 0x0f and 0x10 */
13218static const struct hda_bind_ctls alc268_bind_beep_sw = {
13219	.ops = &snd_hda_bind_sw,
13220	.values = {
13221		HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
13222		HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
13223		0
13224	},
13225};
13226
13227static const struct snd_kcontrol_new alc268_beep_mixer[] = {
13228	HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
13229	HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
13230	{ }
13231};
13232
13233static const struct hda_verb alc268_eapd_verbs[] = {
13234	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13235	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13236	{ }
13237};
13238
13239/* Toshiba specific */
13240static const struct hda_verb alc268_toshiba_verbs[] = {
13241	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13242	{ } /* end */
13243};
13244
13245/* Acer specific */
13246/* bind volumes of both NID 0x02 and 0x03 */
13247static const struct hda_bind_ctls alc268_acer_bind_master_vol = {
13248	.ops = &snd_hda_bind_vol,
13249	.values = {
13250		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13251		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13252		0
13253	},
13254};
13255
13256static void alc268_acer_setup(struct hda_codec *codec)
13257{
13258	struct alc_spec *spec = codec->spec;
13259
13260	spec->autocfg.hp_pins[0] = 0x14;
13261	spec->autocfg.speaker_pins[0] = 0x15;
13262	spec->automute = 1;
13263	spec->automute_mode = ALC_AUTOMUTE_AMP;
13264}
13265
13266#define alc268_acer_master_sw_get	alc262_hp_master_sw_get
13267#define alc268_acer_master_sw_put	alc262_hp_master_sw_put
13268
13269static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13270	/* output mixer control */
13271	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13272	{
13273		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13274		.name = "Master Playback Switch",
13275		.subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
13276		.info = snd_ctl_boolean_mono_info,
13277		.get = alc268_acer_master_sw_get,
13278		.put = alc268_acer_master_sw_put,
13279	},
13280	HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13281	{ }
13282};
13283
13284static const struct snd_kcontrol_new alc268_acer_mixer[] = {
13285	/* output mixer control */
13286	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13287	{
13288		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13289		.name = "Master Playback Switch",
13290		.subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13291		.info = snd_ctl_boolean_mono_info,
13292		.get = alc268_acer_master_sw_get,
13293		.put = alc268_acer_master_sw_put,
13294	},
13295	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13296	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13297	HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13298	{ }
13299};
13300
13301static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13302	/* output mixer control */
13303	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13304	{
13305		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13306		.name = "Master Playback Switch",
13307		.subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13308		.info = snd_ctl_boolean_mono_info,
13309		.get = alc268_acer_master_sw_get,
13310		.put = alc268_acer_master_sw_put,
13311	},
13312	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13313	HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13314	{ }
13315};
13316
13317static const struct hda_verb alc268_acer_aspire_one_verbs[] = {
13318	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13319	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13320	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13321	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13322	{0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13323	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13324	{ }
13325};
13326
13327static const struct hda_verb alc268_acer_verbs[] = {
13328	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13329	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13330	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13331	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13332	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13333	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13334	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13335	{ }
13336};
13337
13338/* unsolicited event for HP jack sensing */
13339#define alc268_toshiba_setup		alc262_hippo_setup
13340
13341static void alc268_acer_lc_setup(struct hda_codec *codec)
13342{
13343	struct alc_spec *spec = codec->spec;
13344	spec->autocfg.hp_pins[0] = 0x15;
13345	spec->autocfg.speaker_pins[0] = 0x14;
13346	spec->automute = 1;
13347	spec->automute_mode = ALC_AUTOMUTE_AMP;
13348	spec->ext_mic.pin = 0x18;
13349	spec->ext_mic.mux_idx = 0;
13350	spec->int_mic.pin = 0x12;
13351	spec->int_mic.mux_idx = 6;
13352	spec->auto_mic = 1;
13353}
13354
13355static const struct snd_kcontrol_new alc268_dell_mixer[] = {
13356	/* output mixer control */
13357	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13358	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13359	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13360	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13361	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13362	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13363	{ }
13364};
13365
13366static const struct hda_verb alc268_dell_verbs[] = {
13367	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13368	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13369	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13370	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13371	{ }
13372};
13373
13374/* mute/unmute internal speaker according to the hp jack and mute state */
13375static void alc268_dell_setup(struct hda_codec *codec)
13376{
13377	struct alc_spec *spec = codec->spec;
13378
13379	spec->autocfg.hp_pins[0] = 0x15;
13380	spec->autocfg.speaker_pins[0] = 0x14;
13381	spec->ext_mic.pin = 0x18;
13382	spec->ext_mic.mux_idx = 0;
13383	spec->int_mic.pin = 0x19;
13384	spec->int_mic.mux_idx = 1;
13385	spec->auto_mic = 1;
13386	spec->automute = 1;
13387	spec->automute_mode = ALC_AUTOMUTE_PIN;
13388}
13389
13390static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13391	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13392	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13393	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13394	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13395	HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13396	HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
13397	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13398	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13399	{ }
13400};
13401
13402static const struct hda_verb alc267_quanta_il1_verbs[] = {
13403	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13404	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13405	{ }
13406};
13407
13408static void alc267_quanta_il1_setup(struct hda_codec *codec)
13409{
13410	struct alc_spec *spec = codec->spec;
13411	spec->autocfg.hp_pins[0] = 0x15;
13412	spec->autocfg.speaker_pins[0] = 0x14;
13413	spec->ext_mic.pin = 0x18;
13414	spec->ext_mic.mux_idx = 0;
13415	spec->int_mic.pin = 0x19;
13416	spec->int_mic.mux_idx = 1;
13417	spec->auto_mic = 1;
13418	spec->automute = 1;
13419	spec->automute_mode = ALC_AUTOMUTE_PIN;
13420}
13421
13422/*
13423 * generic initialization of ADC, input mixers and output mixers
13424 */
13425static const struct hda_verb alc268_base_init_verbs[] = {
13426	/* Unmute DAC0-1 and set vol = 0 */
13427	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13428	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13429
13430	/*
13431	 * Set up output mixers (0x0c - 0x0e)
13432	 */
13433	/* set vol=0 to output mixers */
13434	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13435        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13436
13437	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13438	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13439
13440	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13441	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13442	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13443	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13444	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13445	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13446	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13447	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13448
13449	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13450	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13451	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13452	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13453	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13454
13455	/* set PCBEEP vol = 0, mute connections */
13456	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13457	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13458	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13459
13460	/* Unmute Selector 23h,24h and set the default input to mic-in */
13461
13462	{0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13463	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13464	{0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13465	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13466
13467	{ }
13468};
13469
13470/*
13471 * generic initialization of ADC, input mixers and output mixers
13472 */
13473static const struct hda_verb alc268_volume_init_verbs[] = {
13474	/* set output DAC */
13475	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13476	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13477
13478	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13479	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13480	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13481	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13482	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13483
13484	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13485	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13486	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13487
13488	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13489	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13490
13491	/* set PCBEEP vol = 0, mute connections */
13492	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13493	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13494	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13495
13496	{ }
13497};
13498
13499static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13500	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13501	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13502	{ } /* end */
13503};
13504
13505static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13506	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13507	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13508	_DEFINE_CAPSRC(1),
13509	{ } /* end */
13510};
13511
13512static const struct snd_kcontrol_new alc268_capture_mixer[] = {
13513	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13514	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13515	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13516	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
13517	_DEFINE_CAPSRC(2),
13518	{ } /* end */
13519};
13520
13521static const struct hda_input_mux alc268_capture_source = {
13522	.num_items = 4,
13523	.items = {
13524		{ "Mic", 0x0 },
13525		{ "Front Mic", 0x1 },
13526		{ "Line", 0x2 },
13527		{ "CD", 0x3 },
13528	},
13529};
13530
13531static const struct hda_input_mux alc268_acer_capture_source = {
13532	.num_items = 3,
13533	.items = {
13534		{ "Mic", 0x0 },
13535		{ "Internal Mic", 0x1 },
13536		{ "Line", 0x2 },
13537	},
13538};
13539
13540static const struct hda_input_mux alc268_acer_dmic_capture_source = {
13541	.num_items = 3,
13542	.items = {
13543		{ "Mic", 0x0 },
13544		{ "Internal Mic", 0x6 },
13545		{ "Line", 0x2 },
13546	},
13547};
13548
13549#ifdef CONFIG_SND_DEBUG
13550static const struct snd_kcontrol_new alc268_test_mixer[] = {
13551	/* Volume widgets */
13552	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13553	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13554	HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13555	HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13556	HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13557	HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13558	HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13559	HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13560	HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13561	HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13562	HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13563	HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13564	HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
13565	/* The below appears problematic on some hardwares */
13566	/*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
13567	HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13568	HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13569	HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13570	HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13571
13572	/* Modes for retasking pin widgets */
13573	ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13574	ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13575	ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13576	ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13577
13578	/* Controls for GPIO pins, assuming they are configured as outputs */
13579	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13580	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13581	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13582	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13583
13584	/* Switches to allow the digital SPDIF output pin to be enabled.
13585	 * The ALC268 does not have an SPDIF input.
13586	 */
13587	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13588
13589	/* A switch allowing EAPD to be enabled.  Some laptops seem to use
13590	 * this output to turn on an external amplifier.
13591	 */
13592	ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13593	ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13594
13595	{ } /* end */
13596};
13597#endif
13598
13599/* create input playback/capture controls for the given pin */
13600static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13601				    const char *ctlname, int idx)
13602{
13603	hda_nid_t dac;
13604	int err;
13605
13606	switch (nid) {
13607	case 0x14:
13608	case 0x16:
13609		dac = 0x02;
13610		break;
13611	case 0x15:
13612	case 0x1a: /* ALC259/269 only */
13613	case 0x1b: /* ALC259/269 only */
13614	case 0x21: /* ALC269vb has this pin, too */
13615		dac = 0x03;
13616		break;
13617	default:
13618		snd_printd(KERN_WARNING "hda_codec: "
13619			   "ignoring pin 0x%x as unknown\n", nid);
13620		return 0;
13621	}
13622	if (spec->multiout.dac_nids[0] != dac &&
13623	    spec->multiout.dac_nids[1] != dac) {
13624		err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
13625				  HDA_COMPOSE_AMP_VAL(dac, 3, idx,
13626						      HDA_OUTPUT));
13627		if (err < 0)
13628			return err;
13629		spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
13630	}
13631
13632	if (nid != 0x16)
13633		err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13634			  HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
13635	else /* mono */
13636		err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13637			  HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
13638	if (err < 0)
13639		return err;
13640	return 0;
13641}
13642
13643/* add playback controls from the parsed DAC table */
13644static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13645					     const struct auto_pin_cfg *cfg)
13646{
13647	hda_nid_t nid;
13648	int err;
13649
13650	spec->multiout.dac_nids = spec->private_dac_nids;
13651
13652	nid = cfg->line_out_pins[0];
13653	if (nid) {
13654		const char *name;
13655		if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13656			name = "Speaker";
13657		else
13658			name = "Front";
13659		err = alc268_new_analog_output(spec, nid, name, 0);
13660		if (err < 0)
13661			return err;
13662	}
13663
13664	nid = cfg->speaker_pins[0];
13665	if (nid == 0x1d) {
13666		err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
13667				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13668		if (err < 0)
13669			return err;
13670	} else if (nid) {
13671		err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13672		if (err < 0)
13673			return err;
13674	}
13675	nid = cfg->hp_pins[0];
13676	if (nid) {
13677		err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13678		if (err < 0)
13679			return err;
13680	}
13681
13682	nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13683	if (nid == 0x16) {
13684		err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
13685				  HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
13686		if (err < 0)
13687			return err;
13688	}
13689	return 0;
13690}
13691
13692/* create playback/capture controls for input pins */
13693static int alc268_auto_create_input_ctls(struct hda_codec *codec,
13694						const struct auto_pin_cfg *cfg)
13695{
13696	return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
13697}
13698
13699static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13700					      hda_nid_t nid, int pin_type)
13701{
13702	int idx;
13703
13704	alc_set_pin_output(codec, nid, pin_type);
13705	if (nid == 0x14 || nid == 0x16)
13706		idx = 0;
13707	else
13708		idx = 1;
13709	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13710}
13711
13712static void alc268_auto_init_multi_out(struct hda_codec *codec)
13713{
13714	struct alc_spec *spec = codec->spec;
13715	int i;
13716
13717	for (i = 0; i < spec->autocfg.line_outs; i++) {
13718		hda_nid_t nid = spec->autocfg.line_out_pins[i];
13719		int pin_type = get_pin_type(spec->autocfg.line_out_type);
13720		alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13721	}
13722}
13723
13724static void alc268_auto_init_hp_out(struct hda_codec *codec)
13725{
13726	struct alc_spec *spec = codec->spec;
13727	hda_nid_t pin;
13728	int i;
13729
13730	for (i = 0; i < spec->autocfg.hp_outs; i++) {
13731		pin = spec->autocfg.hp_pins[i];
13732		alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
13733	}
13734	for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13735		pin = spec->autocfg.speaker_pins[i];
13736		alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
13737	}
13738	if (spec->autocfg.mono_out_pin)
13739		snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13740				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13741}
13742
13743static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13744{
13745	struct alc_spec *spec = codec->spec;
13746	hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13747	hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13748	hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13749	unsigned int	dac_vol1, dac_vol2;
13750
13751	if (line_nid == 0x1d || speaker_nid == 0x1d) {
13752		snd_hda_codec_write(codec, speaker_nid, 0,
13753				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13754		/* mute mixer inputs from 0x1d */
13755		snd_hda_codec_write(codec, 0x0f, 0,
13756				    AC_VERB_SET_AMP_GAIN_MUTE,
13757				    AMP_IN_UNMUTE(1));
13758		snd_hda_codec_write(codec, 0x10, 0,
13759				    AC_VERB_SET_AMP_GAIN_MUTE,
13760				    AMP_IN_UNMUTE(1));
13761	} else {
13762		/* unmute mixer inputs from 0x1d */
13763		snd_hda_codec_write(codec, 0x0f, 0,
13764				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13765		snd_hda_codec_write(codec, 0x10, 0,
13766				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13767	}
13768
13769	dac_vol1 = dac_vol2 = 0xb000 | 0x40;	/* set max volume  */
13770	if (line_nid == 0x14)
13771		dac_vol2 = AMP_OUT_ZERO;
13772	else if (line_nid == 0x15)
13773		dac_vol1 = AMP_OUT_ZERO;
13774	if (hp_nid == 0x14)
13775		dac_vol2 = AMP_OUT_ZERO;
13776	else if (hp_nid == 0x15)
13777		dac_vol1 = AMP_OUT_ZERO;
13778	if (line_nid != 0x16 || hp_nid != 0x16 ||
13779	    spec->autocfg.line_out_pins[1] != 0x16 ||
13780	    spec->autocfg.line_out_pins[2] != 0x16)
13781		dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13782
13783	snd_hda_codec_write(codec, 0x02, 0,
13784			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13785	snd_hda_codec_write(codec, 0x03, 0,
13786			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13787}
13788
13789/* pcm configuration: identical with ALC880 */
13790#define alc268_pcm_analog_playback	alc880_pcm_analog_playback
13791#define alc268_pcm_analog_capture	alc880_pcm_analog_capture
13792#define alc268_pcm_analog_alt_capture	alc880_pcm_analog_alt_capture
13793#define alc268_pcm_digital_playback	alc880_pcm_digital_playback
13794
13795/*
13796 * BIOS auto configuration
13797 */
13798static int alc268_parse_auto_config(struct hda_codec *codec)
13799{
13800	struct alc_spec *spec = codec->spec;
13801	int err;
13802	static const hda_nid_t alc268_ignore[] = { 0 };
13803
13804	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13805					   alc268_ignore);
13806	if (err < 0)
13807		return err;
13808	if (!spec->autocfg.line_outs) {
13809		if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13810			spec->multiout.max_channels = 2;
13811			spec->no_analog = 1;
13812			goto dig_only;
13813		}
13814		return 0; /* can't find valid BIOS pin config */
13815	}
13816	err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13817	if (err < 0)
13818		return err;
13819	err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
13820	if (err < 0)
13821		return err;
13822
13823	spec->multiout.max_channels = 2;
13824
13825 dig_only:
13826	/* digital only support output */
13827	alc_auto_parse_digital(codec);
13828	if (spec->kctls.list)
13829		add_mixer(spec, spec->kctls.list);
13830
13831	if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
13832		add_mixer(spec, alc268_beep_mixer);
13833
13834	add_verb(spec, alc268_volume_init_verbs);
13835	spec->num_mux_defs = 2;
13836	spec->input_mux = &spec->private_imux[0];
13837
13838	err = alc_auto_add_mic_boost(codec);
13839	if (err < 0)
13840		return err;
13841
13842	alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
13843
13844	return 1;
13845}
13846
13847#define alc268_auto_init_analog_input	alc882_auto_init_analog_input
13848#define alc268_auto_init_input_src	alc882_auto_init_input_src
13849
13850/* init callback for auto-configuration model -- overriding the default init */
13851static void alc268_auto_init(struct hda_codec *codec)
13852{
13853	struct alc_spec *spec = codec->spec;
13854	alc268_auto_init_multi_out(codec);
13855	alc268_auto_init_hp_out(codec);
13856	alc268_auto_init_mono_speaker_out(codec);
13857	alc268_auto_init_analog_input(codec);
13858	alc268_auto_init_input_src(codec);
13859	alc_auto_init_digital(codec);
13860	if (spec->unsol_event)
13861		alc_inithook(codec);
13862}
13863
13864/*
13865 * configuration and preset
13866 */
13867static const char * const alc268_models[ALC268_MODEL_LAST] = {
13868	[ALC267_QUANTA_IL1]	= "quanta-il1",
13869	[ALC268_3ST]		= "3stack",
13870	[ALC268_TOSHIBA]	= "toshiba",
13871	[ALC268_ACER]		= "acer",
13872	[ALC268_ACER_DMIC]	= "acer-dmic",
13873	[ALC268_ACER_ASPIRE_ONE]	= "acer-aspire",
13874	[ALC268_DELL]		= "dell",
13875	[ALC268_ZEPTO]		= "zepto",
13876#ifdef CONFIG_SND_DEBUG
13877	[ALC268_TEST]		= "test",
13878#endif
13879	[ALC268_AUTO]		= "auto",
13880};
13881
13882static const struct snd_pci_quirk alc268_cfg_tbl[] = {
13883	SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
13884	SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
13885	SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
13886	SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
13887	SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
13888	SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13889						ALC268_ACER_ASPIRE_ONE),
13890	SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
13891	SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron 910", ALC268_AUTO),
13892	SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13893			"Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
13894	/* almost compatible with toshiba but with optional digital outs;
13895	 * auto-probing seems working fine
13896	 */
13897	SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
13898			   ALC268_AUTO),
13899	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
13900	SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
13901	SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
13902	SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
13903	{}
13904};
13905
13906/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13907static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13908	SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13909	SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13910	SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13911			   ALC268_TOSHIBA),
13912	{}
13913};
13914
13915static const struct alc_config_preset alc268_presets[] = {
13916	[ALC267_QUANTA_IL1] = {
13917		.mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13918			    alc268_capture_nosrc_mixer },
13919		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13920				alc267_quanta_il1_verbs },
13921		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
13922		.dac_nids = alc268_dac_nids,
13923		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13924		.adc_nids = alc268_adc_nids_alt,
13925		.hp_nid = 0x03,
13926		.num_channel_mode = ARRAY_SIZE(alc268_modes),
13927		.channel_mode = alc268_modes,
13928		.unsol_event = alc_sku_unsol_event,
13929		.setup = alc267_quanta_il1_setup,
13930		.init_hook = alc_inithook,
13931	},
13932	[ALC268_3ST] = {
13933		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13934			    alc268_beep_mixer },
13935		.init_verbs = { alc268_base_init_verbs },
13936		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
13937		.dac_nids = alc268_dac_nids,
13938                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13939                .adc_nids = alc268_adc_nids_alt,
13940		.capsrc_nids = alc268_capsrc_nids,
13941		.hp_nid = 0x03,
13942		.dig_out_nid = ALC268_DIGOUT_NID,
13943		.num_channel_mode = ARRAY_SIZE(alc268_modes),
13944		.channel_mode = alc268_modes,
13945		.input_mux = &alc268_capture_source,
13946	},
13947	[ALC268_TOSHIBA] = {
13948		.mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
13949			    alc268_beep_mixer },
13950		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13951				alc268_toshiba_verbs },
13952		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
13953		.dac_nids = alc268_dac_nids,
13954		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13955		.adc_nids = alc268_adc_nids_alt,
13956		.capsrc_nids = alc268_capsrc_nids,
13957		.hp_nid = 0x03,
13958		.num_channel_mode = ARRAY_SIZE(alc268_modes),
13959		.channel_mode = alc268_modes,
13960		.input_mux = &alc268_capture_source,
13961		.unsol_event = alc_sku_unsol_event,
13962		.setup = alc268_toshiba_setup,
13963		.init_hook = alc_inithook,
13964	},
13965	[ALC268_ACER] = {
13966		.mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
13967			    alc268_beep_mixer },
13968		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13969				alc268_acer_verbs },
13970		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
13971		.dac_nids = alc268_dac_nids,
13972		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13973		.adc_nids = alc268_adc_nids_alt,
13974		.capsrc_nids = alc268_capsrc_nids,
13975		.hp_nid = 0x02,
13976		.num_channel_mode = ARRAY_SIZE(alc268_modes),
13977		.channel_mode = alc268_modes,
13978		.input_mux = &alc268_acer_capture_source,
13979		.unsol_event = alc_sku_unsol_event,
13980		.setup = alc268_acer_setup,
13981		.init_hook = alc_inithook,
13982	},
13983	[ALC268_ACER_DMIC] = {
13984		.mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13985			    alc268_beep_mixer },
13986		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13987				alc268_acer_verbs },
13988		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
13989		.dac_nids = alc268_dac_nids,
13990		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13991		.adc_nids = alc268_adc_nids_alt,
13992		.capsrc_nids = alc268_capsrc_nids,
13993		.hp_nid = 0x02,
13994		.num_channel_mode = ARRAY_SIZE(alc268_modes),
13995		.channel_mode = alc268_modes,
13996		.input_mux = &alc268_acer_dmic_capture_source,
13997		.unsol_event = alc_sku_unsol_event,
13998		.setup = alc268_acer_setup,
13999		.init_hook = alc_inithook,
14000	},
14001	[ALC268_ACER_ASPIRE_ONE] = {
14002		.mixers = { alc268_acer_aspire_one_mixer,
14003			    alc268_beep_mixer,
14004			    alc268_capture_nosrc_mixer },
14005		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
14006				alc268_acer_aspire_one_verbs },
14007		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
14008		.dac_nids = alc268_dac_nids,
14009		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
14010		.adc_nids = alc268_adc_nids_alt,
14011		.capsrc_nids = alc268_capsrc_nids,
14012		.hp_nid = 0x03,
14013		.num_channel_mode = ARRAY_SIZE(alc268_modes),
14014		.channel_mode = alc268_modes,
14015		.unsol_event = alc_sku_unsol_event,
14016		.setup = alc268_acer_lc_setup,
14017		.init_hook = alc_inithook,
14018	},
14019	[ALC268_DELL] = {
14020		.mixers = { alc268_dell_mixer, alc268_beep_mixer,
14021			    alc268_capture_nosrc_mixer },
14022		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
14023				alc268_dell_verbs },
14024		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
14025		.dac_nids = alc268_dac_nids,
14026		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
14027		.adc_nids = alc268_adc_nids_alt,
14028		.capsrc_nids = alc268_capsrc_nids,
14029		.hp_nid = 0x02,
14030		.num_channel_mode = ARRAY_SIZE(alc268_modes),
14031		.channel_mode = alc268_modes,
14032		.unsol_event = alc_sku_unsol_event,
14033		.setup = alc268_dell_setup,
14034		.init_hook = alc_inithook,
14035	},
14036	[ALC268_ZEPTO] = {
14037		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
14038			    alc268_beep_mixer },
14039		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
14040				alc268_toshiba_verbs },
14041		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
14042		.dac_nids = alc268_dac_nids,
14043		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
14044		.adc_nids = alc268_adc_nids_alt,
14045		.capsrc_nids = alc268_capsrc_nids,
14046		.hp_nid = 0x03,
14047		.dig_out_nid = ALC268_DIGOUT_NID,
14048		.num_channel_mode = ARRAY_SIZE(alc268_modes),
14049		.channel_mode = alc268_modes,
14050		.input_mux = &alc268_capture_source,
14051		.unsol_event = alc_sku_unsol_event,
14052		.setup = alc268_toshiba_setup,
14053		.init_hook = alc_inithook,
14054	},
14055#ifdef CONFIG_SND_DEBUG
14056	[ALC268_TEST] = {
14057		.mixers = { alc268_test_mixer, alc268_capture_mixer },
14058		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
14059				alc268_volume_init_verbs },
14060		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
14061		.dac_nids = alc268_dac_nids,
14062		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
14063		.adc_nids = alc268_adc_nids_alt,
14064		.capsrc_nids = alc268_capsrc_nids,
14065		.hp_nid = 0x03,
14066		.dig_out_nid = ALC268_DIGOUT_NID,
14067		.num_channel_mode = ARRAY_SIZE(alc268_modes),
14068		.channel_mode = alc268_modes,
14069		.input_mux = &alc268_capture_source,
14070	},
14071#endif
14072};
14073
14074static int patch_alc268(struct hda_codec *codec)
14075{
14076	struct alc_spec *spec;
14077	int board_config;
14078	int i, has_beep, err;
14079
14080	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14081	if (spec == NULL)
14082		return -ENOMEM;
14083
14084	codec->spec = spec;
14085
14086	board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
14087						  alc268_models,
14088						  alc268_cfg_tbl);
14089
14090	if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
14091		board_config = snd_hda_check_board_codec_sid_config(codec,
14092			ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
14093
14094	if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
14095		printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14096		       codec->chip_name);
14097		board_config = ALC268_AUTO;
14098	}
14099
14100	if (board_config == ALC268_AUTO) {
14101		/* automatic parse from the BIOS config */
14102		err = alc268_parse_auto_config(codec);
14103		if (err < 0) {
14104			alc_free(codec);
14105			return err;
14106		} else if (!err) {
14107			printk(KERN_INFO
14108			       "hda_codec: Cannot set up configuration "
14109			       "from BIOS.  Using base mode...\n");
14110			board_config = ALC268_3ST;
14111		}
14112	}
14113
14114	if (board_config != ALC268_AUTO)
14115		setup_preset(codec, &alc268_presets[board_config]);
14116
14117	spec->stream_analog_playback = &alc268_pcm_analog_playback;
14118	spec->stream_analog_capture = &alc268_pcm_analog_capture;
14119	spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
14120
14121	spec->stream_digital_playback = &alc268_pcm_digital_playback;
14122
14123	has_beep = 0;
14124	for (i = 0; i < spec->num_mixers; i++) {
14125		if (spec->mixers[i] == alc268_beep_mixer) {
14126			has_beep = 1;
14127			break;
14128		}
14129	}
14130
14131	if (has_beep) {
14132		err = snd_hda_attach_beep_device(codec, 0x1);
14133		if (err < 0) {
14134			alc_free(codec);
14135			return err;
14136		}
14137		if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
14138			/* override the amp caps for beep generator */
14139			snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
14140					  (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
14141					  (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
14142					  (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
14143					  (0 << AC_AMPCAP_MUTE_SHIFT));
14144	}
14145
14146	if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
14147		/* check whether NID 0x07 is valid */
14148		unsigned int wcap = get_wcaps(codec, 0x07);
14149
14150		spec->capsrc_nids = alc268_capsrc_nids;
14151		/* get type */
14152		wcap = get_wcaps_type(wcap);
14153		if (spec->auto_mic ||
14154		    wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
14155			spec->adc_nids = alc268_adc_nids_alt;
14156			spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
14157			if (spec->auto_mic)
14158				fixup_automic_adc(codec);
14159			if (spec->auto_mic || spec->input_mux->num_items == 1)
14160				add_mixer(spec, alc268_capture_nosrc_mixer);
14161			else
14162				add_mixer(spec, alc268_capture_alt_mixer);
14163		} else {
14164			spec->adc_nids = alc268_adc_nids;
14165			spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
14166			add_mixer(spec, alc268_capture_mixer);
14167		}
14168	}
14169
14170	spec->vmaster_nid = 0x02;
14171
14172	codec->patch_ops = alc_patch_ops;
14173	if (board_config == ALC268_AUTO)
14174		spec->init_hook = alc268_auto_init;
14175	spec->shutup = alc_eapd_shutup;
14176
14177	alc_init_jacks(codec);
14178
14179	return 0;
14180}
14181
14182/*
14183 *  ALC269 channel source setting (2 channel)
14184 */
14185#define ALC269_DIGOUT_NID	ALC880_DIGOUT_NID
14186
14187#define alc269_dac_nids		alc260_dac_nids
14188
14189static const hda_nid_t alc269_adc_nids[1] = {
14190	/* ADC1 */
14191	0x08,
14192};
14193
14194static const hda_nid_t alc269_capsrc_nids[1] = {
14195	0x23,
14196};
14197
14198static const hda_nid_t alc269vb_adc_nids[1] = {
14199	/* ADC1 */
14200	0x09,
14201};
14202
14203static const hda_nid_t alc269vb_capsrc_nids[1] = {
14204	0x22,
14205};
14206
14207static const hda_nid_t alc269_adc_candidates[] = {
14208	0x08, 0x09, 0x07, 0x11,
14209};
14210
14211#define alc269_modes		alc260_modes
14212#define alc269_capture_source	alc880_lg_lw_capture_source
14213
14214static const struct snd_kcontrol_new alc269_base_mixer[] = {
14215	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14216	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14217	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14218	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14219	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14220	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14221	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14222	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14223	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14224	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
14225	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14226	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14227	{ } /* end */
14228};
14229
14230static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14231	/* output mixer control */
14232	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14233	{
14234		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14235		.name = "Master Playback Switch",
14236		.subdevice = HDA_SUBDEV_AMP_FLAG,
14237		.info = snd_hda_mixer_amp_switch_info,
14238		.get = snd_hda_mixer_amp_switch_get,
14239		.put = alc268_acer_master_sw_put,
14240		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14241	},
14242	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14243	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14244	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14245	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14246	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14247	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14248	{ }
14249};
14250
14251static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14252	/* output mixer control */
14253	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14254	{
14255		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14256		.name = "Master Playback Switch",
14257		.subdevice = HDA_SUBDEV_AMP_FLAG,
14258		.info = snd_hda_mixer_amp_switch_info,
14259		.get = snd_hda_mixer_amp_switch_get,
14260		.put = alc268_acer_master_sw_put,
14261		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14262	},
14263	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14264	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14265	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14266	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14267	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14268	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14269	HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14270	HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
14271	HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
14272	{ }
14273};
14274
14275static const struct snd_kcontrol_new alc269_laptop_mixer[] = {
14276	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14277	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14278	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14279	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14280	{ } /* end */
14281};
14282
14283static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
14284	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14285	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14286	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14287	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14288	{ } /* end */
14289};
14290
14291static const struct snd_kcontrol_new alc269_asus_mixer[] = {
14292	HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14293	HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14294	{ } /* end */
14295};
14296
14297/* capture mixer elements */
14298static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14299	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14300	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14301	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14302	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14303	{ } /* end */
14304};
14305
14306static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
14307	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14308	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14309	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14310	{ } /* end */
14311};
14312
14313static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14314	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14315	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14316	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14317	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14318	{ } /* end */
14319};
14320
14321static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14322	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14323	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14324	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14325	{ } /* end */
14326};
14327
14328/* FSC amilo */
14329#define alc269_fujitsu_mixer	alc269_laptop_mixer
14330
14331static const struct hda_verb alc269_quanta_fl1_verbs[] = {
14332	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14333	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14334	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14335	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14336	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14337	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14338	{ }
14339};
14340
14341static const struct hda_verb alc269_lifebook_verbs[] = {
14342	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14343	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14344	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14345	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14346	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14347	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14348	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14349	{0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14350	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14351	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14352	{ }
14353};
14354
14355/* toggle speaker-output according to the hp-jack state */
14356static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14357{
14358	alc_hp_automute(codec);
14359
14360	snd_hda_codec_write(codec, 0x20, 0,
14361			AC_VERB_SET_COEF_INDEX, 0x0c);
14362	snd_hda_codec_write(codec, 0x20, 0,
14363			AC_VERB_SET_PROC_COEF, 0x680);
14364
14365	snd_hda_codec_write(codec, 0x20, 0,
14366			AC_VERB_SET_COEF_INDEX, 0x0c);
14367	snd_hda_codec_write(codec, 0x20, 0,
14368			AC_VERB_SET_PROC_COEF, 0x480);
14369}
14370
14371#define alc269_lifebook_speaker_automute \
14372	alc269_quanta_fl1_speaker_automute
14373
14374static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14375{
14376	unsigned int present_laptop;
14377	unsigned int present_dock;
14378
14379	present_laptop	= snd_hda_jack_detect(codec, 0x18);
14380	present_dock	= snd_hda_jack_detect(codec, 0x1b);
14381
14382	/* Laptop mic port overrides dock mic port, design decision */
14383	if (present_dock)
14384		snd_hda_codec_write(codec, 0x23, 0,
14385				AC_VERB_SET_CONNECT_SEL, 0x3);
14386	if (present_laptop)
14387		snd_hda_codec_write(codec, 0x23, 0,
14388				AC_VERB_SET_CONNECT_SEL, 0x0);
14389	if (!present_dock && !present_laptop)
14390		snd_hda_codec_write(codec, 0x23, 0,
14391				AC_VERB_SET_CONNECT_SEL, 0x1);
14392}
14393
14394static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14395				    unsigned int res)
14396{
14397	switch (res >> 26) {
14398	case ALC880_HP_EVENT:
14399		alc269_quanta_fl1_speaker_automute(codec);
14400		break;
14401	case ALC880_MIC_EVENT:
14402		alc_mic_automute(codec);
14403		break;
14404	}
14405}
14406
14407static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14408					unsigned int res)
14409{
14410	if ((res >> 26) == ALC880_HP_EVENT)
14411		alc269_lifebook_speaker_automute(codec);
14412	if ((res >> 26) == ALC880_MIC_EVENT)
14413		alc269_lifebook_mic_autoswitch(codec);
14414}
14415
14416static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14417{
14418	struct alc_spec *spec = codec->spec;
14419	spec->autocfg.hp_pins[0] = 0x15;
14420	spec->autocfg.speaker_pins[0] = 0x14;
14421	spec->automute_mixer_nid[0] = 0x0c;
14422	spec->automute = 1;
14423	spec->automute_mode = ALC_AUTOMUTE_MIXER;
14424	spec->ext_mic.pin = 0x18;
14425	spec->ext_mic.mux_idx = 0;
14426	spec->int_mic.pin = 0x19;
14427	spec->int_mic.mux_idx = 1;
14428	spec->auto_mic = 1;
14429}
14430
14431static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14432{
14433	alc269_quanta_fl1_speaker_automute(codec);
14434	alc_mic_automute(codec);
14435}
14436
14437static void alc269_lifebook_setup(struct hda_codec *codec)
14438{
14439	struct alc_spec *spec = codec->spec;
14440	spec->autocfg.hp_pins[0] = 0x15;
14441	spec->autocfg.hp_pins[1] = 0x1a;
14442	spec->autocfg.speaker_pins[0] = 0x14;
14443	spec->automute_mixer_nid[0] = 0x0c;
14444	spec->automute = 1;
14445	spec->automute_mode = ALC_AUTOMUTE_MIXER;
14446}
14447
14448static void alc269_lifebook_init_hook(struct hda_codec *codec)
14449{
14450	alc269_lifebook_speaker_automute(codec);
14451	alc269_lifebook_mic_autoswitch(codec);
14452}
14453
14454static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {
14455	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14456	{0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14457	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14458	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14459	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14460	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14461	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14462	{}
14463};
14464
14465static const struct hda_verb alc269_laptop_amic_init_verbs[] = {
14466	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14467	{0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14468	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14469	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14470	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14471	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14472	{}
14473};
14474
14475static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14476	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14477	{0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14478	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14479	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14480	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14481	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14482	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14483	{}
14484};
14485
14486static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14487	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14488	{0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14489	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14490	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14491	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14492	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14493	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14494	{}
14495};
14496
14497static const struct hda_verb alc271_acer_dmic_verbs[] = {
14498	{0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14499	{0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14500	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14501	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14502	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14503	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14504	{0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14505	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14506	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14507	{0x22, AC_VERB_SET_CONNECT_SEL, 6},
14508	{ }
14509};
14510
14511static void alc269_laptop_amic_setup(struct hda_codec *codec)
14512{
14513	struct alc_spec *spec = codec->spec;
14514	spec->autocfg.hp_pins[0] = 0x15;
14515	spec->autocfg.speaker_pins[0] = 0x14;
14516	spec->automute_mixer_nid[0] = 0x0c;
14517	spec->automute = 1;
14518	spec->automute_mode = ALC_AUTOMUTE_MIXER;
14519	spec->ext_mic.pin = 0x18;
14520	spec->ext_mic.mux_idx = 0;
14521	spec->int_mic.pin = 0x19;
14522	spec->int_mic.mux_idx = 1;
14523	spec->auto_mic = 1;
14524}
14525
14526static void alc269_laptop_dmic_setup(struct hda_codec *codec)
14527{
14528	struct alc_spec *spec = codec->spec;
14529	spec->autocfg.hp_pins[0] = 0x15;
14530	spec->autocfg.speaker_pins[0] = 0x14;
14531	spec->automute_mixer_nid[0] = 0x0c;
14532	spec->automute = 1;
14533	spec->automute_mode = ALC_AUTOMUTE_MIXER;
14534	spec->ext_mic.pin = 0x18;
14535	spec->ext_mic.mux_idx = 0;
14536	spec->int_mic.pin = 0x12;
14537	spec->int_mic.mux_idx = 5;
14538	spec->auto_mic = 1;
14539}
14540
14541static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
14542{
14543	struct alc_spec *spec = codec->spec;
14544	spec->autocfg.hp_pins[0] = 0x21;
14545	spec->autocfg.speaker_pins[0] = 0x14;
14546	spec->automute_mixer_nid[0] = 0x0c;
14547	spec->automute = 1;
14548	spec->automute_mode = ALC_AUTOMUTE_MIXER;
14549	spec->ext_mic.pin = 0x18;
14550	spec->ext_mic.mux_idx = 0;
14551	spec->int_mic.pin = 0x19;
14552	spec->int_mic.mux_idx = 1;
14553	spec->auto_mic = 1;
14554}
14555
14556static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14557{
14558	struct alc_spec *spec = codec->spec;
14559	spec->autocfg.hp_pins[0] = 0x21;
14560	spec->autocfg.speaker_pins[0] = 0x14;
14561	spec->automute_mixer_nid[0] = 0x0c;
14562	spec->automute = 1;
14563	spec->automute_mode = ALC_AUTOMUTE_MIXER;
14564	spec->ext_mic.pin = 0x18;
14565	spec->ext_mic.mux_idx = 0;
14566	spec->int_mic.pin = 0x12;
14567	spec->int_mic.mux_idx = 6;
14568	spec->auto_mic = 1;
14569}
14570
14571/*
14572 * generic initialization of ADC, input mixers and output mixers
14573 */
14574static const struct hda_verb alc269_init_verbs[] = {
14575	/*
14576	 * Unmute ADC0 and set the default input to mic-in
14577	 */
14578	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14579
14580	/*
14581	 * Set up output mixers (0x02 - 0x03)
14582	 */
14583	/* set vol=0 to output mixers */
14584	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14585	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14586
14587	/* set up input amps for analog loopback */
14588	/* Amp Indices: DAC = 0, mixer = 1 */
14589	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14590	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14591	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14592	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14593	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14594	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14595
14596	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14597	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14598	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14599	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14600	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14601	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14602	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14603
14604	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14605	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14606
14607	/* FIXME: use Mux-type input source selection */
14608	/* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14609	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14610	{0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
14611
14612	/* set EAPD */
14613	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14614	{ }
14615};
14616
14617static const struct hda_verb alc269vb_init_verbs[] = {
14618	/*
14619	 * Unmute ADC0 and set the default input to mic-in
14620	 */
14621	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14622
14623	/*
14624	 * Set up output mixers (0x02 - 0x03)
14625	 */
14626	/* set vol=0 to output mixers */
14627	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14628	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14629
14630	/* set up input amps for analog loopback */
14631	/* Amp Indices: DAC = 0, mixer = 1 */
14632	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14633	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14634	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14635	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14636	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14637	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14638
14639	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14640	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14641	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14642	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14643	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14644	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14645	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14646
14647	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14648	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14649
14650	/* FIXME: use Mux-type input source selection */
14651	/* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14652	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14653	{0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
14654
14655	/* set EAPD */
14656	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14657	{ }
14658};
14659
14660#define alc269_auto_create_multi_out_ctls \
14661	alc268_auto_create_multi_out_ctls
14662#define alc269_auto_create_input_ctls \
14663	alc268_auto_create_input_ctls
14664
14665#ifdef CONFIG_SND_HDA_POWER_SAVE
14666#define alc269_loopbacks	alc880_loopbacks
14667#endif
14668
14669/* pcm configuration: identical with ALC880 */
14670#define alc269_pcm_analog_playback	alc880_pcm_analog_playback
14671#define alc269_pcm_analog_capture	alc880_pcm_analog_capture
14672#define alc269_pcm_digital_playback	alc880_pcm_digital_playback
14673#define alc269_pcm_digital_capture	alc880_pcm_digital_capture
14674
14675static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14676	.substreams = 1,
14677	.channels_min = 2,
14678	.channels_max = 8,
14679	.rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14680	/* NID is set in alc_build_pcms */
14681	.ops = {
14682		.open = alc880_playback_pcm_open,
14683		.prepare = alc880_playback_pcm_prepare,
14684		.cleanup = alc880_playback_pcm_cleanup
14685	},
14686};
14687
14688static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14689	.substreams = 1,
14690	.channels_min = 2,
14691	.channels_max = 2,
14692	.rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14693	/* NID is set in alc_build_pcms */
14694};
14695
14696#ifdef CONFIG_SND_HDA_POWER_SAVE
14697static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14698{
14699	switch (codec->subsystem_id) {
14700	case 0x103c1586:
14701		return 1;
14702	}
14703	return 0;
14704}
14705
14706static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14707{
14708	/* update mute-LED according to the speaker mute state */
14709	if (nid == 0x01 || nid == 0x14) {
14710		int pinval;
14711		if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14712		    HDA_AMP_MUTE)
14713			pinval = 0x24;
14714		else
14715			pinval = 0x20;
14716		/* mic2 vref pin is used for mute LED control */
14717		snd_hda_codec_update_cache(codec, 0x19, 0,
14718					   AC_VERB_SET_PIN_WIDGET_CONTROL,
14719					   pinval);
14720	}
14721	return alc_check_power_status(codec, nid);
14722}
14723#endif /* CONFIG_SND_HDA_POWER_SAVE */
14724
14725static int alc275_setup_dual_adc(struct hda_codec *codec)
14726{
14727	struct alc_spec *spec = codec->spec;
14728
14729	if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14730		return 0;
14731	if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14732	    (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14733		if (spec->ext_mic.pin <= 0x12) {
14734			spec->private_adc_nids[0] = 0x08;
14735			spec->private_adc_nids[1] = 0x11;
14736			spec->private_capsrc_nids[0] = 0x23;
14737			spec->private_capsrc_nids[1] = 0x22;
14738		} else {
14739			spec->private_adc_nids[0] = 0x11;
14740			spec->private_adc_nids[1] = 0x08;
14741			spec->private_capsrc_nids[0] = 0x22;
14742			spec->private_capsrc_nids[1] = 0x23;
14743		}
14744		spec->adc_nids = spec->private_adc_nids;
14745		spec->capsrc_nids = spec->private_capsrc_nids;
14746		spec->num_adc_nids = 2;
14747		spec->dual_adc_switch = 1;
14748		snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14749			    spec->adc_nids[0], spec->adc_nids[1]);
14750		return 1;
14751	}
14752	return 0;
14753}
14754
14755/* different alc269-variants */
14756enum {
14757	ALC269_TYPE_NORMAL,
14758	ALC269_TYPE_ALC258,
14759	ALC269_TYPE_ALC259,
14760	ALC269_TYPE_ALC269VB,
14761	ALC269_TYPE_ALC270,
14762	ALC269_TYPE_ALC271X,
14763};
14764
14765/*
14766 * BIOS auto configuration
14767 */
14768static int alc269_parse_auto_config(struct hda_codec *codec)
14769{
14770	struct alc_spec *spec = codec->spec;
14771	int err;
14772	static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14773
14774	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14775					   alc269_ignore);
14776	if (err < 0)
14777		return err;
14778
14779	err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14780	if (err < 0)
14781		return err;
14782	if (spec->codec_variant == ALC269_TYPE_NORMAL)
14783		err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14784	else
14785		err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14786						 0x22, 0);
14787	if (err < 0)
14788		return err;
14789
14790	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14791
14792	alc_auto_parse_digital(codec);
14793
14794	if (spec->kctls.list)
14795		add_mixer(spec, spec->kctls.list);
14796
14797	if (spec->codec_variant != ALC269_TYPE_NORMAL) {
14798		add_verb(spec, alc269vb_init_verbs);
14799		alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
14800	} else {
14801		add_verb(spec, alc269_init_verbs);
14802		alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
14803	}
14804
14805	spec->num_mux_defs = 1;
14806	spec->input_mux = &spec->private_imux[0];
14807
14808	if (!alc275_setup_dual_adc(codec))
14809		fillup_priv_adc_nids(codec, alc269_adc_candidates,
14810				     sizeof(alc269_adc_candidates));
14811
14812	err = alc_auto_add_mic_boost(codec);
14813	if (err < 0)
14814		return err;
14815
14816	if (!spec->cap_mixer && !spec->no_analog)
14817		set_capture_mixer(codec);
14818
14819	return 1;
14820}
14821
14822#define alc269_auto_init_multi_out	alc268_auto_init_multi_out
14823#define alc269_auto_init_hp_out		alc268_auto_init_hp_out
14824#define alc269_auto_init_analog_input	alc882_auto_init_analog_input
14825#define alc269_auto_init_input_src	alc882_auto_init_input_src
14826
14827
14828/* init callback for auto-configuration model -- overriding the default init */
14829static void alc269_auto_init(struct hda_codec *codec)
14830{
14831	struct alc_spec *spec = codec->spec;
14832	alc269_auto_init_multi_out(codec);
14833	alc269_auto_init_hp_out(codec);
14834	alc269_auto_init_analog_input(codec);
14835	if (!spec->dual_adc_switch)
14836		alc269_auto_init_input_src(codec);
14837	alc_auto_init_digital(codec);
14838	if (spec->unsol_event)
14839		alc_inithook(codec);
14840}
14841
14842static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14843{
14844	int val = alc_read_coef_idx(codec, 0x04);
14845	if (power_up)
14846		val |= 1 << 11;
14847	else
14848		val &= ~(1 << 11);
14849	alc_write_coef_idx(codec, 0x04, val);
14850}
14851
14852static void alc269_shutup(struct hda_codec *codec)
14853{
14854	if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14855		alc269_toggle_power_output(codec, 0);
14856	if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14857		alc269_toggle_power_output(codec, 0);
14858		msleep(150);
14859	}
14860}
14861
14862#ifdef SND_HDA_NEEDS_RESUME
14863static int alc269_resume(struct hda_codec *codec)
14864{
14865	if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14866		alc269_toggle_power_output(codec, 0);
14867		msleep(150);
14868	}
14869
14870	codec->patch_ops.init(codec);
14871
14872	if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
14873		alc269_toggle_power_output(codec, 1);
14874		msleep(200);
14875	}
14876
14877	if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14878		alc269_toggle_power_output(codec, 1);
14879
14880	snd_hda_codec_resume_amp(codec);
14881	snd_hda_codec_resume_cache(codec);
14882	hda_call_check_power_status(codec, 0x01);
14883	return 0;
14884}
14885#endif /* SND_HDA_NEEDS_RESUME */
14886
14887static void alc269_fixup_hweq(struct hda_codec *codec,
14888			       const struct alc_fixup *fix, int action)
14889{
14890	int coef;
14891
14892	if (action != ALC_FIXUP_ACT_INIT)
14893		return;
14894	coef = alc_read_coef_idx(codec, 0x1e);
14895	alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14896}
14897
14898static void alc271_fixup_dmic(struct hda_codec *codec,
14899			      const struct alc_fixup *fix, int action)
14900{
14901	static const struct hda_verb verbs[] = {
14902		{0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14903		{0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14904		{}
14905	};
14906	unsigned int cfg;
14907
14908	if (strcmp(codec->chip_name, "ALC271X"))
14909		return;
14910	cfg = snd_hda_codec_get_pincfg(codec, 0x12);
14911	if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
14912		snd_hda_sequence_write(codec, verbs);
14913}
14914
14915enum {
14916	ALC269_FIXUP_SONY_VAIO,
14917	ALC275_FIXUP_SONY_VAIO_GPIO2,
14918	ALC269_FIXUP_DELL_M101Z,
14919	ALC269_FIXUP_SKU_IGNORE,
14920	ALC269_FIXUP_ASUS_G73JW,
14921	ALC269_FIXUP_LENOVO_EAPD,
14922	ALC275_FIXUP_SONY_HWEQ,
14923	ALC271_FIXUP_DMIC,
14924};
14925
14926static const struct alc_fixup alc269_fixups[] = {
14927	[ALC269_FIXUP_SONY_VAIO] = {
14928		.type = ALC_FIXUP_VERBS,
14929		.v.verbs = (const struct hda_verb[]) {
14930			{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14931			{}
14932		}
14933	},
14934	[ALC275_FIXUP_SONY_VAIO_GPIO2] = {
14935		.type = ALC_FIXUP_VERBS,
14936		.v.verbs = (const struct hda_verb[]) {
14937			{0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14938			{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14939			{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14940			{ }
14941		},
14942		.chained = true,
14943		.chain_id = ALC269_FIXUP_SONY_VAIO
14944	},
14945	[ALC269_FIXUP_DELL_M101Z] = {
14946		.type = ALC_FIXUP_VERBS,
14947		.v.verbs = (const struct hda_verb[]) {
14948			/* Enables internal speaker */
14949			{0x20, AC_VERB_SET_COEF_INDEX, 13},
14950			{0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14951			{}
14952		}
14953	},
14954	[ALC269_FIXUP_SKU_IGNORE] = {
14955		.type = ALC_FIXUP_SKU,
14956		.v.sku = ALC_FIXUP_SKU_IGNORE,
14957	},
14958	[ALC269_FIXUP_ASUS_G73JW] = {
14959		.type = ALC_FIXUP_PINS,
14960		.v.pins = (const struct alc_pincfg[]) {
14961			{ 0x17, 0x99130111 }, /* subwoofer */
14962			{ }
14963		}
14964	},
14965	[ALC269_FIXUP_LENOVO_EAPD] = {
14966		.type = ALC_FIXUP_VERBS,
14967		.v.verbs = (const struct hda_verb[]) {
14968			{0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14969			{}
14970		}
14971	},
14972	[ALC275_FIXUP_SONY_HWEQ] = {
14973		.type = ALC_FIXUP_FUNC,
14974		.v.func = alc269_fixup_hweq,
14975		.chained = true,
14976		.chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
14977	},
14978	[ALC271_FIXUP_DMIC] = {
14979		.type = ALC_FIXUP_FUNC,
14980		.v.func = alc271_fixup_dmic,
14981	},
14982};
14983
14984static const struct snd_pci_quirk alc269_fixup_tbl[] = {
14985	SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
14986	SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14987	SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14988	SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14989	SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
14990	SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
14991	SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
14992	SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
14993	SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14994	SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14995	SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
14996	SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
14997	SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
14998	{}
14999};
15000
15001
15002/*
15003 * configuration and preset
15004 */
15005static const char * const alc269_models[ALC269_MODEL_LAST] = {
15006	[ALC269_BASIC]			= "basic",
15007	[ALC269_QUANTA_FL1]		= "quanta",
15008	[ALC269_AMIC]			= "laptop-amic",
15009	[ALC269_DMIC]			= "laptop-dmic",
15010	[ALC269_FUJITSU]		= "fujitsu",
15011	[ALC269_LIFEBOOK]		= "lifebook",
15012	[ALC269_AUTO]			= "auto",
15013};
15014
15015static const struct snd_pci_quirk alc269_cfg_tbl[] = {
15016	SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
15017	SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
15018	SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
15019		      ALC269_AMIC),
15020	SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
15021	SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
15022	SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
15023	SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
15024	SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
15025	SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
15026	SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
15027	SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
15028	SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
15029	SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
15030	SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
15031	SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
15032	SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
15033	SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
15034	SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
15035	SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
15036	SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
15037	SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
15038	SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
15039	SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
15040	SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
15041	SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
15042	SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
15043	SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
15044	SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
15045	SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
15046	SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
15047	SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
15048	SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
15049	SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
15050	SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
15051	SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
15052	SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
15053	SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
15054	SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
15055	SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
15056	SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
15057		      ALC269_DMIC),
15058	SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
15059		      ALC269_DMIC),
15060	SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
15061	SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
15062	SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
15063	SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
15064	SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
15065	SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
15066	SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
15067	SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
15068	SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
15069	SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
15070	{}
15071};
15072
15073static const struct alc_config_preset alc269_presets[] = {
15074	[ALC269_BASIC] = {
15075		.mixers = { alc269_base_mixer },
15076		.init_verbs = { alc269_init_verbs },
15077		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
15078		.dac_nids = alc269_dac_nids,
15079		.hp_nid = 0x03,
15080		.num_channel_mode = ARRAY_SIZE(alc269_modes),
15081		.channel_mode = alc269_modes,
15082		.input_mux = &alc269_capture_source,
15083	},
15084	[ALC269_QUANTA_FL1] = {
15085		.mixers = { alc269_quanta_fl1_mixer },
15086		.init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
15087		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
15088		.dac_nids = alc269_dac_nids,
15089		.hp_nid = 0x03,
15090		.num_channel_mode = ARRAY_SIZE(alc269_modes),
15091		.channel_mode = alc269_modes,
15092		.input_mux = &alc269_capture_source,
15093		.unsol_event = alc269_quanta_fl1_unsol_event,
15094		.setup = alc269_quanta_fl1_setup,
15095		.init_hook = alc269_quanta_fl1_init_hook,
15096	},
15097	[ALC269_AMIC] = {
15098		.mixers = { alc269_laptop_mixer },
15099		.cap_mixer = alc269_laptop_analog_capture_mixer,
15100		.init_verbs = { alc269_init_verbs,
15101				alc269_laptop_amic_init_verbs },
15102		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
15103		.dac_nids = alc269_dac_nids,
15104		.hp_nid = 0x03,
15105		.num_channel_mode = ARRAY_SIZE(alc269_modes),
15106		.channel_mode = alc269_modes,
15107		.unsol_event = alc_sku_unsol_event,
15108		.setup = alc269_laptop_amic_setup,
15109		.init_hook = alc_inithook,
15110	},
15111	[ALC269_DMIC] = {
15112		.mixers = { alc269_laptop_mixer },
15113		.cap_mixer = alc269_laptop_digital_capture_mixer,
15114		.init_verbs = { alc269_init_verbs,
15115				alc269_laptop_dmic_init_verbs },
15116		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
15117		.dac_nids = alc269_dac_nids,
15118		.hp_nid = 0x03,
15119		.num_channel_mode = ARRAY_SIZE(alc269_modes),
15120		.channel_mode = alc269_modes,
15121		.unsol_event = alc_sku_unsol_event,
15122		.setup = alc269_laptop_dmic_setup,
15123		.init_hook = alc_inithook,
15124	},
15125	[ALC269VB_AMIC] = {
15126		.mixers = { alc269vb_laptop_mixer },
15127		.cap_mixer = alc269vb_laptop_analog_capture_mixer,
15128		.init_verbs = { alc269vb_init_verbs,
15129				alc269vb_laptop_amic_init_verbs },
15130		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
15131		.dac_nids = alc269_dac_nids,
15132		.hp_nid = 0x03,
15133		.num_channel_mode = ARRAY_SIZE(alc269_modes),
15134		.channel_mode = alc269_modes,
15135		.unsol_event = alc_sku_unsol_event,
15136		.setup = alc269vb_laptop_amic_setup,
15137		.init_hook = alc_inithook,
15138	},
15139	[ALC269VB_DMIC] = {
15140		.mixers = { alc269vb_laptop_mixer },
15141		.cap_mixer = alc269vb_laptop_digital_capture_mixer,
15142		.init_verbs = { alc269vb_init_verbs,
15143				alc269vb_laptop_dmic_init_verbs },
15144		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
15145		.dac_nids = alc269_dac_nids,
15146		.hp_nid = 0x03,
15147		.num_channel_mode = ARRAY_SIZE(alc269_modes),
15148		.channel_mode = alc269_modes,
15149		.unsol_event = alc_sku_unsol_event,
15150		.setup = alc269vb_laptop_dmic_setup,
15151		.init_hook = alc_inithook,
15152	},
15153	[ALC269_FUJITSU] = {
15154		.mixers = { alc269_fujitsu_mixer },
15155		.cap_mixer = alc269_laptop_digital_capture_mixer,
15156		.init_verbs = { alc269_init_verbs,
15157				alc269_laptop_dmic_init_verbs },
15158		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
15159		.dac_nids = alc269_dac_nids,
15160		.hp_nid = 0x03,
15161		.num_channel_mode = ARRAY_SIZE(alc269_modes),
15162		.channel_mode = alc269_modes,
15163		.unsol_event = alc_sku_unsol_event,
15164		.setup = alc269_laptop_dmic_setup,
15165		.init_hook = alc_inithook,
15166	},
15167	[ALC269_LIFEBOOK] = {
15168		.mixers = { alc269_lifebook_mixer },
15169		.init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15170		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
15171		.dac_nids = alc269_dac_nids,
15172		.hp_nid = 0x03,
15173		.num_channel_mode = ARRAY_SIZE(alc269_modes),
15174		.channel_mode = alc269_modes,
15175		.input_mux = &alc269_capture_source,
15176		.unsol_event = alc269_lifebook_unsol_event,
15177		.setup = alc269_lifebook_setup,
15178		.init_hook = alc269_lifebook_init_hook,
15179	},
15180	[ALC271_ACER] = {
15181		.mixers = { alc269_asus_mixer },
15182		.cap_mixer = alc269vb_laptop_digital_capture_mixer,
15183		.init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15184		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
15185		.dac_nids = alc269_dac_nids,
15186		.adc_nids = alc262_dmic_adc_nids,
15187		.num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15188		.capsrc_nids = alc262_dmic_capsrc_nids,
15189		.num_channel_mode = ARRAY_SIZE(alc269_modes),
15190		.channel_mode = alc269_modes,
15191		.input_mux = &alc269_capture_source,
15192		.dig_out_nid = ALC880_DIGOUT_NID,
15193		.unsol_event = alc_sku_unsol_event,
15194		.setup = alc269vb_laptop_dmic_setup,
15195		.init_hook = alc_inithook,
15196	},
15197};
15198
15199static int alc269_fill_coef(struct hda_codec *codec)
15200{
15201	int val;
15202
15203	if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
15204		alc_write_coef_idx(codec, 0xf, 0x960b);
15205		alc_write_coef_idx(codec, 0xe, 0x8817);
15206	}
15207
15208	if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
15209		alc_write_coef_idx(codec, 0xf, 0x960b);
15210		alc_write_coef_idx(codec, 0xe, 0x8814);
15211	}
15212
15213	if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
15214		val = alc_read_coef_idx(codec, 0x04);
15215		/* Power up output pin */
15216		alc_write_coef_idx(codec, 0x04, val | (1<<11));
15217	}
15218
15219	if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
15220		val = alc_read_coef_idx(codec, 0xd);
15221		if ((val & 0x0c00) >> 10 != 0x1) {
15222			/* Capless ramp up clock control */
15223			alc_write_coef_idx(codec, 0xd, val | (1<<10));
15224		}
15225		val = alc_read_coef_idx(codec, 0x17);
15226		if ((val & 0x01c0) >> 6 != 0x4) {
15227			/* Class D power on reset */
15228			alc_write_coef_idx(codec, 0x17, val | (1<<7));
15229		}
15230	}
15231
15232	val = alc_read_coef_idx(codec, 0xd); /* Class D */
15233	alc_write_coef_idx(codec, 0xd, val | (1<<14));
15234
15235	val = alc_read_coef_idx(codec, 0x4); /* HP */
15236	alc_write_coef_idx(codec, 0x4, val | (1<<11));
15237
15238	return 0;
15239}
15240
15241static int patch_alc269(struct hda_codec *codec)
15242{
15243	struct alc_spec *spec;
15244	int board_config, coef;
15245	int err;
15246
15247	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15248	if (spec == NULL)
15249		return -ENOMEM;
15250
15251	codec->spec = spec;
15252
15253	alc_auto_parse_customize_define(codec);
15254
15255	if (codec->vendor_id == 0x10ec0269) {
15256		coef = alc_read_coef_idx(codec, 0);
15257		if ((coef & 0x00f0) == 0x0010) {
15258			if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15259			    spec->cdefine.platform_type == 1) {
15260				alc_codec_rename(codec, "ALC271X");
15261				spec->codec_variant = ALC269_TYPE_ALC271X;
15262			} else if ((coef & 0xf000) == 0x1000) {
15263				spec->codec_variant = ALC269_TYPE_ALC270;
15264			} else if ((coef & 0xf000) == 0x2000) {
15265				alc_codec_rename(codec, "ALC259");
15266				spec->codec_variant = ALC269_TYPE_ALC259;
15267			} else if ((coef & 0xf000) == 0x3000) {
15268				alc_codec_rename(codec, "ALC258");
15269				spec->codec_variant = ALC269_TYPE_ALC258;
15270			} else {
15271				alc_codec_rename(codec, "ALC269VB");
15272				spec->codec_variant = ALC269_TYPE_ALC269VB;
15273			}
15274		} else
15275			alc_fix_pll_init(codec, 0x20, 0x04, 15);
15276		alc269_fill_coef(codec);
15277	}
15278
15279	board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15280						  alc269_models,
15281						  alc269_cfg_tbl);
15282
15283	if (board_config < 0) {
15284		printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15285		       codec->chip_name);
15286		board_config = ALC269_AUTO;
15287	}
15288
15289	if (board_config == ALC269_AUTO) {
15290		alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15291		alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15292	}
15293
15294	if (board_config == ALC269_AUTO) {
15295		/* automatic parse from the BIOS config */
15296		err = alc269_parse_auto_config(codec);
15297		if (err < 0) {
15298			alc_free(codec);
15299			return err;
15300		} else if (!err) {
15301			printk(KERN_INFO
15302			       "hda_codec: Cannot set up configuration "
15303			       "from BIOS.  Using base mode...\n");
15304			board_config = ALC269_BASIC;
15305		}
15306	}
15307
15308	if (has_cdefine_beep(codec)) {
15309		err = snd_hda_attach_beep_device(codec, 0x1);
15310		if (err < 0) {
15311			alc_free(codec);
15312			return err;
15313		}
15314	}
15315
15316	if (board_config != ALC269_AUTO)
15317		setup_preset(codec, &alc269_presets[board_config]);
15318
15319	if (board_config == ALC269_QUANTA_FL1) {
15320		/* Due to a hardware problem on Lenovo Ideadpad, we need to
15321		 * fix the sample rate of analog I/O to 44.1kHz
15322		 */
15323		spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15324		spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
15325	} else if (spec->dual_adc_switch) {
15326		spec->stream_analog_playback = &alc269_pcm_analog_playback;
15327		/* switch ADC dynamically */
15328		spec->stream_analog_capture = &dualmic_pcm_analog_capture;
15329	} else {
15330		spec->stream_analog_playback = &alc269_pcm_analog_playback;
15331		spec->stream_analog_capture = &alc269_pcm_analog_capture;
15332	}
15333	spec->stream_digital_playback = &alc269_pcm_digital_playback;
15334	spec->stream_digital_capture = &alc269_pcm_digital_capture;
15335
15336	if (!spec->adc_nids) { /* wasn't filled automatically? use default */
15337		if (spec->codec_variant == ALC269_TYPE_NORMAL) {
15338			spec->adc_nids = alc269_adc_nids;
15339			spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15340			spec->capsrc_nids = alc269_capsrc_nids;
15341		} else {
15342			spec->adc_nids = alc269vb_adc_nids;
15343			spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15344			spec->capsrc_nids = alc269vb_capsrc_nids;
15345		}
15346	}
15347
15348	if (!spec->cap_mixer)
15349		set_capture_mixer(codec);
15350	if (has_cdefine_beep(codec))
15351		set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
15352
15353	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
15354
15355	spec->vmaster_nid = 0x02;
15356
15357	codec->patch_ops = alc_patch_ops;
15358#ifdef SND_HDA_NEEDS_RESUME
15359	codec->patch_ops.resume = alc269_resume;
15360#endif
15361	if (board_config == ALC269_AUTO)
15362		spec->init_hook = alc269_auto_init;
15363	spec->shutup = alc269_shutup;
15364
15365	alc_init_jacks(codec);
15366#ifdef CONFIG_SND_HDA_POWER_SAVE
15367	if (!spec->loopback.amplist)
15368		spec->loopback.amplist = alc269_loopbacks;
15369	if (alc269_mic2_for_mute_led(codec))
15370		codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
15371#endif
15372
15373	return 0;
15374}
15375
15376/*
15377 *  ALC861 channel source setting (2/6 channel selection for 3-stack)
15378 */
15379
15380/*
15381 * set the path ways for 2 channel output
15382 * need to set the codec line out and mic 1 pin widgets to inputs
15383 */
15384static const struct hda_verb alc861_threestack_ch2_init[] = {
15385	/* set pin widget 1Ah (line in) for input */
15386	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15387	/* set pin widget 18h (mic1/2) for input, for mic also enable
15388	 * the vref
15389	 */
15390	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15391
15392	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15393#if 0
15394	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15395	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15396#endif
15397	{ } /* end */
15398};
15399/*
15400 * 6ch mode
15401 * need to set the codec line out and mic 1 pin widgets to outputs
15402 */
15403static const struct hda_verb alc861_threestack_ch6_init[] = {
15404	/* set pin widget 1Ah (line in) for output (Back Surround)*/
15405	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15406	/* set pin widget 18h (mic1) for output (CLFE)*/
15407	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15408
15409	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15410	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15411
15412	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15413#if 0
15414	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15415	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15416#endif
15417	{ } /* end */
15418};
15419
15420static const struct hda_channel_mode alc861_threestack_modes[2] = {
15421	{ 2, alc861_threestack_ch2_init },
15422	{ 6, alc861_threestack_ch6_init },
15423};
15424/* Set mic1 as input and unmute the mixer */
15425static const struct hda_verb alc861_uniwill_m31_ch2_init[] = {
15426	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15427	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15428	{ } /* end */
15429};
15430/* Set mic1 as output and mute mixer */
15431static const struct hda_verb alc861_uniwill_m31_ch4_init[] = {
15432	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15433	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15434	{ } /* end */
15435};
15436
15437static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
15438	{ 2, alc861_uniwill_m31_ch2_init },
15439	{ 4, alc861_uniwill_m31_ch4_init },
15440};
15441
15442/* Set mic1 and line-in as input and unmute the mixer */
15443static const struct hda_verb alc861_asus_ch2_init[] = {
15444	/* set pin widget 1Ah (line in) for input */
15445	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15446	/* set pin widget 18h (mic1/2) for input, for mic also enable
15447	 * the vref
15448	 */
15449	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15450
15451	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15452#if 0
15453	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15454	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15455#endif
15456	{ } /* end */
15457};
15458/* Set mic1 nad line-in as output and mute mixer */
15459static const struct hda_verb alc861_asus_ch6_init[] = {
15460	/* set pin widget 1Ah (line in) for output (Back Surround)*/
15461	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15462	/* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15463	/* set pin widget 18h (mic1) for output (CLFE)*/
15464	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15465	/* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15466	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15467	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15468
15469	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15470#if 0
15471	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15472	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15473#endif
15474	{ } /* end */
15475};
15476
15477static const struct hda_channel_mode alc861_asus_modes[2] = {
15478	{ 2, alc861_asus_ch2_init },
15479	{ 6, alc861_asus_ch6_init },
15480};
15481
15482/* patch-ALC861 */
15483
15484static const struct snd_kcontrol_new alc861_base_mixer[] = {
15485        /* output mixer control */
15486	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15487	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15488	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15489	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15490	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15491
15492        /*Input mixer control */
15493	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15494	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15495	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15496	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15497	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15498	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15499	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15500	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15501	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15502	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15503
15504	{ } /* end */
15505};
15506
15507static const struct snd_kcontrol_new alc861_3ST_mixer[] = {
15508        /* output mixer control */
15509	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15510	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15511	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15512	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15513	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15514
15515	/* Input mixer control */
15516	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15517	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15518	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15519	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15520	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15521	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15522	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15523	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15524	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15525	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15526
15527	{
15528		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15529		.name = "Channel Mode",
15530		.info = alc_ch_mode_info,
15531		.get = alc_ch_mode_get,
15532		.put = alc_ch_mode_put,
15533                .private_value = ARRAY_SIZE(alc861_threestack_modes),
15534	},
15535	{ } /* end */
15536};
15537
15538static const struct snd_kcontrol_new alc861_toshiba_mixer[] = {
15539        /* output mixer control */
15540	HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15541	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15542	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15543
15544	{ } /* end */
15545};
15546
15547static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15548        /* output mixer control */
15549	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15550	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15551	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15552	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15553	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15554
15555	/* Input mixer control */
15556	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15557	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15558	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15559	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15560	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15561	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15562	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15563	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15564	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15565	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15566
15567	{
15568		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15569		.name = "Channel Mode",
15570		.info = alc_ch_mode_info,
15571		.get = alc_ch_mode_get,
15572		.put = alc_ch_mode_put,
15573                .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15574	},
15575	{ } /* end */
15576};
15577
15578static const struct snd_kcontrol_new alc861_asus_mixer[] = {
15579        /* output mixer control */
15580	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15581	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15582	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15583	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15584	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15585
15586	/* Input mixer control */
15587	HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15588	HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15589	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15590	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15591	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15592	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15593	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15594	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15595	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15596	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15597
15598	{
15599		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15600		.name = "Channel Mode",
15601		.info = alc_ch_mode_info,
15602		.get = alc_ch_mode_get,
15603		.put = alc_ch_mode_put,
15604                .private_value = ARRAY_SIZE(alc861_asus_modes),
15605	},
15606	{ }
15607};
15608
15609/* additional mixer */
15610static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
15611	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15612	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15613	{ }
15614};
15615
15616/*
15617 * generic initialization of ADC, input mixers and output mixers
15618 */
15619static const struct hda_verb alc861_base_init_verbs[] = {
15620	/*
15621	 * Unmute ADC0 and set the default input to mic-in
15622	 */
15623	/* port-A for surround (rear panel) */
15624	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15625	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15626	/* port-B for mic-in (rear panel) with vref */
15627	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15628	/* port-C for line-in (rear panel) */
15629	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15630	/* port-D for Front */
15631	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15632	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15633	/* port-E for HP out (front panel) */
15634	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15635	/* route front PCM to HP */
15636	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15637	/* port-F for mic-in (front panel) with vref */
15638	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15639	/* port-G for CLFE (rear panel) */
15640	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15641	{ 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15642	/* port-H for side (rear panel) */
15643	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15644	{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15645	/* CD-in */
15646	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15647	/* route front mic to ADC1*/
15648	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15649	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15650
15651	/* Unmute DAC0~3 & spdif out*/
15652	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15653	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15654	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15655	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15656	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15657
15658	/* Unmute Mixer 14 (mic) 1c (Line in)*/
15659	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15660        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15661	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15662        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15663
15664	/* Unmute Stereo Mixer 15 */
15665	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15666	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15667	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15668	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15669
15670	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15671	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15672	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15673	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15674	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15675	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15676	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15677	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15678	/* hp used DAC 3 (Front) */
15679	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15680        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15681
15682	{ }
15683};
15684
15685static const struct hda_verb alc861_threestack_init_verbs[] = {
15686	/*
15687	 * Unmute ADC0 and set the default input to mic-in
15688	 */
15689	/* port-A for surround (rear panel) */
15690	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15691	/* port-B for mic-in (rear panel) with vref */
15692	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15693	/* port-C for line-in (rear panel) */
15694	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15695	/* port-D for Front */
15696	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15697	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15698	/* port-E for HP out (front panel) */
15699	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15700	/* route front PCM to HP */
15701	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15702	/* port-F for mic-in (front panel) with vref */
15703	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15704	/* port-G for CLFE (rear panel) */
15705	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15706	/* port-H for side (rear panel) */
15707	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15708	/* CD-in */
15709	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15710	/* route front mic to ADC1*/
15711	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15712	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15713	/* Unmute DAC0~3 & spdif out*/
15714	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15715	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15716	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15717	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15718	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15719
15720	/* Unmute Mixer 14 (mic) 1c (Line in)*/
15721	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15722        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15723	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15724        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15725
15726	/* Unmute Stereo Mixer 15 */
15727	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15728	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15729	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15730	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15731
15732	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15733	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15734	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15735	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15736	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15737	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15738	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15739	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15740	/* hp used DAC 3 (Front) */
15741	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15742        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15743	{ }
15744};
15745
15746static const struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15747	/*
15748	 * Unmute ADC0 and set the default input to mic-in
15749	 */
15750	/* port-A for surround (rear panel) */
15751	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15752	/* port-B for mic-in (rear panel) with vref */
15753	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15754	/* port-C for line-in (rear panel) */
15755	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15756	/* port-D for Front */
15757	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15758	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15759	/* port-E for HP out (front panel) */
15760	/* this has to be set to VREF80 */
15761	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15762	/* route front PCM to HP */
15763	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15764	/* port-F for mic-in (front panel) with vref */
15765	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15766	/* port-G for CLFE (rear panel) */
15767	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15768	/* port-H for side (rear panel) */
15769	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15770	/* CD-in */
15771	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15772	/* route front mic to ADC1*/
15773	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15774	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15775	/* Unmute DAC0~3 & spdif out*/
15776	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15777	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15778	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15779	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15780	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15781
15782	/* Unmute Mixer 14 (mic) 1c (Line in)*/
15783	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15784        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15785	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15786        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15787
15788	/* Unmute Stereo Mixer 15 */
15789	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15790	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15791	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15792	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15793
15794	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15795	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15796	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15797	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15798	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15799	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15800	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15801	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15802	/* hp used DAC 3 (Front) */
15803	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15804        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15805	{ }
15806};
15807
15808static const struct hda_verb alc861_asus_init_verbs[] = {
15809	/*
15810	 * Unmute ADC0 and set the default input to mic-in
15811	 */
15812	/* port-A for surround (rear panel)
15813	 * according to codec#0 this is the HP jack
15814	 */
15815	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15816	/* route front PCM to HP */
15817	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15818	/* port-B for mic-in (rear panel) with vref */
15819	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15820	/* port-C for line-in (rear panel) */
15821	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15822	/* port-D for Front */
15823	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15824	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15825	/* port-E for HP out (front panel) */
15826	/* this has to be set to VREF80 */
15827	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15828	/* route front PCM to HP */
15829	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15830	/* port-F for mic-in (front panel) with vref */
15831	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15832	/* port-G for CLFE (rear panel) */
15833	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15834	/* port-H for side (rear panel) */
15835	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15836	/* CD-in */
15837	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15838	/* route front mic to ADC1*/
15839	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15840	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15841	/* Unmute DAC0~3 & spdif out*/
15842	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15843	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15844	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15845	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15846	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15847	/* Unmute Mixer 14 (mic) 1c (Line in)*/
15848	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15849        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15850	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15851        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15852
15853	/* Unmute Stereo Mixer 15 */
15854	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15855	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15856	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15857	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15858
15859	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15860	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15861	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15862	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15863	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15864	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15865	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15866	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15867	/* hp used DAC 3 (Front) */
15868	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15869	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15870	{ }
15871};
15872
15873/* additional init verbs for ASUS laptops */
15874static const struct hda_verb alc861_asus_laptop_init_verbs[] = {
15875	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15876	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15877	{ }
15878};
15879
15880/*
15881 * generic initialization of ADC, input mixers and output mixers
15882 */
15883static const struct hda_verb alc861_auto_init_verbs[] = {
15884	/*
15885	 * Unmute ADC0 and set the default input to mic-in
15886	 */
15887	/* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
15888	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15889
15890	/* Unmute DAC0~3 & spdif out*/
15891	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15892	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15893	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15894	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15895	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15896
15897	/* Unmute Mixer 14 (mic) 1c (Line in)*/
15898	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15899	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15900	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15901	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15902
15903	/* Unmute Stereo Mixer 15 */
15904	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15905	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15906	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15907	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15908
15909	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15910	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15911	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15912	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15913	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15914	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15915	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15916	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15917
15918	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15919	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15920	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15921	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15922	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15923	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15924	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15925	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15926
15927	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},	/* set Mic 1 */
15928
15929	{ }
15930};
15931
15932static const struct hda_verb alc861_toshiba_init_verbs[] = {
15933	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15934
15935	{ }
15936};
15937
15938/* toggle speaker-output according to the hp-jack state */
15939static void alc861_toshiba_automute(struct hda_codec *codec)
15940{
15941	unsigned int present = snd_hda_jack_detect(codec, 0x0f);
15942
15943	snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15944				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15945	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15946				 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
15947}
15948
15949static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15950				       unsigned int res)
15951{
15952	if ((res >> 26) == ALC880_HP_EVENT)
15953		alc861_toshiba_automute(codec);
15954}
15955
15956/* pcm configuration: identical with ALC880 */
15957#define alc861_pcm_analog_playback	alc880_pcm_analog_playback
15958#define alc861_pcm_analog_capture	alc880_pcm_analog_capture
15959#define alc861_pcm_digital_playback	alc880_pcm_digital_playback
15960#define alc861_pcm_digital_capture	alc880_pcm_digital_capture
15961
15962
15963#define ALC861_DIGOUT_NID	0x07
15964
15965static const struct hda_channel_mode alc861_8ch_modes[1] = {
15966	{ 8, NULL }
15967};
15968
15969static const hda_nid_t alc861_dac_nids[4] = {
15970	/* front, surround, clfe, side */
15971	0x03, 0x06, 0x05, 0x04
15972};
15973
15974static const hda_nid_t alc660_dac_nids[3] = {
15975	/* front, clfe, surround */
15976	0x03, 0x05, 0x06
15977};
15978
15979static const hda_nid_t alc861_adc_nids[1] = {
15980	/* ADC0-2 */
15981	0x08,
15982};
15983
15984static const struct hda_input_mux alc861_capture_source = {
15985	.num_items = 5,
15986	.items = {
15987		{ "Mic", 0x0 },
15988		{ "Front Mic", 0x3 },
15989		{ "Line", 0x1 },
15990		{ "CD", 0x4 },
15991		{ "Mixer", 0x5 },
15992	},
15993};
15994
15995static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15996{
15997	struct alc_spec *spec = codec->spec;
15998	hda_nid_t mix, srcs[5];
15999	int i, j, num;
16000
16001	if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
16002		return 0;
16003	num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
16004	if (num < 0)
16005		return 0;
16006	for (i = 0; i < num; i++) {
16007		unsigned int type;
16008		type = get_wcaps_type(get_wcaps(codec, srcs[i]));
16009		if (type != AC_WID_AUD_OUT)
16010			continue;
16011		for (j = 0; j < spec->multiout.num_dacs; j++)
16012			if (spec->multiout.dac_nids[j] == srcs[i])
16013				break;
16014		if (j >= spec->multiout.num_dacs)
16015			return srcs[i];
16016	}
16017	return 0;
16018}
16019
16020/* fill in the dac_nids table from the parsed pin configuration */
16021static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
16022				     const struct auto_pin_cfg *cfg)
16023{
16024	struct alc_spec *spec = codec->spec;
16025	int i;
16026	hda_nid_t nid, dac;
16027
16028	spec->multiout.dac_nids = spec->private_dac_nids;
16029	for (i = 0; i < cfg->line_outs; i++) {
16030		nid = cfg->line_out_pins[i];
16031		dac = alc861_look_for_dac(codec, nid);
16032		if (!dac)
16033			continue;
16034		spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
16035	}
16036	return 0;
16037}
16038
16039static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
16040				  hda_nid_t nid, int idx, unsigned int chs)
16041{
16042	return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
16043			   HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
16044}
16045
16046#define alc861_create_out_sw(codec, pfx, nid, chs) \
16047	__alc861_create_out_sw(codec, pfx, nid, 0, chs)
16048
16049/* add playback controls from the parsed DAC table */
16050static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
16051					     const struct auto_pin_cfg *cfg)
16052{
16053	struct alc_spec *spec = codec->spec;
16054	static const char * const chname[4] = {
16055		"Front", "Surround", NULL /*CLFE*/, "Side"
16056	};
16057	const char *pfx = alc_get_line_out_pfx(spec, true);
16058	hda_nid_t nid;
16059	int i, err, noutputs;
16060
16061	noutputs = cfg->line_outs;
16062	if (spec->multi_ios > 0)
16063		noutputs += spec->multi_ios;
16064
16065	for (i = 0; i < noutputs; i++) {
16066		nid = spec->multiout.dac_nids[i];
16067		if (!nid)
16068			continue;
16069		if (!pfx && i == 2) {
16070			/* Center/LFE */
16071			err = alc861_create_out_sw(codec, "Center", nid, 1);
16072			if (err < 0)
16073				return err;
16074			err = alc861_create_out_sw(codec, "LFE", nid, 2);
16075			if (err < 0)
16076				return err;
16077		} else {
16078			const char *name = pfx;
16079			int index = i;
16080			if (!name) {
16081				name = chname[i];
16082				index = 0;
16083			}
16084			err = __alc861_create_out_sw(codec, name, nid, index, 3);
16085			if (err < 0)
16086				return err;
16087		}
16088	}
16089	return 0;
16090}
16091
16092static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
16093{
16094	struct alc_spec *spec = codec->spec;
16095	int err;
16096	hda_nid_t nid;
16097
16098	if (!pin)
16099		return 0;
16100
16101	if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
16102		nid = alc861_look_for_dac(codec, pin);
16103		if (nid) {
16104			err = alc861_create_out_sw(codec, "Headphone", nid, 3);
16105			if (err < 0)
16106				return err;
16107			spec->multiout.hp_nid = nid;
16108		}
16109	}
16110	return 0;
16111}
16112
16113/* create playback/capture controls for input pins */
16114static int alc861_auto_create_input_ctls(struct hda_codec *codec,
16115						const struct auto_pin_cfg *cfg)
16116{
16117	return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
16118}
16119
16120static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
16121					      hda_nid_t nid,
16122					      int pin_type, hda_nid_t dac)
16123{
16124	hda_nid_t mix, srcs[5];
16125	int i, num;
16126
16127	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
16128			    pin_type);
16129	snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16130			    AMP_OUT_UNMUTE);
16131	if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
16132		return;
16133	num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
16134	if (num < 0)
16135		return;
16136	for (i = 0; i < num; i++) {
16137		unsigned int mute;
16138		if (srcs[i] == dac || srcs[i] == 0x15)
16139			mute = AMP_IN_UNMUTE(i);
16140		else
16141			mute = AMP_IN_MUTE(i);
16142		snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16143				    mute);
16144	}
16145}
16146
16147static void alc861_auto_init_multi_out(struct hda_codec *codec)
16148{
16149	struct alc_spec *spec = codec->spec;
16150	int i;
16151
16152	for (i = 0; i < spec->autocfg.line_outs; i++) {
16153		hda_nid_t nid = spec->autocfg.line_out_pins[i];
16154		int pin_type = get_pin_type(spec->autocfg.line_out_type);
16155		if (nid)
16156			alc861_auto_set_output_and_unmute(codec, nid, pin_type,
16157							  spec->multiout.dac_nids[i]);
16158	}
16159}
16160
16161static void alc861_auto_init_hp_out(struct hda_codec *codec)
16162{
16163	struct alc_spec *spec = codec->spec;
16164
16165	if (spec->autocfg.hp_outs)
16166		alc861_auto_set_output_and_unmute(codec,
16167						  spec->autocfg.hp_pins[0],
16168						  PIN_HP,
16169						  spec->multiout.hp_nid);
16170	if (spec->autocfg.speaker_outs)
16171		alc861_auto_set_output_and_unmute(codec,
16172						  spec->autocfg.speaker_pins[0],
16173						  PIN_OUT,
16174						  spec->multiout.dac_nids[0]);
16175}
16176
16177static void alc861_auto_init_analog_input(struct hda_codec *codec)
16178{
16179	struct alc_spec *spec = codec->spec;
16180	struct auto_pin_cfg *cfg = &spec->autocfg;
16181	int i;
16182
16183	for (i = 0; i < cfg->num_inputs; i++) {
16184		hda_nid_t nid = cfg->inputs[i].pin;
16185		if (nid >= 0x0c && nid <= 0x11)
16186			alc_set_input_pin(codec, nid, cfg->inputs[i].type);
16187	}
16188}
16189
16190/* parse the BIOS configuration and set up the alc_spec */
16191/* return 1 if successful, 0 if the proper config is not found,
16192 * or a negative error code
16193 */
16194static int alc861_parse_auto_config(struct hda_codec *codec)
16195{
16196	struct alc_spec *spec = codec->spec;
16197	int err;
16198	static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
16199
16200	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16201					   alc861_ignore);
16202	if (err < 0)
16203		return err;
16204	if (!spec->autocfg.line_outs)
16205		return 0; /* can't find valid BIOS pin config */
16206
16207	err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
16208	if (err < 0)
16209		return err;
16210	err = alc_auto_add_multi_channel_mode(codec);
16211	if (err < 0)
16212		return err;
16213	err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
16214	if (err < 0)
16215		return err;
16216	err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
16217	if (err < 0)
16218		return err;
16219	err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
16220	if (err < 0)
16221		return err;
16222
16223	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16224
16225	alc_auto_parse_digital(codec);
16226
16227	if (spec->kctls.list)
16228		add_mixer(spec, spec->kctls.list);
16229
16230	add_verb(spec, alc861_auto_init_verbs);
16231
16232	spec->num_mux_defs = 1;
16233	spec->input_mux = &spec->private_imux[0];
16234
16235	spec->adc_nids = alc861_adc_nids;
16236	spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
16237	set_capture_mixer(codec);
16238
16239	alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
16240
16241	return 1;
16242}
16243
16244/* additional initialization for auto-configuration model */
16245static void alc861_auto_init(struct hda_codec *codec)
16246{
16247	struct alc_spec *spec = codec->spec;
16248	alc861_auto_init_multi_out(codec);
16249	alc861_auto_init_hp_out(codec);
16250	alc861_auto_init_analog_input(codec);
16251	alc_auto_init_digital(codec);
16252	if (spec->unsol_event)
16253		alc_inithook(codec);
16254}
16255
16256#ifdef CONFIG_SND_HDA_POWER_SAVE
16257static const struct hda_amp_list alc861_loopbacks[] = {
16258	{ 0x15, HDA_INPUT, 0 },
16259	{ 0x15, HDA_INPUT, 1 },
16260	{ 0x15, HDA_INPUT, 2 },
16261	{ 0x15, HDA_INPUT, 3 },
16262	{ } /* end */
16263};
16264#endif
16265
16266
16267/*
16268 * configuration and preset
16269 */
16270static const char * const alc861_models[ALC861_MODEL_LAST] = {
16271	[ALC861_3ST]		= "3stack",
16272	[ALC660_3ST]		= "3stack-660",
16273	[ALC861_3ST_DIG]	= "3stack-dig",
16274	[ALC861_6ST_DIG]	= "6stack-dig",
16275	[ALC861_UNIWILL_M31]	= "uniwill-m31",
16276	[ALC861_TOSHIBA]	= "toshiba",
16277	[ALC861_ASUS]		= "asus",
16278	[ALC861_ASUS_LAPTOP]	= "asus-laptop",
16279	[ALC861_AUTO]		= "auto",
16280};
16281
16282static const struct snd_pci_quirk alc861_cfg_tbl[] = {
16283	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
16284	SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16285	SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16286	SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
16287	SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
16288	SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
16289	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
16290	/* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16291	 *        Any other models that need this preset?
16292	 */
16293	/* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
16294	SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16295	SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
16296	SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
16297	SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16298	SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16299	/* FIXME: the below seems conflict */
16300	/* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
16301	SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
16302	SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
16303	{}
16304};
16305
16306static const struct alc_config_preset alc861_presets[] = {
16307	[ALC861_3ST] = {
16308		.mixers = { alc861_3ST_mixer },
16309		.init_verbs = { alc861_threestack_init_verbs },
16310		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
16311		.dac_nids = alc861_dac_nids,
16312		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16313		.channel_mode = alc861_threestack_modes,
16314		.need_dac_fix = 1,
16315		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16316		.adc_nids = alc861_adc_nids,
16317		.input_mux = &alc861_capture_source,
16318	},
16319	[ALC861_3ST_DIG] = {
16320		.mixers = { alc861_base_mixer },
16321		.init_verbs = { alc861_threestack_init_verbs },
16322		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
16323		.dac_nids = alc861_dac_nids,
16324		.dig_out_nid = ALC861_DIGOUT_NID,
16325		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16326		.channel_mode = alc861_threestack_modes,
16327		.need_dac_fix = 1,
16328		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16329		.adc_nids = alc861_adc_nids,
16330		.input_mux = &alc861_capture_source,
16331	},
16332	[ALC861_6ST_DIG] = {
16333		.mixers = { alc861_base_mixer },
16334		.init_verbs = { alc861_base_init_verbs },
16335		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
16336		.dac_nids = alc861_dac_nids,
16337		.dig_out_nid = ALC861_DIGOUT_NID,
16338		.num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16339		.channel_mode = alc861_8ch_modes,
16340		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16341		.adc_nids = alc861_adc_nids,
16342		.input_mux = &alc861_capture_source,
16343	},
16344	[ALC660_3ST] = {
16345		.mixers = { alc861_3ST_mixer },
16346		.init_verbs = { alc861_threestack_init_verbs },
16347		.num_dacs = ARRAY_SIZE(alc660_dac_nids),
16348		.dac_nids = alc660_dac_nids,
16349		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16350		.channel_mode = alc861_threestack_modes,
16351		.need_dac_fix = 1,
16352		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16353		.adc_nids = alc861_adc_nids,
16354		.input_mux = &alc861_capture_source,
16355	},
16356	[ALC861_UNIWILL_M31] = {
16357		.mixers = { alc861_uniwill_m31_mixer },
16358		.init_verbs = { alc861_uniwill_m31_init_verbs },
16359		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
16360		.dac_nids = alc861_dac_nids,
16361		.dig_out_nid = ALC861_DIGOUT_NID,
16362		.num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16363		.channel_mode = alc861_uniwill_m31_modes,
16364		.need_dac_fix = 1,
16365		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16366		.adc_nids = alc861_adc_nids,
16367		.input_mux = &alc861_capture_source,
16368	},
16369	[ALC861_TOSHIBA] = {
16370		.mixers = { alc861_toshiba_mixer },
16371		.init_verbs = { alc861_base_init_verbs,
16372				alc861_toshiba_init_verbs },
16373		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
16374		.dac_nids = alc861_dac_nids,
16375		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16376		.channel_mode = alc883_3ST_2ch_modes,
16377		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16378		.adc_nids = alc861_adc_nids,
16379		.input_mux = &alc861_capture_source,
16380		.unsol_event = alc861_toshiba_unsol_event,
16381		.init_hook = alc861_toshiba_automute,
16382	},
16383	[ALC861_ASUS] = {
16384		.mixers = { alc861_asus_mixer },
16385		.init_verbs = { alc861_asus_init_verbs },
16386		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
16387		.dac_nids = alc861_dac_nids,
16388		.dig_out_nid = ALC861_DIGOUT_NID,
16389		.num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16390		.channel_mode = alc861_asus_modes,
16391		.need_dac_fix = 1,
16392		.hp_nid = 0x06,
16393		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16394		.adc_nids = alc861_adc_nids,
16395		.input_mux = &alc861_capture_source,
16396	},
16397	[ALC861_ASUS_LAPTOP] = {
16398		.mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16399		.init_verbs = { alc861_asus_init_verbs,
16400				alc861_asus_laptop_init_verbs },
16401		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
16402		.dac_nids = alc861_dac_nids,
16403		.dig_out_nid = ALC861_DIGOUT_NID,
16404		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16405		.channel_mode = alc883_3ST_2ch_modes,
16406		.need_dac_fix = 1,
16407		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16408		.adc_nids = alc861_adc_nids,
16409		.input_mux = &alc861_capture_source,
16410	},
16411};
16412
16413/* Pin config fixes */
16414enum {
16415	PINFIX_FSC_AMILO_PI1505,
16416};
16417
16418static const struct alc_fixup alc861_fixups[] = {
16419	[PINFIX_FSC_AMILO_PI1505] = {
16420		.type = ALC_FIXUP_PINS,
16421		.v.pins = (const struct alc_pincfg[]) {
16422			{ 0x0b, 0x0221101f }, /* HP */
16423			{ 0x0f, 0x90170310 }, /* speaker */
16424			{ }
16425		}
16426	},
16427};
16428
16429static const struct snd_pci_quirk alc861_fixup_tbl[] = {
16430	SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16431	{}
16432};
16433
16434static int patch_alc861(struct hda_codec *codec)
16435{
16436	struct alc_spec *spec;
16437	int board_config;
16438	int err;
16439
16440	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16441	if (spec == NULL)
16442		return -ENOMEM;
16443
16444	codec->spec = spec;
16445
16446        board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16447						  alc861_models,
16448						  alc861_cfg_tbl);
16449
16450	if (board_config < 0) {
16451		printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16452		       codec->chip_name);
16453		board_config = ALC861_AUTO;
16454	}
16455
16456	if (board_config == ALC861_AUTO) {
16457		alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16458		alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16459	}
16460
16461	if (board_config == ALC861_AUTO) {
16462		/* automatic parse from the BIOS config */
16463		err = alc861_parse_auto_config(codec);
16464		if (err < 0) {
16465			alc_free(codec);
16466			return err;
16467		} else if (!err) {
16468			printk(KERN_INFO
16469			       "hda_codec: Cannot set up configuration "
16470			       "from BIOS.  Using base mode...\n");
16471		   board_config = ALC861_3ST_DIG;
16472		}
16473	}
16474
16475	err = snd_hda_attach_beep_device(codec, 0x23);
16476	if (err < 0) {
16477		alc_free(codec);
16478		return err;
16479	}
16480
16481	if (board_config != ALC861_AUTO)
16482		setup_preset(codec, &alc861_presets[board_config]);
16483
16484	spec->stream_analog_playback = &alc861_pcm_analog_playback;
16485	spec->stream_analog_capture = &alc861_pcm_analog_capture;
16486
16487	spec->stream_digital_playback = &alc861_pcm_digital_playback;
16488	spec->stream_digital_capture = &alc861_pcm_digital_capture;
16489
16490	if (!spec->cap_mixer)
16491		set_capture_mixer(codec);
16492	set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16493
16494	spec->vmaster_nid = 0x03;
16495
16496	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
16497
16498	codec->patch_ops = alc_patch_ops;
16499	if (board_config == ALC861_AUTO) {
16500		spec->init_hook = alc861_auto_init;
16501#ifdef CONFIG_SND_HDA_POWER_SAVE
16502		spec->power_hook = alc_power_eapd;
16503#endif
16504	}
16505#ifdef CONFIG_SND_HDA_POWER_SAVE
16506	if (!spec->loopback.amplist)
16507		spec->loopback.amplist = alc861_loopbacks;
16508#endif
16509
16510	return 0;
16511}
16512
16513/*
16514 * ALC861-VD support
16515 *
16516 * Based on ALC882
16517 *
16518 * In addition, an independent DAC
16519 */
16520#define ALC861VD_DIGOUT_NID	0x06
16521
16522static const hda_nid_t alc861vd_dac_nids[4] = {
16523	/* front, surr, clfe, side surr */
16524	0x02, 0x03, 0x04, 0x05
16525};
16526
16527/* dac_nids for ALC660vd are in a different order - according to
16528 * Realtek's driver.
16529 * This should probably result in a different mixer for 6stack models
16530 * of ALC660vd codecs, but for now there is only 3stack mixer
16531 * - and it is the same as in 861vd.
16532 * adc_nids in ALC660vd are (is) the same as in 861vd
16533 */
16534static const hda_nid_t alc660vd_dac_nids[3] = {
16535	/* front, rear, clfe, rear_surr */
16536	0x02, 0x04, 0x03
16537};
16538
16539static const hda_nid_t alc861vd_adc_nids[1] = {
16540	/* ADC0 */
16541	0x09,
16542};
16543
16544static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
16545
16546/* input MUX */
16547/* FIXME: should be a matrix-type input source selection */
16548static const struct hda_input_mux alc861vd_capture_source = {
16549	.num_items = 4,
16550	.items = {
16551		{ "Mic", 0x0 },
16552		{ "Front Mic", 0x1 },
16553		{ "Line", 0x2 },
16554		{ "CD", 0x4 },
16555	},
16556};
16557
16558static const struct hda_input_mux alc861vd_dallas_capture_source = {
16559	.num_items = 2,
16560	.items = {
16561		{ "Mic", 0x0 },
16562		{ "Internal Mic", 0x1 },
16563	},
16564};
16565
16566static const struct hda_input_mux alc861vd_hp_capture_source = {
16567	.num_items = 2,
16568	.items = {
16569		{ "Front Mic", 0x0 },
16570		{ "ATAPI Mic", 0x1 },
16571	},
16572};
16573
16574/*
16575 * 2ch mode
16576 */
16577static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
16578	{ 2, NULL }
16579};
16580
16581/*
16582 * 6ch mode
16583 */
16584static const struct hda_verb alc861vd_6stack_ch6_init[] = {
16585	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16586	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16587	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16588	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16589	{ } /* end */
16590};
16591
16592/*
16593 * 8ch mode
16594 */
16595static const struct hda_verb alc861vd_6stack_ch8_init[] = {
16596	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16597	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16598	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16599	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16600	{ } /* end */
16601};
16602
16603static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
16604	{ 6, alc861vd_6stack_ch6_init },
16605	{ 8, alc861vd_6stack_ch8_init },
16606};
16607
16608static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16609	{
16610		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16611		.name = "Channel Mode",
16612		.info = alc_ch_mode_info,
16613		.get = alc_ch_mode_get,
16614		.put = alc_ch_mode_put,
16615	},
16616	{ } /* end */
16617};
16618
16619/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16620 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16621 */
16622static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16623	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16624	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16625
16626	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16627	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16628
16629	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16630				HDA_OUTPUT),
16631	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16632				HDA_OUTPUT),
16633	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16634	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16635
16636	HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16637	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16638
16639	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16640
16641	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16642	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16643	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16644
16645	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16646	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16647	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16648
16649	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16650	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16651
16652	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16653	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16654
16655	{ } /* end */
16656};
16657
16658static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16659	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16660	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16661
16662	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16663
16664	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16665	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16666	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16667
16668	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16669	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16670	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16671
16672	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16673	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16674
16675	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16676	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16677
16678	{ } /* end */
16679};
16680
16681static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16682	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16683	/*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16684	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16685
16686	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16687
16688	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16689	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16690	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16691
16692	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16693	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16694	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16695
16696	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16697	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16698
16699	{ } /* end */
16700};
16701
16702/* Pin assignment: Speaker=0x14, HP = 0x15,
16703 *                 Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
16704 */
16705static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
16706	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16707	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
16708	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16709	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16710	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16711	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16712	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16713	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
16714	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16715	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16716	{ } /* end */
16717};
16718
16719/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16720 *                 Front Mic=0x18, ATAPI Mic = 0x19,
16721 */
16722static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16723	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16724	HDA_BIND_MUTE("Front 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("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16728	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16729	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16730	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16731
16732	{ } /* end */
16733};
16734
16735/*
16736 * generic initialization of ADC, input mixers and output mixers
16737 */
16738static const struct hda_verb alc861vd_volume_init_verbs[] = {
16739	/*
16740	 * Unmute ADC0 and set the default input to mic-in
16741	 */
16742	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16743	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16744
16745	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16746	 * the analog-loopback mixer widget
16747	 */
16748	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16749	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16750	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16751	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16752	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16753	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16754
16755	/* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
16756	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16757	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16758	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
16759	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
16760
16761	/*
16762	 * Set up output mixers (0x02 - 0x05)
16763	 */
16764	/* set vol=0 to output mixers */
16765	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16766	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16767	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16768	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16769
16770	/* set up input amps for analog loopback */
16771	/* Amp Indices: DAC = 0, mixer = 1 */
16772	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16773	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16774	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16775	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16776	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16777	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16778	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16779	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16780
16781	{ }
16782};
16783
16784/*
16785 * 3-stack pin configuration:
16786 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16787 */
16788static const struct hda_verb alc861vd_3stack_init_verbs[] = {
16789	/*
16790	 * Set pin mode and muting
16791	 */
16792	/* set front pin widgets 0x14 for output */
16793	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16794	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16795	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16796
16797	/* Mic (rear) pin: input vref at 80% */
16798	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16799	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16800	/* Front Mic pin: input vref at 80% */
16801	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16802	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16803	/* Line In pin: input */
16804	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16805	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16806	/* Line-2 In: Headphone output (output 0 - 0x0c) */
16807	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16808	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16809	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16810	/* CD pin widget for input */
16811	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16812
16813	{ }
16814};
16815
16816/*
16817 * 6-stack pin configuration:
16818 */
16819static const struct hda_verb alc861vd_6stack_init_verbs[] = {
16820	/*
16821	 * Set pin mode and muting
16822	 */
16823	/* set front pin widgets 0x14 for output */
16824	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16825	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16826	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16827
16828	/* Rear Pin: output 1 (0x0d) */
16829	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16830	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16831	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16832	/* CLFE Pin: output 2 (0x0e) */
16833	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16834	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16835	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16836	/* Side Pin: output 3 (0x0f) */
16837	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16838	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16839	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16840
16841	/* Mic (rear) pin: input vref at 80% */
16842	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16843	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16844	/* Front Mic pin: input vref at 80% */
16845	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16846	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16847	/* Line In pin: input */
16848	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16849	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16850	/* Line-2 In: Headphone output (output 0 - 0x0c) */
16851	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16852	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16853	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16854	/* CD pin widget for input */
16855	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16856
16857	{ }
16858};
16859
16860static const struct hda_verb alc861vd_eapd_verbs[] = {
16861	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16862	{ }
16863};
16864
16865static const struct hda_verb alc660vd_eapd_verbs[] = {
16866	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16867	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16868	{ }
16869};
16870
16871static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16872	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16873	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16874	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16875	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16876	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16877	{}
16878};
16879
16880static void alc861vd_lenovo_setup(struct hda_codec *codec)
16881{
16882	struct alc_spec *spec = codec->spec;
16883	spec->autocfg.hp_pins[0] = 0x1b;
16884	spec->autocfg.speaker_pins[0] = 0x14;
16885	spec->automute = 1;
16886	spec->automute_mode = ALC_AUTOMUTE_AMP;
16887}
16888
16889static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16890{
16891	alc_hp_automute(codec);
16892	alc88x_simple_mic_automute(codec);
16893}
16894
16895static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16896					unsigned int res)
16897{
16898	switch (res >> 26) {
16899	case ALC880_MIC_EVENT:
16900		alc88x_simple_mic_automute(codec);
16901		break;
16902	default:
16903		alc_sku_unsol_event(codec, res);
16904		break;
16905	}
16906}
16907
16908static const struct hda_verb alc861vd_dallas_verbs[] = {
16909	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16910	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16911	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16912	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16913
16914	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16915	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16916	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16917	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16918	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16919	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16920	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16921	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16922
16923	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16924	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16925	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16926	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16927	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16928	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16929	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16930	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16931
16932	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16933	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16934	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16935	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16936	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16937	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16938	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16939	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16940
16941	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16942	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16943	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16944	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16945
16946	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16947	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16948	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16949
16950	{ } /* end */
16951};
16952
16953/* toggle speaker-output according to the hp-jack state */
16954static void alc861vd_dallas_setup(struct hda_codec *codec)
16955{
16956	struct alc_spec *spec = codec->spec;
16957
16958	spec->autocfg.hp_pins[0] = 0x15;
16959	spec->autocfg.speaker_pins[0] = 0x14;
16960	spec->automute = 1;
16961	spec->automute_mode = ALC_AUTOMUTE_AMP;
16962}
16963
16964#ifdef CONFIG_SND_HDA_POWER_SAVE
16965#define alc861vd_loopbacks	alc880_loopbacks
16966#endif
16967
16968/* pcm configuration: identical with ALC880 */
16969#define alc861vd_pcm_analog_playback	alc880_pcm_analog_playback
16970#define alc861vd_pcm_analog_capture	alc880_pcm_analog_capture
16971#define alc861vd_pcm_digital_playback	alc880_pcm_digital_playback
16972#define alc861vd_pcm_digital_capture	alc880_pcm_digital_capture
16973
16974/*
16975 * configuration and preset
16976 */
16977static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
16978	[ALC660VD_3ST]		= "3stack-660",
16979	[ALC660VD_3ST_DIG]	= "3stack-660-digout",
16980	[ALC660VD_ASUS_V1S]	= "asus-v1s",
16981	[ALC861VD_3ST]		= "3stack",
16982	[ALC861VD_3ST_DIG]	= "3stack-digout",
16983	[ALC861VD_6ST_DIG]	= "6stack-digout",
16984	[ALC861VD_LENOVO]	= "lenovo",
16985	[ALC861VD_DALLAS]	= "dallas",
16986	[ALC861VD_HP]		= "hp",
16987	[ALC861VD_AUTO]		= "auto",
16988};
16989
16990static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
16991	SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16992	SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
16993	SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
16994	/*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
16995	SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
16996	SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
16997	SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
16998	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
16999	/*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
17000	SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
17001	SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
17002	SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
17003	SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
17004	SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
17005	SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
17006	{}
17007};
17008
17009static const struct alc_config_preset alc861vd_presets[] = {
17010	[ALC660VD_3ST] = {
17011		.mixers = { alc861vd_3st_mixer },
17012		.init_verbs = { alc861vd_volume_init_verbs,
17013				 alc861vd_3stack_init_verbs },
17014		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17015		.dac_nids = alc660vd_dac_nids,
17016		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17017		.channel_mode = alc861vd_3stack_2ch_modes,
17018		.input_mux = &alc861vd_capture_source,
17019	},
17020	[ALC660VD_3ST_DIG] = {
17021		.mixers = { alc861vd_3st_mixer },
17022		.init_verbs = { alc861vd_volume_init_verbs,
17023				 alc861vd_3stack_init_verbs },
17024		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17025		.dac_nids = alc660vd_dac_nids,
17026		.dig_out_nid = ALC861VD_DIGOUT_NID,
17027		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17028		.channel_mode = alc861vd_3stack_2ch_modes,
17029		.input_mux = &alc861vd_capture_source,
17030	},
17031	[ALC861VD_3ST] = {
17032		.mixers = { alc861vd_3st_mixer },
17033		.init_verbs = { alc861vd_volume_init_verbs,
17034				 alc861vd_3stack_init_verbs },
17035		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17036		.dac_nids = alc861vd_dac_nids,
17037		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17038		.channel_mode = alc861vd_3stack_2ch_modes,
17039		.input_mux = &alc861vd_capture_source,
17040	},
17041	[ALC861VD_3ST_DIG] = {
17042		.mixers = { alc861vd_3st_mixer },
17043		.init_verbs = { alc861vd_volume_init_verbs,
17044		 		 alc861vd_3stack_init_verbs },
17045		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17046		.dac_nids = alc861vd_dac_nids,
17047		.dig_out_nid = ALC861VD_DIGOUT_NID,
17048		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17049		.channel_mode = alc861vd_3stack_2ch_modes,
17050		.input_mux = &alc861vd_capture_source,
17051	},
17052	[ALC861VD_6ST_DIG] = {
17053		.mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
17054		.init_verbs = { alc861vd_volume_init_verbs,
17055				alc861vd_6stack_init_verbs },
17056		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17057		.dac_nids = alc861vd_dac_nids,
17058		.dig_out_nid = ALC861VD_DIGOUT_NID,
17059		.num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
17060		.channel_mode = alc861vd_6stack_modes,
17061		.input_mux = &alc861vd_capture_source,
17062	},
17063	[ALC861VD_LENOVO] = {
17064		.mixers = { alc861vd_lenovo_mixer },
17065		.init_verbs = { alc861vd_volume_init_verbs,
17066				alc861vd_3stack_init_verbs,
17067				alc861vd_eapd_verbs,
17068				alc861vd_lenovo_unsol_verbs },
17069		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17070		.dac_nids = alc660vd_dac_nids,
17071		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17072		.channel_mode = alc861vd_3stack_2ch_modes,
17073		.input_mux = &alc861vd_capture_source,
17074		.unsol_event = alc861vd_lenovo_unsol_event,
17075		.setup = alc861vd_lenovo_setup,
17076		.init_hook = alc861vd_lenovo_init_hook,
17077	},
17078	[ALC861VD_DALLAS] = {
17079		.mixers = { alc861vd_dallas_mixer },
17080		.init_verbs = { alc861vd_dallas_verbs },
17081		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17082		.dac_nids = alc861vd_dac_nids,
17083		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17084		.channel_mode = alc861vd_3stack_2ch_modes,
17085		.input_mux = &alc861vd_dallas_capture_source,
17086		.unsol_event = alc_sku_unsol_event,
17087		.setup = alc861vd_dallas_setup,
17088		.init_hook = alc_hp_automute,
17089	},
17090	[ALC861VD_HP] = {
17091		.mixers = { alc861vd_hp_mixer },
17092		.init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
17093		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17094		.dac_nids = alc861vd_dac_nids,
17095		.dig_out_nid = ALC861VD_DIGOUT_NID,
17096		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17097		.channel_mode = alc861vd_3stack_2ch_modes,
17098		.input_mux = &alc861vd_hp_capture_source,
17099		.unsol_event = alc_sku_unsol_event,
17100		.setup = alc861vd_dallas_setup,
17101		.init_hook = alc_hp_automute,
17102	},
17103	[ALC660VD_ASUS_V1S] = {
17104		.mixers = { alc861vd_lenovo_mixer },
17105		.init_verbs = { alc861vd_volume_init_verbs,
17106				alc861vd_3stack_init_verbs,
17107				alc861vd_eapd_verbs,
17108				alc861vd_lenovo_unsol_verbs },
17109		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17110		.dac_nids = alc660vd_dac_nids,
17111		.dig_out_nid = ALC861VD_DIGOUT_NID,
17112		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17113		.channel_mode = alc861vd_3stack_2ch_modes,
17114		.input_mux = &alc861vd_capture_source,
17115		.unsol_event = alc861vd_lenovo_unsol_event,
17116		.setup = alc861vd_lenovo_setup,
17117		.init_hook = alc861vd_lenovo_init_hook,
17118	},
17119};
17120
17121/*
17122 * BIOS auto configuration
17123 */
17124static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
17125						const struct auto_pin_cfg *cfg)
17126{
17127	return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
17128}
17129
17130
17131static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
17132				hda_nid_t nid, int pin_type, int dac_idx)
17133{
17134	alc_set_pin_output(codec, nid, pin_type);
17135}
17136
17137static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
17138{
17139	struct alc_spec *spec = codec->spec;
17140	int i;
17141
17142	for (i = 0; i <= HDA_SIDE; i++) {
17143		hda_nid_t nid = spec->autocfg.line_out_pins[i];
17144		int pin_type = get_pin_type(spec->autocfg.line_out_type);
17145		if (nid)
17146			alc861vd_auto_set_output_and_unmute(codec, nid,
17147							    pin_type, i);
17148	}
17149}
17150
17151
17152static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
17153{
17154	struct alc_spec *spec = codec->spec;
17155	hda_nid_t pin;
17156
17157	pin = spec->autocfg.hp_pins[0];
17158	if (pin) /* connect to front and use dac 0 */
17159		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
17160	pin = spec->autocfg.speaker_pins[0];
17161	if (pin)
17162		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
17163}
17164
17165#define ALC861VD_PIN_CD_NID		ALC880_PIN_CD_NID
17166
17167static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
17168{
17169	struct alc_spec *spec = codec->spec;
17170	struct auto_pin_cfg *cfg = &spec->autocfg;
17171	int i;
17172
17173	for (i = 0; i < cfg->num_inputs; i++) {
17174		hda_nid_t nid = cfg->inputs[i].pin;
17175		if (alc_is_input_pin(codec, nid)) {
17176			alc_set_input_pin(codec, nid, cfg->inputs[i].type);
17177			if (nid != ALC861VD_PIN_CD_NID &&
17178			    (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
17179				snd_hda_codec_write(codec, nid, 0,
17180						AC_VERB_SET_AMP_GAIN_MUTE,
17181						AMP_OUT_MUTE);
17182		}
17183	}
17184}
17185
17186#define alc861vd_auto_init_input_src	alc882_auto_init_input_src
17187
17188#define alc861vd_idx_to_mixer_vol(nid)		((nid) + 0x02)
17189#define alc861vd_idx_to_mixer_switch(nid)	((nid) + 0x0c)
17190
17191/* add playback controls from the parsed DAC table */
17192/* Based on ALC880 version. But ALC861VD has separate,
17193 * different NIDs for mute/unmute switch and volume control */
17194static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17195					     const struct auto_pin_cfg *cfg)
17196{
17197	static const char * const chname[4] = {
17198		"Front", "Surround", "CLFE", "Side"
17199	};
17200	const char *pfx = alc_get_line_out_pfx(spec, true);
17201	hda_nid_t nid_v, nid_s;
17202	int i, err, noutputs;
17203
17204	noutputs = cfg->line_outs;
17205	if (spec->multi_ios > 0)
17206		noutputs += spec->multi_ios;
17207
17208	for (i = 0; i < noutputs; i++) {
17209		if (!spec->multiout.dac_nids[i])
17210			continue;
17211		nid_v = alc861vd_idx_to_mixer_vol(
17212				alc880_dac_to_idx(
17213					spec->multiout.dac_nids[i]));
17214		nid_s = alc861vd_idx_to_mixer_switch(
17215				alc880_dac_to_idx(
17216					spec->multiout.dac_nids[i]));
17217
17218		if (!pfx && i == 2) {
17219			/* Center/LFE */
17220			err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17221					      "Center",
17222					  HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
17223							      HDA_OUTPUT));
17224			if (err < 0)
17225				return err;
17226			err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17227					      "LFE",
17228					  HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
17229							      HDA_OUTPUT));
17230			if (err < 0)
17231				return err;
17232			err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17233					     "Center",
17234					  HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17235							      HDA_INPUT));
17236			if (err < 0)
17237				return err;
17238			err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17239					     "LFE",
17240					  HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17241							      HDA_INPUT));
17242			if (err < 0)
17243				return err;
17244		} else {
17245			const char *name = pfx;
17246			int index = i;
17247			if (!name) {
17248				name = chname[i];
17249				index = 0;
17250			}
17251			err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17252						name, index,
17253					  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17254							      HDA_OUTPUT));
17255			if (err < 0)
17256				return err;
17257			err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17258					       name, index,
17259					  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
17260							      HDA_INPUT));
17261			if (err < 0)
17262				return err;
17263		}
17264	}
17265	return 0;
17266}
17267
17268/* add playback controls for speaker and HP outputs */
17269/* Based on ALC880 version. But ALC861VD has separate,
17270 * different NIDs for mute/unmute switch and volume control */
17271static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17272					hda_nid_t pin, const char *pfx)
17273{
17274	hda_nid_t nid_v, nid_s;
17275	int err;
17276
17277	if (!pin)
17278		return 0;
17279
17280	if (alc880_is_fixed_pin(pin)) {
17281		nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17282		/* specify the DAC as the extra output */
17283		if (!spec->multiout.hp_nid)
17284			spec->multiout.hp_nid = nid_v;
17285		else
17286			spec->multiout.extra_out_nid[0] = nid_v;
17287		/* control HP volume/switch on the output mixer amp */
17288		nid_v = alc861vd_idx_to_mixer_vol(
17289				alc880_fixed_pin_idx(pin));
17290		nid_s = alc861vd_idx_to_mixer_switch(
17291				alc880_fixed_pin_idx(pin));
17292
17293		err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
17294				  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17295		if (err < 0)
17296			return err;
17297		err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
17298				  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17299		if (err < 0)
17300			return err;
17301	} else if (alc880_is_multi_pin(pin)) {
17302		/* set manual connection */
17303		/* we have only a switch on HP-out PIN */
17304		err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
17305				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17306		if (err < 0)
17307			return err;
17308	}
17309	return 0;
17310}
17311
17312/* parse the BIOS configuration and set up the alc_spec
17313 * return 1 if successful, 0 if the proper config is not found,
17314 * or a negative error code
17315 * Based on ALC880 version - had to change it to override
17316 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17317static int alc861vd_parse_auto_config(struct hda_codec *codec)
17318{
17319	struct alc_spec *spec = codec->spec;
17320	int err;
17321	static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
17322
17323	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17324					   alc861vd_ignore);
17325	if (err < 0)
17326		return err;
17327	if (!spec->autocfg.line_outs)
17328		return 0; /* can't find valid BIOS pin config */
17329
17330	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17331	if (err < 0)
17332		return err;
17333	err = alc_auto_add_multi_channel_mode(codec);
17334	if (err < 0)
17335		return err;
17336	err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17337	if (err < 0)
17338		return err;
17339	err = alc861vd_auto_create_extra_out(spec,
17340					     spec->autocfg.speaker_pins[0],
17341					     "Speaker");
17342	if (err < 0)
17343		return err;
17344	err = alc861vd_auto_create_extra_out(spec,
17345					     spec->autocfg.hp_pins[0],
17346					     "Headphone");
17347	if (err < 0)
17348		return err;
17349	err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
17350	if (err < 0)
17351		return err;
17352
17353	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17354
17355	alc_auto_parse_digital(codec);
17356
17357	if (spec->kctls.list)
17358		add_mixer(spec, spec->kctls.list);
17359
17360	add_verb(spec, alc861vd_volume_init_verbs);
17361
17362	spec->num_mux_defs = 1;
17363	spec->input_mux = &spec->private_imux[0];
17364
17365	err = alc_auto_add_mic_boost(codec);
17366	if (err < 0)
17367		return err;
17368
17369	alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
17370
17371	return 1;
17372}
17373
17374/* additional initialization for auto-configuration model */
17375static void alc861vd_auto_init(struct hda_codec *codec)
17376{
17377	struct alc_spec *spec = codec->spec;
17378	alc861vd_auto_init_multi_out(codec);
17379	alc861vd_auto_init_hp_out(codec);
17380	alc861vd_auto_init_analog_input(codec);
17381	alc861vd_auto_init_input_src(codec);
17382	alc_auto_init_digital(codec);
17383	if (spec->unsol_event)
17384		alc_inithook(codec);
17385}
17386
17387enum {
17388	ALC660VD_FIX_ASUS_GPIO1
17389};
17390
17391/* reset GPIO1 */
17392static const struct alc_fixup alc861vd_fixups[] = {
17393	[ALC660VD_FIX_ASUS_GPIO1] = {
17394		.type = ALC_FIXUP_VERBS,
17395		.v.verbs = (const struct hda_verb[]) {
17396			{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17397			{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17398			{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17399			{ }
17400		}
17401	},
17402};
17403
17404static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
17405	SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17406	{}
17407};
17408
17409static int patch_alc861vd(struct hda_codec *codec)
17410{
17411	struct alc_spec *spec;
17412	int err, board_config;
17413
17414	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17415	if (spec == NULL)
17416		return -ENOMEM;
17417
17418	codec->spec = spec;
17419
17420	board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17421						  alc861vd_models,
17422						  alc861vd_cfg_tbl);
17423
17424	if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
17425		printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17426		       codec->chip_name);
17427		board_config = ALC861VD_AUTO;
17428	}
17429
17430	if (board_config == ALC861VD_AUTO) {
17431		alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17432		alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17433	}
17434
17435	if (board_config == ALC861VD_AUTO) {
17436		/* automatic parse from the BIOS config */
17437		err = alc861vd_parse_auto_config(codec);
17438		if (err < 0) {
17439			alc_free(codec);
17440			return err;
17441		} else if (!err) {
17442			printk(KERN_INFO
17443			       "hda_codec: Cannot set up configuration "
17444			       "from BIOS.  Using base mode...\n");
17445			board_config = ALC861VD_3ST;
17446		}
17447	}
17448
17449	err = snd_hda_attach_beep_device(codec, 0x23);
17450	if (err < 0) {
17451		alc_free(codec);
17452		return err;
17453	}
17454
17455	if (board_config != ALC861VD_AUTO)
17456		setup_preset(codec, &alc861vd_presets[board_config]);
17457
17458	if (codec->vendor_id == 0x10ec0660) {
17459		/* always turn on EAPD */
17460		add_verb(spec, alc660vd_eapd_verbs);
17461	}
17462
17463	spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17464	spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17465
17466	spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17467	spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17468
17469	if (!spec->adc_nids) {
17470		spec->adc_nids = alc861vd_adc_nids;
17471		spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17472	}
17473	if (!spec->capsrc_nids)
17474		spec->capsrc_nids = alc861vd_capsrc_nids;
17475
17476	set_capture_mixer(codec);
17477	set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17478
17479	spec->vmaster_nid = 0x02;
17480
17481	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
17482
17483	codec->patch_ops = alc_patch_ops;
17484
17485	if (board_config == ALC861VD_AUTO)
17486		spec->init_hook = alc861vd_auto_init;
17487	spec->shutup = alc_eapd_shutup;
17488#ifdef CONFIG_SND_HDA_POWER_SAVE
17489	if (!spec->loopback.amplist)
17490		spec->loopback.amplist = alc861vd_loopbacks;
17491#endif
17492
17493	return 0;
17494}
17495
17496/*
17497 * ALC662 support
17498 *
17499 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17500 * configuration.  Each pin widget can choose any input DACs and a mixer.
17501 * Each ADC is connected from a mixer of all inputs.  This makes possible
17502 * 6-channel independent captures.
17503 *
17504 * In addition, an independent DAC for the multi-playback (not used in this
17505 * driver yet).
17506 */
17507#define ALC662_DIGOUT_NID	0x06
17508#define ALC662_DIGIN_NID	0x0a
17509
17510static const hda_nid_t alc662_dac_nids[3] = {
17511	/* front, rear, clfe */
17512	0x02, 0x03, 0x04
17513};
17514
17515static const hda_nid_t alc272_dac_nids[2] = {
17516	0x02, 0x03
17517};
17518
17519static const hda_nid_t alc662_adc_nids[2] = {
17520	/* ADC1-2 */
17521	0x09, 0x08
17522};
17523
17524static const hda_nid_t alc272_adc_nids[1] = {
17525	/* ADC1-2 */
17526	0x08,
17527};
17528
17529static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
17530static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
17531
17532
17533/* input MUX */
17534/* FIXME: should be a matrix-type input source selection */
17535static const struct hda_input_mux alc662_capture_source = {
17536	.num_items = 4,
17537	.items = {
17538		{ "Mic", 0x0 },
17539		{ "Front Mic", 0x1 },
17540		{ "Line", 0x2 },
17541		{ "CD", 0x4 },
17542	},
17543};
17544
17545static const struct hda_input_mux alc662_lenovo_101e_capture_source = {
17546	.num_items = 2,
17547	.items = {
17548		{ "Mic", 0x1 },
17549		{ "Line", 0x2 },
17550	},
17551};
17552
17553static const struct hda_input_mux alc663_capture_source = {
17554	.num_items = 3,
17555	.items = {
17556		{ "Mic", 0x0 },
17557		{ "Front Mic", 0x1 },
17558		{ "Line", 0x2 },
17559	},
17560};
17561
17562#if 0 /* set to 1 for testing other input sources below */
17563static const struct hda_input_mux alc272_nc10_capture_source = {
17564	.num_items = 16,
17565	.items = {
17566		{ "Autoselect Mic", 0x0 },
17567		{ "Internal Mic", 0x1 },
17568		{ "In-0x02", 0x2 },
17569		{ "In-0x03", 0x3 },
17570		{ "In-0x04", 0x4 },
17571		{ "In-0x05", 0x5 },
17572		{ "In-0x06", 0x6 },
17573		{ "In-0x07", 0x7 },
17574		{ "In-0x08", 0x8 },
17575		{ "In-0x09", 0x9 },
17576		{ "In-0x0a", 0x0a },
17577		{ "In-0x0b", 0x0b },
17578		{ "In-0x0c", 0x0c },
17579		{ "In-0x0d", 0x0d },
17580		{ "In-0x0e", 0x0e },
17581		{ "In-0x0f", 0x0f },
17582	},
17583};
17584#endif
17585
17586/*
17587 * 2ch mode
17588 */
17589static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
17590	{ 2, NULL }
17591};
17592
17593/*
17594 * 2ch mode
17595 */
17596static const struct hda_verb alc662_3ST_ch2_init[] = {
17597	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17598	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17599	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17600	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17601	{ } /* end */
17602};
17603
17604/*
17605 * 6ch mode
17606 */
17607static const struct hda_verb alc662_3ST_ch6_init[] = {
17608	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17609	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17610	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17611	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17612	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17613	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17614	{ } /* end */
17615};
17616
17617static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17618	{ 2, alc662_3ST_ch2_init },
17619	{ 6, alc662_3ST_ch6_init },
17620};
17621
17622/*
17623 * 2ch mode
17624 */
17625static const struct hda_verb alc662_sixstack_ch6_init[] = {
17626	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17627	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17628	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17629	{ } /* end */
17630};
17631
17632/*
17633 * 6ch mode
17634 */
17635static const struct hda_verb alc662_sixstack_ch8_init[] = {
17636	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17637	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17638	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17639	{ } /* end */
17640};
17641
17642static const struct hda_channel_mode alc662_5stack_modes[2] = {
17643	{ 2, alc662_sixstack_ch6_init },
17644	{ 6, alc662_sixstack_ch8_init },
17645};
17646
17647/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17648 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17649 */
17650
17651static const struct snd_kcontrol_new alc662_base_mixer[] = {
17652	/* output mixer control */
17653	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
17654	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17655	HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
17656	HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
17657	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17658	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17659	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17660	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
17661	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17662
17663	/*Input mixer control */
17664	HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17665	HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17666	HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17667	HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17668	HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17669	HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17670	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17671	HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
17672	{ } /* end */
17673};
17674
17675static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17676	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17677	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17678	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17679	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17680	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17681	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17682	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17683	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17684	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17685	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17686	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17687	{ } /* end */
17688};
17689
17690static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17691	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17692	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17693	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17694	HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
17695	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17696	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17697	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17698	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
17699	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17700	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17701	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17702	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17703	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17704	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17705	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17706	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17707	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17708	{ } /* end */
17709};
17710
17711static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17712	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17713	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
17714	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17715	HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
17716	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17717	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17718	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17719	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17720	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17721	{ } /* end */
17722};
17723
17724static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
17725	HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17726	ALC262_HIPPO_MASTER_SWITCH,
17727
17728	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
17729	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17730	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17731
17732	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
17733	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17734	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17735	{ } /* end */
17736};
17737
17738static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
17739	ALC262_HIPPO_MASTER_SWITCH,
17740	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17741	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17742	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17743	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17744	HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17745	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17746	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17747	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17748	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17749	{ } /* end */
17750};
17751
17752static const struct hda_bind_ctls alc663_asus_bind_master_vol = {
17753	.ops = &snd_hda_bind_vol,
17754	.values = {
17755		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17756		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17757		0
17758	},
17759};
17760
17761static const struct hda_bind_ctls alc663_asus_one_bind_switch = {
17762	.ops = &snd_hda_bind_sw,
17763	.values = {
17764		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17765		HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17766		0
17767	},
17768};
17769
17770static const struct snd_kcontrol_new alc663_m51va_mixer[] = {
17771	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17772	HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17773	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17774	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17775	{ } /* end */
17776};
17777
17778static const struct hda_bind_ctls alc663_asus_tree_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(0x15, 3, 0, HDA_OUTPUT),
17783		HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17784		0
17785	},
17786};
17787
17788static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17789	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17790	HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17791	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17792	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17793	HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17794	HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17795
17796	{ } /* end */
17797};
17798
17799static const struct hda_bind_ctls alc663_asus_four_bind_switch = {
17800	.ops = &snd_hda_bind_sw,
17801	.values = {
17802		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17803		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17804		HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17805		0
17806	},
17807};
17808
17809static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17810	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17811	HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17812	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17813	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17814	HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17815	HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17816	{ } /* end */
17817};
17818
17819static const struct snd_kcontrol_new alc662_1bjd_mixer[] = {
17820	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17821	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17822	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17823	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17824	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17825	HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17826	HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17827	{ } /* end */
17828};
17829
17830static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17831	.ops = &snd_hda_bind_vol,
17832	.values = {
17833		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17834		HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17835		0
17836	},
17837};
17838
17839static const struct hda_bind_ctls alc663_asus_two_bind_switch = {
17840	.ops = &snd_hda_bind_sw,
17841	.values = {
17842		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17843		HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17844		0
17845	},
17846};
17847
17848static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17849	HDA_BIND_VOL("Master Playback Volume",
17850				&alc663_asus_two_bind_master_vol),
17851	HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17852	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17853	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17854	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17855	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17856	{ } /* end */
17857};
17858
17859static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17860	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17861	HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17862	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17863	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17864	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17865	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17866	{ } /* end */
17867};
17868
17869static const struct snd_kcontrol_new alc663_g71v_mixer[] = {
17870	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17871	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17872	HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17873	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17874	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17875
17876	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17877	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17878	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17879	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17880	{ } /* end */
17881};
17882
17883static const struct snd_kcontrol_new alc663_g50v_mixer[] = {
17884	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17885	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17886	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17887
17888	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17889	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17890	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17891	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17892	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17893	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17894	{ } /* end */
17895};
17896
17897static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17898	.ops = &snd_hda_bind_sw,
17899	.values = {
17900		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17901		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17902		HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17903		HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17904		HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17905		0
17906	},
17907};
17908
17909static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17910	.ops = &snd_hda_bind_sw,
17911	.values = {
17912		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17913		HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17914		0
17915	},
17916};
17917
17918static const struct snd_kcontrol_new alc663_mode7_mixer[] = {
17919	HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17920	HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17921	HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17922	HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17923	HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17924	HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17925	HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17926	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17927	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17928	{ } /* end */
17929};
17930
17931static const struct snd_kcontrol_new alc663_mode8_mixer[] = {
17932	HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17933	HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17934	HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17935	HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17936	HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17937	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17938	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17939	{ } /* end */
17940};
17941
17942
17943static const struct snd_kcontrol_new alc662_chmode_mixer[] = {
17944	{
17945		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17946		.name = "Channel Mode",
17947		.info = alc_ch_mode_info,
17948		.get = alc_ch_mode_get,
17949		.put = alc_ch_mode_put,
17950	},
17951	{ } /* end */
17952};
17953
17954static const struct hda_verb alc662_init_verbs[] = {
17955	/* ADC: mute amp left and right */
17956	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17957	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
17958
17959	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17960	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17961	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17962	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17963	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17964	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17965
17966	/* Front Pin: output 0 (0x0c) */
17967	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17968	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17969
17970	/* Rear Pin: output 1 (0x0d) */
17971	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17972	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17973
17974	/* CLFE Pin: output 2 (0x0e) */
17975	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17976	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17977
17978	/* Mic (rear) pin: input vref at 80% */
17979	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17980	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17981	/* Front Mic pin: input vref at 80% */
17982	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17983	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17984	/* Line In pin: input */
17985	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17986	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17987	/* Line-2 In: Headphone output (output 0 - 0x0c) */
17988	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17989	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17990	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17991	/* CD pin widget for input */
17992	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17993
17994	/* FIXME: use matrix-type input source selection */
17995	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17996	/* Input mixer */
17997	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17998	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17999
18000	{ }
18001};
18002
18003static const struct hda_verb alc662_eapd_init_verbs[] = {
18004	/* always trun on EAPD */
18005	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
18006	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
18007	{ }
18008};
18009
18010static const struct hda_verb alc662_sue_init_verbs[] = {
18011	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
18012	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
18013	{}
18014};
18015
18016static const struct hda_verb alc662_eeepc_sue_init_verbs[] = {
18017	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18018	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18019	{}
18020};
18021
18022/* Set Unsolicited Event*/
18023static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
18024	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18025	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18026	{}
18027};
18028
18029static const struct hda_verb alc663_m51va_init_verbs[] = {
18030	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18031	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18032	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18033	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18034	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
18035	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18036	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18037	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18038	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18039	{}
18040};
18041
18042static const struct hda_verb alc663_21jd_amic_init_verbs[] = {
18043	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18044	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18045	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
18046	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18047	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18048	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18049	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18050	{}
18051};
18052
18053static const struct hda_verb alc662_1bjd_amic_init_verbs[] = {
18054	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18055	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18056	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18057	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
18058	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18059	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18060	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18061	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18062	{}
18063};
18064
18065static const struct hda_verb alc663_15jd_amic_init_verbs[] = {
18066	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18067	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18068	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
18069	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18070	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18071	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18072	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18073	{}
18074};
18075
18076static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
18077	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18078	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18079	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18080	{0x21, AC_VERB_SET_CONNECT_SEL, 0x0},	/* Headphone */
18081	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18082	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18083	{0x15, AC_VERB_SET_CONNECT_SEL, 0x0},	/* Headphone */
18084	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18085	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18086	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18087	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18088	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18089	{}
18090};
18091
18092static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
18093	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18094	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18095	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18096	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
18097	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18098	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18099	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
18100	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18101	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18102	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18103	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18104	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18105	{}
18106};
18107
18108static const struct hda_verb alc663_g71v_init_verbs[] = {
18109	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18110	/* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
18111	/* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
18112
18113	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18114	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18115	{0x21, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
18116
18117	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
18118	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
18119	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
18120	{}
18121};
18122
18123static const struct hda_verb alc663_g50v_init_verbs[] = {
18124	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18125	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18126	{0x21, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
18127
18128	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18129	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18130	{}
18131};
18132
18133static const struct hda_verb alc662_ecs_init_verbs[] = {
18134	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
18135	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18136	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18137	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18138	{}
18139};
18140
18141static const struct hda_verb alc272_dell_zm1_init_verbs[] = {
18142	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18143	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18144	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18145	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18146	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18147	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18148	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
18149	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18150	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18151	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18152	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18153	{}
18154};
18155
18156static const struct hda_verb alc272_dell_init_verbs[] = {
18157	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18158	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18159	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18160	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18161	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18162	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18163	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
18164	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18165	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18166	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18167	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18168	{}
18169};
18170
18171static const struct hda_verb alc663_mode7_init_verbs[] = {
18172	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18173	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18174	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18175	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18176	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18177	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18178	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
18179	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18180	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18181	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
18182	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18183	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18184	{0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18185	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18186	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18187	{}
18188};
18189
18190static const struct hda_verb alc663_mode8_init_verbs[] = {
18191	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18192	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18193	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18194	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
18195	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18196	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18197	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18198	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18199	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18200	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18201	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
18202	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18203	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18204	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18205	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18206	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18207	{}
18208};
18209
18210static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
18211	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
18212	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
18213	{ } /* end */
18214};
18215
18216static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
18217	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
18218	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
18219	{ } /* end */
18220};
18221
18222static void alc662_lenovo_101e_setup(struct hda_codec *codec)
18223{
18224	struct alc_spec *spec = codec->spec;
18225
18226	spec->autocfg.hp_pins[0] = 0x1b;
18227	spec->autocfg.line_out_pins[0] = 0x14;
18228	spec->autocfg.speaker_pins[0] = 0x15;
18229	spec->automute = 1;
18230	spec->detect_line = 1;
18231	spec->automute_lines = 1;
18232	spec->automute_mode = ALC_AUTOMUTE_AMP;
18233}
18234
18235static void alc662_eeepc_setup(struct hda_codec *codec)
18236{
18237	struct alc_spec *spec = codec->spec;
18238
18239	alc262_hippo1_setup(codec);
18240	spec->ext_mic.pin = 0x18;
18241	spec->ext_mic.mux_idx = 0;
18242	spec->int_mic.pin = 0x19;
18243	spec->int_mic.mux_idx = 1;
18244	spec->auto_mic = 1;
18245}
18246
18247static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
18248{
18249	struct alc_spec *spec = codec->spec;
18250
18251	spec->autocfg.hp_pins[0] = 0x14;
18252	spec->autocfg.speaker_pins[0] = 0x1b;
18253	spec->automute = 1;
18254	spec->automute_mode = ALC_AUTOMUTE_AMP;
18255}
18256
18257static void alc663_m51va_setup(struct hda_codec *codec)
18258{
18259	struct alc_spec *spec = codec->spec;
18260	spec->autocfg.hp_pins[0] = 0x21;
18261	spec->autocfg.speaker_pins[0] = 0x14;
18262	spec->automute_mixer_nid[0] = 0x0c;
18263	spec->automute = 1;
18264	spec->automute_mode = ALC_AUTOMUTE_MIXER;
18265	spec->ext_mic.pin = 0x18;
18266	spec->ext_mic.mux_idx = 0;
18267	spec->int_mic.pin = 0x12;
18268	spec->int_mic.mux_idx = 9;
18269	spec->auto_mic = 1;
18270}
18271
18272/* ***************** Mode1 ******************************/
18273static void alc663_mode1_setup(struct hda_codec *codec)
18274{
18275	struct alc_spec *spec = codec->spec;
18276	spec->autocfg.hp_pins[0] = 0x21;
18277	spec->autocfg.speaker_pins[0] = 0x14;
18278	spec->automute_mixer_nid[0] = 0x0c;
18279	spec->automute = 1;
18280	spec->automute_mode = ALC_AUTOMUTE_MIXER;
18281	spec->ext_mic.pin = 0x18;
18282	spec->ext_mic.mux_idx = 0;
18283	spec->int_mic.pin = 0x19;
18284	spec->int_mic.mux_idx = 1;
18285	spec->auto_mic = 1;
18286}
18287
18288/* ***************** Mode2 ******************************/
18289static void alc662_mode2_setup(struct hda_codec *codec)
18290{
18291	struct alc_spec *spec = codec->spec;
18292	spec->autocfg.hp_pins[0] = 0x1b;
18293	spec->autocfg.speaker_pins[0] = 0x14;
18294	spec->automute = 1;
18295	spec->automute_mode = ALC_AUTOMUTE_PIN;
18296	spec->ext_mic.pin = 0x18;
18297	spec->ext_mic.mux_idx = 0;
18298	spec->int_mic.pin = 0x19;
18299	spec->int_mic.mux_idx = 1;
18300	spec->auto_mic = 1;
18301}
18302
18303/* ***************** Mode3 ******************************/
18304static void alc663_mode3_setup(struct hda_codec *codec)
18305{
18306	struct alc_spec *spec = codec->spec;
18307	spec->autocfg.hp_pins[0] = 0x21;
18308	spec->autocfg.hp_pins[0] = 0x15;
18309	spec->autocfg.speaker_pins[0] = 0x14;
18310	spec->automute = 1;
18311	spec->automute_mode = ALC_AUTOMUTE_PIN;
18312	spec->ext_mic.pin = 0x18;
18313	spec->ext_mic.mux_idx = 0;
18314	spec->int_mic.pin = 0x19;
18315	spec->int_mic.mux_idx = 1;
18316	spec->auto_mic = 1;
18317}
18318
18319/* ***************** Mode4 ******************************/
18320static void alc663_mode4_setup(struct hda_codec *codec)
18321{
18322	struct alc_spec *spec = codec->spec;
18323	spec->autocfg.hp_pins[0] = 0x21;
18324	spec->autocfg.speaker_pins[0] = 0x14;
18325	spec->autocfg.speaker_pins[1] = 0x16;
18326	spec->automute_mixer_nid[0] = 0x0c;
18327	spec->automute_mixer_nid[1] = 0x0e;
18328	spec->automute = 1;
18329	spec->automute_mode = ALC_AUTOMUTE_MIXER;
18330	spec->ext_mic.pin = 0x18;
18331	spec->ext_mic.mux_idx = 0;
18332	spec->int_mic.pin = 0x19;
18333	spec->int_mic.mux_idx = 1;
18334	spec->auto_mic = 1;
18335}
18336
18337/* ***************** Mode5 ******************************/
18338static void alc663_mode5_setup(struct hda_codec *codec)
18339{
18340	struct alc_spec *spec = codec->spec;
18341	spec->autocfg.hp_pins[0] = 0x15;
18342	spec->autocfg.speaker_pins[0] = 0x14;
18343	spec->autocfg.speaker_pins[1] = 0x16;
18344	spec->automute_mixer_nid[0] = 0x0c;
18345	spec->automute_mixer_nid[1] = 0x0e;
18346	spec->automute = 1;
18347	spec->automute_mode = ALC_AUTOMUTE_MIXER;
18348	spec->ext_mic.pin = 0x18;
18349	spec->ext_mic.mux_idx = 0;
18350	spec->int_mic.pin = 0x19;
18351	spec->int_mic.mux_idx = 1;
18352	spec->auto_mic = 1;
18353}
18354
18355/* ***************** Mode6 ******************************/
18356static void alc663_mode6_setup(struct hda_codec *codec)
18357{
18358	struct alc_spec *spec = codec->spec;
18359	spec->autocfg.hp_pins[0] = 0x1b;
18360	spec->autocfg.hp_pins[0] = 0x15;
18361	spec->autocfg.speaker_pins[0] = 0x14;
18362	spec->automute_mixer_nid[0] = 0x0c;
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/* ***************** Mode7 ******************************/
18373static void alc663_mode7_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] = 0x21;
18378	spec->autocfg.speaker_pins[0] = 0x14;
18379	spec->autocfg.speaker_pins[0] = 0x17;
18380	spec->automute = 1;
18381	spec->automute_mode = ALC_AUTOMUTE_PIN;
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/* ***************** Mode8 ******************************/
18390static void alc663_mode8_setup(struct hda_codec *codec)
18391{
18392	struct alc_spec *spec = codec->spec;
18393	spec->autocfg.hp_pins[0] = 0x21;
18394	spec->autocfg.hp_pins[1] = 0x15;
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 = 0x12;
18402	spec->int_mic.mux_idx = 9;
18403	spec->auto_mic = 1;
18404}
18405
18406static void alc663_g71v_setup(struct hda_codec *codec)
18407{
18408	struct alc_spec *spec = codec->spec;
18409	spec->autocfg.hp_pins[0] = 0x21;
18410	spec->autocfg.line_out_pins[0] = 0x15;
18411	spec->autocfg.speaker_pins[0] = 0x14;
18412	spec->automute = 1;
18413	spec->automute_mode = ALC_AUTOMUTE_AMP;
18414	spec->detect_line = 1;
18415	spec->automute_lines = 1;
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
18423#define alc663_g50v_setup	alc663_m51va_setup
18424
18425static const struct snd_kcontrol_new alc662_ecs_mixer[] = {
18426	HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18427	ALC262_HIPPO_MASTER_SWITCH,
18428
18429	HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
18430	HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18431	HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
18432
18433	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18434	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18435	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18436	{ } /* end */
18437};
18438
18439static const struct snd_kcontrol_new alc272_nc10_mixer[] = {
18440	/* Master Playback automatically created from Speaker and Headphone */
18441	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18442	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18443	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18444	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18445
18446	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18447	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
18448	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
18449
18450	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18451	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18452	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18453	{ } /* end */
18454};
18455
18456#ifdef CONFIG_SND_HDA_POWER_SAVE
18457#define alc662_loopbacks	alc880_loopbacks
18458#endif
18459
18460
18461/* pcm configuration: identical with ALC880 */
18462#define alc662_pcm_analog_playback	alc880_pcm_analog_playback
18463#define alc662_pcm_analog_capture	alc880_pcm_analog_capture
18464#define alc662_pcm_digital_playback	alc880_pcm_digital_playback
18465#define alc662_pcm_digital_capture	alc880_pcm_digital_capture
18466
18467/*
18468 * configuration and preset
18469 */
18470static const char * const alc662_models[ALC662_MODEL_LAST] = {
18471	[ALC662_3ST_2ch_DIG]	= "3stack-dig",
18472	[ALC662_3ST_6ch_DIG]	= "3stack-6ch-dig",
18473	[ALC662_3ST_6ch]	= "3stack-6ch",
18474	[ALC662_5ST_DIG]	= "5stack-dig",
18475	[ALC662_LENOVO_101E]	= "lenovo-101e",
18476	[ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
18477	[ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
18478	[ALC662_ECS] = "ecs",
18479	[ALC663_ASUS_M51VA] = "m51va",
18480	[ALC663_ASUS_G71V] = "g71v",
18481	[ALC663_ASUS_H13] = "h13",
18482	[ALC663_ASUS_G50V] = "g50v",
18483	[ALC663_ASUS_MODE1] = "asus-mode1",
18484	[ALC662_ASUS_MODE2] = "asus-mode2",
18485	[ALC663_ASUS_MODE3] = "asus-mode3",
18486	[ALC663_ASUS_MODE4] = "asus-mode4",
18487	[ALC663_ASUS_MODE5] = "asus-mode5",
18488	[ALC663_ASUS_MODE6] = "asus-mode6",
18489	[ALC663_ASUS_MODE7] = "asus-mode7",
18490	[ALC663_ASUS_MODE8] = "asus-mode8",
18491	[ALC272_DELL]		= "dell",
18492	[ALC272_DELL_ZM1]	= "dell-zm1",
18493	[ALC272_SAMSUNG_NC10]	= "samsung-nc10",
18494	[ALC662_AUTO]		= "auto",
18495};
18496
18497static const struct snd_pci_quirk alc662_cfg_tbl[] = {
18498	SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
18499	SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18500	SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
18501	SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
18502	SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
18503	SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
18504	SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
18505	SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
18506	SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
18507	SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
18508	SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18509	SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
18510	SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
18511	SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18512	SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18513	SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18514	SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18515	SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
18516	SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
18517	SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18518	SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
18519	SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18520	SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18521	SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18522	SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
18523	SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
18524	SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18525	SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18526	SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
18527	SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
18528	SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18529	SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18530	SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
18531	SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
18532	SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
18533	SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18534	SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18535	/*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
18536	SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
18537	SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
18538	SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
18539	SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
18540	SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18541	SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
18542	SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18543	SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18544	SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
18545	SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
18546	SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18547	SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
18548	SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
18549	SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18550	SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18551	/*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18552	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18553	SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
18554	SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
18555	SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
18556	SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
18557	SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18558	SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18559	SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18560	SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
18561	SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18562		      ALC662_3ST_6ch_DIG),
18563	SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
18564	SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
18565	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18566		      ALC662_3ST_6ch_DIG),
18567	SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
18568	SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
18569	SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
18570	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
18571	SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
18572					ALC662_3ST_6ch_DIG),
18573	SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18574			   ALC663_ASUS_H13),
18575	SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
18576	{}
18577};
18578
18579static const struct alc_config_preset alc662_presets[] = {
18580	[ALC662_3ST_2ch_DIG] = {
18581		.mixers = { alc662_3ST_2ch_mixer },
18582		.init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18583		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18584		.dac_nids = alc662_dac_nids,
18585		.dig_out_nid = ALC662_DIGOUT_NID,
18586		.dig_in_nid = ALC662_DIGIN_NID,
18587		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18588		.channel_mode = alc662_3ST_2ch_modes,
18589		.input_mux = &alc662_capture_source,
18590	},
18591	[ALC662_3ST_6ch_DIG] = {
18592		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18593		.init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18594		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18595		.dac_nids = alc662_dac_nids,
18596		.dig_out_nid = ALC662_DIGOUT_NID,
18597		.dig_in_nid = ALC662_DIGIN_NID,
18598		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18599		.channel_mode = alc662_3ST_6ch_modes,
18600		.need_dac_fix = 1,
18601		.input_mux = &alc662_capture_source,
18602	},
18603	[ALC662_3ST_6ch] = {
18604		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18605		.init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18606		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18607		.dac_nids = alc662_dac_nids,
18608		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18609		.channel_mode = alc662_3ST_6ch_modes,
18610		.need_dac_fix = 1,
18611		.input_mux = &alc662_capture_source,
18612	},
18613	[ALC662_5ST_DIG] = {
18614		.mixers = { alc662_base_mixer, alc662_chmode_mixer },
18615		.init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18616		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18617		.dac_nids = alc662_dac_nids,
18618		.dig_out_nid = ALC662_DIGOUT_NID,
18619		.dig_in_nid = ALC662_DIGIN_NID,
18620		.num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18621		.channel_mode = alc662_5stack_modes,
18622		.input_mux = &alc662_capture_source,
18623	},
18624	[ALC662_LENOVO_101E] = {
18625		.mixers = { alc662_lenovo_101e_mixer },
18626		.init_verbs = { alc662_init_verbs,
18627				alc662_eapd_init_verbs,
18628				alc662_sue_init_verbs },
18629		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18630		.dac_nids = alc662_dac_nids,
18631		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18632		.channel_mode = alc662_3ST_2ch_modes,
18633		.input_mux = &alc662_lenovo_101e_capture_source,
18634		.unsol_event = alc_sku_unsol_event,
18635		.setup = alc662_lenovo_101e_setup,
18636		.init_hook = alc_inithook,
18637	},
18638	[ALC662_ASUS_EEEPC_P701] = {
18639		.mixers = { alc662_eeepc_p701_mixer },
18640		.init_verbs = { alc662_init_verbs,
18641				alc662_eapd_init_verbs,
18642				alc662_eeepc_sue_init_verbs },
18643		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18644		.dac_nids = alc662_dac_nids,
18645		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18646		.channel_mode = alc662_3ST_2ch_modes,
18647		.unsol_event = alc_sku_unsol_event,
18648		.setup = alc662_eeepc_setup,
18649		.init_hook = alc_inithook,
18650	},
18651	[ALC662_ASUS_EEEPC_EP20] = {
18652		.mixers = { alc662_eeepc_ep20_mixer,
18653			    alc662_chmode_mixer },
18654		.init_verbs = { alc662_init_verbs,
18655				alc662_eapd_init_verbs,
18656				alc662_eeepc_ep20_sue_init_verbs },
18657		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18658		.dac_nids = alc662_dac_nids,
18659		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18660		.channel_mode = alc662_3ST_6ch_modes,
18661		.input_mux = &alc662_lenovo_101e_capture_source,
18662		.unsol_event = alc_sku_unsol_event,
18663		.setup = alc662_eeepc_ep20_setup,
18664		.init_hook = alc_inithook,
18665	},
18666	[ALC662_ECS] = {
18667		.mixers = { alc662_ecs_mixer },
18668		.init_verbs = { alc662_init_verbs,
18669				alc662_eapd_init_verbs,
18670				alc662_ecs_init_verbs },
18671		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18672		.dac_nids = alc662_dac_nids,
18673		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18674		.channel_mode = alc662_3ST_2ch_modes,
18675		.unsol_event = alc_sku_unsol_event,
18676		.setup = alc662_eeepc_setup,
18677		.init_hook = alc_inithook,
18678	},
18679	[ALC663_ASUS_M51VA] = {
18680		.mixers = { alc663_m51va_mixer },
18681		.init_verbs = { alc662_init_verbs,
18682				alc662_eapd_init_verbs,
18683				alc663_m51va_init_verbs },
18684		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18685		.dac_nids = alc662_dac_nids,
18686		.dig_out_nid = ALC662_DIGOUT_NID,
18687		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18688		.channel_mode = alc662_3ST_2ch_modes,
18689		.unsol_event = alc_sku_unsol_event,
18690		.setup = alc663_m51va_setup,
18691		.init_hook = alc_inithook,
18692	},
18693	[ALC663_ASUS_G71V] = {
18694		.mixers = { alc663_g71v_mixer },
18695		.init_verbs = { alc662_init_verbs,
18696				alc662_eapd_init_verbs,
18697				alc663_g71v_init_verbs },
18698		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18699		.dac_nids = alc662_dac_nids,
18700		.dig_out_nid = ALC662_DIGOUT_NID,
18701		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18702		.channel_mode = alc662_3ST_2ch_modes,
18703		.unsol_event = alc_sku_unsol_event,
18704		.setup = alc663_g71v_setup,
18705		.init_hook = alc_inithook,
18706	},
18707	[ALC663_ASUS_H13] = {
18708		.mixers = { alc663_m51va_mixer },
18709		.init_verbs = { alc662_init_verbs,
18710				alc662_eapd_init_verbs,
18711				alc663_m51va_init_verbs },
18712		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18713		.dac_nids = alc662_dac_nids,
18714		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18715		.channel_mode = alc662_3ST_2ch_modes,
18716		.setup = alc663_m51va_setup,
18717		.unsol_event = alc_sku_unsol_event,
18718		.init_hook = alc_inithook,
18719	},
18720	[ALC663_ASUS_G50V] = {
18721		.mixers = { alc663_g50v_mixer },
18722		.init_verbs = { alc662_init_verbs,
18723				alc662_eapd_init_verbs,
18724				alc663_g50v_init_verbs },
18725		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18726		.dac_nids = alc662_dac_nids,
18727		.dig_out_nid = ALC662_DIGOUT_NID,
18728		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18729		.channel_mode = alc662_3ST_6ch_modes,
18730		.input_mux = &alc663_capture_source,
18731		.unsol_event = alc_sku_unsol_event,
18732		.setup = alc663_g50v_setup,
18733		.init_hook = alc_inithook,
18734	},
18735	[ALC663_ASUS_MODE1] = {
18736		.mixers = { alc663_m51va_mixer },
18737		.cap_mixer = alc662_auto_capture_mixer,
18738		.init_verbs = { alc662_init_verbs,
18739				alc662_eapd_init_verbs,
18740				alc663_21jd_amic_init_verbs },
18741		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18742		.hp_nid = 0x03,
18743		.dac_nids = alc662_dac_nids,
18744		.dig_out_nid = ALC662_DIGOUT_NID,
18745		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18746		.channel_mode = alc662_3ST_2ch_modes,
18747		.unsol_event = alc_sku_unsol_event,
18748		.setup = alc663_mode1_setup,
18749		.init_hook = alc_inithook,
18750	},
18751	[ALC662_ASUS_MODE2] = {
18752		.mixers = { alc662_1bjd_mixer },
18753		.cap_mixer = alc662_auto_capture_mixer,
18754		.init_verbs = { alc662_init_verbs,
18755				alc662_eapd_init_verbs,
18756				alc662_1bjd_amic_init_verbs },
18757		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18758		.dac_nids = alc662_dac_nids,
18759		.dig_out_nid = ALC662_DIGOUT_NID,
18760		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18761		.channel_mode = alc662_3ST_2ch_modes,
18762		.unsol_event = alc_sku_unsol_event,
18763		.setup = alc662_mode2_setup,
18764		.init_hook = alc_inithook,
18765	},
18766	[ALC663_ASUS_MODE3] = {
18767		.mixers = { alc663_two_hp_m1_mixer },
18768		.cap_mixer = alc662_auto_capture_mixer,
18769		.init_verbs = { alc662_init_verbs,
18770				alc662_eapd_init_verbs,
18771				alc663_two_hp_amic_m1_init_verbs },
18772		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18773		.hp_nid = 0x03,
18774		.dac_nids = alc662_dac_nids,
18775		.dig_out_nid = ALC662_DIGOUT_NID,
18776		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18777		.channel_mode = alc662_3ST_2ch_modes,
18778		.unsol_event = alc_sku_unsol_event,
18779		.setup = alc663_mode3_setup,
18780		.init_hook = alc_inithook,
18781	},
18782	[ALC663_ASUS_MODE4] = {
18783		.mixers = { alc663_asus_21jd_clfe_mixer },
18784		.cap_mixer = alc662_auto_capture_mixer,
18785		.init_verbs = { alc662_init_verbs,
18786				alc662_eapd_init_verbs,
18787				alc663_21jd_amic_init_verbs},
18788		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18789		.hp_nid = 0x03,
18790		.dac_nids = alc662_dac_nids,
18791		.dig_out_nid = ALC662_DIGOUT_NID,
18792		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18793		.channel_mode = alc662_3ST_2ch_modes,
18794		.unsol_event = alc_sku_unsol_event,
18795		.setup = alc663_mode4_setup,
18796		.init_hook = alc_inithook,
18797	},
18798	[ALC663_ASUS_MODE5] = {
18799		.mixers = { alc663_asus_15jd_clfe_mixer },
18800		.cap_mixer = alc662_auto_capture_mixer,
18801		.init_verbs = { alc662_init_verbs,
18802				alc662_eapd_init_verbs,
18803				alc663_15jd_amic_init_verbs },
18804		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18805		.hp_nid = 0x03,
18806		.dac_nids = alc662_dac_nids,
18807		.dig_out_nid = ALC662_DIGOUT_NID,
18808		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18809		.channel_mode = alc662_3ST_2ch_modes,
18810		.unsol_event = alc_sku_unsol_event,
18811		.setup = alc663_mode5_setup,
18812		.init_hook = alc_inithook,
18813	},
18814	[ALC663_ASUS_MODE6] = {
18815		.mixers = { alc663_two_hp_m2_mixer },
18816		.cap_mixer = alc662_auto_capture_mixer,
18817		.init_verbs = { alc662_init_verbs,
18818				alc662_eapd_init_verbs,
18819				alc663_two_hp_amic_m2_init_verbs },
18820		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18821		.hp_nid = 0x03,
18822		.dac_nids = alc662_dac_nids,
18823		.dig_out_nid = ALC662_DIGOUT_NID,
18824		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18825		.channel_mode = alc662_3ST_2ch_modes,
18826		.unsol_event = alc_sku_unsol_event,
18827		.setup = alc663_mode6_setup,
18828		.init_hook = alc_inithook,
18829	},
18830	[ALC663_ASUS_MODE7] = {
18831		.mixers = { alc663_mode7_mixer },
18832		.cap_mixer = alc662_auto_capture_mixer,
18833		.init_verbs = { alc662_init_verbs,
18834				alc662_eapd_init_verbs,
18835				alc663_mode7_init_verbs },
18836		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18837		.hp_nid = 0x03,
18838		.dac_nids = alc662_dac_nids,
18839		.dig_out_nid = ALC662_DIGOUT_NID,
18840		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18841		.channel_mode = alc662_3ST_2ch_modes,
18842		.unsol_event = alc_sku_unsol_event,
18843		.setup = alc663_mode7_setup,
18844		.init_hook = alc_inithook,
18845	},
18846	[ALC663_ASUS_MODE8] = {
18847		.mixers = { alc663_mode8_mixer },
18848		.cap_mixer = alc662_auto_capture_mixer,
18849		.init_verbs = { alc662_init_verbs,
18850				alc662_eapd_init_verbs,
18851				alc663_mode8_init_verbs },
18852		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
18853		.hp_nid = 0x03,
18854		.dac_nids = alc662_dac_nids,
18855		.dig_out_nid = ALC662_DIGOUT_NID,
18856		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18857		.channel_mode = alc662_3ST_2ch_modes,
18858		.unsol_event = alc_sku_unsol_event,
18859		.setup = alc663_mode8_setup,
18860		.init_hook = alc_inithook,
18861	},
18862	[ALC272_DELL] = {
18863		.mixers = { alc663_m51va_mixer },
18864		.cap_mixer = alc272_auto_capture_mixer,
18865		.init_verbs = { alc662_init_verbs,
18866				alc662_eapd_init_verbs,
18867				alc272_dell_init_verbs },
18868		.num_dacs = ARRAY_SIZE(alc272_dac_nids),
18869		.dac_nids = alc272_dac_nids,
18870		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18871		.adc_nids = alc272_adc_nids,
18872		.num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18873		.capsrc_nids = alc272_capsrc_nids,
18874		.channel_mode = alc662_3ST_2ch_modes,
18875		.unsol_event = alc_sku_unsol_event,
18876		.setup = alc663_m51va_setup,
18877		.init_hook = alc_inithook,
18878	},
18879	[ALC272_DELL_ZM1] = {
18880		.mixers = { alc663_m51va_mixer },
18881		.cap_mixer = alc662_auto_capture_mixer,
18882		.init_verbs = { alc662_init_verbs,
18883				alc662_eapd_init_verbs,
18884				alc272_dell_zm1_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 = alc662_adc_nids,
18889		.num_adc_nids = 1,
18890		.capsrc_nids = alc662_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_SAMSUNG_NC10] = {
18897		.mixers = { alc272_nc10_mixer },
18898		.init_verbs = { alc662_init_verbs,
18899				alc662_eapd_init_verbs,
18900				alc663_21jd_amic_init_verbs },
18901		.num_dacs = ARRAY_SIZE(alc272_dac_nids),
18902		.dac_nids = alc272_dac_nids,
18903		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18904		.channel_mode = alc662_3ST_2ch_modes,
18905		/*.input_mux = &alc272_nc10_capture_source,*/
18906		.unsol_event = alc_sku_unsol_event,
18907		.setup = alc663_mode4_setup,
18908		.init_hook = alc_inithook,
18909	},
18910};
18911
18912
18913/*
18914 * BIOS auto configuration
18915 */
18916
18917/* convert from MIX nid to DAC */
18918static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
18919{
18920	hda_nid_t list[5];
18921	int i, num;
18922
18923	num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
18924	for (i = 0; i < num; i++) {
18925		if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
18926			return list[i];
18927	}
18928	return 0;
18929}
18930
18931/* go down to the selector widget before the mixer */
18932static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
18933{
18934	hda_nid_t srcs[5];
18935	int num = snd_hda_get_connections(codec, pin, srcs,
18936					  ARRAY_SIZE(srcs));
18937	if (num != 1 ||
18938	    get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
18939		return pin;
18940	return srcs[0];
18941}
18942
18943/* get MIX nid connected to the given pin targeted to DAC */
18944static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
18945				   hda_nid_t dac)
18946{
18947	hda_nid_t mix[5];
18948	int i, num;
18949
18950	pin = alc_go_down_to_selector(codec, pin);
18951	num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18952	for (i = 0; i < num; i++) {
18953		if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
18954			return mix[i];
18955	}
18956	return 0;
18957}
18958
18959/* select the connection from pin to DAC if needed */
18960static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
18961			       hda_nid_t dac)
18962{
18963	hda_nid_t mix[5];
18964	int i, num;
18965
18966	pin = alc_go_down_to_selector(codec, pin);
18967	num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18968	if (num < 2)
18969		return 0;
18970	for (i = 0; i < num; i++) {
18971		if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
18972			snd_hda_codec_update_cache(codec, pin, 0,
18973						   AC_VERB_SET_CONNECT_SEL, i);
18974			return 0;
18975		}
18976	}
18977	return 0;
18978}
18979
18980/* look for an empty DAC slot */
18981static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
18982{
18983	struct alc_spec *spec = codec->spec;
18984	hda_nid_t srcs[5];
18985	int i, j, num;
18986
18987	pin = alc_go_down_to_selector(codec, pin);
18988	num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
18989	for (i = 0; i < num; i++) {
18990		hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
18991		if (!nid)
18992			continue;
18993		for (j = 0; j < spec->multiout.num_dacs; j++)
18994			if (spec->multiout.dac_nids[j] == nid)
18995				break;
18996		if (j >= spec->multiout.num_dacs)
18997			return nid;
18998	}
18999	return 0;
19000}
19001
19002/* fill in the dac_nids table from the parsed pin configuration */
19003static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
19004				     const struct auto_pin_cfg *cfg)
19005{
19006	struct alc_spec *spec = codec->spec;
19007	int i;
19008	hda_nid_t dac;
19009
19010	spec->multiout.dac_nids = spec->private_dac_nids;
19011	for (i = 0; i < cfg->line_outs; i++) {
19012		dac = alc_auto_look_for_dac(codec, cfg->line_out_pins[i]);
19013		if (!dac)
19014			continue;
19015		spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
19016	}
19017	return 0;
19018}
19019
19020static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
19021				       hda_nid_t nid, int idx, unsigned int chs)
19022{
19023	return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
19024			   HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
19025}
19026
19027static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
19028				      hda_nid_t nid, int idx, unsigned int chs)
19029{
19030	return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
19031			   HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
19032}
19033
19034#define alc662_add_vol_ctl(spec, pfx, nid, chs) \
19035	__alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
19036#define alc662_add_sw_ctl(spec, pfx, nid, chs) \
19037	__alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
19038#define alc662_add_stereo_vol(spec, pfx, nid) \
19039	alc662_add_vol_ctl(spec, pfx, nid, 3)
19040#define alc662_add_stereo_sw(spec, pfx, nid) \
19041	alc662_add_sw_ctl(spec, pfx, nid, 3)
19042
19043/* add playback controls from the parsed DAC table */
19044static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
19045					     const struct auto_pin_cfg *cfg)
19046{
19047	struct alc_spec *spec = codec->spec;
19048	static const char * const chname[4] = {
19049		"Front", "Surround", NULL /*CLFE*/, "Side"
19050	};
19051	const char *pfx = alc_get_line_out_pfx(spec, true);
19052	hda_nid_t nid, mix, pin;
19053	int i, err, noutputs;
19054
19055	noutputs = cfg->line_outs;
19056	if (spec->multi_ios > 0)
19057		noutputs += spec->multi_ios;
19058
19059	for (i = 0; i < noutputs; i++) {
19060		nid = spec->multiout.dac_nids[i];
19061		if (!nid)
19062			continue;
19063		if (i >= cfg->line_outs)
19064			pin = spec->multi_io[i - 1].pin;
19065		else
19066			pin = cfg->line_out_pins[i];
19067		mix = alc_auto_dac_to_mix(codec, pin, nid);
19068		if (!mix)
19069			continue;
19070		if (!pfx && i == 2) {
19071			/* Center/LFE */
19072			err = alc662_add_vol_ctl(spec, "Center", nid, 1);
19073			if (err < 0)
19074				return err;
19075			err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
19076			if (err < 0)
19077				return err;
19078			err = alc662_add_sw_ctl(spec, "Center", mix, 1);
19079			if (err < 0)
19080				return err;
19081			err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
19082			if (err < 0)
19083				return err;
19084		} else {
19085			const char *name = pfx;
19086			int index = i;
19087			if (!name) {
19088				name = chname[i];
19089				index = 0;
19090			}
19091			err = __alc662_add_vol_ctl(spec, name, nid, index, 3);
19092			if (err < 0)
19093				return err;
19094			err = __alc662_add_sw_ctl(spec, name, mix, index, 3);
19095			if (err < 0)
19096				return err;
19097		}
19098	}
19099	return 0;
19100}
19101
19102/* add playback controls for speaker and HP outputs */
19103/* return DAC nid if any new DAC is assigned */
19104static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
19105					const char *pfx)
19106{
19107	struct alc_spec *spec = codec->spec;
19108	hda_nid_t nid, mix;
19109	int err;
19110
19111	if (!pin)
19112		return 0;
19113	nid = alc_auto_look_for_dac(codec, pin);
19114	if (!nid) {
19115		/* the corresponding DAC is already occupied */
19116		if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19117			return 0; /* no way */
19118		/* create a switch only */
19119		return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
19120				   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
19121	}
19122
19123	mix = alc_auto_dac_to_mix(codec, pin, nid);
19124	if (!mix)
19125		return 0;
19126	err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19127	if (err < 0)
19128		return err;
19129	err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19130	if (err < 0)
19131		return err;
19132	return nid;
19133}
19134
19135/* create playback/capture controls for input pins */
19136#define alc662_auto_create_input_ctls \
19137	alc882_auto_create_input_ctls
19138
19139static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19140					      hda_nid_t nid, int pin_type,
19141					      hda_nid_t dac)
19142{
19143	int i, num;
19144	hda_nid_t srcs[HDA_MAX_CONNECTIONS];
19145
19146	alc_set_pin_output(codec, nid, pin_type);
19147	num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
19148	for (i = 0; i < num; i++) {
19149		if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
19150			continue;
19151		/* need the manual connection? */
19152		if (num > 1)
19153			snd_hda_codec_write(codec, nid, 0,
19154					    AC_VERB_SET_CONNECT_SEL, i);
19155		/* unmute mixer widget inputs */
19156		snd_hda_codec_write(codec, srcs[i], 0,
19157				    AC_VERB_SET_AMP_GAIN_MUTE,
19158				    AMP_IN_UNMUTE(0));
19159		snd_hda_codec_write(codec, srcs[i], 0,
19160				    AC_VERB_SET_AMP_GAIN_MUTE,
19161				    AMP_IN_UNMUTE(1));
19162		return;
19163	}
19164}
19165
19166static void alc662_auto_init_multi_out(struct hda_codec *codec)
19167{
19168	struct alc_spec *spec = codec->spec;
19169	int pin_type = get_pin_type(spec->autocfg.line_out_type);
19170	int i;
19171
19172	for (i = 0; i <= HDA_SIDE; i++) {
19173		hda_nid_t nid = spec->autocfg.line_out_pins[i];
19174		if (nid)
19175			alc662_auto_set_output_and_unmute(codec, nid, pin_type,
19176					spec->multiout.dac_nids[i]);
19177	}
19178}
19179
19180static void alc662_auto_init_hp_out(struct hda_codec *codec)
19181{
19182	struct alc_spec *spec = codec->spec;
19183	hda_nid_t pin;
19184
19185	pin = spec->autocfg.hp_pins[0];
19186	if (pin)
19187		alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19188						  spec->multiout.hp_nid);
19189	pin = spec->autocfg.speaker_pins[0];
19190	if (pin)
19191		alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19192					spec->multiout.extra_out_nid[0]);
19193}
19194
19195#define ALC662_PIN_CD_NID		ALC880_PIN_CD_NID
19196
19197static void alc662_auto_init_analog_input(struct hda_codec *codec)
19198{
19199	struct alc_spec *spec = codec->spec;
19200	struct auto_pin_cfg *cfg = &spec->autocfg;
19201	int i;
19202
19203	for (i = 0; i < cfg->num_inputs; i++) {
19204		hda_nid_t nid = cfg->inputs[i].pin;
19205		if (alc_is_input_pin(codec, nid)) {
19206			alc_set_input_pin(codec, nid, cfg->inputs[i].type);
19207			if (nid != ALC662_PIN_CD_NID &&
19208			    (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
19209				snd_hda_codec_write(codec, nid, 0,
19210						    AC_VERB_SET_AMP_GAIN_MUTE,
19211						    AMP_OUT_MUTE);
19212		}
19213	}
19214}
19215
19216#define alc662_auto_init_input_src	alc882_auto_init_input_src
19217
19218/*
19219 * multi-io helper
19220 */
19221static int alc_auto_fill_multi_ios(struct hda_codec *codec,
19222				   unsigned int location)
19223{
19224	struct alc_spec *spec = codec->spec;
19225	struct auto_pin_cfg *cfg = &spec->autocfg;
19226	int type, i, num_pins = 0;
19227
19228	for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
19229		for (i = 0; i < cfg->num_inputs; i++) {
19230			hda_nid_t nid = cfg->inputs[i].pin;
19231			hda_nid_t dac;
19232			unsigned int defcfg, caps;
19233			if (cfg->inputs[i].type != type)
19234				continue;
19235			defcfg = snd_hda_codec_get_pincfg(codec, nid);
19236			if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
19237				continue;
19238			if (location && get_defcfg_location(defcfg) != location)
19239				continue;
19240			caps = snd_hda_query_pin_caps(codec, nid);
19241			if (!(caps & AC_PINCAP_OUT))
19242				continue;
19243			dac = alc_auto_look_for_dac(codec, nid);
19244			if (!dac)
19245				continue;
19246			spec->multi_io[num_pins].pin = nid;
19247			spec->multi_io[num_pins].dac = dac;
19248			num_pins++;
19249			spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
19250		}
19251	}
19252	spec->multiout.num_dacs = 1;
19253	if (num_pins < 2)
19254		return 0;
19255	return num_pins;
19256}
19257
19258static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
19259				 struct snd_ctl_elem_info *uinfo)
19260{
19261	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19262	struct alc_spec *spec = codec->spec;
19263
19264	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
19265	uinfo->count = 1;
19266	uinfo->value.enumerated.items = spec->multi_ios + 1;
19267	if (uinfo->value.enumerated.item > spec->multi_ios)
19268		uinfo->value.enumerated.item = spec->multi_ios;
19269	sprintf(uinfo->value.enumerated.name, "%dch",
19270		(uinfo->value.enumerated.item + 1) * 2);
19271	return 0;
19272}
19273
19274static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
19275				struct snd_ctl_elem_value *ucontrol)
19276{
19277	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19278	struct alc_spec *spec = codec->spec;
19279	ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
19280	return 0;
19281}
19282
19283static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
19284{
19285	struct alc_spec *spec = codec->spec;
19286	hda_nid_t nid = spec->multi_io[idx].pin;
19287
19288	if (!spec->multi_io[idx].ctl_in)
19289		spec->multi_io[idx].ctl_in =
19290			snd_hda_codec_read(codec, nid, 0,
19291					   AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
19292	if (output) {
19293		snd_hda_codec_update_cache(codec, nid, 0,
19294					   AC_VERB_SET_PIN_WIDGET_CONTROL,
19295					   PIN_OUT);
19296		if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19297			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19298						 HDA_AMP_MUTE, 0);
19299		alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
19300	} else {
19301		if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19302			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19303						 HDA_AMP_MUTE, HDA_AMP_MUTE);
19304		snd_hda_codec_update_cache(codec, nid, 0,
19305					   AC_VERB_SET_PIN_WIDGET_CONTROL,
19306					   spec->multi_io[idx].ctl_in);
19307	}
19308	return 0;
19309}
19310
19311static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
19312				struct snd_ctl_elem_value *ucontrol)
19313{
19314	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19315	struct alc_spec *spec = codec->spec;
19316	int i, ch;
19317
19318	ch = ucontrol->value.enumerated.item[0];
19319	if (ch < 0 || ch > spec->multi_ios)
19320		return -EINVAL;
19321	if (ch == (spec->ext_channel_count - 1) / 2)
19322		return 0;
19323	spec->ext_channel_count = (ch + 1) * 2;
19324	for (i = 0; i < spec->multi_ios; i++)
19325		alc_set_multi_io(codec, i, i < ch);
19326	spec->multiout.max_channels = spec->ext_channel_count;
19327	return 1;
19328}
19329
19330static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
19331	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
19332	.name = "Channel Mode",
19333	.info = alc_auto_ch_mode_info,
19334	.get = alc_auto_ch_mode_get,
19335	.put = alc_auto_ch_mode_put,
19336};
19337
19338static int alc_auto_add_multi_channel_mode(struct hda_codec *codec)
19339{
19340	struct alc_spec *spec = codec->spec;
19341	struct auto_pin_cfg *cfg = &spec->autocfg;
19342	unsigned int location, defcfg;
19343	int num_pins;
19344
19345	if (cfg->line_outs != 1 ||
19346	    cfg->line_out_type != AUTO_PIN_LINE_OUT)
19347		return 0;
19348
19349	defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
19350	location = get_defcfg_location(defcfg);
19351
19352	num_pins = alc_auto_fill_multi_ios(codec, location);
19353	if (num_pins > 0) {
19354		struct snd_kcontrol_new *knew;
19355
19356		knew = alc_kcontrol_new(spec);
19357		if (!knew)
19358			return -ENOMEM;
19359		*knew = alc_auto_channel_mode_enum;
19360		knew->name = kstrdup("Channel Mode", GFP_KERNEL);
19361		if (!knew->name)
19362			return -ENOMEM;
19363
19364		spec->multi_ios = num_pins;
19365		spec->ext_channel_count = 2;
19366		spec->multiout.num_dacs = num_pins + 1;
19367	}
19368	return 0;
19369}
19370
19371static int alc662_parse_auto_config(struct hda_codec *codec)
19372{
19373	struct alc_spec *spec = codec->spec;
19374	int err;
19375	static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
19376
19377	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19378					   alc662_ignore);
19379	if (err < 0)
19380		return err;
19381	if (!spec->autocfg.line_outs)
19382		return 0; /* can't find valid BIOS pin config */
19383
19384	err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
19385	if (err < 0)
19386		return err;
19387	err = alc_auto_add_multi_channel_mode(codec);
19388	if (err < 0)
19389		return err;
19390	err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
19391	if (err < 0)
19392		return err;
19393	err = alc662_auto_create_extra_out(codec,
19394					   spec->autocfg.speaker_pins[0],
19395					   "Speaker");
19396	if (err < 0)
19397		return err;
19398	if (err)
19399		spec->multiout.extra_out_nid[0] = err;
19400	err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
19401					   "Headphone");
19402	if (err < 0)
19403		return err;
19404	if (err)
19405		spec->multiout.hp_nid = err;
19406	err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
19407	if (err < 0)
19408		return err;
19409
19410	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19411
19412	alc_auto_parse_digital(codec);
19413
19414	if (spec->kctls.list)
19415		add_mixer(spec, spec->kctls.list);
19416
19417	spec->num_mux_defs = 1;
19418	spec->input_mux = &spec->private_imux[0];
19419
19420	err = alc_auto_add_mic_boost(codec);
19421	if (err < 0)
19422		return err;
19423
19424	if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19425	    codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19426	    alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19427	else
19428	    alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
19429
19430	return 1;
19431}
19432
19433/* additional initialization for auto-configuration model */
19434static void alc662_auto_init(struct hda_codec *codec)
19435{
19436	struct alc_spec *spec = codec->spec;
19437	alc662_auto_init_multi_out(codec);
19438	alc662_auto_init_hp_out(codec);
19439	alc662_auto_init_analog_input(codec);
19440	alc662_auto_init_input_src(codec);
19441	alc_auto_init_digital(codec);
19442	if (spec->unsol_event)
19443		alc_inithook(codec);
19444}
19445
19446static void alc272_fixup_mario(struct hda_codec *codec,
19447			       const struct alc_fixup *fix, int action)
19448{
19449	if (action != ALC_FIXUP_ACT_PROBE)
19450		return;
19451	if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19452				      (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19453				      (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19454				      (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19455				      (0 << AC_AMPCAP_MUTE_SHIFT)))
19456		printk(KERN_WARNING
19457		       "hda_codec: failed to override amp caps for NID 0x2\n");
19458}
19459
19460enum {
19461	ALC662_FIXUP_ASPIRE,
19462	ALC662_FIXUP_IDEAPAD,
19463	ALC272_FIXUP_MARIO,
19464	ALC662_FIXUP_CZC_P10T,
19465	ALC662_FIXUP_SKU_IGNORE,
19466};
19467
19468static const struct alc_fixup alc662_fixups[] = {
19469	[ALC662_FIXUP_ASPIRE] = {
19470		.type = ALC_FIXUP_PINS,
19471		.v.pins = (const struct alc_pincfg[]) {
19472			{ 0x15, 0x99130112 }, /* subwoofer */
19473			{ }
19474		}
19475	},
19476	[ALC662_FIXUP_IDEAPAD] = {
19477		.type = ALC_FIXUP_PINS,
19478		.v.pins = (const struct alc_pincfg[]) {
19479			{ 0x17, 0x99130112 }, /* subwoofer */
19480			{ }
19481		}
19482	},
19483	[ALC272_FIXUP_MARIO] = {
19484		.type = ALC_FIXUP_FUNC,
19485		.v.func = alc272_fixup_mario,
19486	},
19487	[ALC662_FIXUP_CZC_P10T] = {
19488		.type = ALC_FIXUP_VERBS,
19489		.v.verbs = (const struct hda_verb[]) {
19490			{0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
19491			{}
19492		}
19493	},
19494	[ALC662_FIXUP_SKU_IGNORE] = {
19495		.type = ALC_FIXUP_SKU,
19496		.v.sku = ALC_FIXUP_SKU_IGNORE,
19497	},
19498};
19499
19500static const struct snd_pci_quirk alc662_fixup_tbl[] = {
19501	SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
19502	SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
19503	SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
19504	SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
19505	SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
19506	SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
19507	SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
19508	{}
19509};
19510
19511static const struct alc_model_fixup alc662_fixup_models[] = {
19512	{.id = ALC272_FIXUP_MARIO, .name = "mario"},
19513	{}
19514};
19515
19516
19517static int patch_alc662(struct hda_codec *codec)
19518{
19519	struct alc_spec *spec;
19520	int err, board_config;
19521	int coef;
19522
19523	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19524	if (!spec)
19525		return -ENOMEM;
19526
19527	codec->spec = spec;
19528
19529	alc_auto_parse_customize_define(codec);
19530
19531	alc_fix_pll_init(codec, 0x20, 0x04, 15);
19532
19533	coef = alc_read_coef_idx(codec, 0);
19534	if (coef == 0x8020 || coef == 0x8011)
19535		alc_codec_rename(codec, "ALC661");
19536	else if (coef & (1 << 14) &&
19537		codec->bus->pci->subsystem_vendor == 0x1025 &&
19538		spec->cdefine.platform_type == 1)
19539		alc_codec_rename(codec, "ALC272X");
19540	else if (coef == 0x4011)
19541		alc_codec_rename(codec, "ALC656");
19542
19543	board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19544						  alc662_models,
19545			  	                  alc662_cfg_tbl);
19546	if (board_config < 0) {
19547		printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19548		       codec->chip_name);
19549		board_config = ALC662_AUTO;
19550	}
19551
19552	if (board_config == ALC662_AUTO) {
19553		alc_pick_fixup(codec, alc662_fixup_models,
19554			       alc662_fixup_tbl, alc662_fixups);
19555		alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
19556		/* automatic parse from the BIOS config */
19557		err = alc662_parse_auto_config(codec);
19558		if (err < 0) {
19559			alc_free(codec);
19560			return err;
19561		} else if (!err) {
19562			printk(KERN_INFO
19563			       "hda_codec: Cannot set up configuration "
19564			       "from BIOS.  Using base mode...\n");
19565			board_config = ALC662_3ST_2ch_DIG;
19566		}
19567	}
19568
19569	if (has_cdefine_beep(codec)) {
19570		err = snd_hda_attach_beep_device(codec, 0x1);
19571		if (err < 0) {
19572			alc_free(codec);
19573			return err;
19574		}
19575	}
19576
19577	if (board_config != ALC662_AUTO)
19578		setup_preset(codec, &alc662_presets[board_config]);
19579
19580	spec->stream_analog_playback = &alc662_pcm_analog_playback;
19581	spec->stream_analog_capture = &alc662_pcm_analog_capture;
19582
19583	spec->stream_digital_playback = &alc662_pcm_digital_playback;
19584	spec->stream_digital_capture = &alc662_pcm_digital_capture;
19585
19586	if (!spec->adc_nids) {
19587		spec->adc_nids = alc662_adc_nids;
19588		spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19589	}
19590	if (!spec->capsrc_nids)
19591		spec->capsrc_nids = alc662_capsrc_nids;
19592
19593	if (!spec->cap_mixer)
19594		set_capture_mixer(codec);
19595
19596	if (has_cdefine_beep(codec)) {
19597		switch (codec->vendor_id) {
19598		case 0x10ec0662:
19599			set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19600			break;
19601		case 0x10ec0272:
19602		case 0x10ec0663:
19603		case 0x10ec0665:
19604			set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19605			break;
19606		case 0x10ec0273:
19607			set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19608			break;
19609		}
19610	}
19611	spec->vmaster_nid = 0x02;
19612
19613	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19614
19615	codec->patch_ops = alc_patch_ops;
19616	if (board_config == ALC662_AUTO)
19617		spec->init_hook = alc662_auto_init;
19618	spec->shutup = alc_eapd_shutup;
19619
19620	alc_init_jacks(codec);
19621
19622#ifdef CONFIG_SND_HDA_POWER_SAVE
19623	if (!spec->loopback.amplist)
19624		spec->loopback.amplist = alc662_loopbacks;
19625#endif
19626
19627	return 0;
19628}
19629
19630static int patch_alc888(struct hda_codec *codec)
19631{
19632	if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19633		kfree(codec->chip_name);
19634		if (codec->vendor_id == 0x10ec0887)
19635			codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19636		else
19637			codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
19638		if (!codec->chip_name) {
19639			alc_free(codec);
19640			return -ENOMEM;
19641		}
19642		return patch_alc662(codec);
19643	}
19644	return patch_alc882(codec);
19645}
19646
19647static int patch_alc899(struct hda_codec *codec)
19648{
19649	if ((alc_read_coef_idx(codec, 0) & 0x2000) != 0x2000) {
19650		kfree(codec->chip_name);
19651		codec->chip_name = kstrdup("ALC898", GFP_KERNEL);
19652	}
19653	return patch_alc882(codec);
19654}
19655
19656/*
19657 * ALC680 support
19658 */
19659#define ALC680_DIGIN_NID	ALC880_DIGIN_NID
19660#define ALC680_DIGOUT_NID	ALC880_DIGOUT_NID
19661#define alc680_modes		alc260_modes
19662
19663static const hda_nid_t alc680_dac_nids[3] = {
19664	/* Lout1, Lout2, hp */
19665	0x02, 0x03, 0x04
19666};
19667
19668static const hda_nid_t alc680_adc_nids[3] = {
19669	/* ADC0-2 */
19670	/* DMIC, MIC, Line-in*/
19671	0x07, 0x08, 0x09
19672};
19673
19674/*
19675 * Analog capture ADC cgange
19676 */
19677static void alc680_rec_autoswitch(struct hda_codec *codec)
19678{
19679	struct alc_spec *spec = codec->spec;
19680	struct auto_pin_cfg *cfg = &spec->autocfg;
19681	int pin_found = 0;
19682	int type_found = AUTO_PIN_LAST;
19683	hda_nid_t nid;
19684	int i;
19685
19686	for (i = 0; i < cfg->num_inputs; i++) {
19687		nid = cfg->inputs[i].pin;
19688		if (!is_jack_detectable(codec, nid))
19689			continue;
19690		if (snd_hda_jack_detect(codec, nid)) {
19691			if (cfg->inputs[i].type < type_found) {
19692				type_found = cfg->inputs[i].type;
19693				pin_found = nid;
19694			}
19695		}
19696	}
19697
19698	nid = 0x07;
19699	if (pin_found)
19700		snd_hda_get_connections(codec, pin_found, &nid, 1);
19701
19702	if (nid != spec->cur_adc)
19703		__snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19704	spec->cur_adc = nid;
19705	snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19706				   spec->cur_adc_format);
19707}
19708
19709static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19710				      struct hda_codec *codec,
19711				      unsigned int stream_tag,
19712				      unsigned int format,
19713				      struct snd_pcm_substream *substream)
19714{
19715	struct alc_spec *spec = codec->spec;
19716
19717	spec->cur_adc = 0x07;
19718	spec->cur_adc_stream_tag = stream_tag;
19719	spec->cur_adc_format = format;
19720
19721	alc680_rec_autoswitch(codec);
19722	return 0;
19723}
19724
19725static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19726				      struct hda_codec *codec,
19727				      struct snd_pcm_substream *substream)
19728{
19729	snd_hda_codec_cleanup_stream(codec, 0x07);
19730	snd_hda_codec_cleanup_stream(codec, 0x08);
19731	snd_hda_codec_cleanup_stream(codec, 0x09);
19732	return 0;
19733}
19734
19735static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19736	.substreams = 1, /* can be overridden */
19737	.channels_min = 2,
19738	.channels_max = 2,
19739	/* NID is set in alc_build_pcms */
19740	.ops = {
19741		.prepare = alc680_capture_pcm_prepare,
19742		.cleanup = alc680_capture_pcm_cleanup
19743	},
19744};
19745
19746static const struct snd_kcontrol_new alc680_base_mixer[] = {
19747	/* output mixer control */
19748	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19749	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19750	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19751	HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
19752	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19753	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19754	HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
19755	{ }
19756};
19757
19758static const struct hda_bind_ctls alc680_bind_cap_vol = {
19759	.ops = &snd_hda_bind_vol,
19760	.values = {
19761		HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19762		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19763		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19764		0
19765	},
19766};
19767
19768static const struct hda_bind_ctls alc680_bind_cap_switch = {
19769	.ops = &snd_hda_bind_sw,
19770	.values = {
19771		HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19772		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19773		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19774		0
19775	},
19776};
19777
19778static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19779	HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19780	HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
19781	{ } /* end */
19782};
19783
19784/*
19785 * generic initialization of ADC, input mixers and output mixers
19786 */
19787static const struct hda_verb alc680_init_verbs[] = {
19788	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19789	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19790	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19791
19792	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19793	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19794	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19795	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19796	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19797	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19798
19799	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19800	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19801	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19802	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19803	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19804
19805	{0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT   | AC_USRSP_EN},
19806	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT  | AC_USRSP_EN},
19807	{0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT  | AC_USRSP_EN},
19808
19809	{ }
19810};
19811
19812/* toggle speaker-output according to the hp-jack state */
19813static void alc680_base_setup(struct hda_codec *codec)
19814{
19815	struct alc_spec *spec = codec->spec;
19816
19817	spec->autocfg.hp_pins[0] = 0x16;
19818	spec->autocfg.speaker_pins[0] = 0x14;
19819	spec->autocfg.speaker_pins[1] = 0x15;
19820	spec->autocfg.num_inputs = 2;
19821	spec->autocfg.inputs[0].pin = 0x18;
19822	spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19823	spec->autocfg.inputs[1].pin = 0x19;
19824	spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
19825	spec->automute = 1;
19826	spec->automute_mode = ALC_AUTOMUTE_AMP;
19827}
19828
19829static void alc680_unsol_event(struct hda_codec *codec,
19830					   unsigned int res)
19831{
19832	if ((res >> 26) == ALC880_HP_EVENT)
19833		alc_hp_automute(codec);
19834	if ((res >> 26) == ALC880_MIC_EVENT)
19835		alc680_rec_autoswitch(codec);
19836}
19837
19838static void alc680_inithook(struct hda_codec *codec)
19839{
19840	alc_hp_automute(codec);
19841	alc680_rec_autoswitch(codec);
19842}
19843
19844/* create input playback/capture controls for the given pin */
19845static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19846				    const char *ctlname, int idx)
19847{
19848	hda_nid_t dac;
19849	int err;
19850
19851	switch (nid) {
19852	case 0x14:
19853		dac = 0x02;
19854		break;
19855	case 0x15:
19856		dac = 0x03;
19857		break;
19858	case 0x16:
19859		dac = 0x04;
19860		break;
19861	default:
19862		return 0;
19863	}
19864	if (spec->multiout.dac_nids[0] != dac &&
19865	    spec->multiout.dac_nids[1] != dac) {
19866		err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19867				  HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19868						      HDA_OUTPUT));
19869		if (err < 0)
19870			return err;
19871
19872		err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19873			  HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19874
19875		if (err < 0)
19876			return err;
19877		spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
19878	}
19879
19880	return 0;
19881}
19882
19883/* add playback controls from the parsed DAC table */
19884static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19885					     const struct auto_pin_cfg *cfg)
19886{
19887	hda_nid_t nid;
19888	int err;
19889
19890	spec->multiout.dac_nids = spec->private_dac_nids;
19891
19892	nid = cfg->line_out_pins[0];
19893	if (nid) {
19894		const char *name;
19895		if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19896			name = "Speaker";
19897		else
19898			name = "Front";
19899		err = alc680_new_analog_output(spec, nid, name, 0);
19900		if (err < 0)
19901			return err;
19902	}
19903
19904	nid = cfg->speaker_pins[0];
19905	if (nid) {
19906		err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19907		if (err < 0)
19908			return err;
19909	}
19910	nid = cfg->hp_pins[0];
19911	if (nid) {
19912		err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19913		if (err < 0)
19914			return err;
19915	}
19916
19917	return 0;
19918}
19919
19920static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19921					      hda_nid_t nid, int pin_type)
19922{
19923	alc_set_pin_output(codec, nid, pin_type);
19924}
19925
19926static void alc680_auto_init_multi_out(struct hda_codec *codec)
19927{
19928	struct alc_spec *spec = codec->spec;
19929	hda_nid_t nid = spec->autocfg.line_out_pins[0];
19930	if (nid) {
19931		int pin_type = get_pin_type(spec->autocfg.line_out_type);
19932		alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19933	}
19934}
19935
19936static void alc680_auto_init_hp_out(struct hda_codec *codec)
19937{
19938	struct alc_spec *spec = codec->spec;
19939	hda_nid_t pin;
19940
19941	pin = spec->autocfg.hp_pins[0];
19942	if (pin)
19943		alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19944	pin = spec->autocfg.speaker_pins[0];
19945	if (pin)
19946		alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19947}
19948
19949/* pcm configuration: identical with ALC880 */
19950#define alc680_pcm_analog_playback	alc880_pcm_analog_playback
19951#define alc680_pcm_analog_capture	alc880_pcm_analog_capture
19952#define alc680_pcm_analog_alt_capture	alc880_pcm_analog_alt_capture
19953#define alc680_pcm_digital_playback	alc880_pcm_digital_playback
19954#define alc680_pcm_digital_capture	alc880_pcm_digital_capture
19955
19956/*
19957 * BIOS auto configuration
19958 */
19959static int alc680_parse_auto_config(struct hda_codec *codec)
19960{
19961	struct alc_spec *spec = codec->spec;
19962	int err;
19963	static const hda_nid_t alc680_ignore[] = { 0 };
19964
19965	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19966					   alc680_ignore);
19967	if (err < 0)
19968		return err;
19969
19970	if (!spec->autocfg.line_outs) {
19971		if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19972			spec->multiout.max_channels = 2;
19973			spec->no_analog = 1;
19974			goto dig_only;
19975		}
19976		return 0; /* can't find valid BIOS pin config */
19977	}
19978	err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19979	if (err < 0)
19980		return err;
19981
19982	spec->multiout.max_channels = 2;
19983
19984 dig_only:
19985	/* digital only support output */
19986	alc_auto_parse_digital(codec);
19987	if (spec->kctls.list)
19988		add_mixer(spec, spec->kctls.list);
19989
19990	add_verb(spec, alc680_init_verbs);
19991
19992	err = alc_auto_add_mic_boost(codec);
19993	if (err < 0)
19994		return err;
19995
19996	return 1;
19997}
19998
19999#define alc680_auto_init_analog_input	alc882_auto_init_analog_input
20000
20001/* init callback for auto-configuration model -- overriding the default init */
20002static void alc680_auto_init(struct hda_codec *codec)
20003{
20004	struct alc_spec *spec = codec->spec;
20005	alc680_auto_init_multi_out(codec);
20006	alc680_auto_init_hp_out(codec);
20007	alc680_auto_init_analog_input(codec);
20008	alc_auto_init_digital(codec);
20009	if (spec->unsol_event)
20010		alc_inithook(codec);
20011}
20012
20013/*
20014 * configuration and preset
20015 */
20016static const char * const alc680_models[ALC680_MODEL_LAST] = {
20017	[ALC680_BASE]		= "base",
20018	[ALC680_AUTO]		= "auto",
20019};
20020
20021static const struct snd_pci_quirk alc680_cfg_tbl[] = {
20022	SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
20023	{}
20024};
20025
20026static const struct alc_config_preset alc680_presets[] = {
20027	[ALC680_BASE] = {
20028		.mixers = { alc680_base_mixer },
20029		.cap_mixer =  alc680_master_capture_mixer,
20030		.init_verbs = { alc680_init_verbs },
20031		.num_dacs = ARRAY_SIZE(alc680_dac_nids),
20032		.dac_nids = alc680_dac_nids,
20033		.dig_out_nid = ALC680_DIGOUT_NID,
20034		.num_channel_mode = ARRAY_SIZE(alc680_modes),
20035		.channel_mode = alc680_modes,
20036		.unsol_event = alc680_unsol_event,
20037		.setup = alc680_base_setup,
20038		.init_hook = alc680_inithook,
20039
20040	},
20041};
20042
20043static int patch_alc680(struct hda_codec *codec)
20044{
20045	struct alc_spec *spec;
20046	int board_config;
20047	int err;
20048
20049	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
20050	if (spec == NULL)
20051		return -ENOMEM;
20052
20053	codec->spec = spec;
20054
20055	board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
20056						  alc680_models,
20057						  alc680_cfg_tbl);
20058
20059	if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
20060		printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
20061		       codec->chip_name);
20062		board_config = ALC680_AUTO;
20063	}
20064
20065	if (board_config == ALC680_AUTO) {
20066		/* automatic parse from the BIOS config */
20067		err = alc680_parse_auto_config(codec);
20068		if (err < 0) {
20069			alc_free(codec);
20070			return err;
20071		} else if (!err) {
20072			printk(KERN_INFO
20073			       "hda_codec: Cannot set up configuration "
20074			       "from BIOS.  Using base mode...\n");
20075			board_config = ALC680_BASE;
20076		}
20077	}
20078
20079	if (board_config != ALC680_AUTO)
20080		setup_preset(codec, &alc680_presets[board_config]);
20081
20082	spec->stream_analog_playback = &alc680_pcm_analog_playback;
20083	spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
20084	spec->stream_digital_playback = &alc680_pcm_digital_playback;
20085	spec->stream_digital_capture = &alc680_pcm_digital_capture;
20086
20087	if (!spec->adc_nids) {
20088		spec->adc_nids = alc680_adc_nids;
20089		spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
20090	}
20091
20092	if (!spec->cap_mixer)
20093		set_capture_mixer(codec);
20094
20095	spec->vmaster_nid = 0x02;
20096
20097	codec->patch_ops = alc_patch_ops;
20098	if (board_config == ALC680_AUTO)
20099		spec->init_hook = alc680_auto_init;
20100
20101	return 0;
20102}
20103
20104/*
20105 * patch entries
20106 */
20107static const struct hda_codec_preset snd_hda_preset_realtek[] = {
20108	{ .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
20109	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
20110	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
20111	{ .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
20112	{ .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
20113	{ .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
20114	{ .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
20115	{ .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
20116	{ .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
20117	{ .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
20118	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
20119	  .patch = patch_alc861 },
20120	{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
20121	{ .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
20122	{ .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
20123	{ .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
20124	  .patch = patch_alc882 },
20125	{ .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
20126	  .patch = patch_alc662 },
20127	{ .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
20128	{ .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
20129	{ .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
20130	{ .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
20131	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
20132	{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
20133	{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
20134	{ .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
20135	  .patch = patch_alc882 },
20136	{ .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
20137	  .patch = patch_alc882 },
20138	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
20139	{ .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
20140	{ .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
20141	  .patch = patch_alc882 },
20142	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
20143	{ .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
20144	{ .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
20145	{ .id = 0x10ec0899, .name = "ALC899", .patch = patch_alc899 },
20146	{} /* terminator */
20147};
20148
20149MODULE_ALIAS("snd-hda-codec-id:10ec*");
20150
20151MODULE_LICENSE("GPL");
20152MODULE_DESCRIPTION("Realtek HD-audio codec");
20153
20154static struct hda_codec_preset_list realtek_list = {
20155	.preset = snd_hda_preset_realtek,
20156	.owner = THIS_MODULE,
20157};
20158
20159static int __init patch_realtek_init(void)
20160{
20161	return snd_hda_add_codec_preset(&realtek_list);
20162}
20163
20164static void __exit patch_realtek_exit(void)
20165{
20166	snd_hda_delete_codec_preset(&realtek_list);
20167}
20168
20169module_init(patch_realtek_init)
20170module_exit(patch_realtek_exit)
20171