patch_realtek.c revision 4953550a6ca399b644ef057626617465d8be9a7b
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 "hda_codec.h"
32#include "hda_local.h"
33#include "hda_beep.h"
34
35#define ALC880_FRONT_EVENT		0x01
36#define ALC880_DCVOL_EVENT		0x02
37#define ALC880_HP_EVENT			0x04
38#define ALC880_MIC_EVENT		0x08
39
40/* ALC880 board config type */
41enum {
42	ALC880_3ST,
43	ALC880_3ST_DIG,
44	ALC880_5ST,
45	ALC880_5ST_DIG,
46	ALC880_W810,
47	ALC880_Z71V,
48	ALC880_6ST,
49	ALC880_6ST_DIG,
50	ALC880_F1734,
51	ALC880_ASUS,
52	ALC880_ASUS_DIG,
53	ALC880_ASUS_W1V,
54	ALC880_ASUS_DIG2,
55	ALC880_FUJITSU,
56	ALC880_UNIWILL_DIG,
57	ALC880_UNIWILL,
58	ALC880_UNIWILL_P53,
59	ALC880_CLEVO,
60	ALC880_TCL_S700,
61	ALC880_LG,
62	ALC880_LG_LW,
63	ALC880_MEDION_RIM,
64#ifdef CONFIG_SND_DEBUG
65	ALC880_TEST,
66#endif
67	ALC880_AUTO,
68	ALC880_MODEL_LAST /* last tag */
69};
70
71/* ALC260 models */
72enum {
73	ALC260_BASIC,
74	ALC260_HP,
75	ALC260_HP_DC7600,
76	ALC260_HP_3013,
77	ALC260_FUJITSU_S702X,
78	ALC260_ACER,
79	ALC260_WILL,
80	ALC260_REPLACER_672V,
81	ALC260_FAVORIT100,
82#ifdef CONFIG_SND_DEBUG
83	ALC260_TEST,
84#endif
85	ALC260_AUTO,
86	ALC260_MODEL_LAST /* last tag */
87};
88
89/* ALC262 models */
90enum {
91	ALC262_BASIC,
92	ALC262_HIPPO,
93	ALC262_HIPPO_1,
94	ALC262_FUJITSU,
95	ALC262_HP_BPC,
96	ALC262_HP_BPC_D7000_WL,
97	ALC262_HP_BPC_D7000_WF,
98	ALC262_HP_TC_T5735,
99	ALC262_HP_RP5700,
100	ALC262_BENQ_ED8,
101	ALC262_SONY_ASSAMD,
102	ALC262_BENQ_T31,
103	ALC262_ULTRA,
104	ALC262_LENOVO_3000,
105	ALC262_NEC,
106	ALC262_TOSHIBA_S06,
107	ALC262_TOSHIBA_RX1,
108	ALC262_TYAN,
109	ALC262_AUTO,
110	ALC262_MODEL_LAST /* last tag */
111};
112
113/* ALC268 models */
114enum {
115	ALC267_QUANTA_IL1,
116	ALC268_3ST,
117	ALC268_TOSHIBA,
118	ALC268_ACER,
119	ALC268_ACER_DMIC,
120	ALC268_ACER_ASPIRE_ONE,
121	ALC268_DELL,
122	ALC268_ZEPTO,
123#ifdef CONFIG_SND_DEBUG
124	ALC268_TEST,
125#endif
126	ALC268_AUTO,
127	ALC268_MODEL_LAST /* last tag */
128};
129
130/* ALC269 models */
131enum {
132	ALC269_BASIC,
133	ALC269_QUANTA_FL1,
134	ALC269_ASUS_EEEPC_P703,
135	ALC269_ASUS_EEEPC_P901,
136	ALC269_FUJITSU,
137	ALC269_LIFEBOOK,
138	ALC269_AUTO,
139	ALC269_MODEL_LAST /* last tag */
140};
141
142/* ALC861 models */
143enum {
144	ALC861_3ST,
145	ALC660_3ST,
146	ALC861_3ST_DIG,
147	ALC861_6ST_DIG,
148	ALC861_UNIWILL_M31,
149	ALC861_TOSHIBA,
150	ALC861_ASUS,
151	ALC861_ASUS_LAPTOP,
152	ALC861_AUTO,
153	ALC861_MODEL_LAST,
154};
155
156/* ALC861-VD models */
157enum {
158	ALC660VD_3ST,
159	ALC660VD_3ST_DIG,
160	ALC660VD_ASUS_V1S,
161	ALC861VD_3ST,
162	ALC861VD_3ST_DIG,
163	ALC861VD_6ST_DIG,
164	ALC861VD_LENOVO,
165	ALC861VD_DALLAS,
166	ALC861VD_HP,
167	ALC861VD_AUTO,
168	ALC861VD_MODEL_LAST,
169};
170
171/* ALC662 models */
172enum {
173	ALC662_3ST_2ch_DIG,
174	ALC662_3ST_6ch_DIG,
175	ALC662_3ST_6ch,
176	ALC662_5ST_DIG,
177	ALC662_LENOVO_101E,
178	ALC662_ASUS_EEEPC_P701,
179	ALC662_ASUS_EEEPC_EP20,
180	ALC663_ASUS_M51VA,
181	ALC663_ASUS_G71V,
182	ALC663_ASUS_H13,
183	ALC663_ASUS_G50V,
184	ALC662_ECS,
185	ALC663_ASUS_MODE1,
186	ALC662_ASUS_MODE2,
187	ALC663_ASUS_MODE3,
188	ALC663_ASUS_MODE4,
189	ALC663_ASUS_MODE5,
190	ALC663_ASUS_MODE6,
191	ALC272_DELL,
192	ALC272_DELL_ZM1,
193	ALC272_SAMSUNG_NC10,
194	ALC662_AUTO,
195	ALC662_MODEL_LAST,
196};
197
198/* ALC882 models */
199enum {
200	ALC882_3ST_DIG,
201	ALC882_6ST_DIG,
202	ALC882_ARIMA,
203	ALC882_W2JC,
204	ALC882_TARGA,
205	ALC882_ASUS_A7J,
206	ALC882_ASUS_A7M,
207	ALC885_MACPRO,
208	ALC885_MBP3,
209	ALC885_MB5,
210	ALC885_IMAC24,
211	ALC883_3ST_2ch_DIG,
212	ALC883_3ST_6ch_DIG,
213	ALC883_3ST_6ch,
214	ALC883_6ST_DIG,
215	ALC883_TARGA_DIG,
216	ALC883_TARGA_2ch_DIG,
217	ALC883_TARGA_8ch_DIG,
218	ALC883_ACER,
219	ALC883_ACER_ASPIRE,
220	ALC888_ACER_ASPIRE_4930G,
221	ALC888_ACER_ASPIRE_6530G,
222	ALC888_ACER_ASPIRE_8930G,
223	ALC883_MEDION,
224	ALC883_MEDION_MD2,
225	ALC883_LAPTOP_EAPD,
226	ALC883_LENOVO_101E_2ch,
227	ALC883_LENOVO_NB0763,
228	ALC888_LENOVO_MS7195_DIG,
229	ALC888_LENOVO_SKY,
230	ALC883_HAIER_W66,
231	ALC888_3ST_HP,
232	ALC888_6ST_DELL,
233	ALC883_MITAC,
234	ALC883_CLEVO_M720,
235	ALC883_FUJITSU_PI2515,
236	ALC888_FUJITSU_XA3530,
237	ALC883_3ST_6ch_INTEL,
238	ALC888_ASUS_M90V,
239	ALC888_ASUS_EEE1601,
240	ALC889A_MB31,
241	ALC1200_ASUS_P5Q,
242	ALC883_SONY_VAIO_TT,
243	ALC882_AUTO,
244	ALC882_MODEL_LAST,
245};
246
247/* for GPIO Poll */
248#define GPIO_MASK	0x03
249
250/* extra amp-initialization sequence types */
251enum {
252	ALC_INIT_NONE,
253	ALC_INIT_DEFAULT,
254	ALC_INIT_GPIO1,
255	ALC_INIT_GPIO2,
256	ALC_INIT_GPIO3,
257};
258
259struct alc_spec {
260	/* codec parameterization */
261	struct snd_kcontrol_new *mixers[5];	/* mixer arrays */
262	unsigned int num_mixers;
263	struct snd_kcontrol_new *cap_mixer;	/* capture mixer */
264	unsigned int beep_amp;	/* beep amp value, set via set_beep_amp() */
265
266	const struct hda_verb *init_verbs[5];	/* initialization verbs
267						 * don't forget NULL
268						 * termination!
269						 */
270	unsigned int num_init_verbs;
271
272	char stream_name_analog[16];	/* analog PCM stream */
273	struct hda_pcm_stream *stream_analog_playback;
274	struct hda_pcm_stream *stream_analog_capture;
275	struct hda_pcm_stream *stream_analog_alt_playback;
276	struct hda_pcm_stream *stream_analog_alt_capture;
277
278	char stream_name_digital[16];	/* digital PCM stream */
279	struct hda_pcm_stream *stream_digital_playback;
280	struct hda_pcm_stream *stream_digital_capture;
281
282	/* playback */
283	struct hda_multi_out multiout;	/* playback set-up
284					 * max_channels, dacs must be set
285					 * dig_out_nid and hp_nid are optional
286					 */
287	hda_nid_t alt_dac_nid;
288	hda_nid_t slave_dig_outs[3];	/* optional - for auto-parsing */
289	int dig_out_type;
290
291	/* capture */
292	unsigned int num_adc_nids;
293	hda_nid_t *adc_nids;
294	hda_nid_t *capsrc_nids;
295	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
296
297	/* capture source */
298	unsigned int num_mux_defs;
299	const struct hda_input_mux *input_mux;
300	unsigned int cur_mux[3];
301
302	/* channel model */
303	const struct hda_channel_mode *channel_mode;
304	int num_channel_mode;
305	int need_dac_fix;
306	int const_channel_count;
307	int ext_channel_count;
308
309	/* PCM information */
310	struct hda_pcm pcm_rec[3];	/* used in alc_build_pcms() */
311
312	/* dynamic controls, init_verbs and input_mux */
313	struct auto_pin_cfg autocfg;
314	struct snd_array kctls;
315	struct hda_input_mux private_imux[3];
316	hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
317	hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
318	hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
319
320	/* hooks */
321	void (*init_hook)(struct hda_codec *codec);
322	void (*unsol_event)(struct hda_codec *codec, unsigned int res);
323
324	/* for pin sensing */
325	unsigned int sense_updated: 1;
326	unsigned int jack_present: 1;
327	unsigned int master_sw: 1;
328
329	/* other flags */
330	unsigned int no_analog :1; /* digital I/O only */
331	int init_amp;
332
333	/* for virtual master */
334	hda_nid_t vmaster_nid;
335#ifdef CONFIG_SND_HDA_POWER_SAVE
336	struct hda_loopback_check loopback;
337#endif
338
339	/* for PLL fix */
340	hda_nid_t pll_nid;
341	unsigned int pll_coef_idx, pll_coef_bit;
342};
343
344/*
345 * configuration template - to be copied to the spec instance
346 */
347struct alc_config_preset {
348	struct snd_kcontrol_new *mixers[5]; /* should be identical size
349					     * with spec
350					     */
351	struct snd_kcontrol_new *cap_mixer; /* capture mixer */
352	const struct hda_verb *init_verbs[5];
353	unsigned int num_dacs;
354	hda_nid_t *dac_nids;
355	hda_nid_t dig_out_nid;		/* optional */
356	hda_nid_t hp_nid;		/* optional */
357	hda_nid_t *slave_dig_outs;
358	unsigned int num_adc_nids;
359	hda_nid_t *adc_nids;
360	hda_nid_t *capsrc_nids;
361	hda_nid_t dig_in_nid;
362	unsigned int num_channel_mode;
363	const struct hda_channel_mode *channel_mode;
364	int need_dac_fix;
365	int const_channel_count;
366	unsigned int num_mux_defs;
367	const struct hda_input_mux *input_mux;
368	void (*unsol_event)(struct hda_codec *, unsigned int);
369	void (*init_hook)(struct hda_codec *);
370#ifdef CONFIG_SND_HDA_POWER_SAVE
371	struct hda_amp_list *loopbacks;
372#endif
373};
374
375
376/*
377 * input MUX handling
378 */
379static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
380			     struct snd_ctl_elem_info *uinfo)
381{
382	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
383	struct alc_spec *spec = codec->spec;
384	unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
385	if (mux_idx >= spec->num_mux_defs)
386		mux_idx = 0;
387	return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
388}
389
390static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
391			    struct snd_ctl_elem_value *ucontrol)
392{
393	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
394	struct alc_spec *spec = codec->spec;
395	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
396
397	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
398	return 0;
399}
400
401static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
402			    struct snd_ctl_elem_value *ucontrol)
403{
404	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
405	struct alc_spec *spec = codec->spec;
406	const struct hda_input_mux *imux;
407	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
408	unsigned int mux_idx;
409	hda_nid_t nid = spec->capsrc_nids ?
410		spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
411	unsigned int type;
412
413	mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
414	imux = &spec->input_mux[mux_idx];
415
416	type = (get_wcaps(codec, nid) & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
417	if (type == AC_WID_AUD_MIX) {
418		/* Matrix-mixer style (e.g. ALC882) */
419		unsigned int *cur_val = &spec->cur_mux[adc_idx];
420		unsigned int i, idx;
421
422		idx = ucontrol->value.enumerated.item[0];
423		if (idx >= imux->num_items)
424			idx = imux->num_items - 1;
425		if (*cur_val == idx)
426			return 0;
427		for (i = 0; i < imux->num_items; i++) {
428			unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
429			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
430						 imux->items[i].index,
431						 HDA_AMP_MUTE, v);
432		}
433		*cur_val = idx;
434		return 1;
435	} else {
436		/* MUX style (e.g. ALC880) */
437		return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
438					     &spec->cur_mux[adc_idx]);
439	}
440}
441
442/*
443 * channel mode setting
444 */
445static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
446			    struct snd_ctl_elem_info *uinfo)
447{
448	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
449	struct alc_spec *spec = codec->spec;
450	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
451				    spec->num_channel_mode);
452}
453
454static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
455			   struct snd_ctl_elem_value *ucontrol)
456{
457	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
458	struct alc_spec *spec = codec->spec;
459	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
460				   spec->num_channel_mode,
461				   spec->ext_channel_count);
462}
463
464static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
465			   struct snd_ctl_elem_value *ucontrol)
466{
467	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
468	struct alc_spec *spec = codec->spec;
469	int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
470				      spec->num_channel_mode,
471				      &spec->ext_channel_count);
472	if (err >= 0 && !spec->const_channel_count) {
473		spec->multiout.max_channels = spec->ext_channel_count;
474		if (spec->need_dac_fix)
475			spec->multiout.num_dacs = spec->multiout.max_channels / 2;
476	}
477	return err;
478}
479
480/*
481 * Control the mode of pin widget settings via the mixer.  "pc" is used
482 * instead of "%" to avoid consequences of accidently treating the % as
483 * being part of a format specifier.  Maximum allowed length of a value is
484 * 63 characters plus NULL terminator.
485 *
486 * Note: some retasking pin complexes seem to ignore requests for input
487 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
488 * are requested.  Therefore order this list so that this behaviour will not
489 * cause problems when mixer clients move through the enum sequentially.
490 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
491 * March 2006.
492 */
493static char *alc_pin_mode_names[] = {
494	"Mic 50pc bias", "Mic 80pc bias",
495	"Line in", "Line out", "Headphone out",
496};
497static unsigned char alc_pin_mode_values[] = {
498	PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
499};
500/* The control can present all 5 options, or it can limit the options based
501 * in the pin being assumed to be exclusively an input or an output pin.  In
502 * addition, "input" pins may or may not process the mic bias option
503 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
504 * accept requests for bias as of chip versions up to March 2006) and/or
505 * wiring in the computer.
506 */
507#define ALC_PIN_DIR_IN              0x00
508#define ALC_PIN_DIR_OUT             0x01
509#define ALC_PIN_DIR_INOUT           0x02
510#define ALC_PIN_DIR_IN_NOMICBIAS    0x03
511#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
512
513/* Info about the pin modes supported by the different pin direction modes.
514 * For each direction the minimum and maximum values are given.
515 */
516static signed char alc_pin_mode_dir_info[5][2] = {
517	{ 0, 2 },    /* ALC_PIN_DIR_IN */
518	{ 3, 4 },    /* ALC_PIN_DIR_OUT */
519	{ 0, 4 },    /* ALC_PIN_DIR_INOUT */
520	{ 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
521	{ 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
522};
523#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
524#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
525#define alc_pin_mode_n_items(_dir) \
526	(alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
527
528static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
529			     struct snd_ctl_elem_info *uinfo)
530{
531	unsigned int item_num = uinfo->value.enumerated.item;
532	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
533
534	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
535	uinfo->count = 1;
536	uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
537
538	if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
539		item_num = alc_pin_mode_min(dir);
540	strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
541	return 0;
542}
543
544static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
545			    struct snd_ctl_elem_value *ucontrol)
546{
547	unsigned int i;
548	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
549	hda_nid_t nid = kcontrol->private_value & 0xffff;
550	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
551	long *valp = ucontrol->value.integer.value;
552	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
553						 AC_VERB_GET_PIN_WIDGET_CONTROL,
554						 0x00);
555
556	/* Find enumerated value for current pinctl setting */
557	i = alc_pin_mode_min(dir);
558	while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
559		i++;
560	*valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
561	return 0;
562}
563
564static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
565			    struct snd_ctl_elem_value *ucontrol)
566{
567	signed int change;
568	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
569	hda_nid_t nid = kcontrol->private_value & 0xffff;
570	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
571	long val = *ucontrol->value.integer.value;
572	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
573						 AC_VERB_GET_PIN_WIDGET_CONTROL,
574						 0x00);
575
576	if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
577		val = alc_pin_mode_min(dir);
578
579	change = pinctl != alc_pin_mode_values[val];
580	if (change) {
581		/* Set pin mode to that requested */
582		snd_hda_codec_write_cache(codec, nid, 0,
583					  AC_VERB_SET_PIN_WIDGET_CONTROL,
584					  alc_pin_mode_values[val]);
585
586		/* Also enable the retasking pin's input/output as required
587		 * for the requested pin mode.  Enum values of 2 or less are
588		 * input modes.
589		 *
590		 * Dynamically switching the input/output buffers probably
591		 * reduces noise slightly (particularly on input) so we'll
592		 * do it.  However, having both input and output buffers
593		 * enabled simultaneously doesn't seem to be problematic if
594		 * this turns out to be necessary in the future.
595		 */
596		if (val <= 2) {
597			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
598						 HDA_AMP_MUTE, HDA_AMP_MUTE);
599			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
600						 HDA_AMP_MUTE, 0);
601		} else {
602			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
603						 HDA_AMP_MUTE, HDA_AMP_MUTE);
604			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
605						 HDA_AMP_MUTE, 0);
606		}
607	}
608	return change;
609}
610
611#define ALC_PIN_MODE(xname, nid, dir) \
612	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
613	  .info = alc_pin_mode_info, \
614	  .get = alc_pin_mode_get, \
615	  .put = alc_pin_mode_put, \
616	  .private_value = nid | (dir<<16) }
617
618/* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
619 * together using a mask with more than one bit set.  This control is
620 * currently used only by the ALC260 test model.  At this stage they are not
621 * needed for any "production" models.
622 */
623#ifdef CONFIG_SND_DEBUG
624#define alc_gpio_data_info	snd_ctl_boolean_mono_info
625
626static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
627			     struct snd_ctl_elem_value *ucontrol)
628{
629	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
630	hda_nid_t nid = kcontrol->private_value & 0xffff;
631	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
632	long *valp = ucontrol->value.integer.value;
633	unsigned int val = snd_hda_codec_read(codec, nid, 0,
634					      AC_VERB_GET_GPIO_DATA, 0x00);
635
636	*valp = (val & mask) != 0;
637	return 0;
638}
639static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
640			     struct snd_ctl_elem_value *ucontrol)
641{
642	signed int change;
643	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
644	hda_nid_t nid = kcontrol->private_value & 0xffff;
645	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
646	long val = *ucontrol->value.integer.value;
647	unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
648						    AC_VERB_GET_GPIO_DATA,
649						    0x00);
650
651	/* Set/unset the masked GPIO bit(s) as needed */
652	change = (val == 0 ? 0 : mask) != (gpio_data & mask);
653	if (val == 0)
654		gpio_data &= ~mask;
655	else
656		gpio_data |= mask;
657	snd_hda_codec_write_cache(codec, nid, 0,
658				  AC_VERB_SET_GPIO_DATA, gpio_data);
659
660	return change;
661}
662#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
663	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
664	  .info = alc_gpio_data_info, \
665	  .get = alc_gpio_data_get, \
666	  .put = alc_gpio_data_put, \
667	  .private_value = nid | (mask<<16) }
668#endif   /* CONFIG_SND_DEBUG */
669
670/* A switch control to allow the enabling of the digital IO pins on the
671 * ALC260.  This is incredibly simplistic; the intention of this control is
672 * to provide something in the test model allowing digital outputs to be
673 * identified if present.  If models are found which can utilise these
674 * outputs a more complete mixer control can be devised for those models if
675 * necessary.
676 */
677#ifdef CONFIG_SND_DEBUG
678#define alc_spdif_ctrl_info	snd_ctl_boolean_mono_info
679
680static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
681			      struct snd_ctl_elem_value *ucontrol)
682{
683	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
684	hda_nid_t nid = kcontrol->private_value & 0xffff;
685	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
686	long *valp = ucontrol->value.integer.value;
687	unsigned int val = snd_hda_codec_read(codec, nid, 0,
688					      AC_VERB_GET_DIGI_CONVERT_1, 0x00);
689
690	*valp = (val & mask) != 0;
691	return 0;
692}
693static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
694			      struct snd_ctl_elem_value *ucontrol)
695{
696	signed int change;
697	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
698	hda_nid_t nid = kcontrol->private_value & 0xffff;
699	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
700	long val = *ucontrol->value.integer.value;
701	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
702						    AC_VERB_GET_DIGI_CONVERT_1,
703						    0x00);
704
705	/* Set/unset the masked control bit(s) as needed */
706	change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
707	if (val==0)
708		ctrl_data &= ~mask;
709	else
710		ctrl_data |= mask;
711	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
712				  ctrl_data);
713
714	return change;
715}
716#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
717	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
718	  .info = alc_spdif_ctrl_info, \
719	  .get = alc_spdif_ctrl_get, \
720	  .put = alc_spdif_ctrl_put, \
721	  .private_value = nid | (mask<<16) }
722#endif   /* CONFIG_SND_DEBUG */
723
724/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
725 * Again, this is only used in the ALC26x test models to help identify when
726 * the EAPD line must be asserted for features to work.
727 */
728#ifdef CONFIG_SND_DEBUG
729#define alc_eapd_ctrl_info	snd_ctl_boolean_mono_info
730
731static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
732			      struct snd_ctl_elem_value *ucontrol)
733{
734	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
735	hda_nid_t nid = kcontrol->private_value & 0xffff;
736	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
737	long *valp = ucontrol->value.integer.value;
738	unsigned int val = snd_hda_codec_read(codec, nid, 0,
739					      AC_VERB_GET_EAPD_BTLENABLE, 0x00);
740
741	*valp = (val & mask) != 0;
742	return 0;
743}
744
745static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
746			      struct snd_ctl_elem_value *ucontrol)
747{
748	int change;
749	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
750	hda_nid_t nid = kcontrol->private_value & 0xffff;
751	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
752	long val = *ucontrol->value.integer.value;
753	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
754						    AC_VERB_GET_EAPD_BTLENABLE,
755						    0x00);
756
757	/* Set/unset the masked control bit(s) as needed */
758	change = (!val ? 0 : mask) != (ctrl_data & mask);
759	if (!val)
760		ctrl_data &= ~mask;
761	else
762		ctrl_data |= mask;
763	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
764				  ctrl_data);
765
766	return change;
767}
768
769#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
770	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
771	  .info = alc_eapd_ctrl_info, \
772	  .get = alc_eapd_ctrl_get, \
773	  .put = alc_eapd_ctrl_put, \
774	  .private_value = nid | (mask<<16) }
775#endif   /* CONFIG_SND_DEBUG */
776
777/*
778 * set up the input pin config (depending on the given auto-pin type)
779 */
780static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
781			      int auto_pin_type)
782{
783	unsigned int val = PIN_IN;
784
785	if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
786		unsigned int pincap;
787		pincap = snd_hda_query_pin_caps(codec, nid);
788		pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
789		if (pincap & AC_PINCAP_VREF_80)
790			val = PIN_VREF80;
791		else if (pincap & AC_PINCAP_VREF_50)
792			val = PIN_VREF50;
793		else if (pincap & AC_PINCAP_VREF_100)
794			val = PIN_VREF100;
795		else if (pincap & AC_PINCAP_VREF_GRD)
796			val = PIN_VREFGRD;
797	}
798	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
799}
800
801/*
802 */
803static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
804{
805	if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
806		return;
807	spec->mixers[spec->num_mixers++] = mix;
808}
809
810static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
811{
812	if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
813		return;
814	spec->init_verbs[spec->num_init_verbs++] = verb;
815}
816
817#ifdef CONFIG_PROC_FS
818/*
819 * hook for proc
820 */
821static void print_realtek_coef(struct snd_info_buffer *buffer,
822			       struct hda_codec *codec, hda_nid_t nid)
823{
824	int coeff;
825
826	if (nid != 0x20)
827		return;
828	coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
829	snd_iprintf(buffer, "  Processing Coefficient: 0x%02x\n", coeff);
830	coeff = snd_hda_codec_read(codec, nid, 0,
831				   AC_VERB_GET_COEF_INDEX, 0);
832	snd_iprintf(buffer, "  Coefficient Index: 0x%02x\n", coeff);
833}
834#else
835#define print_realtek_coef	NULL
836#endif
837
838/*
839 * set up from the preset table
840 */
841static void setup_preset(struct alc_spec *spec,
842			 const struct alc_config_preset *preset)
843{
844	int i;
845
846	for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
847		add_mixer(spec, preset->mixers[i]);
848	spec->cap_mixer = preset->cap_mixer;
849	for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
850	     i++)
851		add_verb(spec, preset->init_verbs[i]);
852
853	spec->channel_mode = preset->channel_mode;
854	spec->num_channel_mode = preset->num_channel_mode;
855	spec->need_dac_fix = preset->need_dac_fix;
856	spec->const_channel_count = preset->const_channel_count;
857
858	if (preset->const_channel_count)
859		spec->multiout.max_channels = preset->const_channel_count;
860	else
861		spec->multiout.max_channels = spec->channel_mode[0].channels;
862	spec->ext_channel_count = spec->channel_mode[0].channels;
863
864	spec->multiout.num_dacs = preset->num_dacs;
865	spec->multiout.dac_nids = preset->dac_nids;
866	spec->multiout.dig_out_nid = preset->dig_out_nid;
867	spec->multiout.slave_dig_outs = preset->slave_dig_outs;
868	spec->multiout.hp_nid = preset->hp_nid;
869
870	spec->num_mux_defs = preset->num_mux_defs;
871	if (!spec->num_mux_defs)
872		spec->num_mux_defs = 1;
873	spec->input_mux = preset->input_mux;
874
875	spec->num_adc_nids = preset->num_adc_nids;
876	spec->adc_nids = preset->adc_nids;
877	spec->capsrc_nids = preset->capsrc_nids;
878	spec->dig_in_nid = preset->dig_in_nid;
879
880	spec->unsol_event = preset->unsol_event;
881	spec->init_hook = preset->init_hook;
882#ifdef CONFIG_SND_HDA_POWER_SAVE
883	spec->loopback.amplist = preset->loopbacks;
884#endif
885}
886
887/* Enable GPIO mask and set output */
888static struct hda_verb alc_gpio1_init_verbs[] = {
889	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
890	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
891	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
892	{ }
893};
894
895static struct hda_verb alc_gpio2_init_verbs[] = {
896	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
897	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
898	{0x01, AC_VERB_SET_GPIO_DATA, 0x02},
899	{ }
900};
901
902static struct hda_verb alc_gpio3_init_verbs[] = {
903	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
904	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
905	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
906	{ }
907};
908
909/*
910 * Fix hardware PLL issue
911 * On some codecs, the analog PLL gating control must be off while
912 * the default value is 1.
913 */
914static void alc_fix_pll(struct hda_codec *codec)
915{
916	struct alc_spec *spec = codec->spec;
917	unsigned int val;
918
919	if (!spec->pll_nid)
920		return;
921	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
922			    spec->pll_coef_idx);
923	val = snd_hda_codec_read(codec, spec->pll_nid, 0,
924				 AC_VERB_GET_PROC_COEF, 0);
925	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
926			    spec->pll_coef_idx);
927	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
928			    val & ~(1 << spec->pll_coef_bit));
929}
930
931static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
932			     unsigned int coef_idx, unsigned int coef_bit)
933{
934	struct alc_spec *spec = codec->spec;
935	spec->pll_nid = nid;
936	spec->pll_coef_idx = coef_idx;
937	spec->pll_coef_bit = coef_bit;
938	alc_fix_pll(codec);
939}
940
941static void alc_automute_pin(struct hda_codec *codec)
942{
943	struct alc_spec *spec = codec->spec;
944	unsigned int present, pincap;
945	unsigned int nid = spec->autocfg.hp_pins[0];
946	int i;
947
948	pincap = snd_hda_query_pin_caps(codec, nid);
949	if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
950		snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0);
951	present = snd_hda_codec_read(codec, nid, 0,
952				     AC_VERB_GET_PIN_SENSE, 0);
953	spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
954	for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
955		nid = spec->autocfg.speaker_pins[i];
956		if (!nid)
957			break;
958		snd_hda_codec_write(codec, nid, 0,
959				    AC_VERB_SET_PIN_WIDGET_CONTROL,
960				    spec->jack_present ? 0 : PIN_OUT);
961	}
962}
963
964#if 0 /* it's broken in some cases -- temporarily disabled */
965static void alc_mic_automute(struct hda_codec *codec)
966{
967	struct alc_spec *spec = codec->spec;
968	unsigned int present;
969	unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
970	unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
971	unsigned int mix_nid = spec->capsrc_nids[0];
972	unsigned int capsrc_idx_mic, capsrc_idx_fmic;
973
974	capsrc_idx_mic = mic_nid - 0x18;
975	capsrc_idx_fmic = fmic_nid - 0x18;
976	present = snd_hda_codec_read(codec, mic_nid, 0,
977				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
978	snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
979		    0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
980	snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
981		    0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
982	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
983			 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
984}
985#else
986#define alc_mic_automute(codec) do {} while(0) /* NOP */
987#endif /* disabled */
988
989/* unsolicited event for HP jack sensing */
990static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
991{
992	if (codec->vendor_id == 0x10ec0880)
993		res >>= 28;
994	else
995		res >>= 26;
996	switch (res) {
997	case ALC880_HP_EVENT:
998		alc_automute_pin(codec);
999		break;
1000	case ALC880_MIC_EVENT:
1001		alc_mic_automute(codec);
1002		break;
1003	}
1004}
1005
1006static void alc_inithook(struct hda_codec *codec)
1007{
1008	alc_automute_pin(codec);
1009	alc_mic_automute(codec);
1010}
1011
1012/* additional initialization for ALC888 variants */
1013static void alc888_coef_init(struct hda_codec *codec)
1014{
1015	unsigned int tmp;
1016
1017	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1018	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1019	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1020	if ((tmp & 0xf0) == 0x20)
1021		/* alc888S-VC */
1022		snd_hda_codec_read(codec, 0x20, 0,
1023				   AC_VERB_SET_PROC_COEF, 0x830);
1024	 else
1025		 /* alc888-VB */
1026		 snd_hda_codec_read(codec, 0x20, 0,
1027				    AC_VERB_SET_PROC_COEF, 0x3030);
1028}
1029
1030static void alc_auto_init_amp(struct hda_codec *codec, int type)
1031{
1032	unsigned int tmp;
1033
1034	switch (type) {
1035	case ALC_INIT_GPIO1:
1036		snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1037		break;
1038	case ALC_INIT_GPIO2:
1039		snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1040		break;
1041	case ALC_INIT_GPIO3:
1042		snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1043		break;
1044	case ALC_INIT_DEFAULT:
1045		switch (codec->vendor_id) {
1046		case 0x10ec0260:
1047			snd_hda_codec_write(codec, 0x0f, 0,
1048					    AC_VERB_SET_EAPD_BTLENABLE, 2);
1049			snd_hda_codec_write(codec, 0x10, 0,
1050					    AC_VERB_SET_EAPD_BTLENABLE, 2);
1051			break;
1052		case 0x10ec0262:
1053		case 0x10ec0267:
1054		case 0x10ec0268:
1055		case 0x10ec0269:
1056		case 0x10ec0272:
1057		case 0x10ec0660:
1058		case 0x10ec0662:
1059		case 0x10ec0663:
1060		case 0x10ec0862:
1061		case 0x10ec0889:
1062			snd_hda_codec_write(codec, 0x14, 0,
1063					    AC_VERB_SET_EAPD_BTLENABLE, 2);
1064			snd_hda_codec_write(codec, 0x15, 0,
1065					    AC_VERB_SET_EAPD_BTLENABLE, 2);
1066			break;
1067		}
1068		switch (codec->vendor_id) {
1069		case 0x10ec0260:
1070			snd_hda_codec_write(codec, 0x1a, 0,
1071					    AC_VERB_SET_COEF_INDEX, 7);
1072			tmp = snd_hda_codec_read(codec, 0x1a, 0,
1073						 AC_VERB_GET_PROC_COEF, 0);
1074			snd_hda_codec_write(codec, 0x1a, 0,
1075					    AC_VERB_SET_COEF_INDEX, 7);
1076			snd_hda_codec_write(codec, 0x1a, 0,
1077					    AC_VERB_SET_PROC_COEF,
1078					    tmp | 0x2010);
1079			break;
1080		case 0x10ec0262:
1081		case 0x10ec0880:
1082		case 0x10ec0882:
1083		case 0x10ec0883:
1084		case 0x10ec0885:
1085		case 0x10ec0887:
1086		case 0x10ec0889:
1087			snd_hda_codec_write(codec, 0x20, 0,
1088					    AC_VERB_SET_COEF_INDEX, 7);
1089			tmp = snd_hda_codec_read(codec, 0x20, 0,
1090						 AC_VERB_GET_PROC_COEF, 0);
1091			snd_hda_codec_write(codec, 0x20, 0,
1092					    AC_VERB_SET_COEF_INDEX, 7);
1093			snd_hda_codec_write(codec, 0x20, 0,
1094					    AC_VERB_SET_PROC_COEF,
1095					    tmp | 0x2010);
1096			break;
1097		case 0x10ec0888:
1098			alc888_coef_init(codec);
1099			break;
1100		case 0x10ec0267:
1101		case 0x10ec0268:
1102			snd_hda_codec_write(codec, 0x20, 0,
1103					    AC_VERB_SET_COEF_INDEX, 7);
1104			tmp = snd_hda_codec_read(codec, 0x20, 0,
1105						 AC_VERB_GET_PROC_COEF, 0);
1106			snd_hda_codec_write(codec, 0x20, 0,
1107					    AC_VERB_SET_COEF_INDEX, 7);
1108			snd_hda_codec_write(codec, 0x20, 0,
1109					    AC_VERB_SET_PROC_COEF,
1110					    tmp | 0x3000);
1111			break;
1112		}
1113		break;
1114	}
1115}
1116
1117static void alc_init_auto_hp(struct hda_codec *codec)
1118{
1119	struct alc_spec *spec = codec->spec;
1120
1121	if (!spec->autocfg.hp_pins[0])
1122		return;
1123
1124	if (!spec->autocfg.speaker_pins[0]) {
1125		if (spec->autocfg.line_out_pins[0] &&
1126		    spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
1127			spec->autocfg.speaker_pins[0] =
1128				spec->autocfg.line_out_pins[0];
1129		else
1130			return;
1131	}
1132
1133	snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1134		    spec->autocfg.hp_pins[0]);
1135	snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1136				  AC_VERB_SET_UNSOLICITED_ENABLE,
1137				  AC_USRSP_EN | ALC880_HP_EVENT);
1138	spec->unsol_event = alc_sku_unsol_event;
1139}
1140
1141/* check subsystem ID and set up device-specific initialization;
1142 * return 1 if initialized, 0 if invalid SSID
1143 */
1144/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1145 *	31 ~ 16 :	Manufacture ID
1146 *	15 ~ 8	:	SKU ID
1147 *	7  ~ 0	:	Assembly ID
1148 *	port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1149 */
1150static int alc_subsystem_id(struct hda_codec *codec,
1151			    hda_nid_t porta, hda_nid_t porte,
1152			    hda_nid_t portd)
1153{
1154	unsigned int ass, tmp, i;
1155	unsigned nid;
1156	struct alc_spec *spec = codec->spec;
1157
1158	ass = codec->subsystem_id & 0xffff;
1159	if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1160		goto do_sku;
1161
1162	/* invalid SSID, check the special NID pin defcfg instead */
1163	/*
1164	 * 31~30	: port connectivity
1165	 * 29~21	: reserve
1166	 * 20		: PCBEEP input
1167	 * 19~16	: Check sum (15:1)
1168	 * 15~1		: Custom
1169	 * 0		: override
1170	*/
1171	nid = 0x1d;
1172	if (codec->vendor_id == 0x10ec0260)
1173		nid = 0x17;
1174	ass = snd_hda_codec_get_pincfg(codec, nid);
1175	snd_printd("realtek: No valid SSID, "
1176		   "checking pincfg 0x%08x for NID 0x%x\n",
1177		   ass, nid);
1178	if (!(ass & 1) && !(ass & 0x100000))
1179		return 0;
1180	if ((ass >> 30) != 1)	/* no physical connection */
1181		return 0;
1182
1183	/* check sum */
1184	tmp = 0;
1185	for (i = 1; i < 16; i++) {
1186		if ((ass >> i) & 1)
1187			tmp++;
1188	}
1189	if (((ass >> 16) & 0xf) != tmp)
1190		return 0;
1191do_sku:
1192	snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1193		   ass & 0xffff, codec->vendor_id);
1194	/*
1195	 * 0 : override
1196	 * 1 :	Swap Jack
1197	 * 2 : 0 --> Desktop, 1 --> Laptop
1198	 * 3~5 : External Amplifier control
1199	 * 7~6 : Reserved
1200	*/
1201	tmp = (ass & 0x38) >> 3;	/* external Amp control */
1202	switch (tmp) {
1203	case 1:
1204		spec->init_amp = ALC_INIT_GPIO1;
1205		break;
1206	case 3:
1207		spec->init_amp = ALC_INIT_GPIO2;
1208		break;
1209	case 7:
1210		spec->init_amp = ALC_INIT_GPIO3;
1211		break;
1212	case 5:
1213		spec->init_amp = ALC_INIT_DEFAULT;
1214		break;
1215	}
1216
1217	/* is laptop or Desktop and enable the function "Mute internal speaker
1218	 * when the external headphone out jack is plugged"
1219	 */
1220	if (!(ass & 0x8000))
1221		return 1;
1222	/*
1223	 * 10~8 : Jack location
1224	 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1225	 * 14~13: Resvered
1226	 * 15   : 1 --> enable the function "Mute internal speaker
1227	 *	        when the external headphone out jack is plugged"
1228	 */
1229	if (!spec->autocfg.hp_pins[0]) {
1230		tmp = (ass >> 11) & 0x3;	/* HP to chassis */
1231		if (tmp == 0)
1232			spec->autocfg.hp_pins[0] = porta;
1233		else if (tmp == 1)
1234			spec->autocfg.hp_pins[0] = porte;
1235		else if (tmp == 2)
1236			spec->autocfg.hp_pins[0] = portd;
1237		else
1238			return 1;
1239	}
1240
1241	alc_init_auto_hp(codec);
1242	return 1;
1243}
1244
1245static void alc_ssid_check(struct hda_codec *codec,
1246			   hda_nid_t porta, hda_nid_t porte, hda_nid_t portd)
1247{
1248	if (!alc_subsystem_id(codec, porta, porte, portd)) {
1249		struct alc_spec *spec = codec->spec;
1250		snd_printd("realtek: "
1251			   "Enable default setup for auto mode as fallback\n");
1252		spec->init_amp = ALC_INIT_DEFAULT;
1253		alc_init_auto_hp(codec);
1254	}
1255}
1256
1257/*
1258 * Fix-up pin default configurations
1259 */
1260
1261struct alc_pincfg {
1262	hda_nid_t nid;
1263	u32 val;
1264};
1265
1266static void alc_fix_pincfg(struct hda_codec *codec,
1267			   const struct snd_pci_quirk *quirk,
1268			   const struct alc_pincfg **pinfix)
1269{
1270	const struct alc_pincfg *cfg;
1271
1272	quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1273	if (!quirk)
1274		return;
1275
1276	cfg = pinfix[quirk->value];
1277	for (; cfg->nid; cfg++)
1278		snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1279}
1280
1281/*
1282 * ALC888
1283 */
1284
1285/*
1286 * 2ch mode
1287 */
1288static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1289/* Mic-in jack as mic in */
1290	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1291	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1292/* Line-in jack as Line in */
1293	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1294	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1295/* Line-Out as Front */
1296	{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1297	{ } /* end */
1298};
1299
1300/*
1301 * 4ch mode
1302 */
1303static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1304/* Mic-in jack as mic in */
1305	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1306	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1307/* Line-in jack as Surround */
1308	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1309	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1310/* Line-Out as Front */
1311	{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1312	{ } /* end */
1313};
1314
1315/*
1316 * 6ch mode
1317 */
1318static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1319/* Mic-in jack as CLFE */
1320	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1321	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1322/* Line-in jack as Surround */
1323	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1324	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1325/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1326	{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1327	{ } /* end */
1328};
1329
1330/*
1331 * 8ch mode
1332 */
1333static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1334/* Mic-in jack as CLFE */
1335	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1336	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1337/* Line-in jack as Surround */
1338	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1339	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1340/* Line-Out as Side */
1341	{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1342	{ } /* end */
1343};
1344
1345static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1346	{ 2, alc888_4ST_ch2_intel_init },
1347	{ 4, alc888_4ST_ch4_intel_init },
1348	{ 6, alc888_4ST_ch6_intel_init },
1349	{ 8, alc888_4ST_ch8_intel_init },
1350};
1351
1352/*
1353 * ALC888 Fujitsu Siemens Amillo xa3530
1354 */
1355
1356static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1357/* Front Mic: set to PIN_IN (empty by default) */
1358	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1359/* Connect Internal HP to Front */
1360	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1361	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1362	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1363/* Connect Bass HP to Front */
1364	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1365	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1366	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1367/* Connect Line-Out side jack (SPDIF) to Side */
1368	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1369	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1370	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1371/* Connect Mic jack to CLFE */
1372	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1373	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1374	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1375/* Connect Line-in jack to Surround */
1376	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1377	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1378	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1379/* Connect HP out jack to Front */
1380	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1381	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1382	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1383/* Enable unsolicited event for HP jack and Line-out jack */
1384	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1385	{0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1386	{}
1387};
1388
1389static void alc_automute_amp(struct hda_codec *codec)
1390{
1391	struct alc_spec *spec = codec->spec;
1392	unsigned int val, mute, pincap;
1393	hda_nid_t nid;
1394	int i;
1395
1396	spec->jack_present = 0;
1397	for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1398		nid = spec->autocfg.hp_pins[i];
1399		if (!nid)
1400			break;
1401		pincap = snd_hda_query_pin_caps(codec, nid);
1402		if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
1403			snd_hda_codec_read(codec, nid, 0,
1404					   AC_VERB_SET_PIN_SENSE, 0);
1405		val = snd_hda_codec_read(codec, nid, 0,
1406					 AC_VERB_GET_PIN_SENSE, 0);
1407		if (val & AC_PINSENSE_PRESENCE) {
1408			spec->jack_present = 1;
1409			break;
1410		}
1411	}
1412
1413	mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1414	/* Toggle internal speakers muting */
1415	for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1416		nid = spec->autocfg.speaker_pins[i];
1417		if (!nid)
1418			break;
1419		snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1420					 HDA_AMP_MUTE, mute);
1421	}
1422}
1423
1424static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1425					 unsigned int res)
1426{
1427	if (codec->vendor_id == 0x10ec0880)
1428		res >>= 28;
1429	else
1430		res >>= 26;
1431	if (res == ALC880_HP_EVENT)
1432		alc_automute_amp(codec);
1433}
1434
1435static void alc888_fujitsu_xa3530_init_hook(struct hda_codec *codec)
1436{
1437	struct alc_spec *spec = codec->spec;
1438
1439	spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1440	spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1441	spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1442	spec->autocfg.speaker_pins[1] = 0x15; /* bass */
1443	alc_automute_amp(codec);
1444}
1445
1446/*
1447 * ALC888 Acer Aspire 4930G model
1448 */
1449
1450static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1451/* Front Mic: set to PIN_IN (empty by default) */
1452	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1453/* Unselect Front Mic by default in input mixer 3 */
1454	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1455/* Enable unsolicited event for HP jack */
1456	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1457/* Connect Internal HP to front */
1458	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1459	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1460	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1461/* Connect HP out to front */
1462	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1463	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1464	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1465	{ }
1466};
1467
1468/*
1469 * ALC888 Acer Aspire 6530G model
1470 */
1471
1472static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
1473/* Bias voltage on for external mic port */
1474	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
1475/* Front Mic: set to PIN_IN (empty by default) */
1476	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1477/* Unselect Front Mic by default in input mixer 3 */
1478	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1479/* Enable unsolicited event for HP jack */
1480	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1481/* Enable speaker output */
1482	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1483	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1484/* Enable headphone output */
1485	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1486	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1487	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1488	{ }
1489};
1490
1491/*
1492 * ALC889 Acer Aspire 8930G model
1493 */
1494
1495static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
1496/* Front Mic: set to PIN_IN (empty by default) */
1497	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1498/* Unselect Front Mic by default in input mixer 3 */
1499	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1500/* Enable unsolicited event for HP jack */
1501	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1502/* Connect Internal Front to Front */
1503	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1504	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1505	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1506/* Connect Internal Rear to Rear */
1507	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1508	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1509	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
1510/* Connect Internal CLFE to CLFE */
1511	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1512	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1513	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1514/* Connect HP out to Front */
1515	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1516	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1517	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1518/* Enable all DACs */
1519/*  DAC DISABLE/MUTE 1? */
1520/*  setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
1521	{0x20, AC_VERB_SET_COEF_INDEX, 0x03},
1522	{0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1523/*  DAC DISABLE/MUTE 2? */
1524/*  some bit here disables the other DACs. Init=0x4900 */
1525	{0x20, AC_VERB_SET_COEF_INDEX, 0x08},
1526	{0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1527/* Enable amplifiers */
1528	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1529	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1530/* DMIC fix
1531 * This laptop has a stereo digital microphone. The mics are only 1cm apart
1532 * which makes the stereo useless. However, either the mic or the ALC889
1533 * makes the signal become a difference/sum signal instead of standard
1534 * stereo, which is annoying. So instead we flip this bit which makes the
1535 * codec replicate the sum signal to both channels, turning it into a
1536 * normal mono mic.
1537 */
1538/*  DMIC_CONTROL? Init value = 0x0001 */
1539	{0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
1540	{0x20, AC_VERB_SET_PROC_COEF, 0x0003},
1541	{ }
1542};
1543
1544static struct hda_input_mux alc888_2_capture_sources[2] = {
1545	/* Front mic only available on one ADC */
1546	{
1547		.num_items = 4,
1548		.items = {
1549			{ "Mic", 0x0 },
1550			{ "Line", 0x2 },
1551			{ "CD", 0x4 },
1552			{ "Front Mic", 0xb },
1553		},
1554	},
1555	{
1556		.num_items = 3,
1557		.items = {
1558			{ "Mic", 0x0 },
1559			{ "Line", 0x2 },
1560			{ "CD", 0x4 },
1561		},
1562	}
1563};
1564
1565static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
1566	/* Interal mic only available on one ADC */
1567	{
1568		.num_items = 5,
1569		.items = {
1570			{ "Ext Mic", 0x0 },
1571			{ "Line In", 0x2 },
1572			{ "CD", 0x4 },
1573			{ "Input Mix", 0xa },
1574			{ "Int Mic", 0xb },
1575		},
1576	},
1577	{
1578		.num_items = 4,
1579		.items = {
1580			{ "Ext Mic", 0x0 },
1581			{ "Line In", 0x2 },
1582			{ "CD", 0x4 },
1583			{ "Input Mix", 0xa },
1584		},
1585	}
1586};
1587
1588static struct hda_input_mux alc889_capture_sources[3] = {
1589	/* Digital mic only available on first "ADC" */
1590	{
1591		.num_items = 5,
1592		.items = {
1593			{ "Mic", 0x0 },
1594			{ "Line", 0x2 },
1595			{ "CD", 0x4 },
1596			{ "Front Mic", 0xb },
1597			{ "Input Mix", 0xa },
1598		},
1599	},
1600	{
1601		.num_items = 4,
1602		.items = {
1603			{ "Mic", 0x0 },
1604			{ "Line", 0x2 },
1605			{ "CD", 0x4 },
1606			{ "Input Mix", 0xa },
1607		},
1608	},
1609	{
1610		.num_items = 4,
1611		.items = {
1612			{ "Mic", 0x0 },
1613			{ "Line", 0x2 },
1614			{ "CD", 0x4 },
1615			{ "Input Mix", 0xa },
1616		},
1617	}
1618};
1619
1620static struct snd_kcontrol_new alc888_base_mixer[] = {
1621	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1622	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1623	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1624	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1625	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1626		HDA_OUTPUT),
1627	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1628	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1629	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1630	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1631	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1632	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1633	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1634	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1635	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1636	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1637	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1638	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1639	{ } /* end */
1640};
1641
1642static void alc888_acer_aspire_4930g_init_hook(struct hda_codec *codec)
1643{
1644	struct alc_spec *spec = codec->spec;
1645
1646	spec->autocfg.hp_pins[0] = 0x15;
1647	spec->autocfg.speaker_pins[0] = 0x14;
1648	alc_automute_amp(codec);
1649}
1650
1651static void alc888_acer_aspire_6530g_init_hook(struct hda_codec *codec)
1652{
1653	struct alc_spec *spec = codec->spec;
1654
1655	spec->autocfg.hp_pins[0] = 0x15;
1656	spec->autocfg.speaker_pins[0] = 0x14;
1657	spec->autocfg.speaker_pins[1] = 0x16;
1658	spec->autocfg.speaker_pins[2] = 0x17;
1659	alc_automute_amp(codec);
1660}
1661
1662static void alc889_acer_aspire_8930g_init_hook(struct hda_codec *codec)
1663{
1664	struct alc_spec *spec = codec->spec;
1665
1666	spec->autocfg.hp_pins[0] = 0x15;
1667	spec->autocfg.speaker_pins[0] = 0x14;
1668	spec->autocfg.speaker_pins[1] = 0x16;
1669	spec->autocfg.speaker_pins[2] = 0x1b;
1670	alc_automute_amp(codec);
1671}
1672
1673/*
1674 * ALC880 3-stack model
1675 *
1676 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1677 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1678 *                 F-Mic = 0x1b, HP = 0x19
1679 */
1680
1681static hda_nid_t alc880_dac_nids[4] = {
1682	/* front, rear, clfe, rear_surr */
1683	0x02, 0x05, 0x04, 0x03
1684};
1685
1686static hda_nid_t alc880_adc_nids[3] = {
1687	/* ADC0-2 */
1688	0x07, 0x08, 0x09,
1689};
1690
1691/* The datasheet says the node 0x07 is connected from inputs,
1692 * but it shows zero connection in the real implementation on some devices.
1693 * Note: this is a 915GAV bug, fixed on 915GLV
1694 */
1695static hda_nid_t alc880_adc_nids_alt[2] = {
1696	/* ADC1-2 */
1697	0x08, 0x09,
1698};
1699
1700#define ALC880_DIGOUT_NID	0x06
1701#define ALC880_DIGIN_NID	0x0a
1702
1703static struct hda_input_mux alc880_capture_source = {
1704	.num_items = 4,
1705	.items = {
1706		{ "Mic", 0x0 },
1707		{ "Front Mic", 0x3 },
1708		{ "Line", 0x2 },
1709		{ "CD", 0x4 },
1710	},
1711};
1712
1713/* channel source setting (2/6 channel selection for 3-stack) */
1714/* 2ch mode */
1715static struct hda_verb alc880_threestack_ch2_init[] = {
1716	/* set line-in to input, mute it */
1717	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1718	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1719	/* set mic-in to input vref 80%, mute it */
1720	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1721	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1722	{ } /* end */
1723};
1724
1725/* 6ch mode */
1726static struct hda_verb alc880_threestack_ch6_init[] = {
1727	/* set line-in to output, unmute it */
1728	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1729	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1730	/* set mic-in to output, unmute it */
1731	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1732	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1733	{ } /* end */
1734};
1735
1736static struct hda_channel_mode alc880_threestack_modes[2] = {
1737	{ 2, alc880_threestack_ch2_init },
1738	{ 6, alc880_threestack_ch6_init },
1739};
1740
1741static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1742	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1743	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1744	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1745	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1746	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1747	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1748	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1749	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1750	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1751	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1752	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1753	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1754	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1755	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1756	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1757	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1758	HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1759	{
1760		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1761		.name = "Channel Mode",
1762		.info = alc_ch_mode_info,
1763		.get = alc_ch_mode_get,
1764		.put = alc_ch_mode_put,
1765	},
1766	{ } /* end */
1767};
1768
1769/* capture mixer elements */
1770static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1771			    struct snd_ctl_elem_info *uinfo)
1772{
1773	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1774	struct alc_spec *spec = codec->spec;
1775	int err;
1776
1777	mutex_lock(&codec->control_mutex);
1778	kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1779						      HDA_INPUT);
1780	err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1781	mutex_unlock(&codec->control_mutex);
1782	return err;
1783}
1784
1785static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1786			   unsigned int size, unsigned int __user *tlv)
1787{
1788	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1789	struct alc_spec *spec = codec->spec;
1790	int err;
1791
1792	mutex_lock(&codec->control_mutex);
1793	kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1794						      HDA_INPUT);
1795	err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1796	mutex_unlock(&codec->control_mutex);
1797	return err;
1798}
1799
1800typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1801			     struct snd_ctl_elem_value *ucontrol);
1802
1803static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1804				 struct snd_ctl_elem_value *ucontrol,
1805				 getput_call_t func)
1806{
1807	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1808	struct alc_spec *spec = codec->spec;
1809	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1810	int err;
1811
1812	mutex_lock(&codec->control_mutex);
1813	kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1814						      3, 0, HDA_INPUT);
1815	err = func(kcontrol, ucontrol);
1816	mutex_unlock(&codec->control_mutex);
1817	return err;
1818}
1819
1820static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1821			   struct snd_ctl_elem_value *ucontrol)
1822{
1823	return alc_cap_getput_caller(kcontrol, ucontrol,
1824				     snd_hda_mixer_amp_volume_get);
1825}
1826
1827static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1828			   struct snd_ctl_elem_value *ucontrol)
1829{
1830	return alc_cap_getput_caller(kcontrol, ucontrol,
1831				     snd_hda_mixer_amp_volume_put);
1832}
1833
1834/* capture mixer elements */
1835#define alc_cap_sw_info		snd_ctl_boolean_stereo_info
1836
1837static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1838			  struct snd_ctl_elem_value *ucontrol)
1839{
1840	return alc_cap_getput_caller(kcontrol, ucontrol,
1841				     snd_hda_mixer_amp_switch_get);
1842}
1843
1844static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1845			  struct snd_ctl_elem_value *ucontrol)
1846{
1847	return alc_cap_getput_caller(kcontrol, ucontrol,
1848				     snd_hda_mixer_amp_switch_put);
1849}
1850
1851#define _DEFINE_CAPMIX(num) \
1852	{ \
1853		.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1854		.name = "Capture Switch", \
1855		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1856		.count = num, \
1857		.info = alc_cap_sw_info, \
1858		.get = alc_cap_sw_get, \
1859		.put = alc_cap_sw_put, \
1860	}, \
1861	{ \
1862		.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1863		.name = "Capture Volume", \
1864		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1865			   SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1866			   SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1867		.count = num, \
1868		.info = alc_cap_vol_info, \
1869		.get = alc_cap_vol_get, \
1870		.put = alc_cap_vol_put, \
1871		.tlv = { .c = alc_cap_vol_tlv }, \
1872	}
1873
1874#define _DEFINE_CAPSRC(num) \
1875	{ \
1876		.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1877		/* .name = "Capture Source", */ \
1878		.name = "Input Source", \
1879		.count = num, \
1880		.info = alc_mux_enum_info, \
1881		.get = alc_mux_enum_get, \
1882		.put = alc_mux_enum_put, \
1883	}
1884
1885#define DEFINE_CAPMIX(num) \
1886static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
1887	_DEFINE_CAPMIX(num),				      \
1888	_DEFINE_CAPSRC(num),				      \
1889	{ } /* end */					      \
1890}
1891
1892#define DEFINE_CAPMIX_NOSRC(num) \
1893static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
1894	_DEFINE_CAPMIX(num),					    \
1895	{ } /* end */						    \
1896}
1897
1898/* up to three ADCs */
1899DEFINE_CAPMIX(1);
1900DEFINE_CAPMIX(2);
1901DEFINE_CAPMIX(3);
1902DEFINE_CAPMIX_NOSRC(1);
1903DEFINE_CAPMIX_NOSRC(2);
1904DEFINE_CAPMIX_NOSRC(3);
1905
1906/*
1907 * ALC880 5-stack model
1908 *
1909 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1910 *      Side = 0x02 (0xd)
1911 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1912 *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1913 */
1914
1915/* additional mixers to alc880_three_stack_mixer */
1916static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1917	HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1918	HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1919	{ } /* end */
1920};
1921
1922/* channel source setting (6/8 channel selection for 5-stack) */
1923/* 6ch mode */
1924static struct hda_verb alc880_fivestack_ch6_init[] = {
1925	/* set line-in to input, mute it */
1926	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1927	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1928	{ } /* end */
1929};
1930
1931/* 8ch mode */
1932static struct hda_verb alc880_fivestack_ch8_init[] = {
1933	/* set line-in to output, unmute it */
1934	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1935	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1936	{ } /* end */
1937};
1938
1939static struct hda_channel_mode alc880_fivestack_modes[2] = {
1940	{ 6, alc880_fivestack_ch6_init },
1941	{ 8, alc880_fivestack_ch8_init },
1942};
1943
1944
1945/*
1946 * ALC880 6-stack model
1947 *
1948 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1949 *      Side = 0x05 (0x0f)
1950 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1951 *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1952 */
1953
1954static hda_nid_t alc880_6st_dac_nids[4] = {
1955	/* front, rear, clfe, rear_surr */
1956	0x02, 0x03, 0x04, 0x05
1957};
1958
1959static struct hda_input_mux alc880_6stack_capture_source = {
1960	.num_items = 4,
1961	.items = {
1962		{ "Mic", 0x0 },
1963		{ "Front Mic", 0x1 },
1964		{ "Line", 0x2 },
1965		{ "CD", 0x4 },
1966	},
1967};
1968
1969/* fixed 8-channels */
1970static struct hda_channel_mode alc880_sixstack_modes[1] = {
1971	{ 8, NULL },
1972};
1973
1974static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1975	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1976	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1977	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1978	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1979	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1980	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1981	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1982	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1983	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1984	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1985	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1986	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1987	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1988	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1989	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1990	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1991	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1992	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1993	{
1994		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1995		.name = "Channel Mode",
1996		.info = alc_ch_mode_info,
1997		.get = alc_ch_mode_get,
1998		.put = alc_ch_mode_put,
1999	},
2000	{ } /* end */
2001};
2002
2003
2004/*
2005 * ALC880 W810 model
2006 *
2007 * W810 has rear IO for:
2008 * Front (DAC 02)
2009 * Surround (DAC 03)
2010 * Center/LFE (DAC 04)
2011 * Digital out (06)
2012 *
2013 * The system also has a pair of internal speakers, and a headphone jack.
2014 * These are both connected to Line2 on the codec, hence to DAC 02.
2015 *
2016 * There is a variable resistor to control the speaker or headphone
2017 * volume. This is a hardware-only device without a software API.
2018 *
2019 * Plugging headphones in will disable the internal speakers. This is
2020 * implemented in hardware, not via the driver using jack sense. In
2021 * a similar fashion, plugging into the rear socket marked "front" will
2022 * disable both the speakers and headphones.
2023 *
2024 * For input, there's a microphone jack, and an "audio in" jack.
2025 * These may not do anything useful with this driver yet, because I
2026 * haven't setup any initialization verbs for these yet...
2027 */
2028
2029static hda_nid_t alc880_w810_dac_nids[3] = {
2030	/* front, rear/surround, clfe */
2031	0x02, 0x03, 0x04
2032};
2033
2034/* fixed 6 channels */
2035static struct hda_channel_mode alc880_w810_modes[1] = {
2036	{ 6, NULL }
2037};
2038
2039/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
2040static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2041	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2042	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2043	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2044	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2045	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2046	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2047	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2048	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2049	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2050	{ } /* end */
2051};
2052
2053
2054/*
2055 * Z710V model
2056 *
2057 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
2058 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2059 *                 Line = 0x1a
2060 */
2061
2062static hda_nid_t alc880_z71v_dac_nids[1] = {
2063	0x02
2064};
2065#define ALC880_Z71V_HP_DAC	0x03
2066
2067/* fixed 2 channels */
2068static struct hda_channel_mode alc880_2_jack_modes[1] = {
2069	{ 2, NULL }
2070};
2071
2072static struct snd_kcontrol_new alc880_z71v_mixer[] = {
2073	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2074	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2075	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2076	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
2077	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2078	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2079	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2080	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2081	{ } /* end */
2082};
2083
2084
2085/*
2086 * ALC880 F1734 model
2087 *
2088 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2089 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2090 */
2091
2092static hda_nid_t alc880_f1734_dac_nids[1] = {
2093	0x03
2094};
2095#define ALC880_F1734_HP_DAC	0x02
2096
2097static struct snd_kcontrol_new alc880_f1734_mixer[] = {
2098	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2099	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2100	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2101	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2102	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2103	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2104	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2105	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2106	{ } /* end */
2107};
2108
2109static struct hda_input_mux alc880_f1734_capture_source = {
2110	.num_items = 2,
2111	.items = {
2112		{ "Mic", 0x1 },
2113		{ "CD", 0x4 },
2114	},
2115};
2116
2117
2118/*
2119 * ALC880 ASUS model
2120 *
2121 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2122 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2123 *  Mic = 0x18, Line = 0x1a
2124 */
2125
2126#define alc880_asus_dac_nids	alc880_w810_dac_nids	/* identical with w810 */
2127#define alc880_asus_modes	alc880_threestack_modes	/* 2/6 channel mode */
2128
2129static struct snd_kcontrol_new alc880_asus_mixer[] = {
2130	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2131	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2132	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2133	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2134	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2135	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2136	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2137	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2138	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2139	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2140	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2141	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2142	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2143	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2144	{
2145		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2146		.name = "Channel Mode",
2147		.info = alc_ch_mode_info,
2148		.get = alc_ch_mode_get,
2149		.put = alc_ch_mode_put,
2150	},
2151	{ } /* end */
2152};
2153
2154/*
2155 * ALC880 ASUS W1V model
2156 *
2157 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2158 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2159 *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2160 */
2161
2162/* additional mixers to alc880_asus_mixer */
2163static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
2164	HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2165	HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2166	{ } /* end */
2167};
2168
2169/* TCL S700 */
2170static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2171	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2172	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2173	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2174	HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2175	HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2176	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2177	HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2178	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2179	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
2180	{ } /* end */
2181};
2182
2183/* Uniwill */
2184static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2185	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2186	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2187	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2188	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2189	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2190	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2191	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2192	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2193	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2194	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2195	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2196	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2197	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2198	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2199	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2200	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2201	{
2202		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2203		.name = "Channel Mode",
2204		.info = alc_ch_mode_info,
2205		.get = alc_ch_mode_get,
2206		.put = alc_ch_mode_put,
2207	},
2208	{ } /* end */
2209};
2210
2211static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2212	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2213	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2214	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2215	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2216	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2217	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2218	HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2219	HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2220	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2221	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2222	{ } /* end */
2223};
2224
2225static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2226	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2227	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2228	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2229	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2230	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2231	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2232	{ } /* end */
2233};
2234
2235/*
2236 * virtual master controls
2237 */
2238
2239/*
2240 * slave controls for virtual master
2241 */
2242static const char *alc_slave_vols[] = {
2243	"Front Playback Volume",
2244	"Surround Playback Volume",
2245	"Center Playback Volume",
2246	"LFE Playback Volume",
2247	"Side Playback Volume",
2248	"Headphone Playback Volume",
2249	"Speaker Playback Volume",
2250	"Mono Playback Volume",
2251	"Line-Out Playback Volume",
2252	"PCM Playback Volume",
2253	NULL,
2254};
2255
2256static const char *alc_slave_sws[] = {
2257	"Front Playback Switch",
2258	"Surround Playback Switch",
2259	"Center Playback Switch",
2260	"LFE Playback Switch",
2261	"Side Playback Switch",
2262	"Headphone Playback Switch",
2263	"Speaker Playback Switch",
2264	"Mono Playback Switch",
2265	"IEC958 Playback Switch",
2266	NULL,
2267};
2268
2269/*
2270 * build control elements
2271 */
2272
2273static void alc_free_kctls(struct hda_codec *codec);
2274
2275/* additional beep mixers; the actual parameters are overwritten at build */
2276static struct snd_kcontrol_new alc_beep_mixer[] = {
2277	HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2278	HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_INPUT),
2279	{ } /* end */
2280};
2281
2282static int alc_build_controls(struct hda_codec *codec)
2283{
2284	struct alc_spec *spec = codec->spec;
2285	int err;
2286	int i;
2287
2288	for (i = 0; i < spec->num_mixers; i++) {
2289		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2290		if (err < 0)
2291			return err;
2292	}
2293	if (spec->cap_mixer) {
2294		err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2295		if (err < 0)
2296			return err;
2297	}
2298	if (spec->multiout.dig_out_nid) {
2299		err = snd_hda_create_spdif_out_ctls(codec,
2300						    spec->multiout.dig_out_nid);
2301		if (err < 0)
2302			return err;
2303		if (!spec->no_analog) {
2304			err = snd_hda_create_spdif_share_sw(codec,
2305							    &spec->multiout);
2306			if (err < 0)
2307				return err;
2308			spec->multiout.share_spdif = 1;
2309		}
2310	}
2311	if (spec->dig_in_nid) {
2312		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2313		if (err < 0)
2314			return err;
2315	}
2316
2317	/* create beep controls if needed */
2318	if (spec->beep_amp) {
2319		struct snd_kcontrol_new *knew;
2320		for (knew = alc_beep_mixer; knew->name; knew++) {
2321			struct snd_kcontrol *kctl;
2322			kctl = snd_ctl_new1(knew, codec);
2323			if (!kctl)
2324				return -ENOMEM;
2325			kctl->private_value = spec->beep_amp;
2326			err = snd_hda_ctl_add(codec, kctl);
2327			if (err < 0)
2328				return err;
2329		}
2330	}
2331
2332	/* if we have no master control, let's create it */
2333	if (!spec->no_analog &&
2334	    !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
2335		unsigned int vmaster_tlv[4];
2336		snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
2337					HDA_OUTPUT, vmaster_tlv);
2338		err = snd_hda_add_vmaster(codec, "Master Playback Volume",
2339					  vmaster_tlv, alc_slave_vols);
2340		if (err < 0)
2341			return err;
2342	}
2343	if (!spec->no_analog &&
2344	    !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2345		err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2346					  NULL, alc_slave_sws);
2347		if (err < 0)
2348			return err;
2349	}
2350
2351	alc_free_kctls(codec); /* no longer needed */
2352	return 0;
2353}
2354
2355
2356/*
2357 * initialize the codec volumes, etc
2358 */
2359
2360/*
2361 * generic initialization of ADC, input mixers and output mixers
2362 */
2363static struct hda_verb alc880_volume_init_verbs[] = {
2364	/*
2365	 * Unmute ADC0-2 and set the default input to mic-in
2366	 */
2367	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2368	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2369	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2370	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2371	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2372	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2373
2374	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2375	 * mixer widget
2376	 * Note: PASD motherboards uses the Line In 2 as the input for front
2377	 * panel mic (mic 2)
2378	 */
2379	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
2380	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2381	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2382	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2383	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2384	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2385	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2386	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2387
2388	/*
2389	 * Set up output mixers (0x0c - 0x0f)
2390	 */
2391	/* set vol=0 to output mixers */
2392	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2393	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2394	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2395	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2396	/* set up input amps for analog loopback */
2397	/* Amp Indices: DAC = 0, mixer = 1 */
2398	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2399	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2400	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2401	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2402	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2403	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2404	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2405	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2406
2407	{ }
2408};
2409
2410/*
2411 * 3-stack pin configuration:
2412 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2413 */
2414static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2415	/*
2416	 * preset connection lists of input pins
2417	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2418	 */
2419	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2420	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2421	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2422
2423	/*
2424	 * Set pin mode and muting
2425	 */
2426	/* set front pin widgets 0x14 for output */
2427	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2428	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2429	/* Mic1 (rear panel) pin widget for input and vref at 80% */
2430	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2431	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2432	/* Mic2 (as headphone out) for HP output */
2433	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2434	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2435	/* Line In pin widget for input */
2436	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2437	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2438	/* Line2 (as front mic) pin widget for input and vref at 80% */
2439	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2440	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2441	/* CD pin widget for input */
2442	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2443
2444	{ }
2445};
2446
2447/*
2448 * 5-stack pin configuration:
2449 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2450 * line-in/side = 0x1a, f-mic = 0x1b
2451 */
2452static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2453	/*
2454	 * preset connection lists of input pins
2455	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2456	 */
2457	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2458	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
2459
2460	/*
2461	 * Set pin mode and muting
2462	 */
2463	/* set pin widgets 0x14-0x17 for output */
2464	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2465	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2466	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2467	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2468	/* unmute pins for output (no gain on this amp) */
2469	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2470	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2471	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2472	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2473
2474	/* Mic1 (rear panel) pin widget for input and vref at 80% */
2475	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2476	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2477	/* Mic2 (as headphone out) for HP output */
2478	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2479	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2480	/* Line In pin widget for input */
2481	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2482	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2483	/* Line2 (as front mic) pin widget for input and vref at 80% */
2484	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2485	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2486	/* CD pin widget for input */
2487	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2488
2489	{ }
2490};
2491
2492/*
2493 * W810 pin configuration:
2494 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2495 */
2496static struct hda_verb alc880_pin_w810_init_verbs[] = {
2497	/* hphone/speaker input selector: front DAC */
2498	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
2499
2500	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2501	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2502	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2503	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2504	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2505	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2506
2507	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2508	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2509
2510	{ }
2511};
2512
2513/*
2514 * Z71V pin configuration:
2515 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2516 */
2517static struct hda_verb alc880_pin_z71v_init_verbs[] = {
2518	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2519	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2520	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2521	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2522
2523	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2524	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2525	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2526	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2527
2528	{ }
2529};
2530
2531/*
2532 * 6-stack pin configuration:
2533 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2534 * f-mic = 0x19, line = 0x1a, HP = 0x1b
2535 */
2536static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2537	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2538
2539	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2540	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2541	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2542	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2543	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2544	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2545	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2546	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2547
2548	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2549	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2550	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2551	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2552	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2553	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2554	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2555	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2556	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2557
2558	{ }
2559};
2560
2561/*
2562 * Uniwill pin configuration:
2563 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2564 * line = 0x1a
2565 */
2566static struct hda_verb alc880_uniwill_init_verbs[] = {
2567	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2568
2569	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2570	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2571	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2572	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2573	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2574	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2575	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2576	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2577	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2578	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2579	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2580	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2581	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2582	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2583
2584	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2585	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2586	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2587	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2588	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2589	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2590	/* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2591	/* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2592	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2593
2594	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2595	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2596
2597	{ }
2598};
2599
2600/*
2601* Uniwill P53
2602* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
2603 */
2604static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2605	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2606
2607	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2608	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2609	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2610	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2611	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2612	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2613	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2614	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2615	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2616	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2617	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2618	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2619
2620	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2621	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2622	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2623	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2624	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2625	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2626
2627	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2628	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2629
2630	{ }
2631};
2632
2633static struct hda_verb alc880_beep_init_verbs[] = {
2634	{ 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2635	{ }
2636};
2637
2638/* auto-toggle front mic */
2639static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2640{
2641 	unsigned int present;
2642	unsigned char bits;
2643
2644	present = snd_hda_codec_read(codec, 0x18, 0,
2645				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2646	bits = present ? HDA_AMP_MUTE : 0;
2647	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2648}
2649
2650static void alc880_uniwill_init_hook(struct hda_codec *codec)
2651{
2652	struct alc_spec *spec = codec->spec;
2653
2654	spec->autocfg.hp_pins[0] = 0x14;
2655	spec->autocfg.speaker_pins[0] = 0x15;
2656	spec->autocfg.speaker_pins[0] = 0x16;
2657	alc_automute_amp(codec);
2658	alc880_uniwill_mic_automute(codec);
2659}
2660
2661static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2662				       unsigned int res)
2663{
2664	/* Looks like the unsol event is incompatible with the standard
2665	 * definition.  4bit tag is placed at 28 bit!
2666	 */
2667	switch (res >> 28) {
2668	case ALC880_MIC_EVENT:
2669		alc880_uniwill_mic_automute(codec);
2670		break;
2671	default:
2672		alc_automute_amp_unsol_event(codec, res);
2673		break;
2674	}
2675}
2676
2677static void alc880_uniwill_p53_init_hook(struct hda_codec *codec)
2678{
2679	struct alc_spec *spec = codec->spec;
2680
2681	spec->autocfg.hp_pins[0] = 0x14;
2682	spec->autocfg.speaker_pins[0] = 0x15;
2683	alc_automute_amp(codec);
2684}
2685
2686static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2687{
2688	unsigned int present;
2689
2690	present = snd_hda_codec_read(codec, 0x21, 0,
2691				     AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2692	present &= HDA_AMP_VOLMASK;
2693	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2694				 HDA_AMP_VOLMASK, present);
2695	snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2696				 HDA_AMP_VOLMASK, present);
2697}
2698
2699static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2700					   unsigned int res)
2701{
2702	/* Looks like the unsol event is incompatible with the standard
2703	 * definition.  4bit tag is placed at 28 bit!
2704	 */
2705	if ((res >> 28) == ALC880_DCVOL_EVENT)
2706		alc880_uniwill_p53_dcvol_automute(codec);
2707	else
2708		alc_automute_amp_unsol_event(codec, res);
2709}
2710
2711/*
2712 * F1734 pin configuration:
2713 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2714 */
2715static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2716	{0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2717	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2718	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2719	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2720	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2721
2722	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2723	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2724	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2725	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2726
2727	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2728	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2729	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2730	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2731	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2732	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2733	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2734	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2735	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2736
2737	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2738	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2739
2740	{ }
2741};
2742
2743/*
2744 * ASUS pin configuration:
2745 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2746 */
2747static struct hda_verb alc880_pin_asus_init_verbs[] = {
2748	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2749	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2750	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2751	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2752
2753	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2754	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2755	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2756	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2757	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2758	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2759	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2760	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2761
2762	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2763	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2764	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2765	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2766	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2767	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2768	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2769	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2770	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2771
2772	{ }
2773};
2774
2775/* Enable GPIO mask and set output */
2776#define alc880_gpio1_init_verbs	alc_gpio1_init_verbs
2777#define alc880_gpio2_init_verbs	alc_gpio2_init_verbs
2778#define alc880_gpio3_init_verbs	alc_gpio3_init_verbs
2779
2780/* Clevo m520g init */
2781static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2782	/* headphone output */
2783	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2784	/* line-out */
2785	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2786	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2787	/* Line-in */
2788	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2789	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2790	/* CD */
2791	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2792	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2793	/* Mic1 (rear panel) */
2794	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2795	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2796	/* Mic2 (front panel) */
2797	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2798	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2799	/* headphone */
2800	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2801	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2802        /* change to EAPD mode */
2803	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2804	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2805
2806	{ }
2807};
2808
2809static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2810	/* change to EAPD mode */
2811	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2812	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2813
2814	/* Headphone output */
2815	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2816	/* Front output*/
2817	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2818	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2819
2820	/* Line In pin widget for input */
2821	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2822	/* CD pin widget for input */
2823	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2824	/* Mic1 (rear panel) pin widget for input and vref at 80% */
2825	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2826
2827	/* change to EAPD mode */
2828	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2829	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
2830
2831	{ }
2832};
2833
2834/*
2835 * LG m1 express dual
2836 *
2837 * Pin assignment:
2838 *   Rear Line-In/Out (blue): 0x14
2839 *   Build-in Mic-In: 0x15
2840 *   Speaker-out: 0x17
2841 *   HP-Out (green): 0x1b
2842 *   Mic-In/Out (red): 0x19
2843 *   SPDIF-Out: 0x1e
2844 */
2845
2846/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2847static hda_nid_t alc880_lg_dac_nids[3] = {
2848	0x05, 0x02, 0x03
2849};
2850
2851/* seems analog CD is not working */
2852static struct hda_input_mux alc880_lg_capture_source = {
2853	.num_items = 3,
2854	.items = {
2855		{ "Mic", 0x1 },
2856		{ "Line", 0x5 },
2857		{ "Internal Mic", 0x6 },
2858	},
2859};
2860
2861/* 2,4,6 channel modes */
2862static struct hda_verb alc880_lg_ch2_init[] = {
2863	/* set line-in and mic-in to input */
2864	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2865	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2866	{ }
2867};
2868
2869static struct hda_verb alc880_lg_ch4_init[] = {
2870	/* set line-in to out and mic-in to input */
2871	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2872	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2873	{ }
2874};
2875
2876static struct hda_verb alc880_lg_ch6_init[] = {
2877	/* set line-in and mic-in to output */
2878	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2879	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2880	{ }
2881};
2882
2883static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2884	{ 2, alc880_lg_ch2_init },
2885	{ 4, alc880_lg_ch4_init },
2886	{ 6, alc880_lg_ch6_init },
2887};
2888
2889static struct snd_kcontrol_new alc880_lg_mixer[] = {
2890	HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2891	HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2892	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2893	HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2894	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2895	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2896	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2897	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2898	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2899	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2900	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2901	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2902	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2903	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2904	{
2905		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2906		.name = "Channel Mode",
2907		.info = alc_ch_mode_info,
2908		.get = alc_ch_mode_get,
2909		.put = alc_ch_mode_put,
2910	},
2911	{ } /* end */
2912};
2913
2914static struct hda_verb alc880_lg_init_verbs[] = {
2915	/* set capture source to mic-in */
2916	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2917	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2918	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2919	/* mute all amp mixer inputs */
2920	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2921	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2922	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2923	/* line-in to input */
2924	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2925	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2926	/* built-in mic */
2927	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2928	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2929	/* speaker-out */
2930	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2931	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2932	/* mic-in to input */
2933	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2934	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2935	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2936	/* HP-out */
2937	{0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2938	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2939	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2940	/* jack sense */
2941	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2942	{ }
2943};
2944
2945/* toggle speaker-output according to the hp-jack state */
2946static void alc880_lg_init_hook(struct hda_codec *codec)
2947{
2948	struct alc_spec *spec = codec->spec;
2949
2950	spec->autocfg.hp_pins[0] = 0x1b;
2951	spec->autocfg.speaker_pins[0] = 0x17;
2952	alc_automute_amp(codec);
2953}
2954
2955/*
2956 * LG LW20
2957 *
2958 * Pin assignment:
2959 *   Speaker-out: 0x14
2960 *   Mic-In: 0x18
2961 *   Built-in Mic-In: 0x19
2962 *   Line-In: 0x1b
2963 *   HP-Out: 0x1a
2964 *   SPDIF-Out: 0x1e
2965 */
2966
2967static struct hda_input_mux alc880_lg_lw_capture_source = {
2968	.num_items = 3,
2969	.items = {
2970		{ "Mic", 0x0 },
2971		{ "Internal Mic", 0x1 },
2972		{ "Line In", 0x2 },
2973	},
2974};
2975
2976#define alc880_lg_lw_modes alc880_threestack_modes
2977
2978static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2979	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2980	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2981	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2982	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2983	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2984	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2985	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2986	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2987	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2988	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2989	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2990	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2991	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2992	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2993	{
2994		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2995		.name = "Channel Mode",
2996		.info = alc_ch_mode_info,
2997		.get = alc_ch_mode_get,
2998		.put = alc_ch_mode_put,
2999	},
3000	{ } /* end */
3001};
3002
3003static struct hda_verb alc880_lg_lw_init_verbs[] = {
3004	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3005	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3006	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3007
3008	/* set capture source to mic-in */
3009	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3010	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3011	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3012	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3013	/* speaker-out */
3014	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3015	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3016	/* HP-out */
3017	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3018	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3019	/* mic-in to input */
3020	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3021	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3022	/* built-in mic */
3023	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3024	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3025	/* jack sense */
3026	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3027	{ }
3028};
3029
3030/* toggle speaker-output according to the hp-jack state */
3031static void alc880_lg_lw_init_hook(struct hda_codec *codec)
3032{
3033	struct alc_spec *spec = codec->spec;
3034
3035	spec->autocfg.hp_pins[0] = 0x1b;
3036	spec->autocfg.speaker_pins[0] = 0x14;
3037	alc_automute_amp(codec);
3038}
3039
3040static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3041	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3042	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3043	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3044	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3045	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3046	HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3047	{ } /* end */
3048};
3049
3050static struct hda_input_mux alc880_medion_rim_capture_source = {
3051	.num_items = 2,
3052	.items = {
3053		{ "Mic", 0x0 },
3054		{ "Internal Mic", 0x1 },
3055	},
3056};
3057
3058static struct hda_verb alc880_medion_rim_init_verbs[] = {
3059	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3060
3061	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3062	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3063
3064	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3065	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3066	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3067	/* Mic2 (as headphone out) for HP output */
3068	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3069	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3070	/* Internal Speaker */
3071	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3072	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3073
3074	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3075	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
3076
3077	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3078	{ }
3079};
3080
3081/* toggle speaker-output according to the hp-jack state */
3082static void alc880_medion_rim_automute(struct hda_codec *codec)
3083{
3084	struct alc_spec *spec = codec->spec;
3085	alc_automute_amp(codec);
3086	/* toggle EAPD */
3087	if (spec->jack_present)
3088		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3089	else
3090		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3091}
3092
3093static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3094					  unsigned int res)
3095{
3096	/* Looks like the unsol event is incompatible with the standard
3097	 * definition.  4bit tag is placed at 28 bit!
3098	 */
3099	if ((res >> 28) == ALC880_HP_EVENT)
3100		alc880_medion_rim_automute(codec);
3101}
3102
3103static void alc880_medion_rim_init_hook(struct hda_codec *codec)
3104{
3105	struct alc_spec *spec = codec->spec;
3106
3107	spec->autocfg.hp_pins[0] = 0x14;
3108	spec->autocfg.speaker_pins[0] = 0x1b;
3109	alc880_medion_rim_automute(codec);
3110}
3111
3112#ifdef CONFIG_SND_HDA_POWER_SAVE
3113static struct hda_amp_list alc880_loopbacks[] = {
3114	{ 0x0b, HDA_INPUT, 0 },
3115	{ 0x0b, HDA_INPUT, 1 },
3116	{ 0x0b, HDA_INPUT, 2 },
3117	{ 0x0b, HDA_INPUT, 3 },
3118	{ 0x0b, HDA_INPUT, 4 },
3119	{ } /* end */
3120};
3121
3122static struct hda_amp_list alc880_lg_loopbacks[] = {
3123	{ 0x0b, HDA_INPUT, 1 },
3124	{ 0x0b, HDA_INPUT, 6 },
3125	{ 0x0b, HDA_INPUT, 7 },
3126	{ } /* end */
3127};
3128#endif
3129
3130/*
3131 * Common callbacks
3132 */
3133
3134static int alc_init(struct hda_codec *codec)
3135{
3136	struct alc_spec *spec = codec->spec;
3137	unsigned int i;
3138
3139	alc_fix_pll(codec);
3140	alc_auto_init_amp(codec, spec->init_amp);
3141
3142	for (i = 0; i < spec->num_init_verbs; i++)
3143		snd_hda_sequence_write(codec, spec->init_verbs[i]);
3144
3145	if (spec->init_hook)
3146		spec->init_hook(codec);
3147
3148	return 0;
3149}
3150
3151static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3152{
3153	struct alc_spec *spec = codec->spec;
3154
3155	if (spec->unsol_event)
3156		spec->unsol_event(codec, res);
3157}
3158
3159#ifdef CONFIG_SND_HDA_POWER_SAVE
3160static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3161{
3162	struct alc_spec *spec = codec->spec;
3163	return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3164}
3165#endif
3166
3167/*
3168 * Analog playback callbacks
3169 */
3170static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3171				    struct hda_codec *codec,
3172				    struct snd_pcm_substream *substream)
3173{
3174	struct alc_spec *spec = codec->spec;
3175	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3176					     hinfo);
3177}
3178
3179static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3180				       struct hda_codec *codec,
3181				       unsigned int stream_tag,
3182				       unsigned int format,
3183				       struct snd_pcm_substream *substream)
3184{
3185	struct alc_spec *spec = codec->spec;
3186	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3187						stream_tag, format, substream);
3188}
3189
3190static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3191				       struct hda_codec *codec,
3192				       struct snd_pcm_substream *substream)
3193{
3194	struct alc_spec *spec = codec->spec;
3195	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3196}
3197
3198/*
3199 * Digital out
3200 */
3201static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3202					struct hda_codec *codec,
3203					struct snd_pcm_substream *substream)
3204{
3205	struct alc_spec *spec = codec->spec;
3206	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3207}
3208
3209static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3210					   struct hda_codec *codec,
3211					   unsigned int stream_tag,
3212					   unsigned int format,
3213					   struct snd_pcm_substream *substream)
3214{
3215	struct alc_spec *spec = codec->spec;
3216	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3217					     stream_tag, format, substream);
3218}
3219
3220static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3221					   struct hda_codec *codec,
3222					   struct snd_pcm_substream *substream)
3223{
3224	struct alc_spec *spec = codec->spec;
3225	return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3226}
3227
3228static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3229					 struct hda_codec *codec,
3230					 struct snd_pcm_substream *substream)
3231{
3232	struct alc_spec *spec = codec->spec;
3233	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3234}
3235
3236/*
3237 * Analog capture
3238 */
3239static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3240				      struct hda_codec *codec,
3241				      unsigned int stream_tag,
3242				      unsigned int format,
3243				      struct snd_pcm_substream *substream)
3244{
3245	struct alc_spec *spec = codec->spec;
3246
3247	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
3248				   stream_tag, 0, format);
3249	return 0;
3250}
3251
3252static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3253				      struct hda_codec *codec,
3254				      struct snd_pcm_substream *substream)
3255{
3256	struct alc_spec *spec = codec->spec;
3257
3258	snd_hda_codec_cleanup_stream(codec,
3259				     spec->adc_nids[substream->number + 1]);
3260	return 0;
3261}
3262
3263
3264/*
3265 */
3266static struct hda_pcm_stream alc880_pcm_analog_playback = {
3267	.substreams = 1,
3268	.channels_min = 2,
3269	.channels_max = 8,
3270	/* NID is set in alc_build_pcms */
3271	.ops = {
3272		.open = alc880_playback_pcm_open,
3273		.prepare = alc880_playback_pcm_prepare,
3274		.cleanup = alc880_playback_pcm_cleanup
3275	},
3276};
3277
3278static struct hda_pcm_stream alc880_pcm_analog_capture = {
3279	.substreams = 1,
3280	.channels_min = 2,
3281	.channels_max = 2,
3282	/* NID is set in alc_build_pcms */
3283};
3284
3285static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3286	.substreams = 1,
3287	.channels_min = 2,
3288	.channels_max = 2,
3289	/* NID is set in alc_build_pcms */
3290};
3291
3292static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3293	.substreams = 2, /* can be overridden */
3294	.channels_min = 2,
3295	.channels_max = 2,
3296	/* NID is set in alc_build_pcms */
3297	.ops = {
3298		.prepare = alc880_alt_capture_pcm_prepare,
3299		.cleanup = alc880_alt_capture_pcm_cleanup
3300	},
3301};
3302
3303static struct hda_pcm_stream alc880_pcm_digital_playback = {
3304	.substreams = 1,
3305	.channels_min = 2,
3306	.channels_max = 2,
3307	/* NID is set in alc_build_pcms */
3308	.ops = {
3309		.open = alc880_dig_playback_pcm_open,
3310		.close = alc880_dig_playback_pcm_close,
3311		.prepare = alc880_dig_playback_pcm_prepare,
3312		.cleanup = alc880_dig_playback_pcm_cleanup
3313	},
3314};
3315
3316static struct hda_pcm_stream alc880_pcm_digital_capture = {
3317	.substreams = 1,
3318	.channels_min = 2,
3319	.channels_max = 2,
3320	/* NID is set in alc_build_pcms */
3321};
3322
3323/* Used by alc_build_pcms to flag that a PCM has no playback stream */
3324static struct hda_pcm_stream alc_pcm_null_stream = {
3325	.substreams = 0,
3326	.channels_min = 0,
3327	.channels_max = 0,
3328};
3329
3330static int alc_build_pcms(struct hda_codec *codec)
3331{
3332	struct alc_spec *spec = codec->spec;
3333	struct hda_pcm *info = spec->pcm_rec;
3334	int i;
3335
3336	codec->num_pcms = 1;
3337	codec->pcm_info = info;
3338
3339	if (spec->no_analog)
3340		goto skip_analog;
3341
3342	snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3343		 "%s Analog", codec->chip_name);
3344	info->name = spec->stream_name_analog;
3345
3346	if (spec->stream_analog_playback) {
3347		if (snd_BUG_ON(!spec->multiout.dac_nids))
3348			return -EINVAL;
3349		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3350		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3351	}
3352	if (spec->stream_analog_capture) {
3353		if (snd_BUG_ON(!spec->adc_nids))
3354			return -EINVAL;
3355		info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3356		info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3357	}
3358
3359	if (spec->channel_mode) {
3360		info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3361		for (i = 0; i < spec->num_channel_mode; i++) {
3362			if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3363				info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3364			}
3365		}
3366	}
3367
3368 skip_analog:
3369	/* SPDIF for stream index #1 */
3370	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
3371		snprintf(spec->stream_name_digital,
3372			 sizeof(spec->stream_name_digital),
3373			 "%s Digital", codec->chip_name);
3374		codec->num_pcms = 2;
3375	        codec->slave_dig_outs = spec->multiout.slave_dig_outs;
3376		info = spec->pcm_rec + 1;
3377		info->name = spec->stream_name_digital;
3378		if (spec->dig_out_type)
3379			info->pcm_type = spec->dig_out_type;
3380		else
3381			info->pcm_type = HDA_PCM_TYPE_SPDIF;
3382		if (spec->multiout.dig_out_nid &&
3383		    spec->stream_digital_playback) {
3384			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3385			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3386		}
3387		if (spec->dig_in_nid &&
3388		    spec->stream_digital_capture) {
3389			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3390			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3391		}
3392		/* FIXME: do we need this for all Realtek codec models? */
3393		codec->spdif_status_reset = 1;
3394	}
3395
3396	if (spec->no_analog)
3397		return 0;
3398
3399	/* If the use of more than one ADC is requested for the current
3400	 * model, configure a second analog capture-only PCM.
3401	 */
3402	/* Additional Analaog capture for index #2 */
3403	if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3404	    (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
3405		codec->num_pcms = 3;
3406		info = spec->pcm_rec + 2;
3407		info->name = spec->stream_name_analog;
3408		if (spec->alt_dac_nid) {
3409			info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3410				*spec->stream_analog_alt_playback;
3411			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3412				spec->alt_dac_nid;
3413		} else {
3414			info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3415				alc_pcm_null_stream;
3416			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3417		}
3418		if (spec->num_adc_nids > 1) {
3419			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3420				*spec->stream_analog_alt_capture;
3421			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3422				spec->adc_nids[1];
3423			info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3424				spec->num_adc_nids - 1;
3425		} else {
3426			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3427				alc_pcm_null_stream;
3428			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
3429		}
3430	}
3431
3432	return 0;
3433}
3434
3435static void alc_free_kctls(struct hda_codec *codec)
3436{
3437	struct alc_spec *spec = codec->spec;
3438
3439	if (spec->kctls.list) {
3440		struct snd_kcontrol_new *kctl = spec->kctls.list;
3441		int i;
3442		for (i = 0; i < spec->kctls.used; i++)
3443			kfree(kctl[i].name);
3444	}
3445	snd_array_free(&spec->kctls);
3446}
3447
3448static void alc_free(struct hda_codec *codec)
3449{
3450	struct alc_spec *spec = codec->spec;
3451
3452	if (!spec)
3453		return;
3454
3455	alc_free_kctls(codec);
3456	kfree(spec);
3457	snd_hda_detach_beep_device(codec);
3458}
3459
3460#ifdef SND_HDA_NEEDS_RESUME
3461static int alc_resume(struct hda_codec *codec)
3462{
3463	codec->patch_ops.init(codec);
3464	snd_hda_codec_resume_amp(codec);
3465	snd_hda_codec_resume_cache(codec);
3466	return 0;
3467}
3468#endif
3469
3470/*
3471 */
3472static struct hda_codec_ops alc_patch_ops = {
3473	.build_controls = alc_build_controls,
3474	.build_pcms = alc_build_pcms,
3475	.init = alc_init,
3476	.free = alc_free,
3477	.unsol_event = alc_unsol_event,
3478#ifdef SND_HDA_NEEDS_RESUME
3479	.resume = alc_resume,
3480#endif
3481#ifdef CONFIG_SND_HDA_POWER_SAVE
3482	.check_power_status = alc_check_power_status,
3483#endif
3484};
3485
3486
3487/*
3488 * Test configuration for debugging
3489 *
3490 * Almost all inputs/outputs are enabled.  I/O pins can be configured via
3491 * enum controls.
3492 */
3493#ifdef CONFIG_SND_DEBUG
3494static hda_nid_t alc880_test_dac_nids[4] = {
3495	0x02, 0x03, 0x04, 0x05
3496};
3497
3498static struct hda_input_mux alc880_test_capture_source = {
3499	.num_items = 7,
3500	.items = {
3501		{ "In-1", 0x0 },
3502		{ "In-2", 0x1 },
3503		{ "In-3", 0x2 },
3504		{ "In-4", 0x3 },
3505		{ "CD", 0x4 },
3506		{ "Front", 0x5 },
3507		{ "Surround", 0x6 },
3508	},
3509};
3510
3511static struct hda_channel_mode alc880_test_modes[4] = {
3512	{ 2, NULL },
3513	{ 4, NULL },
3514	{ 6, NULL },
3515	{ 8, NULL },
3516};
3517
3518static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3519				 struct snd_ctl_elem_info *uinfo)
3520{
3521	static char *texts[] = {
3522		"N/A", "Line Out", "HP Out",
3523		"In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3524	};
3525	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3526	uinfo->count = 1;
3527	uinfo->value.enumerated.items = 8;
3528	if (uinfo->value.enumerated.item >= 8)
3529		uinfo->value.enumerated.item = 7;
3530	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3531	return 0;
3532}
3533
3534static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3535				struct snd_ctl_elem_value *ucontrol)
3536{
3537	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3538	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3539	unsigned int pin_ctl, item = 0;
3540
3541	pin_ctl = snd_hda_codec_read(codec, nid, 0,
3542				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3543	if (pin_ctl & AC_PINCTL_OUT_EN) {
3544		if (pin_ctl & AC_PINCTL_HP_EN)
3545			item = 2;
3546		else
3547			item = 1;
3548	} else if (pin_ctl & AC_PINCTL_IN_EN) {
3549		switch (pin_ctl & AC_PINCTL_VREFEN) {
3550		case AC_PINCTL_VREF_HIZ: item = 3; break;
3551		case AC_PINCTL_VREF_50:  item = 4; break;
3552		case AC_PINCTL_VREF_GRD: item = 5; break;
3553		case AC_PINCTL_VREF_80:  item = 6; break;
3554		case AC_PINCTL_VREF_100: item = 7; break;
3555		}
3556	}
3557	ucontrol->value.enumerated.item[0] = item;
3558	return 0;
3559}
3560
3561static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3562				struct snd_ctl_elem_value *ucontrol)
3563{
3564	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3565	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3566	static unsigned int ctls[] = {
3567		0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3568		AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3569		AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3570		AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3571		AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3572		AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3573	};
3574	unsigned int old_ctl, new_ctl;
3575
3576	old_ctl = snd_hda_codec_read(codec, nid, 0,
3577				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3578	new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3579	if (old_ctl != new_ctl) {
3580		int val;
3581		snd_hda_codec_write_cache(codec, nid, 0,
3582					  AC_VERB_SET_PIN_WIDGET_CONTROL,
3583					  new_ctl);
3584		val = ucontrol->value.enumerated.item[0] >= 3 ?
3585			HDA_AMP_MUTE : 0;
3586		snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3587					 HDA_AMP_MUTE, val);
3588		return 1;
3589	}
3590	return 0;
3591}
3592
3593static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3594				 struct snd_ctl_elem_info *uinfo)
3595{
3596	static char *texts[] = {
3597		"Front", "Surround", "CLFE", "Side"
3598	};
3599	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3600	uinfo->count = 1;
3601	uinfo->value.enumerated.items = 4;
3602	if (uinfo->value.enumerated.item >= 4)
3603		uinfo->value.enumerated.item = 3;
3604	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3605	return 0;
3606}
3607
3608static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3609				struct snd_ctl_elem_value *ucontrol)
3610{
3611	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3612	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3613	unsigned int sel;
3614
3615	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3616	ucontrol->value.enumerated.item[0] = sel & 3;
3617	return 0;
3618}
3619
3620static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3621				struct snd_ctl_elem_value *ucontrol)
3622{
3623	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3624	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3625	unsigned int sel;
3626
3627	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3628	if (ucontrol->value.enumerated.item[0] != sel) {
3629		sel = ucontrol->value.enumerated.item[0] & 3;
3630		snd_hda_codec_write_cache(codec, nid, 0,
3631					  AC_VERB_SET_CONNECT_SEL, sel);
3632		return 1;
3633	}
3634	return 0;
3635}
3636
3637#define PIN_CTL_TEST(xname,nid) {			\
3638		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
3639			.name = xname,		       \
3640			.info = alc_test_pin_ctl_info, \
3641			.get = alc_test_pin_ctl_get,   \
3642			.put = alc_test_pin_ctl_put,   \
3643			.private_value = nid	       \
3644			}
3645
3646#define PIN_SRC_TEST(xname,nid) {			\
3647		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
3648			.name = xname,		       \
3649			.info = alc_test_pin_src_info, \
3650			.get = alc_test_pin_src_get,   \
3651			.put = alc_test_pin_src_put,   \
3652			.private_value = nid	       \
3653			}
3654
3655static struct snd_kcontrol_new alc880_test_mixer[] = {
3656	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3657	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3658	HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3659	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3660	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3661	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3662	HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3663	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
3664	PIN_CTL_TEST("Front Pin Mode", 0x14),
3665	PIN_CTL_TEST("Surround Pin Mode", 0x15),
3666	PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3667	PIN_CTL_TEST("Side Pin Mode", 0x17),
3668	PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3669	PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3670	PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3671	PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3672	PIN_SRC_TEST("In-1 Pin Source", 0x18),
3673	PIN_SRC_TEST("In-2 Pin Source", 0x19),
3674	PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3675	PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3676	HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3677	HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3678	HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3679	HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3680	HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3681	HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3682	HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3683	HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3684	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3685	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
3686	{
3687		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3688		.name = "Channel Mode",
3689		.info = alc_ch_mode_info,
3690		.get = alc_ch_mode_get,
3691		.put = alc_ch_mode_put,
3692	},
3693	{ } /* end */
3694};
3695
3696static struct hda_verb alc880_test_init_verbs[] = {
3697	/* Unmute inputs of 0x0c - 0x0f */
3698	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3699	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3700	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3701	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3702	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3703	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3704	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3705	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3706	/* Vol output for 0x0c-0x0f */
3707	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3708	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3709	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3710	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3711	/* Set output pins 0x14-0x17 */
3712	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3713	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3714	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3715	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3716	/* Unmute output pins 0x14-0x17 */
3717	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3718	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3719	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3720	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3721	/* Set input pins 0x18-0x1c */
3722	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3723	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3724	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3725	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3726	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3727	/* Mute input pins 0x18-0x1b */
3728	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3729	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3730	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3731	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3732	/* ADC set up */
3733	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3734	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3735	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3736	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3737	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3738	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3739	/* Analog input/passthru */
3740	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3741	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3742	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3743	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3744	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3745	{ }
3746};
3747#endif
3748
3749/*
3750 */
3751
3752static const char *alc880_models[ALC880_MODEL_LAST] = {
3753	[ALC880_3ST]		= "3stack",
3754	[ALC880_TCL_S700]	= "tcl",
3755	[ALC880_3ST_DIG]	= "3stack-digout",
3756	[ALC880_CLEVO]		= "clevo",
3757	[ALC880_5ST]		= "5stack",
3758	[ALC880_5ST_DIG]	= "5stack-digout",
3759	[ALC880_W810]		= "w810",
3760	[ALC880_Z71V]		= "z71v",
3761	[ALC880_6ST]		= "6stack",
3762	[ALC880_6ST_DIG]	= "6stack-digout",
3763	[ALC880_ASUS]		= "asus",
3764	[ALC880_ASUS_W1V]	= "asus-w1v",
3765	[ALC880_ASUS_DIG]	= "asus-dig",
3766	[ALC880_ASUS_DIG2]	= "asus-dig2",
3767	[ALC880_UNIWILL_DIG]	= "uniwill",
3768	[ALC880_UNIWILL_P53]	= "uniwill-p53",
3769	[ALC880_FUJITSU]	= "fujitsu",
3770	[ALC880_F1734]		= "F1734",
3771	[ALC880_LG]		= "lg",
3772	[ALC880_LG_LW]		= "lg-lw",
3773	[ALC880_MEDION_RIM]	= "medion",
3774#ifdef CONFIG_SND_DEBUG
3775	[ALC880_TEST]		= "test",
3776#endif
3777	[ALC880_AUTO]		= "auto",
3778};
3779
3780static struct snd_pci_quirk alc880_cfg_tbl[] = {
3781	SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3782	SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3783	SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3784	SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3785	SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3786	SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3787	SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3788	SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3789	SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3790	SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3791	SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3792	SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3793	SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3794	SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3795	SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3796	SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3797	SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3798	SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3799	/* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3800	SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3801	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3802	SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3803	SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3804	SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3805	SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3806	SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
3807	SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3808	SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3809	SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3810	SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3811	SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3812	SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3813	SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3814	SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3815	SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3816	SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3817	SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3818	SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3819	SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3820	SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3821	SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3822	SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3823	SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3824	SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3825	SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3826	SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3827	SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3828	SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3829	SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3830	SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3831	SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3832	SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3833	SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3834	SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3835	SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3836	SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3837	SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3838	SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3839	SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3840	SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3841	SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3842	SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3843	SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3844	SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3845	SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3846	SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3847	SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3848	SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3849	/* default Intel */
3850	SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
3851	SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3852	SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3853	{}
3854};
3855
3856/*
3857 * ALC880 codec presets
3858 */
3859static struct alc_config_preset alc880_presets[] = {
3860	[ALC880_3ST] = {
3861		.mixers = { alc880_three_stack_mixer },
3862		.init_verbs = { alc880_volume_init_verbs,
3863				alc880_pin_3stack_init_verbs },
3864		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3865		.dac_nids = alc880_dac_nids,
3866		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3867		.channel_mode = alc880_threestack_modes,
3868		.need_dac_fix = 1,
3869		.input_mux = &alc880_capture_source,
3870	},
3871	[ALC880_3ST_DIG] = {
3872		.mixers = { alc880_three_stack_mixer },
3873		.init_verbs = { alc880_volume_init_verbs,
3874				alc880_pin_3stack_init_verbs },
3875		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3876		.dac_nids = alc880_dac_nids,
3877		.dig_out_nid = ALC880_DIGOUT_NID,
3878		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3879		.channel_mode = alc880_threestack_modes,
3880		.need_dac_fix = 1,
3881		.input_mux = &alc880_capture_source,
3882	},
3883	[ALC880_TCL_S700] = {
3884		.mixers = { alc880_tcl_s700_mixer },
3885		.init_verbs = { alc880_volume_init_verbs,
3886				alc880_pin_tcl_S700_init_verbs,
3887				alc880_gpio2_init_verbs },
3888		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3889		.dac_nids = alc880_dac_nids,
3890		.adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
3891		.num_adc_nids = 1, /* single ADC */
3892		.hp_nid = 0x03,
3893		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3894		.channel_mode = alc880_2_jack_modes,
3895		.input_mux = &alc880_capture_source,
3896	},
3897	[ALC880_5ST] = {
3898		.mixers = { alc880_three_stack_mixer,
3899			    alc880_five_stack_mixer},
3900		.init_verbs = { alc880_volume_init_verbs,
3901				alc880_pin_5stack_init_verbs },
3902		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3903		.dac_nids = alc880_dac_nids,
3904		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3905		.channel_mode = alc880_fivestack_modes,
3906		.input_mux = &alc880_capture_source,
3907	},
3908	[ALC880_5ST_DIG] = {
3909		.mixers = { alc880_three_stack_mixer,
3910			    alc880_five_stack_mixer },
3911		.init_verbs = { alc880_volume_init_verbs,
3912				alc880_pin_5stack_init_verbs },
3913		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3914		.dac_nids = alc880_dac_nids,
3915		.dig_out_nid = ALC880_DIGOUT_NID,
3916		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3917		.channel_mode = alc880_fivestack_modes,
3918		.input_mux = &alc880_capture_source,
3919	},
3920	[ALC880_6ST] = {
3921		.mixers = { alc880_six_stack_mixer },
3922		.init_verbs = { alc880_volume_init_verbs,
3923				alc880_pin_6stack_init_verbs },
3924		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3925		.dac_nids = alc880_6st_dac_nids,
3926		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3927		.channel_mode = alc880_sixstack_modes,
3928		.input_mux = &alc880_6stack_capture_source,
3929	},
3930	[ALC880_6ST_DIG] = {
3931		.mixers = { alc880_six_stack_mixer },
3932		.init_verbs = { alc880_volume_init_verbs,
3933				alc880_pin_6stack_init_verbs },
3934		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3935		.dac_nids = alc880_6st_dac_nids,
3936		.dig_out_nid = ALC880_DIGOUT_NID,
3937		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3938		.channel_mode = alc880_sixstack_modes,
3939		.input_mux = &alc880_6stack_capture_source,
3940	},
3941	[ALC880_W810] = {
3942		.mixers = { alc880_w810_base_mixer },
3943		.init_verbs = { alc880_volume_init_verbs,
3944				alc880_pin_w810_init_verbs,
3945				alc880_gpio2_init_verbs },
3946		.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3947		.dac_nids = alc880_w810_dac_nids,
3948		.dig_out_nid = ALC880_DIGOUT_NID,
3949		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3950		.channel_mode = alc880_w810_modes,
3951		.input_mux = &alc880_capture_source,
3952	},
3953	[ALC880_Z71V] = {
3954		.mixers = { alc880_z71v_mixer },
3955		.init_verbs = { alc880_volume_init_verbs,
3956				alc880_pin_z71v_init_verbs },
3957		.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3958		.dac_nids = alc880_z71v_dac_nids,
3959		.dig_out_nid = ALC880_DIGOUT_NID,
3960		.hp_nid = 0x03,
3961		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3962		.channel_mode = alc880_2_jack_modes,
3963		.input_mux = &alc880_capture_source,
3964	},
3965	[ALC880_F1734] = {
3966		.mixers = { alc880_f1734_mixer },
3967		.init_verbs = { alc880_volume_init_verbs,
3968				alc880_pin_f1734_init_verbs },
3969		.num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3970		.dac_nids = alc880_f1734_dac_nids,
3971		.hp_nid = 0x02,
3972		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3973		.channel_mode = alc880_2_jack_modes,
3974		.input_mux = &alc880_f1734_capture_source,
3975		.unsol_event = alc880_uniwill_p53_unsol_event,
3976		.init_hook = alc880_uniwill_p53_init_hook,
3977	},
3978	[ALC880_ASUS] = {
3979		.mixers = { alc880_asus_mixer },
3980		.init_verbs = { alc880_volume_init_verbs,
3981				alc880_pin_asus_init_verbs,
3982				alc880_gpio1_init_verbs },
3983		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3984		.dac_nids = alc880_asus_dac_nids,
3985		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3986		.channel_mode = alc880_asus_modes,
3987		.need_dac_fix = 1,
3988		.input_mux = &alc880_capture_source,
3989	},
3990	[ALC880_ASUS_DIG] = {
3991		.mixers = { alc880_asus_mixer },
3992		.init_verbs = { alc880_volume_init_verbs,
3993				alc880_pin_asus_init_verbs,
3994				alc880_gpio1_init_verbs },
3995		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3996		.dac_nids = alc880_asus_dac_nids,
3997		.dig_out_nid = ALC880_DIGOUT_NID,
3998		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3999		.channel_mode = alc880_asus_modes,
4000		.need_dac_fix = 1,
4001		.input_mux = &alc880_capture_source,
4002	},
4003	[ALC880_ASUS_DIG2] = {
4004		.mixers = { alc880_asus_mixer },
4005		.init_verbs = { alc880_volume_init_verbs,
4006				alc880_pin_asus_init_verbs,
4007				alc880_gpio2_init_verbs }, /* use GPIO2 */
4008		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4009		.dac_nids = alc880_asus_dac_nids,
4010		.dig_out_nid = ALC880_DIGOUT_NID,
4011		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4012		.channel_mode = alc880_asus_modes,
4013		.need_dac_fix = 1,
4014		.input_mux = &alc880_capture_source,
4015	},
4016	[ALC880_ASUS_W1V] = {
4017		.mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
4018		.init_verbs = { alc880_volume_init_verbs,
4019				alc880_pin_asus_init_verbs,
4020				alc880_gpio1_init_verbs },
4021		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4022		.dac_nids = alc880_asus_dac_nids,
4023		.dig_out_nid = ALC880_DIGOUT_NID,
4024		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4025		.channel_mode = alc880_asus_modes,
4026		.need_dac_fix = 1,
4027		.input_mux = &alc880_capture_source,
4028	},
4029	[ALC880_UNIWILL_DIG] = {
4030		.mixers = { alc880_asus_mixer },
4031		.init_verbs = { alc880_volume_init_verbs,
4032				alc880_pin_asus_init_verbs },
4033		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4034		.dac_nids = alc880_asus_dac_nids,
4035		.dig_out_nid = ALC880_DIGOUT_NID,
4036		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4037		.channel_mode = alc880_asus_modes,
4038		.need_dac_fix = 1,
4039		.input_mux = &alc880_capture_source,
4040	},
4041	[ALC880_UNIWILL] = {
4042		.mixers = { alc880_uniwill_mixer },
4043		.init_verbs = { alc880_volume_init_verbs,
4044				alc880_uniwill_init_verbs },
4045		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4046		.dac_nids = alc880_asus_dac_nids,
4047		.dig_out_nid = ALC880_DIGOUT_NID,
4048		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4049		.channel_mode = alc880_threestack_modes,
4050		.need_dac_fix = 1,
4051		.input_mux = &alc880_capture_source,
4052		.unsol_event = alc880_uniwill_unsol_event,
4053		.init_hook = alc880_uniwill_init_hook,
4054	},
4055	[ALC880_UNIWILL_P53] = {
4056		.mixers = { alc880_uniwill_p53_mixer },
4057		.init_verbs = { alc880_volume_init_verbs,
4058				alc880_uniwill_p53_init_verbs },
4059		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4060		.dac_nids = alc880_asus_dac_nids,
4061		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4062		.channel_mode = alc880_threestack_modes,
4063		.input_mux = &alc880_capture_source,
4064		.unsol_event = alc880_uniwill_p53_unsol_event,
4065		.init_hook = alc880_uniwill_p53_init_hook,
4066	},
4067	[ALC880_FUJITSU] = {
4068		.mixers = { alc880_fujitsu_mixer },
4069		.init_verbs = { alc880_volume_init_verbs,
4070				alc880_uniwill_p53_init_verbs,
4071	       			alc880_beep_init_verbs },
4072		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
4073		.dac_nids = alc880_dac_nids,
4074		.dig_out_nid = ALC880_DIGOUT_NID,
4075		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4076		.channel_mode = alc880_2_jack_modes,
4077		.input_mux = &alc880_capture_source,
4078		.unsol_event = alc880_uniwill_p53_unsol_event,
4079		.init_hook = alc880_uniwill_p53_init_hook,
4080	},
4081	[ALC880_CLEVO] = {
4082		.mixers = { alc880_three_stack_mixer },
4083		.init_verbs = { alc880_volume_init_verbs,
4084				alc880_pin_clevo_init_verbs },
4085		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
4086		.dac_nids = alc880_dac_nids,
4087		.hp_nid = 0x03,
4088		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4089		.channel_mode = alc880_threestack_modes,
4090		.need_dac_fix = 1,
4091		.input_mux = &alc880_capture_source,
4092	},
4093	[ALC880_LG] = {
4094		.mixers = { alc880_lg_mixer },
4095		.init_verbs = { alc880_volume_init_verbs,
4096				alc880_lg_init_verbs },
4097		.num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4098		.dac_nids = alc880_lg_dac_nids,
4099		.dig_out_nid = ALC880_DIGOUT_NID,
4100		.num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4101		.channel_mode = alc880_lg_ch_modes,
4102		.need_dac_fix = 1,
4103		.input_mux = &alc880_lg_capture_source,
4104		.unsol_event = alc_automute_amp_unsol_event,
4105		.init_hook = alc880_lg_init_hook,
4106#ifdef CONFIG_SND_HDA_POWER_SAVE
4107		.loopbacks = alc880_lg_loopbacks,
4108#endif
4109	},
4110	[ALC880_LG_LW] = {
4111		.mixers = { alc880_lg_lw_mixer },
4112		.init_verbs = { alc880_volume_init_verbs,
4113				alc880_lg_lw_init_verbs },
4114		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
4115		.dac_nids = alc880_dac_nids,
4116		.dig_out_nid = ALC880_DIGOUT_NID,
4117		.num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4118		.channel_mode = alc880_lg_lw_modes,
4119		.input_mux = &alc880_lg_lw_capture_source,
4120		.unsol_event = alc_automute_amp_unsol_event,
4121		.init_hook = alc880_lg_lw_init_hook,
4122	},
4123	[ALC880_MEDION_RIM] = {
4124		.mixers = { alc880_medion_rim_mixer },
4125		.init_verbs = { alc880_volume_init_verbs,
4126				alc880_medion_rim_init_verbs,
4127				alc_gpio2_init_verbs },
4128		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
4129		.dac_nids = alc880_dac_nids,
4130		.dig_out_nid = ALC880_DIGOUT_NID,
4131		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4132		.channel_mode = alc880_2_jack_modes,
4133		.input_mux = &alc880_medion_rim_capture_source,
4134		.unsol_event = alc880_medion_rim_unsol_event,
4135		.init_hook = alc880_medion_rim_init_hook,
4136	},
4137#ifdef CONFIG_SND_DEBUG
4138	[ALC880_TEST] = {
4139		.mixers = { alc880_test_mixer },
4140		.init_verbs = { alc880_test_init_verbs },
4141		.num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4142		.dac_nids = alc880_test_dac_nids,
4143		.dig_out_nid = ALC880_DIGOUT_NID,
4144		.num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4145		.channel_mode = alc880_test_modes,
4146		.input_mux = &alc880_test_capture_source,
4147	},
4148#endif
4149};
4150
4151/*
4152 * Automatic parse of I/O pins from the BIOS configuration
4153 */
4154
4155enum {
4156	ALC_CTL_WIDGET_VOL,
4157	ALC_CTL_WIDGET_MUTE,
4158	ALC_CTL_BIND_MUTE,
4159};
4160static struct snd_kcontrol_new alc880_control_templates[] = {
4161	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4162	HDA_CODEC_MUTE(NULL, 0, 0, 0),
4163	HDA_BIND_MUTE(NULL, 0, 0, 0),
4164};
4165
4166/* add dynamic controls */
4167static int add_control(struct alc_spec *spec, int type, const char *name,
4168		       unsigned long val)
4169{
4170	struct snd_kcontrol_new *knew;
4171
4172	snd_array_init(&spec->kctls, sizeof(*knew), 32);
4173	knew = snd_array_new(&spec->kctls);
4174	if (!knew)
4175		return -ENOMEM;
4176	*knew = alc880_control_templates[type];
4177	knew->name = kstrdup(name, GFP_KERNEL);
4178	if (!knew->name)
4179		return -ENOMEM;
4180	knew->private_value = val;
4181	return 0;
4182}
4183
4184#define alc880_is_fixed_pin(nid)	((nid) >= 0x14 && (nid) <= 0x17)
4185#define alc880_fixed_pin_idx(nid)	((nid) - 0x14)
4186#define alc880_is_multi_pin(nid)	((nid) >= 0x18)
4187#define alc880_multi_pin_idx(nid)	((nid) - 0x18)
4188#define alc880_is_input_pin(nid)	((nid) >= 0x18)
4189#define alc880_input_pin_idx(nid)	((nid) - 0x18)
4190#define alc880_idx_to_dac(nid)		((nid) + 0x02)
4191#define alc880_dac_to_idx(nid)		((nid) - 0x02)
4192#define alc880_idx_to_mixer(nid)	((nid) + 0x0c)
4193#define alc880_idx_to_selector(nid)	((nid) + 0x10)
4194#define ALC880_PIN_CD_NID		0x1c
4195
4196/* fill in the dac_nids table from the parsed pin configuration */
4197static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4198				     const struct auto_pin_cfg *cfg)
4199{
4200	hda_nid_t nid;
4201	int assigned[4];
4202	int i, j;
4203
4204	memset(assigned, 0, sizeof(assigned));
4205	spec->multiout.dac_nids = spec->private_dac_nids;
4206
4207	/* check the pins hardwired to audio widget */
4208	for (i = 0; i < cfg->line_outs; i++) {
4209		nid = cfg->line_out_pins[i];
4210		if (alc880_is_fixed_pin(nid)) {
4211			int idx = alc880_fixed_pin_idx(nid);
4212			spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
4213			assigned[idx] = 1;
4214		}
4215	}
4216	/* left pins can be connect to any audio widget */
4217	for (i = 0; i < cfg->line_outs; i++) {
4218		nid = cfg->line_out_pins[i];
4219		if (alc880_is_fixed_pin(nid))
4220			continue;
4221		/* search for an empty channel */
4222		for (j = 0; j < cfg->line_outs; j++) {
4223			if (!assigned[j]) {
4224				spec->multiout.dac_nids[i] =
4225					alc880_idx_to_dac(j);
4226				assigned[j] = 1;
4227				break;
4228			}
4229		}
4230	}
4231	spec->multiout.num_dacs = cfg->line_outs;
4232	return 0;
4233}
4234
4235/* add playback controls from the parsed DAC table */
4236static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4237					     const struct auto_pin_cfg *cfg)
4238{
4239	char name[32];
4240	static const char *chname[4] = {
4241		"Front", "Surround", NULL /*CLFE*/, "Side"
4242	};
4243	hda_nid_t nid;
4244	int i, err;
4245
4246	for (i = 0; i < cfg->line_outs; i++) {
4247		if (!spec->multiout.dac_nids[i])
4248			continue;
4249		nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4250		if (i == 2) {
4251			/* Center/LFE */
4252			err = add_control(spec, ALC_CTL_WIDGET_VOL,
4253					  "Center Playback Volume",
4254					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4255							      HDA_OUTPUT));
4256			if (err < 0)
4257				return err;
4258			err = add_control(spec, ALC_CTL_WIDGET_VOL,
4259					  "LFE Playback Volume",
4260					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4261							      HDA_OUTPUT));
4262			if (err < 0)
4263				return err;
4264			err = add_control(spec, ALC_CTL_BIND_MUTE,
4265					  "Center Playback Switch",
4266					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4267							      HDA_INPUT));
4268			if (err < 0)
4269				return err;
4270			err = add_control(spec, ALC_CTL_BIND_MUTE,
4271					  "LFE Playback Switch",
4272					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4273							      HDA_INPUT));
4274			if (err < 0)
4275				return err;
4276		} else {
4277			sprintf(name, "%s Playback Volume", chname[i]);
4278			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4279					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4280							      HDA_OUTPUT));
4281			if (err < 0)
4282				return err;
4283			sprintf(name, "%s Playback Switch", chname[i]);
4284			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4285					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4286							      HDA_INPUT));
4287			if (err < 0)
4288				return err;
4289		}
4290	}
4291	return 0;
4292}
4293
4294/* add playback controls for speaker and HP outputs */
4295static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4296					const char *pfx)
4297{
4298	hda_nid_t nid;
4299	int err;
4300	char name[32];
4301
4302	if (!pin)
4303		return 0;
4304
4305	if (alc880_is_fixed_pin(pin)) {
4306		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
4307		/* specify the DAC as the extra output */
4308		if (!spec->multiout.hp_nid)
4309			spec->multiout.hp_nid = nid;
4310		else
4311			spec->multiout.extra_out_nid[0] = nid;
4312		/* control HP volume/switch on the output mixer amp */
4313		nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
4314		sprintf(name, "%s Playback Volume", pfx);
4315		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4316				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4317		if (err < 0)
4318			return err;
4319		sprintf(name, "%s Playback Switch", pfx);
4320		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4321				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4322		if (err < 0)
4323			return err;
4324	} else if (alc880_is_multi_pin(pin)) {
4325		/* set manual connection */
4326		/* we have only a switch on HP-out PIN */
4327		sprintf(name, "%s Playback Switch", pfx);
4328		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4329				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4330		if (err < 0)
4331			return err;
4332	}
4333	return 0;
4334}
4335
4336/* create input playback/capture controls for the given pin */
4337static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4338			    const char *ctlname,
4339			    int idx, hda_nid_t mix_nid)
4340{
4341	char name[32];
4342	int err;
4343
4344	sprintf(name, "%s Playback Volume", ctlname);
4345	err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4346			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4347	if (err < 0)
4348		return err;
4349	sprintf(name, "%s Playback Switch", ctlname);
4350	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4351			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4352	if (err < 0)
4353		return err;
4354	return 0;
4355}
4356
4357/* create playback/capture controls for input pins */
4358static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
4359						const struct auto_pin_cfg *cfg)
4360{
4361	struct hda_input_mux *imux = &spec->private_imux[0];
4362	int i, err, idx;
4363
4364	for (i = 0; i < AUTO_PIN_LAST; i++) {
4365		if (alc880_is_input_pin(cfg->input_pins[i])) {
4366			idx = alc880_input_pin_idx(cfg->input_pins[i]);
4367			err = new_analog_input(spec, cfg->input_pins[i],
4368					       auto_pin_cfg_labels[i],
4369					       idx, 0x0b);
4370			if (err < 0)
4371				return err;
4372			imux->items[imux->num_items].label =
4373				auto_pin_cfg_labels[i];
4374			imux->items[imux->num_items].index =
4375				alc880_input_pin_idx(cfg->input_pins[i]);
4376			imux->num_items++;
4377		}
4378	}
4379	return 0;
4380}
4381
4382static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4383			       unsigned int pin_type)
4384{
4385	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4386			    pin_type);
4387	/* unmute pin */
4388	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4389			    AMP_OUT_UNMUTE);
4390}
4391
4392static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4393					      hda_nid_t nid, int pin_type,
4394					      int dac_idx)
4395{
4396	alc_set_pin_output(codec, nid, pin_type);
4397	/* need the manual connection? */
4398	if (alc880_is_multi_pin(nid)) {
4399		struct alc_spec *spec = codec->spec;
4400		int idx = alc880_multi_pin_idx(nid);
4401		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4402				    AC_VERB_SET_CONNECT_SEL,
4403				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4404	}
4405}
4406
4407static int get_pin_type(int line_out_type)
4408{
4409	if (line_out_type == AUTO_PIN_HP_OUT)
4410		return PIN_HP;
4411	else
4412		return PIN_OUT;
4413}
4414
4415static void alc880_auto_init_multi_out(struct hda_codec *codec)
4416{
4417	struct alc_spec *spec = codec->spec;
4418	int i;
4419
4420	for (i = 0; i < spec->autocfg.line_outs; i++) {
4421		hda_nid_t nid = spec->autocfg.line_out_pins[i];
4422		int pin_type = get_pin_type(spec->autocfg.line_out_type);
4423		alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
4424	}
4425}
4426
4427static void alc880_auto_init_extra_out(struct hda_codec *codec)
4428{
4429	struct alc_spec *spec = codec->spec;
4430	hda_nid_t pin;
4431
4432	pin = spec->autocfg.speaker_pins[0];
4433	if (pin) /* connect to front */
4434		alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
4435	pin = spec->autocfg.hp_pins[0];
4436	if (pin) /* connect to front */
4437		alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4438}
4439
4440static void alc880_auto_init_analog_input(struct hda_codec *codec)
4441{
4442	struct alc_spec *spec = codec->spec;
4443	int i;
4444
4445	for (i = 0; i < AUTO_PIN_LAST; i++) {
4446		hda_nid_t nid = spec->autocfg.input_pins[i];
4447		if (alc880_is_input_pin(nid)) {
4448			alc_set_input_pin(codec, nid, i);
4449			if (nid != ALC880_PIN_CD_NID &&
4450			    (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
4451				snd_hda_codec_write(codec, nid, 0,
4452						    AC_VERB_SET_AMP_GAIN_MUTE,
4453						    AMP_OUT_MUTE);
4454		}
4455	}
4456}
4457
4458/* parse the BIOS configuration and set up the alc_spec */
4459/* return 1 if successful, 0 if the proper config is not found,
4460 * or a negative error code
4461 */
4462static int alc880_parse_auto_config(struct hda_codec *codec)
4463{
4464	struct alc_spec *spec = codec->spec;
4465	int i, err;
4466	static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
4467
4468	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4469					   alc880_ignore);
4470	if (err < 0)
4471		return err;
4472	if (!spec->autocfg.line_outs)
4473		return 0; /* can't find valid BIOS pin config */
4474
4475	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4476	if (err < 0)
4477		return err;
4478	err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4479	if (err < 0)
4480		return err;
4481	err = alc880_auto_create_extra_out(spec,
4482					   spec->autocfg.speaker_pins[0],
4483					   "Speaker");
4484	if (err < 0)
4485		return err;
4486	err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4487					   "Headphone");
4488	if (err < 0)
4489		return err;
4490	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
4491	if (err < 0)
4492		return err;
4493
4494	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4495
4496	/* check multiple SPDIF-out (for recent codecs) */
4497	for (i = 0; i < spec->autocfg.dig_outs; i++) {
4498		hda_nid_t dig_nid;
4499		err = snd_hda_get_connections(codec,
4500					      spec->autocfg.dig_out_pins[i],
4501					      &dig_nid, 1);
4502		if (err < 0)
4503			continue;
4504		if (!i)
4505			spec->multiout.dig_out_nid = dig_nid;
4506		else {
4507			spec->multiout.slave_dig_outs = spec->slave_dig_outs;
4508			spec->slave_dig_outs[i - 1] = dig_nid;
4509			if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1)
4510				break;
4511		}
4512	}
4513	if (spec->autocfg.dig_in_pin)
4514		spec->dig_in_nid = ALC880_DIGIN_NID;
4515
4516	if (spec->kctls.list)
4517		add_mixer(spec, spec->kctls.list);
4518
4519	add_verb(spec, alc880_volume_init_verbs);
4520
4521	spec->num_mux_defs = 1;
4522	spec->input_mux = &spec->private_imux[0];
4523
4524	alc_ssid_check(codec, 0x15, 0x1b, 0x14);
4525
4526	return 1;
4527}
4528
4529/* additional initialization for auto-configuration model */
4530static void alc880_auto_init(struct hda_codec *codec)
4531{
4532	struct alc_spec *spec = codec->spec;
4533	alc880_auto_init_multi_out(codec);
4534	alc880_auto_init_extra_out(codec);
4535	alc880_auto_init_analog_input(codec);
4536	if (spec->unsol_event)
4537		alc_inithook(codec);
4538}
4539
4540static void set_capture_mixer(struct alc_spec *spec)
4541{
4542	static struct snd_kcontrol_new *caps[2][3] = {
4543		{ alc_capture_mixer_nosrc1,
4544		  alc_capture_mixer_nosrc2,
4545		  alc_capture_mixer_nosrc3 },
4546		{ alc_capture_mixer1,
4547		  alc_capture_mixer2,
4548		  alc_capture_mixer3 },
4549	};
4550	if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
4551		int mux;
4552		if (spec->input_mux && spec->input_mux->num_items > 1)
4553			mux = 1;
4554		else
4555			mux = 0;
4556		spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
4557	}
4558}
4559
4560#define set_beep_amp(spec, nid, idx, dir) \
4561	((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
4562
4563/*
4564 * OK, here we have finally the patch for ALC880
4565 */
4566
4567static int patch_alc880(struct hda_codec *codec)
4568{
4569	struct alc_spec *spec;
4570	int board_config;
4571	int err;
4572
4573	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4574	if (spec == NULL)
4575		return -ENOMEM;
4576
4577	codec->spec = spec;
4578
4579	board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4580						  alc880_models,
4581						  alc880_cfg_tbl);
4582	if (board_config < 0) {
4583		printk(KERN_INFO "hda_codec: Unknown model for %s, "
4584		       "trying auto-probe from BIOS...\n", codec->chip_name);
4585		board_config = ALC880_AUTO;
4586	}
4587
4588	if (board_config == ALC880_AUTO) {
4589		/* automatic parse from the BIOS config */
4590		err = alc880_parse_auto_config(codec);
4591		if (err < 0) {
4592			alc_free(codec);
4593			return err;
4594		} else if (!err) {
4595			printk(KERN_INFO
4596			       "hda_codec: Cannot set up configuration "
4597			       "from BIOS.  Using 3-stack mode...\n");
4598			board_config = ALC880_3ST;
4599		}
4600	}
4601
4602	err = snd_hda_attach_beep_device(codec, 0x1);
4603	if (err < 0) {
4604		alc_free(codec);
4605		return err;
4606	}
4607
4608	if (board_config != ALC880_AUTO)
4609		setup_preset(spec, &alc880_presets[board_config]);
4610
4611	spec->stream_analog_playback = &alc880_pcm_analog_playback;
4612	spec->stream_analog_capture = &alc880_pcm_analog_capture;
4613	spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
4614
4615	spec->stream_digital_playback = &alc880_pcm_digital_playback;
4616	spec->stream_digital_capture = &alc880_pcm_digital_capture;
4617
4618	if (!spec->adc_nids && spec->input_mux) {
4619		/* check whether NID 0x07 is valid */
4620		unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
4621		/* get type */
4622		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
4623		if (wcap != AC_WID_AUD_IN) {
4624			spec->adc_nids = alc880_adc_nids_alt;
4625			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
4626		} else {
4627			spec->adc_nids = alc880_adc_nids;
4628			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
4629		}
4630	}
4631	set_capture_mixer(spec);
4632	set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4633
4634	spec->vmaster_nid = 0x0c;
4635
4636	codec->patch_ops = alc_patch_ops;
4637	if (board_config == ALC880_AUTO)
4638		spec->init_hook = alc880_auto_init;
4639#ifdef CONFIG_SND_HDA_POWER_SAVE
4640	if (!spec->loopback.amplist)
4641		spec->loopback.amplist = alc880_loopbacks;
4642#endif
4643	codec->proc_widget_hook = print_realtek_coef;
4644
4645	return 0;
4646}
4647
4648
4649/*
4650 * ALC260 support
4651 */
4652
4653static hda_nid_t alc260_dac_nids[1] = {
4654	/* front */
4655	0x02,
4656};
4657
4658static hda_nid_t alc260_adc_nids[1] = {
4659	/* ADC0 */
4660	0x04,
4661};
4662
4663static hda_nid_t alc260_adc_nids_alt[1] = {
4664	/* ADC1 */
4665	0x05,
4666};
4667
4668/* NIDs used when simultaneous access to both ADCs makes sense.  Note that
4669 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4670 */
4671static hda_nid_t alc260_dual_adc_nids[2] = {
4672	/* ADC0, ADC1 */
4673	0x04, 0x05
4674};
4675
4676#define ALC260_DIGOUT_NID	0x03
4677#define ALC260_DIGIN_NID	0x06
4678
4679static struct hda_input_mux alc260_capture_source = {
4680	.num_items = 4,
4681	.items = {
4682		{ "Mic", 0x0 },
4683		{ "Front Mic", 0x1 },
4684		{ "Line", 0x2 },
4685		{ "CD", 0x4 },
4686	},
4687};
4688
4689/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
4690 * headphone jack and the internal CD lines since these are the only pins at
4691 * which audio can appear.  For flexibility, also allow the option of
4692 * recording the mixer output on the second ADC (ADC0 doesn't have a
4693 * connection to the mixer output).
4694 */
4695static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4696	{
4697		.num_items = 3,
4698		.items = {
4699			{ "Mic/Line", 0x0 },
4700			{ "CD", 0x4 },
4701			{ "Headphone", 0x2 },
4702		},
4703	},
4704	{
4705		.num_items = 4,
4706		.items = {
4707			{ "Mic/Line", 0x0 },
4708			{ "CD", 0x4 },
4709			{ "Headphone", 0x2 },
4710			{ "Mixer", 0x5 },
4711		},
4712	},
4713
4714};
4715
4716/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4717 * the Fujitsu S702x, but jacks are marked differently.
4718 */
4719static struct hda_input_mux alc260_acer_capture_sources[2] = {
4720	{
4721		.num_items = 4,
4722		.items = {
4723			{ "Mic", 0x0 },
4724			{ "Line", 0x2 },
4725			{ "CD", 0x4 },
4726			{ "Headphone", 0x5 },
4727		},
4728	},
4729	{
4730		.num_items = 5,
4731		.items = {
4732			{ "Mic", 0x0 },
4733			{ "Line", 0x2 },
4734			{ "CD", 0x4 },
4735			{ "Headphone", 0x6 },
4736			{ "Mixer", 0x5 },
4737		},
4738	},
4739};
4740
4741/* Maxdata Favorit 100XS */
4742static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
4743	{
4744		.num_items = 2,
4745		.items = {
4746			{ "Line/Mic", 0x0 },
4747			{ "CD", 0x4 },
4748		},
4749	},
4750	{
4751		.num_items = 3,
4752		.items = {
4753			{ "Line/Mic", 0x0 },
4754			{ "CD", 0x4 },
4755			{ "Mixer", 0x5 },
4756		},
4757	},
4758};
4759
4760/*
4761 * This is just place-holder, so there's something for alc_build_pcms to look
4762 * at when it calculates the maximum number of channels. ALC260 has no mixer
4763 * element which allows changing the channel mode, so the verb list is
4764 * never used.
4765 */
4766static struct hda_channel_mode alc260_modes[1] = {
4767	{ 2, NULL },
4768};
4769
4770
4771/* Mixer combinations
4772 *
4773 * basic: base_output + input + pc_beep + capture
4774 * HP: base_output + input + capture_alt
4775 * HP_3013: hp_3013 + input + capture
4776 * fujitsu: fujitsu + capture
4777 * acer: acer + capture
4778 */
4779
4780static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4781	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4782	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4783	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4784	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4785	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4786	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4787	{ } /* end */
4788};
4789
4790static struct snd_kcontrol_new alc260_input_mixer[] = {
4791	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4792	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4793	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4794	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4795	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4796	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4797	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4798	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4799	{ } /* end */
4800};
4801
4802/* update HP, line and mono out pins according to the master switch */
4803static void alc260_hp_master_update(struct hda_codec *codec,
4804				    hda_nid_t hp, hda_nid_t line,
4805				    hda_nid_t mono)
4806{
4807	struct alc_spec *spec = codec->spec;
4808	unsigned int val = spec->master_sw ? PIN_HP : 0;
4809	/* change HP and line-out pins */
4810	snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4811			    val);
4812	snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4813			    val);
4814	/* mono (speaker) depending on the HP jack sense */
4815	val = (val && !spec->jack_present) ? PIN_OUT : 0;
4816	snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4817			    val);
4818}
4819
4820static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4821				   struct snd_ctl_elem_value *ucontrol)
4822{
4823	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4824	struct alc_spec *spec = codec->spec;
4825	*ucontrol->value.integer.value = spec->master_sw;
4826	return 0;
4827}
4828
4829static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4830				   struct snd_ctl_elem_value *ucontrol)
4831{
4832	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4833	struct alc_spec *spec = codec->spec;
4834	int val = !!*ucontrol->value.integer.value;
4835	hda_nid_t hp, line, mono;
4836
4837	if (val == spec->master_sw)
4838		return 0;
4839	spec->master_sw = val;
4840	hp = (kcontrol->private_value >> 16) & 0xff;
4841	line = (kcontrol->private_value >> 8) & 0xff;
4842	mono = kcontrol->private_value & 0xff;
4843	alc260_hp_master_update(codec, hp, line, mono);
4844	return 1;
4845}
4846
4847static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4848	{
4849		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4850		.name = "Master Playback Switch",
4851		.info = snd_ctl_boolean_mono_info,
4852		.get = alc260_hp_master_sw_get,
4853		.put = alc260_hp_master_sw_put,
4854		.private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4855	},
4856	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4857	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4858	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4859	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4860	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4861			      HDA_OUTPUT),
4862	HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4863	{ } /* end */
4864};
4865
4866static struct hda_verb alc260_hp_unsol_verbs[] = {
4867	{0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4868	{},
4869};
4870
4871static void alc260_hp_automute(struct hda_codec *codec)
4872{
4873	struct alc_spec *spec = codec->spec;
4874	unsigned int present;
4875
4876	present = snd_hda_codec_read(codec, 0x10, 0,
4877				     AC_VERB_GET_PIN_SENSE, 0);
4878	spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4879	alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4880}
4881
4882static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4883{
4884	if ((res >> 26) == ALC880_HP_EVENT)
4885		alc260_hp_automute(codec);
4886}
4887
4888static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4889	{
4890		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4891		.name = "Master Playback Switch",
4892		.info = snd_ctl_boolean_mono_info,
4893		.get = alc260_hp_master_sw_get,
4894		.put = alc260_hp_master_sw_put,
4895		.private_value = (0x15 << 16) | (0x10 << 8) | 0x11
4896	},
4897	HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4898	HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4899	HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4900	HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4901	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4902	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4903	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4904	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4905	{ } /* end */
4906};
4907
4908static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4909	.ops = &snd_hda_bind_vol,
4910	.values = {
4911		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4912		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4913		HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4914		0
4915	},
4916};
4917
4918static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4919	.ops = &snd_hda_bind_sw,
4920	.values = {
4921		HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4922		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4923		0
4924	},
4925};
4926
4927static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4928	HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4929	HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4930	HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4931	HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4932	{ } /* end */
4933};
4934
4935static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4936	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4937	{},
4938};
4939
4940static void alc260_hp_3013_automute(struct hda_codec *codec)
4941{
4942	struct alc_spec *spec = codec->spec;
4943	unsigned int present;
4944
4945	present = snd_hda_codec_read(codec, 0x15, 0,
4946				     AC_VERB_GET_PIN_SENSE, 0);
4947	spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4948	alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
4949}
4950
4951static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4952				       unsigned int res)
4953{
4954	if ((res >> 26) == ALC880_HP_EVENT)
4955		alc260_hp_3013_automute(codec);
4956}
4957
4958static void alc260_hp_3012_automute(struct hda_codec *codec)
4959{
4960	unsigned int present, bits;
4961
4962	present = snd_hda_codec_read(codec, 0x10, 0,
4963			AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4964
4965	bits = present ? 0 : PIN_OUT;
4966	snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4967			    bits);
4968	snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4969			    bits);
4970	snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4971			    bits);
4972}
4973
4974static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4975				       unsigned int res)
4976{
4977	if ((res >> 26) == ALC880_HP_EVENT)
4978		alc260_hp_3012_automute(codec);
4979}
4980
4981/* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12,
4982 * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
4983 */
4984static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4985	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4986	HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4987	ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4988	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4989	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4990	HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4991	HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4992	ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4993	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4994	HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4995	{ } /* end */
4996};
4997
4998/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
4999 * versions of the ALC260 don't act on requests to enable mic bias from NID
5000 * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
5001 * datasheet doesn't mention this restriction.  At this stage it's not clear
5002 * whether this behaviour is intentional or is a hardware bug in chip
5003 * revisions available in early 2006.  Therefore for now allow the
5004 * "Headphone Jack Mode" control to span all choices, but if it turns out
5005 * that the lack of mic bias for this NID is intentional we could change the
5006 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5007 *
5008 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
5009 * don't appear to make the mic bias available from the "line" jack, even
5010 * though the NID used for this jack (0x14) can supply it.  The theory is
5011 * that perhaps Acer have included blocking capacitors between the ALC260
5012 * and the output jack.  If this turns out to be the case for all such
5013 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
5014 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
5015 *
5016 * The C20x Tablet series have a mono internal speaker which is controlled
5017 * via the chip's Mono sum widget and pin complex, so include the necessary
5018 * controls for such models.  On models without a "mono speaker" the control
5019 * won't do anything.
5020 */
5021static struct snd_kcontrol_new alc260_acer_mixer[] = {
5022	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5023	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5024	ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5025	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5026			      HDA_OUTPUT),
5027	HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
5028			   HDA_INPUT),
5029	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5030	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5031	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5032	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5033	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5034	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5035	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5036	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5037	{ } /* end */
5038};
5039
5040/* Maxdata Favorit 100XS: one output and one input (0x12) jack
5041 */
5042static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
5043	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5044	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5045	ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5046	HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5047	HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5048	ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5049	{ } /* end */
5050};
5051
5052/* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
5053 * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
5054 */
5055static struct snd_kcontrol_new alc260_will_mixer[] = {
5056	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5057	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5058	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5059	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5060	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5061	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5062	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5063	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5064	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5065	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5066	{ } /* end */
5067};
5068
5069/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
5070 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
5071 */
5072static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
5073	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5074	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5075	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5076	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5077	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5078	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
5079	HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
5080	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5081	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5082	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5083	{ } /* end */
5084};
5085
5086/*
5087 * initialization verbs
5088 */
5089static struct hda_verb alc260_init_verbs[] = {
5090	/* Line In pin widget for input */
5091	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5092	/* CD pin widget for input */
5093	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5094	/* Mic1 (rear panel) pin widget for input and vref at 80% */
5095	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5096	/* Mic2 (front panel) pin widget for input and vref at 80% */
5097	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5098	/* LINE-2 is used for line-out in rear */
5099	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5100	/* select line-out */
5101	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
5102	/* LINE-OUT pin */
5103	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5104	/* enable HP */
5105	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5106	/* enable Mono */
5107	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5108	/* mute capture amp left and right */
5109	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5110	/* set connection select to line in (default select for this ADC) */
5111	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5112	/* mute capture amp left and right */
5113	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5114	/* set connection select to line in (default select for this ADC) */
5115	{0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
5116	/* set vol=0 Line-Out mixer amp left and right */
5117	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5118	/* unmute pin widget amp left and right (no gain on this amp) */
5119	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5120	/* set vol=0 HP mixer amp left and right */
5121	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5122	/* unmute pin widget amp left and right (no gain on this amp) */
5123	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5124	/* set vol=0 Mono mixer amp left and right */
5125	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5126	/* unmute pin widget amp left and right (no gain on this amp) */
5127	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5128	/* unmute LINE-2 out pin */
5129	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5130	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5131	 * Line In 2 = 0x03
5132	 */
5133	/* mute analog inputs */
5134	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5135	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5136	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5137	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5138	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5139	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5140	/* mute Front out path */
5141	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5142	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5143	/* mute Headphone out path */
5144	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5145	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5146	/* mute Mono out path */
5147	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5148	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5149	{ }
5150};
5151
5152#if 0 /* should be identical with alc260_init_verbs? */
5153static struct hda_verb alc260_hp_init_verbs[] = {
5154	/* Headphone and output */
5155	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5156	/* mono output */
5157	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5158	/* Mic1 (rear panel) pin widget for input and vref at 80% */
5159	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5160	/* Mic2 (front panel) pin widget for input and vref at 80% */
5161	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5162	/* Line In pin widget for input */
5163	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5164	/* Line-2 pin widget for output */
5165	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5166	/* CD pin widget for input */
5167	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5168	/* unmute amp left and right */
5169	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5170	/* set connection select to line in (default select for this ADC) */
5171	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5172	/* unmute Line-Out mixer amp left and right (volume = 0) */
5173	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5174	/* mute pin widget amp left and right (no gain on this amp) */
5175	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5176	/* unmute HP mixer amp left and right (volume = 0) */
5177	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5178	/* mute pin widget amp left and right (no gain on this amp) */
5179	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5180	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5181	 * Line In 2 = 0x03
5182	 */
5183	/* mute analog inputs */
5184	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5185	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5186	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5187	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5188	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5189	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5190	/* Unmute Front out path */
5191	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5192	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5193	/* Unmute Headphone out path */
5194	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5195	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5196	/* Unmute Mono out path */
5197	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5198	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5199	{ }
5200};
5201#endif
5202
5203static struct hda_verb alc260_hp_3013_init_verbs[] = {
5204	/* Line out and output */
5205	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5206	/* mono output */
5207	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5208	/* Mic1 (rear panel) pin widget for input and vref at 80% */
5209	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5210	/* Mic2 (front panel) pin widget for input and vref at 80% */
5211	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5212	/* Line In pin widget for input */
5213	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5214	/* Headphone pin widget for output */
5215	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5216	/* CD pin widget for input */
5217	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5218	/* unmute amp left and right */
5219	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5220	/* set connection select to line in (default select for this ADC) */
5221	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5222	/* unmute Line-Out mixer amp left and right (volume = 0) */
5223	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5224	/* mute pin widget amp left and right (no gain on this amp) */
5225	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5226	/* unmute HP mixer amp left and right (volume = 0) */
5227	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5228	/* mute pin widget amp left and right (no gain on this amp) */
5229	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5230	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5231	 * Line In 2 = 0x03
5232	 */
5233	/* mute analog inputs */
5234	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5235	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5236	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5237	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5238	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5239	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5240	/* Unmute Front out path */
5241	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5242	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5243	/* Unmute Headphone out path */
5244	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5245	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5246	/* Unmute Mono out path */
5247	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5248	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5249	{ }
5250};
5251
5252/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
5253 * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
5254 * audio = 0x16, internal speaker = 0x10.
5255 */
5256static struct hda_verb alc260_fujitsu_init_verbs[] = {
5257	/* Disable all GPIOs */
5258	{0x01, AC_VERB_SET_GPIO_MASK, 0},
5259	/* Internal speaker is connected to headphone pin */
5260	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5261	/* Headphone/Line-out jack connects to Line1 pin; make it an output */
5262	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5263	/* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5264	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5265	/* Ensure all other unused pins are disabled and muted. */
5266	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5267	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5268	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5269	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5270	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5271	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5272	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5273	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5274
5275	/* Disable digital (SPDIF) pins */
5276	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5277	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5278
5279	/* Ensure Line1 pin widget takes its input from the OUT1 sum bus
5280	 * when acting as an output.
5281	 */
5282	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5283
5284	/* Start with output sum widgets muted and their output gains at min */
5285	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5286	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5287	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5288	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5289	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5290	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5291	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5292	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5293	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5294
5295	/* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5296	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5297	/* Unmute Line1 pin widget output buffer since it starts as an output.
5298	 * If the pin mode is changed by the user the pin mode control will
5299	 * take care of enabling the pin's input/output buffers as needed.
5300	 * Therefore there's no need to enable the input buffer at this
5301	 * stage.
5302	 */
5303	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5304	/* Unmute input buffer of pin widget used for Line-in (no equiv
5305	 * mixer ctrl)
5306	 */
5307	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5308
5309	/* Mute capture amp left and right */
5310	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5311	/* Set ADC connection select to match default mixer setting - line
5312	 * in (on mic1 pin)
5313	 */
5314	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5315
5316	/* Do the same for the second ADC: mute capture input amp and
5317	 * set ADC connection to line in (on mic1 pin)
5318	 */
5319	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5320	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5321
5322	/* Mute all inputs to mixer widget (even unconnected ones) */
5323	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5324	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5325	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5326	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5327	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5328	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5329	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5330	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5331
5332	{ }
5333};
5334
5335/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5336 * similar laptops (adapted from Fujitsu init verbs).
5337 */
5338static struct hda_verb alc260_acer_init_verbs[] = {
5339	/* On TravelMate laptops, GPIO 0 enables the internal speaker and
5340	 * the headphone jack.  Turn this on and rely on the standard mute
5341	 * methods whenever the user wants to turn these outputs off.
5342	 */
5343	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5344	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5345	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5346	/* Internal speaker/Headphone jack is connected to Line-out pin */
5347	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5348	/* Internal microphone/Mic jack is connected to Mic1 pin */
5349	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5350	/* Line In jack is connected to Line1 pin */
5351	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5352	/* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5353	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5354	/* Ensure all other unused pins are disabled and muted. */
5355	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5356	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5357	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5358	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5359	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5360	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5361	/* Disable digital (SPDIF) pins */
5362	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5363	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5364
5365	/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5366	 * bus when acting as outputs.
5367	 */
5368	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5369	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5370
5371	/* Start with output sum widgets muted and their output gains at min */
5372	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5373	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5374	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5375	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5376	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5377	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5378	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5379	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5380	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5381
5382	/* Unmute Line-out pin widget amp left and right
5383	 * (no equiv mixer ctrl)
5384	 */
5385	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5386	/* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5387	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5388	/* Unmute Mic1 and Line1 pin widget input buffers since they start as
5389	 * inputs. If the pin mode is changed by the user the pin mode control
5390	 * will take care of enabling the pin's input/output buffers as needed.
5391	 * Therefore there's no need to enable the input buffer at this
5392	 * stage.
5393	 */
5394	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5395	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5396
5397	/* Mute capture amp left and right */
5398	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5399	/* Set ADC connection select to match default mixer setting - mic
5400	 * (on mic1 pin)
5401	 */
5402	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5403
5404	/* Do similar with the second ADC: mute capture input amp and
5405	 * set ADC connection to mic to match ALSA's default state.
5406	 */
5407	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5408	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5409
5410	/* Mute all inputs to mixer widget (even unconnected ones) */
5411	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5412	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5413	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5414	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5415	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5416	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5417	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5418	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5419
5420	{ }
5421};
5422
5423/* Initialisation sequence for Maxdata Favorit 100XS
5424 * (adapted from Acer init verbs).
5425 */
5426static struct hda_verb alc260_favorit100_init_verbs[] = {
5427	/* GPIO 0 enables the output jack.
5428	 * Turn this on and rely on the standard mute
5429	 * methods whenever the user wants to turn these outputs off.
5430	 */
5431	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5432	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5433	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5434	/* Line/Mic input jack is connected to Mic1 pin */
5435	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5436	/* Ensure all other unused pins are disabled and muted. */
5437	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5438	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5439	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5440	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5441	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5442	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5443	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5444	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5445	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5446	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5447	/* Disable digital (SPDIF) pins */
5448	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5449	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5450
5451	/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5452	 * bus when acting as outputs.
5453	 */
5454	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5455	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5456
5457	/* Start with output sum widgets muted and their output gains at min */
5458	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5459	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5460	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5461	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5462	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5463	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5464	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5465	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5466	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5467
5468	/* Unmute Line-out pin widget amp left and right
5469	 * (no equiv mixer ctrl)
5470	 */
5471	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5472	/* Unmute Mic1 and Line1 pin widget input buffers since they start as
5473	 * inputs. If the pin mode is changed by the user the pin mode control
5474	 * will take care of enabling the pin's input/output buffers as needed.
5475	 * Therefore there's no need to enable the input buffer at this
5476	 * stage.
5477	 */
5478	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5479
5480	/* Mute capture amp left and right */
5481	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5482	/* Set ADC connection select to match default mixer setting - mic
5483	 * (on mic1 pin)
5484	 */
5485	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5486
5487	/* Do similar with the second ADC: mute capture input amp and
5488	 * set ADC connection to mic to match ALSA's default state.
5489	 */
5490	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5491	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5492
5493	/* Mute all inputs to mixer widget (even unconnected ones) */
5494	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5495	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5496	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5497	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5498	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5499	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5500	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5501	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5502
5503	{ }
5504};
5505
5506static struct hda_verb alc260_will_verbs[] = {
5507	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5508	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
5509	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
5510	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5511	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5512	{0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
5513	{}
5514};
5515
5516static struct hda_verb alc260_replacer_672v_verbs[] = {
5517	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5518	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5519	{0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
5520
5521	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5522	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5523	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5524
5525	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5526	{}
5527};
5528
5529/* toggle speaker-output according to the hp-jack state */
5530static void alc260_replacer_672v_automute(struct hda_codec *codec)
5531{
5532        unsigned int present;
5533
5534	/* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
5535        present = snd_hda_codec_read(codec, 0x0f, 0,
5536                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5537	if (present) {
5538		snd_hda_codec_write_cache(codec, 0x01, 0,
5539					  AC_VERB_SET_GPIO_DATA, 1);
5540		snd_hda_codec_write_cache(codec, 0x0f, 0,
5541					  AC_VERB_SET_PIN_WIDGET_CONTROL,
5542					  PIN_HP);
5543	} else {
5544		snd_hda_codec_write_cache(codec, 0x01, 0,
5545					  AC_VERB_SET_GPIO_DATA, 0);
5546		snd_hda_codec_write_cache(codec, 0x0f, 0,
5547					  AC_VERB_SET_PIN_WIDGET_CONTROL,
5548					  PIN_OUT);
5549	}
5550}
5551
5552static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
5553                                       unsigned int res)
5554{
5555        if ((res >> 26) == ALC880_HP_EVENT)
5556                alc260_replacer_672v_automute(codec);
5557}
5558
5559static struct hda_verb alc260_hp_dc7600_verbs[] = {
5560	{0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
5561	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5562	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5563	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5564	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5565	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5566	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5567	{0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5568	{0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5569	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5570	{}
5571};
5572
5573/* Test configuration for debugging, modelled after the ALC880 test
5574 * configuration.
5575 */
5576#ifdef CONFIG_SND_DEBUG
5577static hda_nid_t alc260_test_dac_nids[1] = {
5578	0x02,
5579};
5580static hda_nid_t alc260_test_adc_nids[2] = {
5581	0x04, 0x05,
5582};
5583/* For testing the ALC260, each input MUX needs its own definition since
5584 * the signal assignments are different.  This assumes that the first ADC
5585 * is NID 0x04.
5586 */
5587static struct hda_input_mux alc260_test_capture_sources[2] = {
5588	{
5589		.num_items = 7,
5590		.items = {
5591			{ "MIC1 pin", 0x0 },
5592			{ "MIC2 pin", 0x1 },
5593			{ "LINE1 pin", 0x2 },
5594			{ "LINE2 pin", 0x3 },
5595			{ "CD pin", 0x4 },
5596			{ "LINE-OUT pin", 0x5 },
5597			{ "HP-OUT pin", 0x6 },
5598		},
5599        },
5600	{
5601		.num_items = 8,
5602		.items = {
5603			{ "MIC1 pin", 0x0 },
5604			{ "MIC2 pin", 0x1 },
5605			{ "LINE1 pin", 0x2 },
5606			{ "LINE2 pin", 0x3 },
5607			{ "CD pin", 0x4 },
5608			{ "Mixer", 0x5 },
5609			{ "LINE-OUT pin", 0x6 },
5610			{ "HP-OUT pin", 0x7 },
5611		},
5612        },
5613};
5614static struct snd_kcontrol_new alc260_test_mixer[] = {
5615	/* Output driver widgets */
5616	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5617	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5618	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5619	HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
5620	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5621	HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
5622
5623	/* Modes for retasking pin widgets
5624	 * Note: the ALC260 doesn't seem to act on requests to enable mic
5625         * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
5626         * mention this restriction.  At this stage it's not clear whether
5627         * this behaviour is intentional or is a hardware bug in chip
5628         * revisions available at least up until early 2006.  Therefore for
5629         * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5630         * choices, but if it turns out that the lack of mic bias for these
5631         * NIDs is intentional we could change their modes from
5632         * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5633	 */
5634	ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5635	ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5636	ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5637	ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5638	ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5639	ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5640
5641	/* Loopback mixer controls */
5642	HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5643	HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5644	HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5645	HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5646	HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5647	HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5648	HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5649	HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5650	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5651	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5652	HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5653	HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5654	HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5655	HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5656
5657	/* Controls for GPIO pins, assuming they are configured as outputs */
5658	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5659	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5660	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5661	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5662
5663	/* Switches to allow the digital IO pins to be enabled.  The datasheet
5664	 * is ambigious as to which NID is which; testing on laptops which
5665	 * make this output available should provide clarification.
5666	 */
5667	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5668	ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5669
5670	/* A switch allowing EAPD to be enabled.  Some laptops seem to use
5671	 * this output to turn on an external amplifier.
5672	 */
5673	ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5674	ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5675
5676	{ } /* end */
5677};
5678static struct hda_verb alc260_test_init_verbs[] = {
5679	/* Enable all GPIOs as outputs with an initial value of 0 */
5680	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5681	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5682	{0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5683
5684	/* Enable retasking pins as output, initially without power amp */
5685	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5686	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5687	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5688	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5689	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5690	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5691
5692	/* Disable digital (SPDIF) pins initially, but users can enable
5693	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
5694	 * payload also sets the generation to 0, output to be in "consumer"
5695	 * PCM format, copyright asserted, no pre-emphasis and no validity
5696	 * control.
5697	 */
5698	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5699	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5700
5701	/* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
5702	 * OUT1 sum bus when acting as an output.
5703	 */
5704	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5705	{0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5706	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5707	{0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5708
5709	/* Start with output sum widgets muted and their output gains at min */
5710	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5711	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5712	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5713	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5714	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5715	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5716	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5717	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5718	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5719
5720	/* Unmute retasking pin widget output buffers since the default
5721	 * state appears to be output.  As the pin mode is changed by the
5722	 * user the pin mode control will take care of enabling the pin's
5723	 * input/output buffers as needed.
5724	 */
5725	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5726	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5727	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5728	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5729	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5730	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5731	/* Also unmute the mono-out pin widget */
5732	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5733
5734	/* Mute capture amp left and right */
5735	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5736	/* Set ADC connection select to match default mixer setting (mic1
5737	 * pin)
5738	 */
5739	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5740
5741	/* Do the same for the second ADC: mute capture input amp and
5742	 * set ADC connection to mic1 pin
5743	 */
5744	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5745	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5746
5747	/* Mute all inputs to mixer widget (even unconnected ones) */
5748	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5749	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5750	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5751	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5752	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5753	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5754	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5755	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5756
5757	{ }
5758};
5759#endif
5760
5761#define alc260_pcm_analog_playback	alc880_pcm_analog_alt_playback
5762#define alc260_pcm_analog_capture	alc880_pcm_analog_capture
5763
5764#define alc260_pcm_digital_playback	alc880_pcm_digital_playback
5765#define alc260_pcm_digital_capture	alc880_pcm_digital_capture
5766
5767/*
5768 * for BIOS auto-configuration
5769 */
5770
5771static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
5772					const char *pfx, int *vol_bits)
5773{
5774	hda_nid_t nid_vol;
5775	unsigned long vol_val, sw_val;
5776	char name[32];
5777	int err;
5778
5779	if (nid >= 0x0f && nid < 0x11) {
5780		nid_vol = nid - 0x7;
5781		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5782		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5783	} else if (nid == 0x11) {
5784		nid_vol = nid - 0x7;
5785		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5786		sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5787	} else if (nid >= 0x12 && nid <= 0x15) {
5788		nid_vol = 0x08;
5789		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5790		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5791	} else
5792		return 0; /* N/A */
5793
5794	if (!(*vol_bits & (1 << nid_vol))) {
5795		/* first control for the volume widget */
5796		snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5797		err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5798		if (err < 0)
5799			return err;
5800		*vol_bits |= (1 << nid_vol);
5801	}
5802	snprintf(name, sizeof(name), "%s Playback Switch", pfx);
5803	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5804	if (err < 0)
5805		return err;
5806	return 1;
5807}
5808
5809/* add playback controls from the parsed DAC table */
5810static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5811					     const struct auto_pin_cfg *cfg)
5812{
5813	hda_nid_t nid;
5814	int err;
5815	int vols = 0;
5816
5817	spec->multiout.num_dacs = 1;
5818	spec->multiout.dac_nids = spec->private_dac_nids;
5819	spec->multiout.dac_nids[0] = 0x02;
5820
5821	nid = cfg->line_out_pins[0];
5822	if (nid) {
5823		err = alc260_add_playback_controls(spec, nid, "Front", &vols);
5824		if (err < 0)
5825			return err;
5826	}
5827
5828	nid = cfg->speaker_pins[0];
5829	if (nid) {
5830		err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
5831		if (err < 0)
5832			return err;
5833	}
5834
5835	nid = cfg->hp_pins[0];
5836	if (nid) {
5837		err = alc260_add_playback_controls(spec, nid, "Headphone",
5838						   &vols);
5839		if (err < 0)
5840			return err;
5841	}
5842	return 0;
5843}
5844
5845/* create playback/capture controls for input pins */
5846static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5847						const struct auto_pin_cfg *cfg)
5848{
5849	struct hda_input_mux *imux = &spec->private_imux[0];
5850	int i, err, idx;
5851
5852	for (i = 0; i < AUTO_PIN_LAST; i++) {
5853		if (cfg->input_pins[i] >= 0x12) {
5854			idx = cfg->input_pins[i] - 0x12;
5855			err = new_analog_input(spec, cfg->input_pins[i],
5856					       auto_pin_cfg_labels[i], idx,
5857					       0x07);
5858			if (err < 0)
5859				return err;
5860			imux->items[imux->num_items].label =
5861				auto_pin_cfg_labels[i];
5862			imux->items[imux->num_items].index = idx;
5863			imux->num_items++;
5864		}
5865		if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
5866			idx = cfg->input_pins[i] - 0x09;
5867			err = new_analog_input(spec, cfg->input_pins[i],
5868					       auto_pin_cfg_labels[i], idx,
5869					       0x07);
5870			if (err < 0)
5871				return err;
5872			imux->items[imux->num_items].label =
5873				auto_pin_cfg_labels[i];
5874			imux->items[imux->num_items].index = idx;
5875			imux->num_items++;
5876		}
5877	}
5878	return 0;
5879}
5880
5881static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5882					      hda_nid_t nid, int pin_type,
5883					      int sel_idx)
5884{
5885	alc_set_pin_output(codec, nid, pin_type);
5886	/* need the manual connection? */
5887	if (nid >= 0x12) {
5888		int idx = nid - 0x12;
5889		snd_hda_codec_write(codec, idx + 0x0b, 0,
5890				    AC_VERB_SET_CONNECT_SEL, sel_idx);
5891	}
5892}
5893
5894static void alc260_auto_init_multi_out(struct hda_codec *codec)
5895{
5896	struct alc_spec *spec = codec->spec;
5897	hda_nid_t nid;
5898
5899	nid = spec->autocfg.line_out_pins[0];
5900	if (nid) {
5901		int pin_type = get_pin_type(spec->autocfg.line_out_type);
5902		alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5903	}
5904
5905	nid = spec->autocfg.speaker_pins[0];
5906	if (nid)
5907		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5908
5909	nid = spec->autocfg.hp_pins[0];
5910	if (nid)
5911		alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5912}
5913
5914#define ALC260_PIN_CD_NID		0x16
5915static void alc260_auto_init_analog_input(struct hda_codec *codec)
5916{
5917	struct alc_spec *spec = codec->spec;
5918	int i;
5919
5920	for (i = 0; i < AUTO_PIN_LAST; i++) {
5921		hda_nid_t nid = spec->autocfg.input_pins[i];
5922		if (nid >= 0x12) {
5923			alc_set_input_pin(codec, nid, i);
5924			if (nid != ALC260_PIN_CD_NID &&
5925			    (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
5926				snd_hda_codec_write(codec, nid, 0,
5927						    AC_VERB_SET_AMP_GAIN_MUTE,
5928						    AMP_OUT_MUTE);
5929		}
5930	}
5931}
5932
5933/*
5934 * generic initialization of ADC, input mixers and output mixers
5935 */
5936static struct hda_verb alc260_volume_init_verbs[] = {
5937	/*
5938	 * Unmute ADC0-1 and set the default input to mic-in
5939	 */
5940	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5941	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5942	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5943	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5944
5945	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5946	 * mixer widget
5947	 * Note: PASD motherboards uses the Line In 2 as the input for
5948	 * front panel mic (mic 2)
5949	 */
5950	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5951	/* mute analog inputs */
5952	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5953	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5954	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5955	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5956	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5957
5958	/*
5959	 * Set up output mixers (0x08 - 0x0a)
5960	 */
5961	/* set vol=0 to output mixers */
5962	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5963	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5964	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5965	/* set up input amps for analog loopback */
5966	/* Amp Indices: DAC = 0, mixer = 1 */
5967	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5968	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5969	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5970	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5971	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5972	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5973
5974	{ }
5975};
5976
5977static int alc260_parse_auto_config(struct hda_codec *codec)
5978{
5979	struct alc_spec *spec = codec->spec;
5980	int err;
5981	static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5982
5983	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5984					   alc260_ignore);
5985	if (err < 0)
5986		return err;
5987	err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5988	if (err < 0)
5989		return err;
5990	if (!spec->kctls.list)
5991		return 0; /* can't find valid BIOS pin config */
5992	err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5993	if (err < 0)
5994		return err;
5995
5996	spec->multiout.max_channels = 2;
5997
5998	if (spec->autocfg.dig_outs)
5999		spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
6000	if (spec->kctls.list)
6001		add_mixer(spec, spec->kctls.list);
6002
6003	add_verb(spec, alc260_volume_init_verbs);
6004
6005	spec->num_mux_defs = 1;
6006	spec->input_mux = &spec->private_imux[0];
6007
6008	alc_ssid_check(codec, 0x10, 0x15, 0x0f);
6009
6010	return 1;
6011}
6012
6013/* additional initialization for auto-configuration model */
6014static void alc260_auto_init(struct hda_codec *codec)
6015{
6016	struct alc_spec *spec = codec->spec;
6017	alc260_auto_init_multi_out(codec);
6018	alc260_auto_init_analog_input(codec);
6019	if (spec->unsol_event)
6020		alc_inithook(codec);
6021}
6022
6023#ifdef CONFIG_SND_HDA_POWER_SAVE
6024static struct hda_amp_list alc260_loopbacks[] = {
6025	{ 0x07, HDA_INPUT, 0 },
6026	{ 0x07, HDA_INPUT, 1 },
6027	{ 0x07, HDA_INPUT, 2 },
6028	{ 0x07, HDA_INPUT, 3 },
6029	{ 0x07, HDA_INPUT, 4 },
6030	{ } /* end */
6031};
6032#endif
6033
6034/*
6035 * ALC260 configurations
6036 */
6037static const char *alc260_models[ALC260_MODEL_LAST] = {
6038	[ALC260_BASIC]		= "basic",
6039	[ALC260_HP]		= "hp",
6040	[ALC260_HP_3013]	= "hp-3013",
6041	[ALC260_HP_DC7600]	= "hp-dc7600",
6042	[ALC260_FUJITSU_S702X]	= "fujitsu",
6043	[ALC260_ACER]		= "acer",
6044	[ALC260_WILL]		= "will",
6045	[ALC260_REPLACER_672V]	= "replacer",
6046	[ALC260_FAVORIT100]	= "favorit100",
6047#ifdef CONFIG_SND_DEBUG
6048	[ALC260_TEST]		= "test",
6049#endif
6050	[ALC260_AUTO]		= "auto",
6051};
6052
6053static struct snd_pci_quirk alc260_cfg_tbl[] = {
6054	SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
6055	SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
6056	SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
6057	SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
6058	SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
6059	SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
6060	SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
6061	SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
6062	SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
6063	SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
6064	SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
6065	SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
6066	SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
6067	SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
6068	SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
6069	SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
6070	SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
6071	SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
6072	SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
6073	{}
6074};
6075
6076static struct alc_config_preset alc260_presets[] = {
6077	[ALC260_BASIC] = {
6078		.mixers = { alc260_base_output_mixer,
6079			    alc260_input_mixer },
6080		.init_verbs = { alc260_init_verbs },
6081		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
6082		.dac_nids = alc260_dac_nids,
6083		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6084		.adc_nids = alc260_adc_nids,
6085		.num_channel_mode = ARRAY_SIZE(alc260_modes),
6086		.channel_mode = alc260_modes,
6087		.input_mux = &alc260_capture_source,
6088	},
6089	[ALC260_HP] = {
6090		.mixers = { alc260_hp_output_mixer,
6091			    alc260_input_mixer },
6092		.init_verbs = { alc260_init_verbs,
6093				alc260_hp_unsol_verbs },
6094		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
6095		.dac_nids = alc260_dac_nids,
6096		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6097		.adc_nids = alc260_adc_nids_alt,
6098		.num_channel_mode = ARRAY_SIZE(alc260_modes),
6099		.channel_mode = alc260_modes,
6100		.input_mux = &alc260_capture_source,
6101		.unsol_event = alc260_hp_unsol_event,
6102		.init_hook = alc260_hp_automute,
6103	},
6104	[ALC260_HP_DC7600] = {
6105		.mixers = { alc260_hp_dc7600_mixer,
6106			    alc260_input_mixer },
6107		.init_verbs = { alc260_init_verbs,
6108				alc260_hp_dc7600_verbs },
6109		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
6110		.dac_nids = alc260_dac_nids,
6111		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6112		.adc_nids = alc260_adc_nids_alt,
6113		.num_channel_mode = ARRAY_SIZE(alc260_modes),
6114		.channel_mode = alc260_modes,
6115		.input_mux = &alc260_capture_source,
6116		.unsol_event = alc260_hp_3012_unsol_event,
6117		.init_hook = alc260_hp_3012_automute,
6118	},
6119	[ALC260_HP_3013] = {
6120		.mixers = { alc260_hp_3013_mixer,
6121			    alc260_input_mixer },
6122		.init_verbs = { alc260_hp_3013_init_verbs,
6123				alc260_hp_3013_unsol_verbs },
6124		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
6125		.dac_nids = alc260_dac_nids,
6126		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6127		.adc_nids = alc260_adc_nids_alt,
6128		.num_channel_mode = ARRAY_SIZE(alc260_modes),
6129		.channel_mode = alc260_modes,
6130		.input_mux = &alc260_capture_source,
6131		.unsol_event = alc260_hp_3013_unsol_event,
6132		.init_hook = alc260_hp_3013_automute,
6133	},
6134	[ALC260_FUJITSU_S702X] = {
6135		.mixers = { alc260_fujitsu_mixer },
6136		.init_verbs = { alc260_fujitsu_init_verbs },
6137		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
6138		.dac_nids = alc260_dac_nids,
6139		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6140		.adc_nids = alc260_dual_adc_nids,
6141		.num_channel_mode = ARRAY_SIZE(alc260_modes),
6142		.channel_mode = alc260_modes,
6143		.num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
6144		.input_mux = alc260_fujitsu_capture_sources,
6145	},
6146	[ALC260_ACER] = {
6147		.mixers = { alc260_acer_mixer },
6148		.init_verbs = { alc260_acer_init_verbs },
6149		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
6150		.dac_nids = alc260_dac_nids,
6151		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6152		.adc_nids = alc260_dual_adc_nids,
6153		.num_channel_mode = ARRAY_SIZE(alc260_modes),
6154		.channel_mode = alc260_modes,
6155		.num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
6156		.input_mux = alc260_acer_capture_sources,
6157	},
6158	[ALC260_FAVORIT100] = {
6159		.mixers = { alc260_favorit100_mixer },
6160		.init_verbs = { alc260_favorit100_init_verbs },
6161		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
6162		.dac_nids = alc260_dac_nids,
6163		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6164		.adc_nids = alc260_dual_adc_nids,
6165		.num_channel_mode = ARRAY_SIZE(alc260_modes),
6166		.channel_mode = alc260_modes,
6167		.num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
6168		.input_mux = alc260_favorit100_capture_sources,
6169	},
6170	[ALC260_WILL] = {
6171		.mixers = { alc260_will_mixer },
6172		.init_verbs = { alc260_init_verbs, alc260_will_verbs },
6173		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
6174		.dac_nids = alc260_dac_nids,
6175		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6176		.adc_nids = alc260_adc_nids,
6177		.dig_out_nid = ALC260_DIGOUT_NID,
6178		.num_channel_mode = ARRAY_SIZE(alc260_modes),
6179		.channel_mode = alc260_modes,
6180		.input_mux = &alc260_capture_source,
6181	},
6182	[ALC260_REPLACER_672V] = {
6183		.mixers = { alc260_replacer_672v_mixer },
6184		.init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6185		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
6186		.dac_nids = alc260_dac_nids,
6187		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6188		.adc_nids = alc260_adc_nids,
6189		.dig_out_nid = ALC260_DIGOUT_NID,
6190		.num_channel_mode = ARRAY_SIZE(alc260_modes),
6191		.channel_mode = alc260_modes,
6192		.input_mux = &alc260_capture_source,
6193		.unsol_event = alc260_replacer_672v_unsol_event,
6194		.init_hook = alc260_replacer_672v_automute,
6195	},
6196#ifdef CONFIG_SND_DEBUG
6197	[ALC260_TEST] = {
6198		.mixers = { alc260_test_mixer },
6199		.init_verbs = { alc260_test_init_verbs },
6200		.num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6201		.dac_nids = alc260_test_dac_nids,
6202		.num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6203		.adc_nids = alc260_test_adc_nids,
6204		.num_channel_mode = ARRAY_SIZE(alc260_modes),
6205		.channel_mode = alc260_modes,
6206		.num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6207		.input_mux = alc260_test_capture_sources,
6208	},
6209#endif
6210};
6211
6212static int patch_alc260(struct hda_codec *codec)
6213{
6214	struct alc_spec *spec;
6215	int err, board_config;
6216
6217	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6218	if (spec == NULL)
6219		return -ENOMEM;
6220
6221	codec->spec = spec;
6222
6223	board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6224						  alc260_models,
6225						  alc260_cfg_tbl);
6226	if (board_config < 0) {
6227		snd_printd(KERN_INFO "hda_codec: Unknown model for %s, "
6228			   "trying auto-probe from BIOS...\n",
6229			   codec->chip_name);
6230		board_config = ALC260_AUTO;
6231	}
6232
6233	if (board_config == ALC260_AUTO) {
6234		/* automatic parse from the BIOS config */
6235		err = alc260_parse_auto_config(codec);
6236		if (err < 0) {
6237			alc_free(codec);
6238			return err;
6239		} else if (!err) {
6240			printk(KERN_INFO
6241			       "hda_codec: Cannot set up configuration "
6242			       "from BIOS.  Using base mode...\n");
6243			board_config = ALC260_BASIC;
6244		}
6245	}
6246
6247	err = snd_hda_attach_beep_device(codec, 0x1);
6248	if (err < 0) {
6249		alc_free(codec);
6250		return err;
6251	}
6252
6253	if (board_config != ALC260_AUTO)
6254		setup_preset(spec, &alc260_presets[board_config]);
6255
6256	spec->stream_analog_playback = &alc260_pcm_analog_playback;
6257	spec->stream_analog_capture = &alc260_pcm_analog_capture;
6258
6259	spec->stream_digital_playback = &alc260_pcm_digital_playback;
6260	spec->stream_digital_capture = &alc260_pcm_digital_capture;
6261
6262	if (!spec->adc_nids && spec->input_mux) {
6263		/* check whether NID 0x04 is valid */
6264		unsigned int wcap = get_wcaps(codec, 0x04);
6265		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6266		/* get type */
6267		if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6268			spec->adc_nids = alc260_adc_nids_alt;
6269			spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
6270		} else {
6271			spec->adc_nids = alc260_adc_nids;
6272			spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6273		}
6274	}
6275	set_capture_mixer(spec);
6276	set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
6277
6278	spec->vmaster_nid = 0x08;
6279
6280	codec->patch_ops = alc_patch_ops;
6281	if (board_config == ALC260_AUTO)
6282		spec->init_hook = alc260_auto_init;
6283#ifdef CONFIG_SND_HDA_POWER_SAVE
6284	if (!spec->loopback.amplist)
6285		spec->loopback.amplist = alc260_loopbacks;
6286#endif
6287	codec->proc_widget_hook = print_realtek_coef;
6288
6289	return 0;
6290}
6291
6292
6293/*
6294 * ALC882/883/885/888/889 support
6295 *
6296 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6297 * configuration.  Each pin widget can choose any input DACs and a mixer.
6298 * Each ADC is connected from a mixer of all inputs.  This makes possible
6299 * 6-channel independent captures.
6300 *
6301 * In addition, an independent DAC for the multi-playback (not used in this
6302 * driver yet).
6303 */
6304#define ALC882_DIGOUT_NID	0x06
6305#define ALC882_DIGIN_NID	0x0a
6306#define ALC883_DIGOUT_NID	ALC882_DIGOUT_NID
6307#define ALC883_DIGIN_NID	ALC882_DIGIN_NID
6308#define ALC1200_DIGOUT_NID	0x10
6309
6310
6311static struct hda_channel_mode alc882_ch_modes[1] = {
6312	{ 8, NULL }
6313};
6314
6315/* DACs */
6316static hda_nid_t alc882_dac_nids[4] = {
6317	/* front, rear, clfe, rear_surr */
6318	0x02, 0x03, 0x04, 0x05
6319};
6320#define alc883_dac_nids		alc882_dac_nids
6321
6322/* ADCs */
6323#define alc882_adc_nids		alc880_adc_nids
6324#define alc882_adc_nids_alt	alc880_adc_nids_alt
6325#define alc883_adc_nids		alc882_adc_nids_alt
6326static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
6327static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
6328#define alc889_adc_nids		alc880_adc_nids
6329
6330static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6331static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
6332#define alc883_capsrc_nids	alc882_capsrc_nids_alt
6333static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
6334#define alc889_capsrc_nids	alc882_capsrc_nids
6335
6336/* input MUX */
6337/* FIXME: should be a matrix-type input source selection */
6338
6339static struct hda_input_mux alc882_capture_source = {
6340	.num_items = 4,
6341	.items = {
6342		{ "Mic", 0x0 },
6343		{ "Front Mic", 0x1 },
6344		{ "Line", 0x2 },
6345		{ "CD", 0x4 },
6346	},
6347};
6348
6349#define alc883_capture_source	alc882_capture_source
6350
6351static struct hda_input_mux mb5_capture_source = {
6352	.num_items = 3,
6353	.items = {
6354		{ "Mic", 0x1 },
6355		{ "Line", 0x2 },
6356		{ "CD", 0x4 },
6357	},
6358};
6359
6360static struct hda_input_mux alc883_3stack_6ch_intel = {
6361	.num_items = 4,
6362	.items = {
6363		{ "Mic", 0x1 },
6364		{ "Front Mic", 0x0 },
6365		{ "Line", 0x2 },
6366		{ "CD", 0x4 },
6367	},
6368};
6369
6370static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6371	.num_items = 2,
6372	.items = {
6373		{ "Mic", 0x1 },
6374		{ "Line", 0x2 },
6375	},
6376};
6377
6378static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6379	.num_items = 4,
6380	.items = {
6381		{ "Mic", 0x0 },
6382		{ "iMic", 0x1 },
6383		{ "Line", 0x2 },
6384		{ "CD", 0x4 },
6385	},
6386};
6387
6388static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6389	.num_items = 2,
6390	.items = {
6391		{ "Mic", 0x0 },
6392		{ "Int Mic", 0x1 },
6393	},
6394};
6395
6396static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6397	.num_items = 3,
6398	.items = {
6399		{ "Mic", 0x0 },
6400		{ "Front Mic", 0x1 },
6401		{ "Line", 0x4 },
6402	},
6403};
6404
6405static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6406	.num_items = 2,
6407	.items = {
6408		{ "Mic", 0x0 },
6409		{ "Line", 0x2 },
6410	},
6411};
6412
6413static struct hda_input_mux alc889A_mb31_capture_source = {
6414	.num_items = 2,
6415	.items = {
6416		{ "Mic", 0x0 },
6417		/* Front Mic (0x01) unused */
6418		{ "Line", 0x2 },
6419		/* Line 2 (0x03) unused */
6420		/* CD (0x04) unsused? */
6421	},
6422};
6423
6424/*
6425 * 2ch mode
6426 */
6427static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6428	{ 2, NULL }
6429};
6430
6431/*
6432 * 2ch mode
6433 */
6434static struct hda_verb alc882_3ST_ch2_init[] = {
6435	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6436	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6437	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6438	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6439	{ } /* end */
6440};
6441
6442/*
6443 * 4ch mode
6444 */
6445static struct hda_verb alc882_3ST_ch4_init[] = {
6446	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6447	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6448	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6449	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6450	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6451	{ } /* end */
6452};
6453
6454/*
6455 * 6ch mode
6456 */
6457static struct hda_verb alc882_3ST_ch6_init[] = {
6458	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6459	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6460	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6461	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6462	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6463	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6464	{ } /* end */
6465};
6466
6467static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
6468	{ 2, alc882_3ST_ch2_init },
6469	{ 4, alc882_3ST_ch4_init },
6470	{ 6, alc882_3ST_ch6_init },
6471};
6472
6473#define alc883_3ST_6ch_modes	alc882_3ST_6ch_modes
6474
6475/*
6476 * 6ch mode
6477 */
6478static struct hda_verb alc882_sixstack_ch6_init[] = {
6479	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6480	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6481	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6482	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6483	{ } /* end */
6484};
6485
6486/*
6487 * 8ch mode
6488 */
6489static struct hda_verb alc882_sixstack_ch8_init[] = {
6490	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6491	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6492	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6493	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6494	{ } /* end */
6495};
6496
6497static struct hda_channel_mode alc882_sixstack_modes[2] = {
6498	{ 6, alc882_sixstack_ch6_init },
6499	{ 8, alc882_sixstack_ch8_init },
6500};
6501
6502/*
6503 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
6504 */
6505
6506/*
6507 * 2ch mode
6508 */
6509static struct hda_verb alc885_mbp_ch2_init[] = {
6510	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6511	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6512	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6513	{ } /* end */
6514};
6515
6516/*
6517 * 6ch mode
6518 */
6519static struct hda_verb alc885_mbp_ch6_init[] = {
6520	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6521	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6522	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6523	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6524	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6525	{ } /* end */
6526};
6527
6528static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
6529	{ 2, alc885_mbp_ch2_init },
6530	{ 6, alc885_mbp_ch6_init },
6531};
6532
6533/*
6534 * 2ch
6535 * Speakers/Woofer/HP = Front
6536 * LineIn = Input
6537 */
6538static struct hda_verb alc885_mb5_ch2_init[] = {
6539	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6540	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6541	{ } /* end */
6542};
6543
6544/*
6545 * 6ch mode
6546 * Speakers/HP = Front
6547 * Woofer = LFE
6548 * LineIn = Surround
6549 */
6550static struct hda_verb alc885_mb5_ch6_init[] = {
6551	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6552	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6553	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6554	{ } /* end */
6555};
6556
6557static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
6558	{ 2, alc885_mb5_ch2_init },
6559	{ 6, alc885_mb5_ch6_init },
6560};
6561
6562
6563/*
6564 * 2ch mode
6565 */
6566static struct hda_verb alc883_4ST_ch2_init[] = {
6567	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6568	{ 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6569	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6570	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6571	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6572	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6573	{ } /* end */
6574};
6575
6576/*
6577 * 4ch mode
6578 */
6579static struct hda_verb alc883_4ST_ch4_init[] = {
6580	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6581	{ 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6582	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6583	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6584	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6585	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6586	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6587	{ } /* end */
6588};
6589
6590/*
6591 * 6ch mode
6592 */
6593static struct hda_verb alc883_4ST_ch6_init[] = {
6594	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6595	{ 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6596	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6597	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6598	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6599	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6600	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6601	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6602	{ } /* end */
6603};
6604
6605/*
6606 * 8ch mode
6607 */
6608static struct hda_verb alc883_4ST_ch8_init[] = {
6609	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6610	{ 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6611	{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
6612	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6613	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6614	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6615	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6616	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6617	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6618	{ } /* end */
6619};
6620
6621static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
6622	{ 2, alc883_4ST_ch2_init },
6623	{ 4, alc883_4ST_ch4_init },
6624	{ 6, alc883_4ST_ch6_init },
6625	{ 8, alc883_4ST_ch8_init },
6626};
6627
6628
6629/*
6630 * 2ch mode
6631 */
6632static struct hda_verb alc883_3ST_ch2_intel_init[] = {
6633	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6634	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6635	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6636	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6637	{ } /* end */
6638};
6639
6640/*
6641 * 4ch mode
6642 */
6643static struct hda_verb alc883_3ST_ch4_intel_init[] = {
6644	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6645	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6646	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6647	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6648	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6649	{ } /* end */
6650};
6651
6652/*
6653 * 6ch mode
6654 */
6655static struct hda_verb alc883_3ST_ch6_intel_init[] = {
6656	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6657	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6658	{ 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
6659	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6660	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6661	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6662	{ } /* end */
6663};
6664
6665static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
6666	{ 2, alc883_3ST_ch2_intel_init },
6667	{ 4, alc883_3ST_ch4_intel_init },
6668	{ 6, alc883_3ST_ch6_intel_init },
6669};
6670
6671/*
6672 * 6ch mode
6673 */
6674static struct hda_verb alc883_sixstack_ch6_init[] = {
6675	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6676	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6677	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6678	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6679	{ } /* end */
6680};
6681
6682/*
6683 * 8ch mode
6684 */
6685static struct hda_verb alc883_sixstack_ch8_init[] = {
6686	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6687	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6688	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6689	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6690	{ } /* end */
6691};
6692
6693static struct hda_channel_mode alc883_sixstack_modes[2] = {
6694	{ 6, alc883_sixstack_ch6_init },
6695	{ 8, alc883_sixstack_ch8_init },
6696};
6697
6698
6699/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6700 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6701 */
6702static struct snd_kcontrol_new alc882_base_mixer[] = {
6703	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6704	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6705	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6706	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6707	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6708	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6709	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6710	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6711	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6712	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6713	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6714	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6715	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6716	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6717	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6718	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6719	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6720	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6721	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6722	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6723	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6724	{ } /* end */
6725};
6726
6727static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
6728	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6729	HDA_BIND_MUTE   ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
6730	HDA_CODEC_MUTE  ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
6731	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6732	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6733	HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6734	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
6735	HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
6736	HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
6737	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
6738	{ } /* end */
6739};
6740
6741static struct snd_kcontrol_new alc885_mb5_mixer[] = {
6742	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6743	HDA_BIND_MUTE   ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
6744	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6745	HDA_BIND_MUTE   ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
6746	HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
6747	HDA_BIND_MUTE   ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
6748	HDA_CODEC_VOLUME("HP Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
6749	HDA_BIND_MUTE   ("HP Playback Switch", 0x0f, 0x02, HDA_INPUT),
6750	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6751	HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6752	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
6753	HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
6754	HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
6755	HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
6756	{ } /* end */
6757};
6758
6759static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
6760	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6761	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6762	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6763	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6764	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6765	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6766	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6767	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6768	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6769	{ } /* end */
6770};
6771
6772static struct snd_kcontrol_new alc882_targa_mixer[] = {
6773	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6774	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6775	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6776	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6777	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6778	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6779	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6780	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6781	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6782	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6783	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6784	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6785	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6786	{ } /* end */
6787};
6788
6789/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
6790 *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
6791 */
6792static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
6793	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6794	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6795	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6796	HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
6797	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6798	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6799	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6800	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6801	HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
6802	HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
6803	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6804	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6805	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6806	{ } /* end */
6807};
6808
6809static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
6810	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6811	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6812	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6813	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6814	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6815	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6816	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6817	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6818	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6819	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6820	{ } /* end */
6821};
6822
6823static struct snd_kcontrol_new alc882_chmode_mixer[] = {
6824	{
6825		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6826		.name = "Channel Mode",
6827		.info = alc_ch_mode_info,
6828		.get = alc_ch_mode_get,
6829		.put = alc_ch_mode_put,
6830	},
6831	{ } /* end */
6832};
6833
6834static struct hda_verb alc882_base_init_verbs[] = {
6835	/* Front mixer: unmute input/output amp left and right (volume = 0) */
6836	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6837	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6838	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6839	/* Rear mixer */
6840	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6841	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6842	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6843	/* CLFE mixer */
6844	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6845	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6846	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6847	/* Side mixer */
6848	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6849	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6850	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6851
6852	/* Front Pin: output 0 (0x0c) */
6853	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6854	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6855	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6856	/* Rear Pin: output 1 (0x0d) */
6857	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6858	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6859	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6860	/* CLFE Pin: output 2 (0x0e) */
6861	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6862	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6863	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6864	/* Side Pin: output 3 (0x0f) */
6865	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6866	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6867	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6868	/* Mic (rear) pin: input vref at 80% */
6869	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6870	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6871	/* Front Mic pin: input vref at 80% */
6872	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6873	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6874	/* Line In pin: input */
6875	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6876	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6877	/* Line-2 In: Headphone output (output 0 - 0x0c) */
6878	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6879	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6880	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6881	/* CD pin widget for input */
6882	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6883
6884	/* FIXME: use matrix-type input source selection */
6885	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6886	/* Input mixer2 */
6887	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6888	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6889	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6890	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6891	/* Input mixer3 */
6892	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6893	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6894	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6895	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6896	/* ADC2: mute amp left and right */
6897	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6898	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6899	/* ADC3: mute amp left and right */
6900	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6901	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6902
6903	{ }
6904};
6905
6906static struct hda_verb alc882_adc1_init_verbs[] = {
6907	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6908	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6909	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6910	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6911	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6912	/* ADC1: mute amp left and right */
6913	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6914	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6915	{ }
6916};
6917
6918/* HACK - expand to two elements */
6919#define alc882_init_verbs	alc882_base_init_verbs, alc882_adc1_init_verbs
6920
6921static struct hda_verb alc882_eapd_verbs[] = {
6922	/* change to EAPD mode */
6923	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6924	{0x20, AC_VERB_SET_PROC_COEF, 0x3060},
6925	{ }
6926};
6927
6928#define alc883_init_verbs	alc882_base_init_verbs
6929
6930/* Mac Pro test */
6931static struct snd_kcontrol_new alc882_macpro_mixer[] = {
6932	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6933	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6934	HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
6935	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
6936	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
6937	/* FIXME: this looks suspicious...
6938	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
6939	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
6940	*/
6941	{ } /* end */
6942};
6943
6944static struct hda_verb alc882_macpro_init_verbs[] = {
6945	/* Front mixer: unmute input/output amp left and right (volume = 0) */
6946	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6947	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6948	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6949	/* Front Pin: output 0 (0x0c) */
6950	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6951	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6952	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6953	/* Front Mic pin: input vref at 80% */
6954	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6955	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6956	/* Speaker:  output */
6957	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6958	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6959	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
6960	/* Headphone output (output 0 - 0x0c) */
6961	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6962	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6963	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6964
6965	/* FIXME: use matrix-type input source selection */
6966	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6967	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6968	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6969	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6970	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6971	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6972	/* Input mixer2 */
6973	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6974	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6975	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6976	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6977	/* Input mixer3 */
6978	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6979	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6980	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6981	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6982	/* ADC1: mute amp left and right */
6983	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6984	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6985	/* ADC2: mute amp left and right */
6986	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6987	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6988	/* ADC3: mute amp left and right */
6989	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6990	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6991
6992	{ }
6993};
6994
6995/* Macbook 5,1 */
6996static struct hda_verb alc885_mb5_init_verbs[] = {
6997	/* DACs */
6998	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6999	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7000	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7001	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7002	/* Front mixer */
7003	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7004	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7005	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7006	/* Surround mixer */
7007	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7008	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7009	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7010	/* LFE mixer */
7011	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7012	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7013	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7014	/* HP mixer */
7015	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7016	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7017	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7018	/* Front Pin (0x0c) */
7019	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7020	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7021	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7022	/* LFE Pin (0x0e) */
7023	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7024	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7025	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
7026	/* HP Pin (0x0f) */
7027	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7028	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7029	{0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
7030	/* Front Mic pin: input vref at 80% */
7031	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7032	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7033	/* Line In pin */
7034	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7035	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7036
7037	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7038	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7039	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7040	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7041	{ }
7042};
7043
7044/* Macbook Pro rev3 */
7045static struct hda_verb alc885_mbp3_init_verbs[] = {
7046	/* Front mixer: unmute input/output amp left and right (volume = 0) */
7047	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7048	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7049	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7050	/* Rear mixer */
7051	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7052	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7053	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7054	/* Front Pin: output 0 (0x0c) */
7055	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7056	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7057	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7058	/* HP Pin: output 0 (0x0d) */
7059	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
7060	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7061	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7062	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7063	/* Mic (rear) pin: input vref at 80% */
7064	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7065	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7066	/* Front Mic pin: input vref at 80% */
7067	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7068	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7069	/* Line In pin: use output 1 when in LineOut mode */
7070	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7071	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7072	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
7073
7074	/* FIXME: use matrix-type input source selection */
7075	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7076	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7077	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7078	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7079	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7080	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7081	/* Input mixer2 */
7082	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7083	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7084	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7085	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7086	/* Input mixer3 */
7087	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7088	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7089	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7090	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7091	/* ADC1: mute amp left and right */
7092	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7093	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7094	/* ADC2: mute amp left and right */
7095	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7096	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7097	/* ADC3: mute amp left and right */
7098	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7099	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7100
7101	{ }
7102};
7103
7104/* iMac 24 mixer. */
7105static struct snd_kcontrol_new alc885_imac24_mixer[] = {
7106	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7107	HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
7108	{ } /* end */
7109};
7110
7111/* iMac 24 init verbs. */
7112static struct hda_verb alc885_imac24_init_verbs[] = {
7113	/* Internal speakers: output 0 (0x0c) */
7114	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7115	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7116	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7117	/* Internal speakers: output 0 (0x0c) */
7118	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7119	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7120	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7121	/* Headphone: output 0 (0x0c) */
7122	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7123	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7124	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7125	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7126	/* Front Mic: input vref at 80% */
7127	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7128	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7129	{ }
7130};
7131
7132/* Toggle speaker-output according to the hp-jack state */
7133static void alc885_imac24_automute_init_hook(struct hda_codec *codec)
7134{
7135	struct alc_spec *spec = codec->spec;
7136
7137	spec->autocfg.hp_pins[0] = 0x14;
7138	spec->autocfg.speaker_pins[0] = 0x18;
7139	spec->autocfg.speaker_pins[1] = 0x1a;
7140	alc_automute_amp(codec);
7141}
7142
7143static void alc885_mbp3_init_hook(struct hda_codec *codec)
7144{
7145	struct alc_spec *spec = codec->spec;
7146
7147	spec->autocfg.hp_pins[0] = 0x15;
7148	spec->autocfg.speaker_pins[0] = 0x14;
7149	alc_automute_amp(codec);
7150}
7151
7152
7153static struct hda_verb alc882_targa_verbs[] = {
7154	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7155	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7156
7157	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7158	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7159
7160	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7161	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7162	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7163
7164	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7165	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7166	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7167	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
7168	{ } /* end */
7169};
7170
7171/* toggle speaker-output according to the hp-jack state */
7172static void alc882_targa_automute(struct hda_codec *codec)
7173{
7174	struct alc_spec *spec = codec->spec;
7175	alc_automute_amp(codec);
7176	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7177				  spec->jack_present ? 1 : 3);
7178}
7179
7180static void alc882_targa_init_hook(struct hda_codec *codec)
7181{
7182	struct alc_spec *spec = codec->spec;
7183
7184	spec->autocfg.hp_pins[0] = 0x14;
7185	spec->autocfg.speaker_pins[0] = 0x1b;
7186	alc882_targa_automute(codec);
7187}
7188
7189static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
7190{
7191	if ((res >> 26) == ALC880_HP_EVENT)
7192		alc882_targa_automute(codec);
7193}
7194
7195static struct hda_verb alc882_asus_a7j_verbs[] = {
7196	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7197	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7198
7199	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7200	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7201	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7202
7203	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7204	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7205	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7206
7207	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7208	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7209	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7210	{ } /* end */
7211};
7212
7213static struct hda_verb alc882_asus_a7m_verbs[] = {
7214	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7215	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7216
7217	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7218	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7219	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7220
7221	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7222	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7223	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7224
7225	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7226	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7227	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7228 	{ } /* end */
7229};
7230
7231static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
7232{
7233	unsigned int gpiostate, gpiomask, gpiodir;
7234
7235	gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
7236				       AC_VERB_GET_GPIO_DATA, 0);
7237
7238	if (!muted)
7239		gpiostate |= (1 << pin);
7240	else
7241		gpiostate &= ~(1 << pin);
7242
7243	gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
7244				      AC_VERB_GET_GPIO_MASK, 0);
7245	gpiomask |= (1 << pin);
7246
7247	gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
7248				     AC_VERB_GET_GPIO_DIRECTION, 0);
7249	gpiodir |= (1 << pin);
7250
7251
7252	snd_hda_codec_write(codec, codec->afg, 0,
7253			    AC_VERB_SET_GPIO_MASK, gpiomask);
7254	snd_hda_codec_write(codec, codec->afg, 0,
7255			    AC_VERB_SET_GPIO_DIRECTION, gpiodir);
7256
7257	msleep(1);
7258
7259	snd_hda_codec_write(codec, codec->afg, 0,
7260			    AC_VERB_SET_GPIO_DATA, gpiostate);
7261}
7262
7263/* set up GPIO at initialization */
7264static void alc885_macpro_init_hook(struct hda_codec *codec)
7265{
7266	alc882_gpio_mute(codec, 0, 0);
7267	alc882_gpio_mute(codec, 1, 0);
7268}
7269
7270/* set up GPIO and update auto-muting at initialization */
7271static void alc885_imac24_init_hook(struct hda_codec *codec)
7272{
7273	alc885_macpro_init_hook(codec);
7274	alc885_imac24_automute_init_hook(codec);
7275}
7276
7277/*
7278 * generic initialization of ADC, input mixers and output mixers
7279 */
7280static struct hda_verb alc883_auto_init_verbs[] = {
7281	/*
7282	 * Unmute ADC0-2 and set the default input to mic-in
7283	 */
7284	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7285	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7286	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7287	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7288
7289	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7290	 * mixer widget
7291	 * Note: PASD motherboards uses the Line In 2 as the input for
7292	 * front panel mic (mic 2)
7293	 */
7294	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7295	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7296	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7297	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7298	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7299	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7300
7301	/*
7302	 * Set up output mixers (0x0c - 0x0f)
7303	 */
7304	/* set vol=0 to output mixers */
7305	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7306	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7307	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7308	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7309	/* set up input amps for analog loopback */
7310	/* Amp Indices: DAC = 0, mixer = 1 */
7311	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7312	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7313	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7314	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7315	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7316	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7317	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7318	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7319	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7320	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7321
7322	/* FIXME: use matrix-type input source selection */
7323	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7324	/* Input mixer2 */
7325	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7326	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7327	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7328	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7329	/* Input mixer3 */
7330	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7331	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7332	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7333	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7334
7335	{ }
7336};
7337
7338/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
7339static struct hda_verb alc889A_mb31_ch2_init[] = {
7340	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},             /* HP as front */
7341	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7342	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},    /* Line as input */
7343	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},   /* Line off */
7344	{ } /* end */
7345};
7346
7347/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
7348static struct hda_verb alc889A_mb31_ch4_init[] = {
7349	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},             /* HP as front */
7350	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7351	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},   /* Line as output */
7352	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7353	{ } /* end */
7354};
7355
7356/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
7357static struct hda_verb alc889A_mb31_ch5_init[] = {
7358	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},             /* HP as rear */
7359	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7360	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},    /* Line as input */
7361	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},   /* Line off */
7362	{ } /* end */
7363};
7364
7365/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
7366static struct hda_verb alc889A_mb31_ch6_init[] = {
7367	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},             /* HP as front */
7368	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},   /* Subwoofer off */
7369	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},   /* Line as output */
7370	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7371	{ } /* end */
7372};
7373
7374static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
7375	{ 2, alc889A_mb31_ch2_init },
7376	{ 4, alc889A_mb31_ch4_init },
7377	{ 5, alc889A_mb31_ch5_init },
7378	{ 6, alc889A_mb31_ch6_init },
7379};
7380
7381static struct hda_verb alc883_medion_eapd_verbs[] = {
7382        /* eanable EAPD on medion laptop */
7383	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7384	{0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7385	{ }
7386};
7387
7388#define alc883_base_mixer	alc882_base_mixer
7389
7390static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7391	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7392	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7393	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7394	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7395	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7396	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7397	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7398	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7399	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7400	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7401	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7402	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7403	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7404	{ } /* end */
7405};
7406
7407static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7408	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7409	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7410	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7411	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7412	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7413	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7414	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7415	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7416	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7417	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7418	{ } /* end */
7419};
7420
7421static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7422	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7423	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7424	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7425	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7426	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7427	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7428	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7429	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7430	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7431	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7432	{ } /* end */
7433};
7434
7435static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7436	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7437	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7438	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7439	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7440	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7441	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7442	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7443	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7444	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7445	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7446	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7447	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7448	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7449	{ } /* end */
7450};
7451
7452static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7453	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7454	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7455	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7456	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7457	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7458	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7459	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7460	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7461	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7462	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7463	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7464	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7465	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7466	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7467	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7468	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7469	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7470	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7471	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7472	{ } /* end */
7473};
7474
7475static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7476	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7477	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7478	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7479	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7480	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7481			      HDA_OUTPUT),
7482	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7483	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7484	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7485	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7486	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7487	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7488	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7489	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7490	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7491	HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7492	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7493	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7494	HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7495	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7496	{ } /* end */
7497};
7498
7499static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7500	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7501	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7502	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7503	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7504	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7505	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7506	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7507	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7508	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7509	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7510	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7511	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7512	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7513	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7514	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7515	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7516	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7517	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7518	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7519	{ } /* end */
7520};
7521
7522static struct snd_kcontrol_new alc883_targa_mixer[] = {
7523	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7524	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7525	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7526	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7527	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7528	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7529	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7530	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7531	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7532	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7533	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7534	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7535	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7536	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7537	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7538	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7539	{ } /* end */
7540};
7541
7542static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
7543	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7544	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7545	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7546	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7547	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7548	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7549	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7550	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7551	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7552	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7553	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7554	{ } /* end */
7555};
7556
7557static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7558	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7559	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7560	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7561	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7562	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7563	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7564	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7565	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7566	{ } /* end */
7567};
7568
7569static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7570	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7571	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7572	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7573	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7574	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7575	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7576	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7577	HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7578	HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7579	{ } /* end */
7580};
7581
7582static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7583	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7584	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7585	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7586	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7587	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7588	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7589	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7590	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7591	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7592	{ } /* end */
7593};
7594
7595static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7596	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7597	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7598	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7599	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7600	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7601	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7602	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7603	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7604	{ } /* end */
7605};
7606
7607static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
7608	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7609	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7610	HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7611	HDA_BIND_MUTE("LFE Playback Switch", 0x0f, 2, HDA_INPUT),
7612	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7613	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7614	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7615	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7616	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7617	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7618	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7619	{ } /* end */
7620};
7621
7622static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7623	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7624	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7625	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7626	HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7627	HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7628						0x0d, 1, 0x0, HDA_OUTPUT),
7629	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7630	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7631	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7632	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7633	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7634	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7635	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7636	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7637	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7638	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7639	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7640	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7641	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7642	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7643	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7644	{ } /* end */
7645};
7646
7647static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
7648	/* Output mixers */
7649	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7650	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7651	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7652	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7653	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
7654		HDA_OUTPUT),
7655	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
7656	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
7657	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
7658	/* Output switches */
7659	HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
7660	HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
7661	HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
7662	/* Boost mixers */
7663	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7664	HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
7665	/* Input mixers */
7666	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7667	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
7668	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7669	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7670	{ } /* end */
7671};
7672
7673static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
7674	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7675	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7676	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7677	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7678	HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7679	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7680	{ } /* end */
7681};
7682
7683static struct hda_bind_ctls alc883_bind_cap_vol = {
7684	.ops = &snd_hda_bind_vol,
7685	.values = {
7686		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7687		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7688		0
7689	},
7690};
7691
7692static struct hda_bind_ctls alc883_bind_cap_switch = {
7693	.ops = &snd_hda_bind_sw,
7694	.values = {
7695		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7696		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7697		0
7698	},
7699};
7700
7701static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7702	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7703	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7704	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7705	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7706	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7707	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7708	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7709	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7710	{ } /* end */
7711};
7712
7713static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
7714	HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7715	HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7716	{
7717		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7718		/* .name = "Capture Source", */
7719		.name = "Input Source",
7720		.count = 1,
7721		.info = alc_mux_enum_info,
7722		.get = alc_mux_enum_get,
7723		.put = alc_mux_enum_put,
7724	},
7725	{ } /* end */
7726};
7727
7728static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7729	{
7730		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7731		.name = "Channel Mode",
7732		.info = alc_ch_mode_info,
7733		.get = alc_ch_mode_get,
7734		.put = alc_ch_mode_put,
7735	},
7736	{ } /* end */
7737};
7738
7739/* toggle speaker-output according to the hp-jack state */
7740static void alc883_mitac_init_hook(struct hda_codec *codec)
7741{
7742	struct alc_spec *spec = codec->spec;
7743
7744	spec->autocfg.hp_pins[0] = 0x15;
7745	spec->autocfg.speaker_pins[0] = 0x14;
7746	spec->autocfg.speaker_pins[1] = 0x17;
7747	alc_automute_amp(codec);
7748}
7749
7750/* auto-toggle front mic */
7751/*
7752static void alc883_mitac_mic_automute(struct hda_codec *codec)
7753{
7754	unsigned int present;
7755	unsigned char bits;
7756
7757	present = snd_hda_codec_read(codec, 0x18, 0,
7758				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7759	bits = present ? HDA_AMP_MUTE : 0;
7760	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7761}
7762*/
7763
7764static struct hda_verb alc883_mitac_verbs[] = {
7765	/* HP */
7766	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7767	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7768	/* Subwoofer */
7769	{0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7770	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7771
7772	/* enable unsolicited event */
7773	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7774	/* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7775
7776	{ } /* end */
7777};
7778
7779static struct hda_verb alc883_clevo_m720_verbs[] = {
7780	/* HP */
7781	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7782	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7783	/* Int speaker */
7784	{0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
7785	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7786
7787	/* enable unsolicited event */
7788	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7789	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
7790
7791	{ } /* end */
7792};
7793
7794static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
7795	/* HP */
7796	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7797	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7798	/* Subwoofer */
7799	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7800	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7801
7802	/* enable unsolicited event */
7803	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7804
7805	{ } /* end */
7806};
7807
7808static struct hda_verb alc883_targa_verbs[] = {
7809	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7810	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7811
7812	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7813	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7814
7815/* Connect Line-Out side jack (SPDIF) to Side */
7816	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7817	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7818	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7819/* Connect Mic jack to CLFE */
7820	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7821	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7822	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
7823/* Connect Line-in jack to Surround */
7824	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7825	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7826	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
7827/* Connect HP out jack to Front */
7828	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7829	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7830	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7831
7832	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7833
7834	{ } /* end */
7835};
7836
7837static struct hda_verb alc883_lenovo_101e_verbs[] = {
7838	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7839	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7840        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7841	{ } /* end */
7842};
7843
7844static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7845        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7846	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7847        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7848        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7849	{ } /* end */
7850};
7851
7852static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7853	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7854	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7855	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7856	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7857	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
7858	{ } /* end */
7859};
7860
7861static struct hda_verb alc883_haier_w66_verbs[] = {
7862	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7863	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7864
7865	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7866
7867	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7868	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7869	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7870	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7871	{ } /* end */
7872};
7873
7874static struct hda_verb alc888_lenovo_sky_verbs[] = {
7875	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7876	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7877	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7878	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7879	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7880	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7881	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7882	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7883	{ } /* end */
7884};
7885
7886static struct hda_verb alc888_6st_dell_verbs[] = {
7887	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7888	{ }
7889};
7890
7891static struct hda_verb alc883_vaiott_verbs[] = {
7892	/* HP */
7893	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7894	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7895
7896	/* enable unsolicited event */
7897	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7898
7899	{ } /* end */
7900};
7901
7902static void alc888_3st_hp_init_hook(struct hda_codec *codec)
7903{
7904	struct alc_spec *spec = codec->spec;
7905
7906	spec->autocfg.hp_pins[0] = 0x1b;
7907	spec->autocfg.speaker_pins[0] = 0x14;
7908	spec->autocfg.speaker_pins[1] = 0x16;
7909	spec->autocfg.speaker_pins[2] = 0x18;
7910	alc_automute_amp(codec);
7911}
7912
7913static struct hda_verb alc888_3st_hp_verbs[] = {
7914	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Front: output 0 (0x0c) */
7915	{0x16, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Rear : output 1 (0x0d) */
7916	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02},	/* CLFE : output 2 (0x0e) */
7917	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7918	{ } /* end */
7919};
7920
7921/*
7922 * 2ch mode
7923 */
7924static struct hda_verb alc888_3st_hp_2ch_init[] = {
7925	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7926	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7927	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7928	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7929	{ } /* end */
7930};
7931
7932/*
7933 * 4ch mode
7934 */
7935static struct hda_verb alc888_3st_hp_4ch_init[] = {
7936	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7937	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7938	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7939	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7940	{ 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
7941	{ } /* end */
7942};
7943
7944/*
7945 * 6ch mode
7946 */
7947static struct hda_verb alc888_3st_hp_6ch_init[] = {
7948	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7949	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7950	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7951	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7952	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7953	{ 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
7954	{ } /* end */
7955};
7956
7957static struct hda_channel_mode alc888_3st_hp_modes[3] = {
7958	{ 2, alc888_3st_hp_2ch_init },
7959	{ 4, alc888_3st_hp_4ch_init },
7960	{ 6, alc888_3st_hp_6ch_init },
7961};
7962
7963/* toggle front-jack and RCA according to the hp-jack state */
7964static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7965{
7966 	unsigned int present;
7967
7968 	present = snd_hda_codec_read(codec, 0x1b, 0,
7969				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7970	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7971				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7972	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7973				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7974}
7975
7976/* toggle RCA according to the front-jack state */
7977static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7978{
7979 	unsigned int present;
7980
7981 	present = snd_hda_codec_read(codec, 0x14, 0,
7982				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7983	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7984				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7985}
7986
7987static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7988					     unsigned int res)
7989{
7990	if ((res >> 26) == ALC880_HP_EVENT)
7991		alc888_lenovo_ms7195_front_automute(codec);
7992	if ((res >> 26) == ALC880_FRONT_EVENT)
7993		alc888_lenovo_ms7195_rca_automute(codec);
7994}
7995
7996static struct hda_verb alc883_medion_md2_verbs[] = {
7997	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7998	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7999
8000	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8001
8002	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8003	{ } /* end */
8004};
8005
8006/* toggle speaker-output according to the hp-jack state */
8007static void alc883_medion_md2_init_hook(struct hda_codec *codec)
8008{
8009	struct alc_spec *spec = codec->spec;
8010
8011	spec->autocfg.hp_pins[0] = 0x14;
8012	spec->autocfg.speaker_pins[0] = 0x15;
8013	alc_automute_amp(codec);
8014}
8015
8016/* toggle speaker-output according to the hp-jack state */
8017#define alc883_targa_init_hook		alc882_targa_init_hook
8018#define alc883_targa_unsol_event	alc882_targa_unsol_event
8019
8020static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8021{
8022	unsigned int present;
8023
8024	present = snd_hda_codec_read(codec, 0x18, 0,
8025				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8026	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8027				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8028}
8029
8030static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
8031{
8032	struct alc_spec *spec = codec->spec;
8033
8034	spec->autocfg.hp_pins[0] = 0x15;
8035	spec->autocfg.speaker_pins[0] = 0x14;
8036	alc_automute_amp(codec);
8037	alc883_clevo_m720_mic_automute(codec);
8038}
8039
8040static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
8041					   unsigned int res)
8042{
8043	switch (res >> 26) {
8044	case ALC880_MIC_EVENT:
8045		alc883_clevo_m720_mic_automute(codec);
8046		break;
8047	default:
8048		alc_automute_amp_unsol_event(codec, res);
8049		break;
8050	}
8051}
8052
8053/* toggle speaker-output according to the hp-jack state */
8054static void alc883_2ch_fujitsu_pi2515_init_hook(struct hda_codec *codec)
8055{
8056	struct alc_spec *spec = codec->spec;
8057
8058	spec->autocfg.hp_pins[0] = 0x14;
8059	spec->autocfg.speaker_pins[0] = 0x15;
8060	alc_automute_amp(codec);
8061}
8062
8063static void alc883_haier_w66_init_hook(struct hda_codec *codec)
8064{
8065	struct alc_spec *spec = codec->spec;
8066
8067	spec->autocfg.hp_pins[0] = 0x1b;
8068	spec->autocfg.speaker_pins[0] = 0x14;
8069	alc_automute_amp(codec);
8070}
8071
8072static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8073{
8074 	unsigned int present;
8075	unsigned char bits;
8076
8077	present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
8078		& AC_PINSENSE_PRESENCE;
8079	bits = present ? HDA_AMP_MUTE : 0;
8080	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8081				 HDA_AMP_MUTE, bits);
8082}
8083
8084static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8085{
8086 	unsigned int present;
8087	unsigned char bits;
8088
8089 	present = snd_hda_codec_read(codec, 0x1b, 0,
8090				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8091	bits = present ? HDA_AMP_MUTE : 0;
8092	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8093				 HDA_AMP_MUTE, bits);
8094	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8095				 HDA_AMP_MUTE, bits);
8096}
8097
8098static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8099					   unsigned int res)
8100{
8101	if ((res >> 26) == ALC880_HP_EVENT)
8102		alc883_lenovo_101e_all_automute(codec);
8103	if ((res >> 26) == ALC880_FRONT_EVENT)
8104		alc883_lenovo_101e_ispeaker_automute(codec);
8105}
8106
8107/* toggle speaker-output according to the hp-jack state */
8108static void alc883_acer_aspire_init_hook(struct hda_codec *codec)
8109{
8110	struct alc_spec *spec = codec->spec;
8111
8112	spec->autocfg.hp_pins[0] = 0x14;
8113	spec->autocfg.speaker_pins[0] = 0x15;
8114	spec->autocfg.speaker_pins[1] = 0x16;
8115	alc_automute_amp(codec);
8116}
8117
8118static struct hda_verb alc883_acer_eapd_verbs[] = {
8119	/* HP Pin: output 0 (0x0c) */
8120	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8121	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8122	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8123	/* Front Pin: output 0 (0x0c) */
8124	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8125	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8126	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8127	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8128        /* eanable EAPD on medion laptop */
8129	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8130	{0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8131	/* enable unsolicited event */
8132	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8133	{ }
8134};
8135
8136static void alc888_6st_dell_init_hook(struct hda_codec *codec)
8137{
8138	struct alc_spec *spec = codec->spec;
8139
8140	spec->autocfg.hp_pins[0] = 0x1b;
8141	spec->autocfg.speaker_pins[0] = 0x14;
8142	spec->autocfg.speaker_pins[1] = 0x15;
8143	spec->autocfg.speaker_pins[2] = 0x16;
8144	spec->autocfg.speaker_pins[3] = 0x17;
8145	alc_automute_amp(codec);
8146}
8147
8148static void alc888_lenovo_sky_init_hook(struct hda_codec *codec)
8149{
8150	struct alc_spec *spec = codec->spec;
8151
8152	spec->autocfg.hp_pins[0] = 0x1b;
8153	spec->autocfg.speaker_pins[0] = 0x14;
8154	spec->autocfg.speaker_pins[1] = 0x15;
8155	spec->autocfg.speaker_pins[2] = 0x16;
8156	spec->autocfg.speaker_pins[3] = 0x17;
8157	spec->autocfg.speaker_pins[4] = 0x1a;
8158	alc_automute_amp(codec);
8159}
8160
8161static void alc883_vaiott_init_hook(struct hda_codec *codec)
8162{
8163	struct alc_spec *spec = codec->spec;
8164
8165	spec->autocfg.hp_pins[0] = 0x15;
8166	spec->autocfg.speaker_pins[0] = 0x14;
8167	spec->autocfg.speaker_pins[1] = 0x17;
8168	alc_automute_amp(codec);
8169}
8170
8171static struct hda_verb alc888_asus_m90v_verbs[] = {
8172	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8173	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8174	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8175	/* enable unsolicited event */
8176	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8177	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8178	{ } /* end */
8179};
8180
8181static void alc883_nb_mic_automute(struct hda_codec *codec)
8182{
8183	unsigned int present;
8184
8185	present = snd_hda_codec_read(codec, 0x18, 0,
8186				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8187	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8188			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8189	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8190			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8191}
8192
8193static void alc883_M90V_init_hook(struct hda_codec *codec)
8194{
8195	struct alc_spec *spec = codec->spec;
8196
8197	spec->autocfg.hp_pins[0] = 0x1b;
8198	spec->autocfg.speaker_pins[0] = 0x14;
8199	spec->autocfg.speaker_pins[1] = 0x15;
8200	spec->autocfg.speaker_pins[2] = 0x16;
8201	alc_automute_pin(codec);
8202}
8203
8204static void alc883_mode2_unsol_event(struct hda_codec *codec,
8205					   unsigned int res)
8206{
8207	switch (res >> 26) {
8208	case ALC880_MIC_EVENT:
8209		alc883_nb_mic_automute(codec);
8210		break;
8211	default:
8212		alc_sku_unsol_event(codec, res);
8213		break;
8214	}
8215}
8216
8217static void alc883_mode2_inithook(struct hda_codec *codec)
8218{
8219	alc883_M90V_init_hook(codec);
8220	alc883_nb_mic_automute(codec);
8221}
8222
8223static struct hda_verb alc888_asus_eee1601_verbs[] = {
8224	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8225	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8226	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8227	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8228	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8229	{0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8230	{0x20, AC_VERB_SET_PROC_COEF,  0x0838},
8231	/* enable unsolicited event */
8232	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8233	{ } /* end */
8234};
8235
8236static void alc883_eee1601_inithook(struct hda_codec *codec)
8237{
8238	struct alc_spec *spec = codec->spec;
8239
8240	spec->autocfg.hp_pins[0] = 0x14;
8241	spec->autocfg.speaker_pins[0] = 0x1b;
8242	alc_automute_pin(codec);
8243}
8244
8245static struct hda_verb alc889A_mb31_verbs[] = {
8246	/* Init rear pin (used as headphone output) */
8247	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},    /* Apple Headphones */
8248	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},           /* Connect to front */
8249	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8250	/* Init line pin (used as output in 4ch and 6ch mode) */
8251	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},           /* Connect to CLFE */
8252	/* Init line 2 pin (used as headphone out by default) */
8253	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},  /* Use as input */
8254	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
8255	{ } /* end */
8256};
8257
8258/* Mute speakers according to the headphone jack state */
8259static void alc889A_mb31_automute(struct hda_codec *codec)
8260{
8261	unsigned int present;
8262
8263	/* Mute only in 2ch or 4ch mode */
8264	if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
8265	    == 0x00) {
8266		present = snd_hda_codec_read(codec, 0x15, 0,
8267			AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
8268		snd_hda_codec_amp_stereo(codec, 0x14,  HDA_OUTPUT, 0,
8269			HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8270		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8271			HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8272	}
8273}
8274
8275static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
8276{
8277	if ((res >> 26) == ALC880_HP_EVENT)
8278		alc889A_mb31_automute(codec);
8279}
8280
8281
8282#ifdef CONFIG_SND_HDA_POWER_SAVE
8283#define alc882_loopbacks	alc880_loopbacks
8284#endif
8285
8286/* pcm configuration: identical with ALC880 */
8287#define alc882_pcm_analog_playback	alc880_pcm_analog_playback
8288#define alc882_pcm_analog_capture	alc880_pcm_analog_capture
8289#define alc882_pcm_digital_playback	alc880_pcm_digital_playback
8290#define alc882_pcm_digital_capture	alc880_pcm_digital_capture
8291
8292static hda_nid_t alc883_slave_dig_outs[] = {
8293	ALC1200_DIGOUT_NID, 0,
8294};
8295
8296static hda_nid_t alc1200_slave_dig_outs[] = {
8297	ALC883_DIGOUT_NID, 0,
8298};
8299
8300/*
8301 * configuration and preset
8302 */
8303static const char *alc882_models[ALC882_MODEL_LAST] = {
8304	[ALC882_3ST_DIG]	= "3stack-dig",
8305	[ALC882_6ST_DIG]	= "6stack-dig",
8306	[ALC882_ARIMA]		= "arima",
8307	[ALC882_W2JC]		= "w2jc",
8308	[ALC882_TARGA]		= "targa",
8309	[ALC882_ASUS_A7J]	= "asus-a7j",
8310	[ALC882_ASUS_A7M]	= "asus-a7m",
8311	[ALC885_MACPRO]		= "macpro",
8312	[ALC885_MB5]		= "mb5",
8313	[ALC885_MBP3]		= "mbp3",
8314	[ALC885_IMAC24]		= "imac24",
8315	[ALC883_3ST_2ch_DIG]	= "3stack-2ch-dig",
8316	[ALC883_3ST_6ch_DIG]	= "3stack-6ch-dig",
8317	[ALC883_3ST_6ch]	= "3stack-6ch",
8318	[ALC883_6ST_DIG]	= "alc883-6stack-dig",
8319	[ALC883_TARGA_DIG]	= "targa-dig",
8320	[ALC883_TARGA_2ch_DIG]	= "targa-2ch-dig",
8321	[ALC883_TARGA_8ch_DIG]	= "targa-8ch-dig",
8322	[ALC883_ACER]		= "acer",
8323	[ALC883_ACER_ASPIRE]	= "acer-aspire",
8324	[ALC888_ACER_ASPIRE_4930G]	= "acer-aspire-4930g",
8325	[ALC888_ACER_ASPIRE_6530G]	= "acer-aspire-6530g",
8326	[ALC888_ACER_ASPIRE_8930G]	= "acer-aspire-8930g",
8327	[ALC883_MEDION]		= "medion",
8328	[ALC883_MEDION_MD2]	= "medion-md2",
8329	[ALC883_LAPTOP_EAPD]	= "laptop-eapd",
8330	[ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8331	[ALC883_LENOVO_NB0763]	= "lenovo-nb0763",
8332	[ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8333	[ALC888_LENOVO_SKY] = "lenovo-sky",
8334	[ALC883_HAIER_W66] 	= "haier-w66",
8335	[ALC888_3ST_HP]		= "3stack-hp",
8336	[ALC888_6ST_DELL]	= "6stack-dell",
8337	[ALC883_MITAC]		= "mitac",
8338	[ALC883_CLEVO_M720]	= "clevo-m720",
8339	[ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8340	[ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
8341	[ALC883_3ST_6ch_INTEL]	= "3stack-6ch-intel",
8342	[ALC1200_ASUS_P5Q]	= "asus-p5q",
8343	[ALC889A_MB31]		= "mb31",
8344	[ALC883_SONY_VAIO_TT]	= "sony-vaio-tt",
8345	[ALC882_AUTO]		= "auto",
8346};
8347
8348static struct snd_pci_quirk alc882_cfg_tbl[] = {
8349	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
8350
8351	SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8352	SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
8353	SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
8354	SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8355	SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8356	SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8357	SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8358		ALC888_ACER_ASPIRE_4930G),
8359	SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
8360		ALC888_ACER_ASPIRE_4930G),
8361	SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
8362		ALC888_ACER_ASPIRE_8930G),
8363	SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
8364		ALC888_ACER_ASPIRE_8930G),
8365	SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
8366	SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
8367	SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
8368		ALC888_ACER_ASPIRE_6530G),
8369	SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
8370		ALC888_ACER_ASPIRE_6530G),
8371	/* default Acer -- disabled as it causes more problems.
8372	 *    model=auto should work fine now
8373	 */
8374	/* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
8375
8376	SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8377
8378	SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8379	SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8380	SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8381	SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8382	SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
8383	SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
8384
8385	SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
8386	SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
8387	SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
8388	SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8389	SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
8390	SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
8391	SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
8392	SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8393	SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
8394	SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
8395	SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8396
8397	SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
8398	SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8399	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
8400	SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
8401	SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8402	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8403	SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8404	SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8405	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
8406
8407	SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8408	SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8409	SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8410	SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
8411	SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8412	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
8413	SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8414	SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8415	SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8416	SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8417	SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8418	SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8419	SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8420	SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8421	SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8422	SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8423	SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8424	SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
8425	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8426	SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8427	SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8428	SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
8429	SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8430	SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8431	SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8432	SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
8433	SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8434
8435	SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8436	SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8437	SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8438	SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
8439	SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8440	/* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
8441	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8442	SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
8443		      ALC883_FUJITSU_PI2515),
8444	SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
8445		ALC888_FUJITSU_XA3530),
8446	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8447	SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8448	SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8449	SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8450	SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8451	SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8452	SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
8453	SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8454	SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8455
8456	SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8457	SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8458	SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
8459	SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL),
8460	SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8461
8462	{}
8463};
8464
8465/* codec SSID table for Intel Mac */
8466static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
8467	SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
8468	SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
8469	SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
8470	SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
8471	SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
8472	SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
8473	SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
8474	SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
8475	SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
8476	SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
8477	SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
8478	/* FIXME: HP jack sense seems not working for MBP 5,1, so apparently
8479	 * no perfect solution yet
8480	 */
8481	SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
8482	{} /* terminator */
8483};
8484
8485static struct alc_config_preset alc882_presets[] = {
8486	[ALC882_3ST_DIG] = {
8487		.mixers = { alc882_base_mixer },
8488		.init_verbs = { alc882_init_verbs },
8489		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
8490		.dac_nids = alc882_dac_nids,
8491		.dig_out_nid = ALC882_DIGOUT_NID,
8492		.dig_in_nid = ALC882_DIGIN_NID,
8493		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
8494		.channel_mode = alc882_ch_modes,
8495		.need_dac_fix = 1,
8496		.input_mux = &alc882_capture_source,
8497	},
8498	[ALC882_6ST_DIG] = {
8499		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
8500		.init_verbs = { alc882_init_verbs },
8501		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
8502		.dac_nids = alc882_dac_nids,
8503		.dig_out_nid = ALC882_DIGOUT_NID,
8504		.dig_in_nid = ALC882_DIGIN_NID,
8505		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
8506		.channel_mode = alc882_sixstack_modes,
8507		.input_mux = &alc882_capture_source,
8508	},
8509	[ALC882_ARIMA] = {
8510		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
8511		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
8512		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
8513		.dac_nids = alc882_dac_nids,
8514		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
8515		.channel_mode = alc882_sixstack_modes,
8516		.input_mux = &alc882_capture_source,
8517	},
8518	[ALC882_W2JC] = {
8519		.mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8520		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
8521				alc880_gpio1_init_verbs },
8522		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
8523		.dac_nids = alc882_dac_nids,
8524		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
8525		.channel_mode = alc880_threestack_modes,
8526		.need_dac_fix = 1,
8527		.input_mux = &alc882_capture_source,
8528		.dig_out_nid = ALC882_DIGOUT_NID,
8529	},
8530	[ALC885_MBP3] = {
8531		.mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
8532		.init_verbs = { alc885_mbp3_init_verbs,
8533				alc880_gpio1_init_verbs },
8534		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
8535		.dac_nids = alc882_dac_nids,
8536		.channel_mode = alc885_mbp_6ch_modes,
8537		.num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
8538		.input_mux = &alc882_capture_source,
8539		.dig_out_nid = ALC882_DIGOUT_NID,
8540		.dig_in_nid = ALC882_DIGIN_NID,
8541		.unsol_event = alc_automute_amp_unsol_event,
8542		.init_hook = alc885_mbp3_init_hook,
8543	},
8544	[ALC885_MB5] = {
8545		.mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
8546		.init_verbs = { alc885_mb5_init_verbs,
8547				alc880_gpio1_init_verbs },
8548		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
8549		.dac_nids = alc882_dac_nids,
8550		.channel_mode = alc885_mb5_6ch_modes,
8551		.num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
8552		.input_mux = &mb5_capture_source,
8553		.dig_out_nid = ALC882_DIGOUT_NID,
8554		.dig_in_nid = ALC882_DIGIN_NID,
8555	},
8556	[ALC885_MACPRO] = {
8557		.mixers = { alc882_macpro_mixer },
8558		.init_verbs = { alc882_macpro_init_verbs },
8559		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
8560		.dac_nids = alc882_dac_nids,
8561		.dig_out_nid = ALC882_DIGOUT_NID,
8562		.dig_in_nid = ALC882_DIGIN_NID,
8563		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
8564		.channel_mode = alc882_ch_modes,
8565		.input_mux = &alc882_capture_source,
8566		.init_hook = alc885_macpro_init_hook,
8567	},
8568	[ALC885_IMAC24] = {
8569		.mixers = { alc885_imac24_mixer },
8570		.init_verbs = { alc885_imac24_init_verbs },
8571		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
8572		.dac_nids = alc882_dac_nids,
8573		.dig_out_nid = ALC882_DIGOUT_NID,
8574		.dig_in_nid = ALC882_DIGIN_NID,
8575		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
8576		.channel_mode = alc882_ch_modes,
8577		.input_mux = &alc882_capture_source,
8578		.unsol_event = alc_automute_amp_unsol_event,
8579		.init_hook = alc885_imac24_init_hook,
8580	},
8581	[ALC882_TARGA] = {
8582		.mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8583		.init_verbs = { alc882_init_verbs, alc882_targa_verbs},
8584		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
8585		.dac_nids = alc882_dac_nids,
8586		.dig_out_nid = ALC882_DIGOUT_NID,
8587		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
8588		.adc_nids = alc882_adc_nids,
8589		.capsrc_nids = alc882_capsrc_nids,
8590		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
8591		.channel_mode = alc882_3ST_6ch_modes,
8592		.need_dac_fix = 1,
8593		.input_mux = &alc882_capture_source,
8594		.unsol_event = alc882_targa_unsol_event,
8595		.init_hook = alc882_targa_init_hook,
8596	},
8597	[ALC882_ASUS_A7J] = {
8598		.mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8599		.init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
8600		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
8601		.dac_nids = alc882_dac_nids,
8602		.dig_out_nid = ALC882_DIGOUT_NID,
8603		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
8604		.adc_nids = alc882_adc_nids,
8605		.capsrc_nids = alc882_capsrc_nids,
8606		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
8607		.channel_mode = alc882_3ST_6ch_modes,
8608		.need_dac_fix = 1,
8609		.input_mux = &alc882_capture_source,
8610	},
8611	[ALC882_ASUS_A7M] = {
8612		.mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8613		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
8614				alc880_gpio1_init_verbs,
8615				alc882_asus_a7m_verbs },
8616		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
8617		.dac_nids = alc882_dac_nids,
8618		.dig_out_nid = ALC882_DIGOUT_NID,
8619		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
8620		.channel_mode = alc880_threestack_modes,
8621		.need_dac_fix = 1,
8622		.input_mux = &alc882_capture_source,
8623	},
8624	[ALC883_3ST_2ch_DIG] = {
8625		.mixers = { alc883_3ST_2ch_mixer },
8626		.init_verbs = { alc883_init_verbs },
8627		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8628		.dac_nids = alc883_dac_nids,
8629		.dig_out_nid = ALC883_DIGOUT_NID,
8630		.dig_in_nid = ALC883_DIGIN_NID,
8631		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8632		.channel_mode = alc883_3ST_2ch_modes,
8633		.input_mux = &alc883_capture_source,
8634	},
8635	[ALC883_3ST_6ch_DIG] = {
8636		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8637		.init_verbs = { alc883_init_verbs },
8638		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8639		.dac_nids = alc883_dac_nids,
8640		.dig_out_nid = ALC883_DIGOUT_NID,
8641		.dig_in_nid = ALC883_DIGIN_NID,
8642		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8643		.channel_mode = alc883_3ST_6ch_modes,
8644		.need_dac_fix = 1,
8645		.input_mux = &alc883_capture_source,
8646	},
8647	[ALC883_3ST_6ch] = {
8648		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8649		.init_verbs = { alc883_init_verbs },
8650		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8651		.dac_nids = alc883_dac_nids,
8652		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8653		.channel_mode = alc883_3ST_6ch_modes,
8654		.need_dac_fix = 1,
8655		.input_mux = &alc883_capture_source,
8656	},
8657	[ALC883_3ST_6ch_INTEL] = {
8658		.mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8659		.init_verbs = { alc883_init_verbs },
8660		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8661		.dac_nids = alc883_dac_nids,
8662		.dig_out_nid = ALC883_DIGOUT_NID,
8663		.dig_in_nid = ALC883_DIGIN_NID,
8664		.slave_dig_outs = alc883_slave_dig_outs,
8665		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8666		.channel_mode = alc883_3ST_6ch_intel_modes,
8667		.need_dac_fix = 1,
8668		.input_mux = &alc883_3stack_6ch_intel,
8669	},
8670	[ALC883_6ST_DIG] = {
8671		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
8672		.init_verbs = { alc883_init_verbs },
8673		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8674		.dac_nids = alc883_dac_nids,
8675		.dig_out_nid = ALC883_DIGOUT_NID,
8676		.dig_in_nid = ALC883_DIGIN_NID,
8677		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8678		.channel_mode = alc883_sixstack_modes,
8679		.input_mux = &alc883_capture_source,
8680	},
8681	[ALC883_TARGA_DIG] = {
8682		.mixers = { alc883_targa_mixer, alc883_chmode_mixer },
8683		.init_verbs = { alc883_init_verbs, alc883_targa_verbs},
8684		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8685		.dac_nids = alc883_dac_nids,
8686		.dig_out_nid = ALC883_DIGOUT_NID,
8687		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8688		.channel_mode = alc883_3ST_6ch_modes,
8689		.need_dac_fix = 1,
8690		.input_mux = &alc883_capture_source,
8691		.unsol_event = alc883_targa_unsol_event,
8692		.init_hook = alc883_targa_init_hook,
8693	},
8694	[ALC883_TARGA_2ch_DIG] = {
8695		.mixers = { alc883_targa_2ch_mixer},
8696		.init_verbs = { alc883_init_verbs, alc883_targa_verbs},
8697		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8698		.dac_nids = alc883_dac_nids,
8699		.adc_nids = alc883_adc_nids_alt,
8700		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8701		.dig_out_nid = ALC883_DIGOUT_NID,
8702		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8703		.channel_mode = alc883_3ST_2ch_modes,
8704		.input_mux = &alc883_capture_source,
8705		.unsol_event = alc883_targa_unsol_event,
8706		.init_hook = alc883_targa_init_hook,
8707	},
8708	[ALC883_TARGA_8ch_DIG] = {
8709		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
8710		.init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
8711				alc883_targa_verbs },
8712		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8713		.dac_nids = alc883_dac_nids,
8714		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8715		.adc_nids = alc883_adc_nids_rev,
8716		.capsrc_nids = alc883_capsrc_nids_rev,
8717		.dig_out_nid = ALC883_DIGOUT_NID,
8718		.dig_in_nid = ALC883_DIGIN_NID,
8719		.num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
8720		.channel_mode = alc883_4ST_8ch_modes,
8721		.need_dac_fix = 1,
8722		.input_mux = &alc883_capture_source,
8723		.unsol_event = alc883_targa_unsol_event,
8724		.init_hook = alc883_targa_init_hook,
8725	},
8726	[ALC883_ACER] = {
8727		.mixers = { alc883_base_mixer },
8728		/* On TravelMate laptops, GPIO 0 enables the internal speaker
8729		 * and the headphone jack.  Turn this on and rely on the
8730		 * standard mute methods whenever the user wants to turn
8731		 * these outputs off.
8732		 */
8733		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8734		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8735		.dac_nids = alc883_dac_nids,
8736		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8737		.channel_mode = alc883_3ST_2ch_modes,
8738		.input_mux = &alc883_capture_source,
8739	},
8740	[ALC883_ACER_ASPIRE] = {
8741		.mixers = { alc883_acer_aspire_mixer },
8742		.init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
8743		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8744		.dac_nids = alc883_dac_nids,
8745		.dig_out_nid = ALC883_DIGOUT_NID,
8746		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8747		.channel_mode = alc883_3ST_2ch_modes,
8748		.input_mux = &alc883_capture_source,
8749		.unsol_event = alc_automute_amp_unsol_event,
8750		.init_hook = alc883_acer_aspire_init_hook,
8751	},
8752	[ALC888_ACER_ASPIRE_4930G] = {
8753		.mixers = { alc888_base_mixer,
8754				alc883_chmode_mixer },
8755		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
8756				alc888_acer_aspire_4930g_verbs },
8757		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8758		.dac_nids = alc883_dac_nids,
8759		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8760		.adc_nids = alc883_adc_nids_rev,
8761		.capsrc_nids = alc883_capsrc_nids_rev,
8762		.dig_out_nid = ALC883_DIGOUT_NID,
8763		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8764		.channel_mode = alc883_3ST_6ch_modes,
8765		.need_dac_fix = 1,
8766		.num_mux_defs =
8767			ARRAY_SIZE(alc888_2_capture_sources),
8768		.input_mux = alc888_2_capture_sources,
8769		.unsol_event = alc_automute_amp_unsol_event,
8770		.init_hook = alc888_acer_aspire_4930g_init_hook,
8771	},
8772	[ALC888_ACER_ASPIRE_6530G] = {
8773		.mixers = { alc888_acer_aspire_6530_mixer },
8774		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
8775				alc888_acer_aspire_6530g_verbs },
8776		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8777		.dac_nids = alc883_dac_nids,
8778		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8779		.adc_nids = alc883_adc_nids_rev,
8780		.capsrc_nids = alc883_capsrc_nids_rev,
8781		.dig_out_nid = ALC883_DIGOUT_NID,
8782		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8783		.channel_mode = alc883_3ST_2ch_modes,
8784		.num_mux_defs =
8785			ARRAY_SIZE(alc888_2_capture_sources),
8786		.input_mux = alc888_acer_aspire_6530_sources,
8787		.unsol_event = alc_automute_amp_unsol_event,
8788		.init_hook = alc888_acer_aspire_6530g_init_hook,
8789	},
8790	[ALC888_ACER_ASPIRE_8930G] = {
8791		.mixers = { alc888_base_mixer,
8792				alc883_chmode_mixer },
8793		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
8794				alc889_acer_aspire_8930g_verbs },
8795		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8796		.dac_nids = alc883_dac_nids,
8797		.num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
8798		.adc_nids = alc889_adc_nids,
8799		.capsrc_nids = alc889_capsrc_nids,
8800		.dig_out_nid = ALC883_DIGOUT_NID,
8801		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8802		.channel_mode = alc883_3ST_6ch_modes,
8803		.need_dac_fix = 1,
8804		.const_channel_count = 6,
8805		.num_mux_defs =
8806			ARRAY_SIZE(alc889_capture_sources),
8807		.input_mux = alc889_capture_sources,
8808		.unsol_event = alc_automute_amp_unsol_event,
8809		.init_hook = alc889_acer_aspire_8930g_init_hook,
8810	},
8811	[ALC883_MEDION] = {
8812		.mixers = { alc883_fivestack_mixer,
8813			    alc883_chmode_mixer },
8814		.init_verbs = { alc883_init_verbs,
8815				alc883_medion_eapd_verbs },
8816		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8817		.dac_nids = alc883_dac_nids,
8818		.adc_nids = alc883_adc_nids_alt,
8819		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8820		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8821		.channel_mode = alc883_sixstack_modes,
8822		.input_mux = &alc883_capture_source,
8823	},
8824	[ALC883_MEDION_MD2] = {
8825		.mixers = { alc883_medion_md2_mixer},
8826		.init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8827		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8828		.dac_nids = alc883_dac_nids,
8829		.dig_out_nid = ALC883_DIGOUT_NID,
8830		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8831		.channel_mode = alc883_3ST_2ch_modes,
8832		.input_mux = &alc883_capture_source,
8833		.unsol_event = alc_automute_amp_unsol_event,
8834		.init_hook = alc883_medion_md2_init_hook,
8835	},
8836	[ALC883_LAPTOP_EAPD] = {
8837		.mixers = { alc883_base_mixer },
8838		.init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8839		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8840		.dac_nids = alc883_dac_nids,
8841		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8842		.channel_mode = alc883_3ST_2ch_modes,
8843		.input_mux = &alc883_capture_source,
8844	},
8845	[ALC883_CLEVO_M720] = {
8846		.mixers = { alc883_clevo_m720_mixer },
8847		.init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
8848		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8849		.dac_nids = alc883_dac_nids,
8850		.dig_out_nid = ALC883_DIGOUT_NID,
8851		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8852		.channel_mode = alc883_3ST_2ch_modes,
8853		.input_mux = &alc883_capture_source,
8854		.unsol_event = alc883_clevo_m720_unsol_event,
8855		.init_hook = alc883_clevo_m720_init_hook,
8856	},
8857	[ALC883_LENOVO_101E_2ch] = {
8858		.mixers = { alc883_lenovo_101e_2ch_mixer},
8859		.init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8860		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8861		.dac_nids = alc883_dac_nids,
8862		.adc_nids = alc883_adc_nids_alt,
8863		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8864		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8865		.channel_mode = alc883_3ST_2ch_modes,
8866		.input_mux = &alc883_lenovo_101e_capture_source,
8867		.unsol_event = alc883_lenovo_101e_unsol_event,
8868		.init_hook = alc883_lenovo_101e_all_automute,
8869	},
8870	[ALC883_LENOVO_NB0763] = {
8871		.mixers = { alc883_lenovo_nb0763_mixer },
8872		.init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8873		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8874		.dac_nids = alc883_dac_nids,
8875		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8876		.channel_mode = alc883_3ST_2ch_modes,
8877		.need_dac_fix = 1,
8878		.input_mux = &alc883_lenovo_nb0763_capture_source,
8879		.unsol_event = alc_automute_amp_unsol_event,
8880		.init_hook = alc883_medion_md2_init_hook,
8881	},
8882	[ALC888_LENOVO_MS7195_DIG] = {
8883		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8884		.init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8885		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8886		.dac_nids = alc883_dac_nids,
8887		.dig_out_nid = ALC883_DIGOUT_NID,
8888		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8889		.channel_mode = alc883_3ST_6ch_modes,
8890		.need_dac_fix = 1,
8891		.input_mux = &alc883_capture_source,
8892		.unsol_event = alc883_lenovo_ms7195_unsol_event,
8893		.init_hook = alc888_lenovo_ms7195_front_automute,
8894	},
8895	[ALC883_HAIER_W66] = {
8896		.mixers = { alc883_targa_2ch_mixer},
8897		.init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8898		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8899		.dac_nids = alc883_dac_nids,
8900		.dig_out_nid = ALC883_DIGOUT_NID,
8901		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8902		.channel_mode = alc883_3ST_2ch_modes,
8903		.input_mux = &alc883_capture_source,
8904		.unsol_event = alc_automute_amp_unsol_event,
8905		.init_hook = alc883_haier_w66_init_hook,
8906	},
8907	[ALC888_3ST_HP] = {
8908		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8909		.init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8910		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8911		.dac_nids = alc883_dac_nids,
8912		.num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
8913		.channel_mode = alc888_3st_hp_modes,
8914		.need_dac_fix = 1,
8915		.input_mux = &alc883_capture_source,
8916		.unsol_event = alc_automute_amp_unsol_event,
8917		.init_hook = alc888_3st_hp_init_hook,
8918	},
8919	[ALC888_6ST_DELL] = {
8920		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
8921		.init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
8922		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8923		.dac_nids = alc883_dac_nids,
8924		.dig_out_nid = ALC883_DIGOUT_NID,
8925		.dig_in_nid = ALC883_DIGIN_NID,
8926		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8927		.channel_mode = alc883_sixstack_modes,
8928		.input_mux = &alc883_capture_source,
8929		.unsol_event = alc_automute_amp_unsol_event,
8930		.init_hook = alc888_6st_dell_init_hook,
8931	},
8932	[ALC883_MITAC] = {
8933		.mixers = { alc883_mitac_mixer },
8934		.init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8935		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8936		.dac_nids = alc883_dac_nids,
8937		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8938		.channel_mode = alc883_3ST_2ch_modes,
8939		.input_mux = &alc883_capture_source,
8940		.unsol_event = alc_automute_amp_unsol_event,
8941		.init_hook = alc883_mitac_init_hook,
8942	},
8943	[ALC883_FUJITSU_PI2515] = {
8944		.mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8945		.init_verbs = { alc883_init_verbs,
8946				alc883_2ch_fujitsu_pi2515_verbs},
8947		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8948		.dac_nids = alc883_dac_nids,
8949		.dig_out_nid = ALC883_DIGOUT_NID,
8950		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8951		.channel_mode = alc883_3ST_2ch_modes,
8952		.input_mux = &alc883_fujitsu_pi2515_capture_source,
8953		.unsol_event = alc_automute_amp_unsol_event,
8954		.init_hook = alc883_2ch_fujitsu_pi2515_init_hook,
8955	},
8956	[ALC888_FUJITSU_XA3530] = {
8957		.mixers = { alc888_base_mixer, alc883_chmode_mixer },
8958		.init_verbs = { alc883_init_verbs,
8959			alc888_fujitsu_xa3530_verbs },
8960		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8961		.dac_nids = alc883_dac_nids,
8962		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8963		.adc_nids = alc883_adc_nids_rev,
8964		.capsrc_nids = alc883_capsrc_nids_rev,
8965		.dig_out_nid = ALC883_DIGOUT_NID,
8966		.num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
8967		.channel_mode = alc888_4ST_8ch_intel_modes,
8968		.num_mux_defs =
8969			ARRAY_SIZE(alc888_2_capture_sources),
8970		.input_mux = alc888_2_capture_sources,
8971		.unsol_event = alc_automute_amp_unsol_event,
8972		.init_hook = alc888_fujitsu_xa3530_init_hook,
8973	},
8974	[ALC888_LENOVO_SKY] = {
8975		.mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
8976		.init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
8977		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8978		.dac_nids = alc883_dac_nids,
8979		.dig_out_nid = ALC883_DIGOUT_NID,
8980		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8981		.channel_mode = alc883_sixstack_modes,
8982		.need_dac_fix = 1,
8983		.input_mux = &alc883_lenovo_sky_capture_source,
8984		.unsol_event = alc_automute_amp_unsol_event,
8985		.init_hook = alc888_lenovo_sky_init_hook,
8986	},
8987	[ALC888_ASUS_M90V] = {
8988		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8989		.init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
8990		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8991		.dac_nids = alc883_dac_nids,
8992		.dig_out_nid = ALC883_DIGOUT_NID,
8993		.dig_in_nid = ALC883_DIGIN_NID,
8994		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8995		.channel_mode = alc883_3ST_6ch_modes,
8996		.need_dac_fix = 1,
8997		.input_mux = &alc883_fujitsu_pi2515_capture_source,
8998		.unsol_event = alc883_mode2_unsol_event,
8999		.init_hook = alc883_mode2_inithook,
9000	},
9001	[ALC888_ASUS_EEE1601] = {
9002		.mixers = { alc883_asus_eee1601_mixer },
9003		.cap_mixer = alc883_asus_eee1601_cap_mixer,
9004		.init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
9005		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
9006		.dac_nids = alc883_dac_nids,
9007		.dig_out_nid = ALC883_DIGOUT_NID,
9008		.dig_in_nid = ALC883_DIGIN_NID,
9009		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9010		.channel_mode = alc883_3ST_2ch_modes,
9011		.need_dac_fix = 1,
9012		.input_mux = &alc883_asus_eee1601_capture_source,
9013		.unsol_event = alc_sku_unsol_event,
9014		.init_hook = alc883_eee1601_inithook,
9015	},
9016	[ALC1200_ASUS_P5Q] = {
9017		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
9018		.init_verbs = { alc883_init_verbs },
9019		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
9020		.dac_nids = alc883_dac_nids,
9021		.dig_out_nid = ALC1200_DIGOUT_NID,
9022		.dig_in_nid = ALC883_DIGIN_NID,
9023		.slave_dig_outs = alc1200_slave_dig_outs,
9024		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9025		.channel_mode = alc883_sixstack_modes,
9026		.input_mux = &alc883_capture_source,
9027	},
9028	[ALC889A_MB31] = {
9029		.mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
9030		.init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
9031			alc880_gpio1_init_verbs },
9032		.adc_nids = alc883_adc_nids,
9033		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
9034		.dac_nids = alc883_dac_nids,
9035		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
9036		.channel_mode = alc889A_mb31_6ch_modes,
9037		.num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
9038		.input_mux = &alc889A_mb31_capture_source,
9039		.dig_out_nid = ALC883_DIGOUT_NID,
9040		.unsol_event = alc889A_mb31_unsol_event,
9041		.init_hook = alc889A_mb31_automute,
9042	},
9043	[ALC883_SONY_VAIO_TT] = {
9044		.mixers = { alc883_vaiott_mixer },
9045		.init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
9046		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
9047		.dac_nids = alc883_dac_nids,
9048		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9049		.channel_mode = alc883_3ST_2ch_modes,
9050		.input_mux = &alc883_capture_source,
9051		.unsol_event = alc_automute_amp_unsol_event,
9052		.init_hook = alc883_vaiott_init_hook,
9053	},
9054};
9055
9056
9057/*
9058 * Pin config fixes
9059 */
9060enum {
9061	PINFIX_ABIT_AW9D_MAX
9062};
9063
9064static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
9065	{ 0x15, 0x01080104 }, /* side */
9066	{ 0x16, 0x01011012 }, /* rear */
9067	{ 0x17, 0x01016011 }, /* clfe */
9068	{ }
9069};
9070
9071static const struct alc_pincfg *alc882_pin_fixes[] = {
9072	[PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
9073};
9074
9075static struct snd_pci_quirk alc882_pinfix_tbl[] = {
9076	SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
9077	{}
9078};
9079
9080/*
9081 * BIOS auto configuration
9082 */
9083static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9084					      hda_nid_t nid, int pin_type,
9085					      int dac_idx)
9086{
9087	/* set as output */
9088	struct alc_spec *spec = codec->spec;
9089	int idx;
9090
9091	alc_set_pin_output(codec, nid, pin_type);
9092	if (spec->multiout.dac_nids[dac_idx] == 0x25)
9093		idx = 4;
9094	else
9095		idx = spec->multiout.dac_nids[dac_idx] - 2;
9096	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9097
9098}
9099
9100static void alc882_auto_init_multi_out(struct hda_codec *codec)
9101{
9102	struct alc_spec *spec = codec->spec;
9103	int i;
9104
9105	for (i = 0; i <= HDA_SIDE; i++) {
9106		hda_nid_t nid = spec->autocfg.line_out_pins[i];
9107		int pin_type = get_pin_type(spec->autocfg.line_out_type);
9108		if (nid)
9109			alc882_auto_set_output_and_unmute(codec, nid, pin_type,
9110							  i);
9111	}
9112}
9113
9114static void alc882_auto_init_hp_out(struct hda_codec *codec)
9115{
9116	struct alc_spec *spec = codec->spec;
9117	hda_nid_t pin;
9118
9119	pin = spec->autocfg.hp_pins[0];
9120	if (pin) /* connect to front */
9121		/* use dac 0 */
9122		alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
9123	pin = spec->autocfg.speaker_pins[0];
9124	if (pin)
9125		alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9126}
9127
9128#define alc882_is_input_pin(nid)	alc880_is_input_pin(nid)
9129#define ALC882_PIN_CD_NID		ALC880_PIN_CD_NID
9130
9131static void alc882_auto_init_analog_input(struct hda_codec *codec)
9132{
9133	struct alc_spec *spec = codec->spec;
9134	int i;
9135
9136	for (i = 0; i < AUTO_PIN_LAST; i++) {
9137		hda_nid_t nid = spec->autocfg.input_pins[i];
9138		if (!nid)
9139			continue;
9140		alc_set_input_pin(codec, nid, AUTO_PIN_FRONT_MIC /*i*/);
9141		if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
9142			snd_hda_codec_write(codec, nid, 0,
9143					    AC_VERB_SET_AMP_GAIN_MUTE,
9144					    AMP_OUT_MUTE);
9145	}
9146}
9147
9148static void alc882_auto_init_input_src(struct hda_codec *codec)
9149{
9150	struct alc_spec *spec = codec->spec;
9151	int c;
9152
9153	for (c = 0; c < spec->num_adc_nids; c++) {
9154		hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
9155		hda_nid_t nid = spec->capsrc_nids[c];
9156		unsigned int mux_idx;
9157		const struct hda_input_mux *imux;
9158		int conns, mute, idx, item;
9159
9160		conns = snd_hda_get_connections(codec, nid, conn_list,
9161						ARRAY_SIZE(conn_list));
9162		if (conns < 0)
9163			continue;
9164		mux_idx = c >= spec->num_mux_defs ? 0 : c;
9165		imux = &spec->input_mux[mux_idx];
9166		for (idx = 0; idx < conns; idx++) {
9167			/* if the current connection is the selected one,
9168			 * unmute it as default - otherwise mute it
9169			 */
9170			mute = AMP_IN_MUTE(idx);
9171			for (item = 0; item < imux->num_items; item++) {
9172				if (imux->items[item].index == idx) {
9173					if (spec->cur_mux[c] == item)
9174						mute = AMP_IN_UNMUTE(idx);
9175					break;
9176				}
9177			}
9178			/* check if we have a selector or mixer
9179			 * we could check for the widget type instead, but
9180			 * just check for Amp-In presence (in case of mixer
9181			 * without amp-in there is something wrong, this
9182			 * function shouldn't be used or capsrc nid is wrong)
9183			 */
9184			if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9185				snd_hda_codec_write(codec, nid, 0,
9186						    AC_VERB_SET_AMP_GAIN_MUTE,
9187						    mute);
9188			else if (mute != AMP_IN_MUTE(idx))
9189				snd_hda_codec_write(codec, nid, 0,
9190						    AC_VERB_SET_CONNECT_SEL,
9191						    idx);
9192		}
9193	}
9194}
9195
9196/* add mic boosts if needed */
9197static int alc_auto_add_mic_boost(struct hda_codec *codec)
9198{
9199	struct alc_spec *spec = codec->spec;
9200	int err;
9201	hda_nid_t nid;
9202
9203	nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
9204	if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
9205		err = add_control(spec, ALC_CTL_WIDGET_VOL,
9206				  "Mic Boost",
9207				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9208		if (err < 0)
9209			return err;
9210	}
9211	nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
9212	if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
9213		err = add_control(spec, ALC_CTL_WIDGET_VOL,
9214				  "Front Mic Boost",
9215				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9216		if (err < 0)
9217			return err;
9218	}
9219	return 0;
9220}
9221
9222/* almost identical with ALC880 parser... */
9223static int alc882_parse_auto_config(struct hda_codec *codec)
9224{
9225	struct alc_spec *spec = codec->spec;
9226	struct auto_pin_cfg *autocfg = &spec->autocfg;
9227	unsigned int wcap;
9228	int i;
9229	int err = alc880_parse_auto_config(codec);
9230
9231	if (err < 0)
9232		return err;
9233	else if (!err)
9234		return 0; /* no config found */
9235
9236	err = alc_auto_add_mic_boost(codec);
9237	if (err < 0)
9238		return err;
9239
9240	/* hack - override the init verbs */
9241	spec->init_verbs[0] = alc883_auto_init_verbs;
9242	/* if ADC 0x07 is available, initialize it, too */
9243	wcap = get_wcaps(codec, 0x07);
9244	wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
9245	if (wcap == AC_WID_AUD_IN)
9246		add_verb(spec, alc882_adc1_init_verbs);
9247
9248	/* digital-mic input pin is excluded in alc880_auto_create..()
9249	 * because it's under 0x18
9250	 */
9251	if (autocfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
9252	    autocfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
9253		struct hda_input_mux *imux = &spec->private_imux[0];
9254		for (i = 1; i < 3; i++)
9255			memcpy(&spec->private_imux[i],
9256			       &spec->private_imux[0],
9257			       sizeof(spec->private_imux[0]));
9258		imux->items[imux->num_items].label = "Int DMic";
9259		imux->items[imux->num_items].index = 0x0b;
9260		imux->num_items++;
9261		spec->num_mux_defs = 3;
9262		spec->input_mux = spec->private_imux;
9263	}
9264
9265	return 1; /* config found */
9266}
9267
9268/* additional initialization for auto-configuration model */
9269static void alc882_auto_init(struct hda_codec *codec)
9270{
9271	struct alc_spec *spec = codec->spec;
9272	alc882_auto_init_multi_out(codec);
9273	alc882_auto_init_hp_out(codec);
9274	alc882_auto_init_analog_input(codec);
9275	alc882_auto_init_input_src(codec);
9276	if (spec->unsol_event)
9277		alc_inithook(codec);
9278}
9279
9280static int patch_alc882(struct hda_codec *codec)
9281{
9282	struct alc_spec *spec;
9283	int err, board_config;
9284
9285	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9286	if (spec == NULL)
9287		return -ENOMEM;
9288
9289	codec->spec = spec;
9290
9291	switch (codec->vendor_id) {
9292	case 0x10ec0882:
9293	case 0x10ec0885:
9294		break;
9295	default:
9296		/* ALC883 and variants */
9297		alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9298		break;
9299	}
9300
9301	board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
9302						  alc882_models,
9303						  alc882_cfg_tbl);
9304
9305	if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
9306		board_config = snd_hda_check_board_codec_sid_config(codec,
9307			ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
9308
9309	if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9310		printk(KERN_INFO "hda_codec: Unknown model for %s, "
9311		       "trying auto-probe from BIOS...\n",
9312		       codec->chip_name);
9313		board_config = ALC882_AUTO;
9314	}
9315
9316	alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
9317
9318	if (board_config == ALC882_AUTO) {
9319		/* automatic parse from the BIOS config */
9320		err = alc882_parse_auto_config(codec);
9321		if (err < 0) {
9322			alc_free(codec);
9323			return err;
9324		} else if (!err) {
9325			printk(KERN_INFO
9326			       "hda_codec: Cannot set up configuration "
9327			       "from BIOS.  Using base mode...\n");
9328			board_config = ALC882_3ST_DIG;
9329		}
9330	}
9331
9332	err = snd_hda_attach_beep_device(codec, 0x1);
9333	if (err < 0) {
9334		alc_free(codec);
9335		return err;
9336	}
9337
9338	if (board_config != ALC882_AUTO)
9339		setup_preset(spec, &alc882_presets[board_config]);
9340
9341	spec->stream_analog_playback = &alc882_pcm_analog_playback;
9342	spec->stream_analog_capture = &alc882_pcm_analog_capture;
9343	/* FIXME: setup DAC5 */
9344	/*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
9345	spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
9346
9347	spec->stream_digital_playback = &alc882_pcm_digital_playback;
9348	spec->stream_digital_capture = &alc882_pcm_digital_capture;
9349
9350	if (codec->vendor_id == 0x10ec0888)
9351		spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
9352
9353	if (!spec->adc_nids && spec->input_mux) {
9354		int i;
9355		spec->num_adc_nids = 0;
9356		for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
9357			hda_nid_t cap;
9358			hda_nid_t nid = alc882_adc_nids[i];
9359			unsigned int wcap = get_wcaps(codec, nid);
9360			/* get type */
9361			wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
9362			if (wcap != AC_WID_AUD_IN)
9363				continue;
9364			spec->private_adc_nids[spec->num_adc_nids] = nid;
9365			err = snd_hda_get_connections(codec, nid, &cap, 1);
9366			if (err < 0)
9367				continue;
9368			spec->private_capsrc_nids[spec->num_adc_nids] = cap;
9369			spec->num_adc_nids++;
9370		}
9371		spec->adc_nids = spec->private_adc_nids;
9372		spec->capsrc_nids = spec->private_capsrc_nids;
9373	}
9374
9375	set_capture_mixer(spec);
9376	set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9377
9378	spec->vmaster_nid = 0x0c;
9379
9380	codec->patch_ops = alc_patch_ops;
9381	if (board_config == ALC882_AUTO)
9382		spec->init_hook = alc882_auto_init;
9383#ifdef CONFIG_SND_HDA_POWER_SAVE
9384	if (!spec->loopback.amplist)
9385		spec->loopback.amplist = alc882_loopbacks;
9386#endif
9387	codec->proc_widget_hook = print_realtek_coef;
9388
9389	return 0;
9390}
9391
9392
9393/*
9394 * ALC262 support
9395 */
9396
9397#define ALC262_DIGOUT_NID	ALC880_DIGOUT_NID
9398#define ALC262_DIGIN_NID	ALC880_DIGIN_NID
9399
9400#define alc262_dac_nids		alc260_dac_nids
9401#define alc262_adc_nids		alc882_adc_nids
9402#define alc262_adc_nids_alt	alc882_adc_nids_alt
9403#define alc262_capsrc_nids	alc882_capsrc_nids
9404#define alc262_capsrc_nids_alt	alc882_capsrc_nids_alt
9405
9406#define alc262_modes		alc260_modes
9407#define alc262_capture_source	alc882_capture_source
9408
9409static hda_nid_t alc262_dmic_adc_nids[1] = {
9410	/* ADC0 */
9411	0x09
9412};
9413
9414static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
9415
9416static struct snd_kcontrol_new alc262_base_mixer[] = {
9417	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9418	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9419	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9420	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9421	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9422	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9423	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9424	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9425	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9426	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9427	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9428	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9429	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
9430	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9431	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9432	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9433	{ } /* end */
9434};
9435
9436/* update HP, line and mono-out pins according to the master switch */
9437static void alc262_hp_master_update(struct hda_codec *codec)
9438{
9439	struct alc_spec *spec = codec->spec;
9440	int val = spec->master_sw;
9441
9442	/* HP & line-out */
9443	snd_hda_codec_write_cache(codec, 0x1b, 0,
9444				  AC_VERB_SET_PIN_WIDGET_CONTROL,
9445				  val ? PIN_HP : 0);
9446	snd_hda_codec_write_cache(codec, 0x15, 0,
9447				  AC_VERB_SET_PIN_WIDGET_CONTROL,
9448				  val ? PIN_HP : 0);
9449	/* mono (speaker) depending on the HP jack sense */
9450	val = val && !spec->jack_present;
9451	snd_hda_codec_write_cache(codec, 0x16, 0,
9452				  AC_VERB_SET_PIN_WIDGET_CONTROL,
9453				  val ? PIN_OUT : 0);
9454}
9455
9456static void alc262_hp_bpc_automute(struct hda_codec *codec)
9457{
9458	struct alc_spec *spec = codec->spec;
9459	unsigned int presence;
9460	presence = snd_hda_codec_read(codec, 0x1b, 0,
9461				      AC_VERB_GET_PIN_SENSE, 0);
9462	spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9463	alc262_hp_master_update(codec);
9464}
9465
9466static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
9467{
9468	if ((res >> 26) != ALC880_HP_EVENT)
9469		return;
9470	alc262_hp_bpc_automute(codec);
9471}
9472
9473static void alc262_hp_wildwest_automute(struct hda_codec *codec)
9474{
9475	struct alc_spec *spec = codec->spec;
9476	unsigned int presence;
9477	presence = snd_hda_codec_read(codec, 0x15, 0,
9478				      AC_VERB_GET_PIN_SENSE, 0);
9479	spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9480	alc262_hp_master_update(codec);
9481}
9482
9483static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
9484					   unsigned int res)
9485{
9486	if ((res >> 26) != ALC880_HP_EVENT)
9487		return;
9488	alc262_hp_wildwest_automute(codec);
9489}
9490
9491#define alc262_hp_master_sw_get		alc260_hp_master_sw_get
9492
9493static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9494				   struct snd_ctl_elem_value *ucontrol)
9495{
9496	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9497	struct alc_spec *spec = codec->spec;
9498	int val = !!*ucontrol->value.integer.value;
9499
9500	if (val == spec->master_sw)
9501		return 0;
9502	spec->master_sw = val;
9503	alc262_hp_master_update(codec);
9504	return 1;
9505}
9506
9507#define ALC262_HP_MASTER_SWITCH					\
9508	{							\
9509		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,		\
9510		.name = "Master Playback Switch",		\
9511		.info = snd_ctl_boolean_mono_info,		\
9512		.get = alc262_hp_master_sw_get,			\
9513		.put = alc262_hp_master_sw_put,			\
9514	}
9515
9516static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
9517	ALC262_HP_MASTER_SWITCH,
9518	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9519	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9520	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9521	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9522			      HDA_OUTPUT),
9523	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9524			    HDA_OUTPUT),
9525	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9526	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9527	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9528	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9529	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9530	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9531	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9532	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9533	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9534	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9535	HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9536	HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9537	{ } /* end */
9538};
9539
9540static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
9541	ALC262_HP_MASTER_SWITCH,
9542	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9543	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9544	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9545	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9546	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9547			      HDA_OUTPUT),
9548	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9549			    HDA_OUTPUT),
9550	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9551	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
9552	HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
9553	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9554	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9555	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9556	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9557	{ } /* end */
9558};
9559
9560static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9561	HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9562	HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9563	HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
9564	{ } /* end */
9565};
9566
9567/* mute/unmute internal speaker according to the hp jack and mute state */
9568static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9569{
9570	struct alc_spec *spec = codec->spec;
9571
9572	spec->autocfg.hp_pins[0] = 0x15;
9573	spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */
9574	alc_automute_amp(codec);
9575}
9576
9577static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
9578	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9579	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9580	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9581	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9582	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9583	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9584	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9585	{ } /* end */
9586};
9587
9588static struct hda_verb alc262_hp_t5735_verbs[] = {
9589	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9590	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9591
9592	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9593	{ }
9594};
9595
9596static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
9597	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9598	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9599	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9600	HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
9601	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9602	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9603	{ } /* end */
9604};
9605
9606static struct hda_verb alc262_hp_rp5700_verbs[] = {
9607	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9608	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9609	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9610	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9611	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9612	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9613	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9614	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9615	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9616	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9617	{}
9618};
9619
9620static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9621	.num_items = 1,
9622	.items = {
9623		{ "Line", 0x1 },
9624	},
9625};
9626
9627/* bind hp and internal speaker mute (with plug check) as master switch */
9628static void alc262_hippo_master_update(struct hda_codec *codec)
9629{
9630	struct alc_spec *spec = codec->spec;
9631	hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9632	hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
9633	hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
9634	unsigned int mute;
9635
9636	/* HP */
9637	mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
9638	snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
9639				 HDA_AMP_MUTE, mute);
9640	/* mute internal speaker per jack sense */
9641	if (spec->jack_present)
9642		mute = HDA_AMP_MUTE;
9643	if (line_nid)
9644		snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
9645					 HDA_AMP_MUTE, mute);
9646	if (speaker_nid && speaker_nid != line_nid)
9647		snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
9648					 HDA_AMP_MUTE, mute);
9649}
9650
9651#define alc262_hippo_master_sw_get	alc262_hp_master_sw_get
9652
9653static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
9654				      struct snd_ctl_elem_value *ucontrol)
9655{
9656	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9657	struct alc_spec *spec = codec->spec;
9658	int val = !!*ucontrol->value.integer.value;
9659
9660	if (val == spec->master_sw)
9661		return 0;
9662	spec->master_sw = val;
9663	alc262_hippo_master_update(codec);
9664	return 1;
9665}
9666
9667#define ALC262_HIPPO_MASTER_SWITCH				\
9668	{							\
9669		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,		\
9670		.name = "Master Playback Switch",		\
9671		.info = snd_ctl_boolean_mono_info,		\
9672		.get = alc262_hippo_master_sw_get,		\
9673		.put = alc262_hippo_master_sw_put,		\
9674	}
9675
9676static struct snd_kcontrol_new alc262_hippo_mixer[] = {
9677	ALC262_HIPPO_MASTER_SWITCH,
9678	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9679	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9680	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9681	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9682	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9683	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9684	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9685	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9686	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9687	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9688	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9689	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9690	{ } /* end */
9691};
9692
9693static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
9694	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9695	ALC262_HIPPO_MASTER_SWITCH,
9696	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9697	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9698	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9699	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9700	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9701	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9702	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9703	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9704	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9705	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9706	{ } /* end */
9707};
9708
9709/* mute/unmute internal speaker according to the hp jack and mute state */
9710static void alc262_hippo_automute(struct hda_codec *codec)
9711{
9712	struct alc_spec *spec = codec->spec;
9713	hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9714	unsigned int present;
9715
9716	/* need to execute and sync at first */
9717	snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
9718	present = snd_hda_codec_read(codec, hp_nid, 0,
9719				     AC_VERB_GET_PIN_SENSE, 0);
9720	spec->jack_present = (present & 0x80000000) != 0;
9721	alc262_hippo_master_update(codec);
9722}
9723
9724static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
9725{
9726	if ((res >> 26) != ALC880_HP_EVENT)
9727		return;
9728	alc262_hippo_automute(codec);
9729}
9730
9731static void alc262_hippo_init_hook(struct hda_codec *codec)
9732{
9733	struct alc_spec *spec = codec->spec;
9734
9735	spec->autocfg.hp_pins[0] = 0x15;
9736	spec->autocfg.speaker_pins[0] = 0x14;
9737	alc262_hippo_automute(codec);
9738}
9739
9740static void alc262_hippo1_init_hook(struct hda_codec *codec)
9741{
9742	struct alc_spec *spec = codec->spec;
9743
9744	spec->autocfg.hp_pins[0] = 0x1b;
9745	spec->autocfg.speaker_pins[0] = 0x14;
9746	alc262_hippo_automute(codec);
9747}
9748
9749
9750static struct snd_kcontrol_new alc262_sony_mixer[] = {
9751	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9752	ALC262_HIPPO_MASTER_SWITCH,
9753	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9754	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9755	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9756	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9757	{ } /* end */
9758};
9759
9760static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9761	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9762	ALC262_HIPPO_MASTER_SWITCH,
9763	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9764	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9765	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9766	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9767	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9768	{ } /* end */
9769};
9770
9771static struct snd_kcontrol_new alc262_tyan_mixer[] = {
9772	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9773	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9774	HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
9775	HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
9776	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9777	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9778	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9779	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9780	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9781	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9782	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9783	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9784	{ } /* end */
9785};
9786
9787static struct hda_verb alc262_tyan_verbs[] = {
9788	/* Headphone automute */
9789	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9790	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9791	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9792
9793	/* P11 AUX_IN, white 4-pin connector */
9794	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9795	{0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
9796	{0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
9797	{0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
9798
9799	{}
9800};
9801
9802/* unsolicited event for HP jack sensing */
9803static void alc262_tyan_init_hook(struct hda_codec *codec)
9804{
9805	struct alc_spec *spec = codec->spec;
9806
9807	spec->autocfg.hp_pins[0] = 0x1b;
9808	spec->autocfg.speaker_pins[0] = 0x15;
9809	alc_automute_amp(codec);
9810}
9811
9812
9813#define alc262_capture_mixer		alc882_capture_mixer
9814#define alc262_capture_alt_mixer	alc882_capture_alt_mixer
9815
9816/*
9817 * generic initialization of ADC, input mixers and output mixers
9818 */
9819static struct hda_verb alc262_init_verbs[] = {
9820	/*
9821	 * Unmute ADC0-2 and set the default input to mic-in
9822	 */
9823	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9824	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9825	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9826	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9827	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9828	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9829
9830	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9831	 * mixer widget
9832	 * Note: PASD motherboards uses the Line In 2 as the input for
9833	 * front panel mic (mic 2)
9834	 */
9835	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9836	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9837	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9838	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9839	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9840	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9841
9842	/*
9843	 * Set up output mixers (0x0c - 0x0e)
9844	 */
9845	/* set vol=0 to output mixers */
9846	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9847	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9848	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9849	/* set up input amps for analog loopback */
9850	/* Amp Indices: DAC = 0, mixer = 1 */
9851	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9852	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9853	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9854	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9855	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9856	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9857
9858	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9859	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9860	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9861	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9862	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9863	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9864
9865	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9866	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9867	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9868	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9869	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9870
9871	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9872	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9873
9874	/* FIXME: use matrix-type input source selection */
9875	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9876	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9877	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9878	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9879	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9880	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9881	/* Input mixer2 */
9882	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9883	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9884	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9885	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9886	/* Input mixer3 */
9887	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9888	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9889	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9890	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9891
9892	{ }
9893};
9894
9895static struct hda_verb alc262_eapd_verbs[] = {
9896	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9897	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9898	{ }
9899};
9900
9901static struct hda_verb alc262_hippo_unsol_verbs[] = {
9902	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9903	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9904	{}
9905};
9906
9907static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9908	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9909	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9910	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9911
9912	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9913	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9914	{}
9915};
9916
9917static struct hda_verb alc262_sony_unsol_verbs[] = {
9918	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9919	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9920	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},	// Front Mic
9921
9922	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9923	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9924	{}
9925};
9926
9927static struct hda_input_mux alc262_dmic_capture_source = {
9928	.num_items = 2,
9929	.items = {
9930		{ "Int DMic", 0x9 },
9931		{ "Mic", 0x0 },
9932	},
9933};
9934
9935static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9936	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9937	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9938	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9939	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9940	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9941	{ } /* end */
9942};
9943
9944static struct hda_verb alc262_toshiba_s06_verbs[] = {
9945	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9946	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9947	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9948	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9949	{0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9950	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9951	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9952	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9953	{}
9954};
9955
9956static void alc262_dmic_automute(struct hda_codec *codec)
9957{
9958	unsigned int present;
9959
9960	present = snd_hda_codec_read(codec, 0x18, 0,
9961					AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9962	snd_hda_codec_write(codec, 0x22, 0,
9963				AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9964}
9965
9966
9967/* unsolicited event for HP jack sensing */
9968static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9969				       unsigned int res)
9970{
9971	if ((res >> 26) == ALC880_MIC_EVENT)
9972		alc262_dmic_automute(codec);
9973	else
9974		alc_sku_unsol_event(codec, res);
9975}
9976
9977static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9978{
9979	struct alc_spec *spec = codec->spec;
9980
9981	spec->autocfg.hp_pins[0] = 0x15;
9982	spec->autocfg.speaker_pins[0] = 0x14;
9983	alc_automute_pin(codec);
9984	alc262_dmic_automute(codec);
9985}
9986
9987/*
9988 * nec model
9989 *  0x15 = headphone
9990 *  0x16 = internal speaker
9991 *  0x18 = external mic
9992 */
9993
9994static struct snd_kcontrol_new alc262_nec_mixer[] = {
9995	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9996	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
9997
9998	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9999	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10000	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10001
10002	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10003	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10004	{ } /* end */
10005};
10006
10007static struct hda_verb alc262_nec_verbs[] = {
10008	/* Unmute Speaker */
10009	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10010
10011	/* Headphone */
10012	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10013	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10014
10015	/* External mic to headphone */
10016	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10017	/* External mic to speaker */
10018	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10019	{}
10020};
10021
10022/*
10023 * fujitsu model
10024 *  0x14 = headphone/spdif-out, 0x15 = internal speaker,
10025 *  0x1b = port replicator headphone out
10026 */
10027
10028#define ALC_HP_EVENT	0x37
10029
10030static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
10031	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10032	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10033	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10034	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10035	{}
10036};
10037
10038static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
10039	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10040	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10041	{}
10042};
10043
10044static struct hda_input_mux alc262_fujitsu_capture_source = {
10045	.num_items = 3,
10046	.items = {
10047		{ "Mic", 0x0 },
10048		{ "Int Mic", 0x1 },
10049		{ "CD", 0x4 },
10050	},
10051};
10052
10053static struct hda_input_mux alc262_HP_capture_source = {
10054	.num_items = 5,
10055	.items = {
10056		{ "Mic", 0x0 },
10057		{ "Front Mic", 0x1 },
10058		{ "Line", 0x2 },
10059		{ "CD", 0x4 },
10060		{ "AUX IN", 0x6 },
10061	},
10062};
10063
10064static struct hda_input_mux alc262_HP_D7000_capture_source = {
10065	.num_items = 4,
10066	.items = {
10067		{ "Mic", 0x0 },
10068		{ "Front Mic", 0x2 },
10069		{ "Line", 0x1 },
10070		{ "CD", 0x4 },
10071	},
10072};
10073
10074/* mute/unmute internal speaker according to the hp jacks and mute state */
10075static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
10076{
10077	struct alc_spec *spec = codec->spec;
10078	unsigned int mute;
10079
10080	if (force || !spec->sense_updated) {
10081		unsigned int present;
10082		/* need to execute and sync at first */
10083		snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
10084		/* check laptop HP jack */
10085		present = snd_hda_codec_read(codec, 0x14, 0,
10086					     AC_VERB_GET_PIN_SENSE, 0);
10087		/* need to execute and sync at first */
10088		snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10089		/* check docking HP jack */
10090		present |= snd_hda_codec_read(codec, 0x1b, 0,
10091					      AC_VERB_GET_PIN_SENSE, 0);
10092		if (present & AC_PINSENSE_PRESENCE)
10093			spec->jack_present = 1;
10094		else
10095			spec->jack_present = 0;
10096		spec->sense_updated = 1;
10097	}
10098	/* unmute internal speaker only if both HPs are unplugged and
10099	 * master switch is on
10100	 */
10101	if (spec->jack_present)
10102		mute = HDA_AMP_MUTE;
10103	else
10104		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10105	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10106				 HDA_AMP_MUTE, mute);
10107}
10108
10109/* unsolicited event for HP jack sensing */
10110static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
10111				       unsigned int res)
10112{
10113	if ((res >> 26) != ALC_HP_EVENT)
10114		return;
10115	alc262_fujitsu_automute(codec, 1);
10116}
10117
10118static void alc262_fujitsu_init_hook(struct hda_codec *codec)
10119{
10120	alc262_fujitsu_automute(codec, 1);
10121}
10122
10123/* bind volumes of both NID 0x0c and 0x0d */
10124static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
10125	.ops = &snd_hda_bind_vol,
10126	.values = {
10127		HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
10128		HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
10129		0
10130	},
10131};
10132
10133/* mute/unmute internal speaker according to the hp jack and mute state */
10134static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
10135{
10136	struct alc_spec *spec = codec->spec;
10137	unsigned int mute;
10138
10139	if (force || !spec->sense_updated) {
10140		unsigned int present_int_hp;
10141		/* need to execute and sync at first */
10142		snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10143		present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
10144					AC_VERB_GET_PIN_SENSE, 0);
10145		spec->jack_present = (present_int_hp & 0x80000000) != 0;
10146		spec->sense_updated = 1;
10147	}
10148	if (spec->jack_present) {
10149		/* mute internal speaker */
10150		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10151					 HDA_AMP_MUTE, HDA_AMP_MUTE);
10152		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10153					 HDA_AMP_MUTE, HDA_AMP_MUTE);
10154	} else {
10155		/* unmute internal speaker if necessary */
10156		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10157		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10158					 HDA_AMP_MUTE, mute);
10159		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10160					 HDA_AMP_MUTE, mute);
10161	}
10162}
10163
10164/* unsolicited event for HP jack sensing */
10165static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
10166				       unsigned int res)
10167{
10168	if ((res >> 26) != ALC_HP_EVENT)
10169		return;
10170	alc262_lenovo_3000_automute(codec, 1);
10171}
10172
10173/* bind hp and internal speaker mute (with plug check) */
10174static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
10175					 struct snd_ctl_elem_value *ucontrol)
10176{
10177	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10178	long *valp = ucontrol->value.integer.value;
10179	int change;
10180
10181	change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10182						 HDA_AMP_MUTE,
10183						 valp ? 0 : HDA_AMP_MUTE);
10184	change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10185						 HDA_AMP_MUTE,
10186						 valp ? 0 : HDA_AMP_MUTE);
10187
10188	if (change)
10189		alc262_fujitsu_automute(codec, 0);
10190	return change;
10191}
10192
10193static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
10194	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10195	{
10196		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10197		.name = "Master Playback Switch",
10198		.info = snd_hda_mixer_amp_switch_info,
10199		.get = snd_hda_mixer_amp_switch_get,
10200		.put = alc262_fujitsu_master_sw_put,
10201		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10202	},
10203	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10204	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10205	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10206	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10207	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10208	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10209	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10210	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10211	{ } /* end */
10212};
10213
10214/* bind hp and internal speaker mute (with plug check) */
10215static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
10216					 struct snd_ctl_elem_value *ucontrol)
10217{
10218	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10219	long *valp = ucontrol->value.integer.value;
10220	int change;
10221
10222	change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10223						 HDA_AMP_MUTE,
10224						 valp ? 0 : HDA_AMP_MUTE);
10225
10226	if (change)
10227		alc262_lenovo_3000_automute(codec, 0);
10228	return change;
10229}
10230
10231static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10232	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10233	{
10234		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10235		.name = "Master Playback Switch",
10236		.info = snd_hda_mixer_amp_switch_info,
10237		.get = snd_hda_mixer_amp_switch_get,
10238		.put = alc262_lenovo_3000_master_sw_put,
10239		.private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
10240	},
10241	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10242	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10243	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10244	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10245	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10246	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10247	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10248	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10249	{ } /* end */
10250};
10251
10252static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
10253	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10254	ALC262_HIPPO_MASTER_SWITCH,
10255	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10256	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10257	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10258	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10259	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10260	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10261	{ } /* end */
10262};
10263
10264/* additional init verbs for Benq laptops */
10265static struct hda_verb alc262_EAPD_verbs[] = {
10266	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10267	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
10268	{}
10269};
10270
10271static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
10272	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10273	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10274
10275	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10276	{0x20, AC_VERB_SET_PROC_COEF,  0x3050},
10277	{}
10278};
10279
10280/* Samsung Q1 Ultra Vista model setup */
10281static struct snd_kcontrol_new alc262_ultra_mixer[] = {
10282	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10283	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10284	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10285	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10286	HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
10287	HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
10288	{ } /* end */
10289};
10290
10291static struct hda_verb alc262_ultra_verbs[] = {
10292	/* output mixer */
10293	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10294	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10295	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10296	/* speaker */
10297	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10298	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10299	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10300	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10301	/* HP */
10302	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10303	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10304	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10305	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10306	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10307	/* internal mic */
10308	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10309	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10310	/* ADC, choose mic */
10311	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10312	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10313	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10314	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10315	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10316	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10317	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10318	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10319	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10320	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
10321	{}
10322};
10323
10324/* mute/unmute internal speaker according to the hp jack and mute state */
10325static void alc262_ultra_automute(struct hda_codec *codec)
10326{
10327	struct alc_spec *spec = codec->spec;
10328	unsigned int mute;
10329
10330	mute = 0;
10331	/* auto-mute only when HP is used as HP */
10332	if (!spec->cur_mux[0]) {
10333		unsigned int present;
10334		/* need to execute and sync at first */
10335		snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
10336		present = snd_hda_codec_read(codec, 0x15, 0,
10337					     AC_VERB_GET_PIN_SENSE, 0);
10338		spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
10339		if (spec->jack_present)
10340			mute = HDA_AMP_MUTE;
10341	}
10342	/* mute/unmute internal speaker */
10343	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10344				 HDA_AMP_MUTE, mute);
10345	/* mute/unmute HP */
10346	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10347				 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
10348}
10349
10350/* unsolicited event for HP jack sensing */
10351static void alc262_ultra_unsol_event(struct hda_codec *codec,
10352				       unsigned int res)
10353{
10354	if ((res >> 26) != ALC880_HP_EVENT)
10355		return;
10356	alc262_ultra_automute(codec);
10357}
10358
10359static struct hda_input_mux alc262_ultra_capture_source = {
10360	.num_items = 2,
10361	.items = {
10362		{ "Mic", 0x1 },
10363		{ "Headphone", 0x7 },
10364	},
10365};
10366
10367static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
10368				     struct snd_ctl_elem_value *ucontrol)
10369{
10370	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10371	struct alc_spec *spec = codec->spec;
10372	int ret;
10373
10374	ret = alc_mux_enum_put(kcontrol, ucontrol);
10375	if (!ret)
10376		return 0;
10377	/* reprogram the HP pin as mic or HP according to the input source */
10378	snd_hda_codec_write_cache(codec, 0x15, 0,
10379				  AC_VERB_SET_PIN_WIDGET_CONTROL,
10380				  spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
10381	alc262_ultra_automute(codec); /* mute/unmute HP */
10382	return ret;
10383}
10384
10385static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
10386	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10387	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10388	{
10389		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10390		.name = "Capture Source",
10391		.info = alc_mux_enum_info,
10392		.get = alc_mux_enum_get,
10393		.put = alc262_ultra_mux_enum_put,
10394	},
10395	{ } /* end */
10396};
10397
10398/* add playback controls from the parsed DAC table */
10399static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
10400					     const struct auto_pin_cfg *cfg)
10401{
10402	hda_nid_t nid;
10403	int err;
10404
10405	spec->multiout.num_dacs = 1;	/* only use one dac */
10406	spec->multiout.dac_nids = spec->private_dac_nids;
10407	spec->multiout.dac_nids[0] = 2;
10408
10409	nid = cfg->line_out_pins[0];
10410	if (nid) {
10411		err = add_control(spec, ALC_CTL_WIDGET_VOL,
10412				  "Front Playback Volume",
10413				  HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
10414		if (err < 0)
10415			return err;
10416		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10417				  "Front Playback Switch",
10418				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10419		if (err < 0)
10420			return err;
10421	}
10422
10423	nid = cfg->speaker_pins[0];
10424	if (nid) {
10425		if (nid == 0x16) {
10426			err = add_control(spec, ALC_CTL_WIDGET_VOL,
10427					  "Speaker Playback Volume",
10428					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10429							      HDA_OUTPUT));
10430			if (err < 0)
10431				return err;
10432			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10433					  "Speaker Playback Switch",
10434					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10435							      HDA_OUTPUT));
10436			if (err < 0)
10437				return err;
10438		} else {
10439			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10440					  "Speaker Playback Switch",
10441					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10442							      HDA_OUTPUT));
10443			if (err < 0)
10444				return err;
10445		}
10446	}
10447	nid = cfg->hp_pins[0];
10448	if (nid) {
10449		/* spec->multiout.hp_nid = 2; */
10450		if (nid == 0x16) {
10451			err = add_control(spec, ALC_CTL_WIDGET_VOL,
10452					  "Headphone Playback Volume",
10453					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10454							      HDA_OUTPUT));
10455			if (err < 0)
10456				return err;
10457			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10458					  "Headphone Playback Switch",
10459					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10460							      HDA_OUTPUT));
10461			if (err < 0)
10462				return err;
10463		} else {
10464			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10465					  "Headphone Playback Switch",
10466					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10467							      HDA_OUTPUT));
10468			if (err < 0)
10469				return err;
10470		}
10471	}
10472	return 0;
10473}
10474
10475static int alc262_auto_create_analog_input_ctls(struct alc_spec *spec,
10476						const struct auto_pin_cfg *cfg)
10477{
10478	int err;
10479
10480	err = alc880_auto_create_analog_input_ctls(spec, cfg);
10481	if (err < 0)
10482		return err;
10483	/* digital-mic input pin is excluded in alc880_auto_create..()
10484	 * because it's under 0x18
10485	 */
10486	if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
10487	    cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
10488		struct hda_input_mux *imux = &spec->private_imux[0];
10489		imux->items[imux->num_items].label = "Int Mic";
10490		imux->items[imux->num_items].index = 0x09;
10491		imux->num_items++;
10492	}
10493	return 0;
10494}
10495
10496
10497/*
10498 * generic initialization of ADC, input mixers and output mixers
10499 */
10500static struct hda_verb alc262_volume_init_verbs[] = {
10501	/*
10502	 * Unmute ADC0-2 and set the default input to mic-in
10503	 */
10504	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10505	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10506	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10507	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10508	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10509	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10510
10511	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10512	 * mixer widget
10513	 * Note: PASD motherboards uses the Line In 2 as the input for
10514	 * front panel mic (mic 2)
10515	 */
10516	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10517	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10518	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10519	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10520	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10521	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10522
10523	/*
10524	 * Set up output mixers (0x0c - 0x0f)
10525	 */
10526	/* set vol=0 to output mixers */
10527	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10528	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10529	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10530
10531	/* set up input amps for analog loopback */
10532	/* Amp Indices: DAC = 0, mixer = 1 */
10533	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10534	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10535	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10536	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10537	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10538	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10539
10540	/* FIXME: use matrix-type input source selection */
10541	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10542	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10543	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10544	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10545	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10546	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10547	/* Input mixer2 */
10548	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10549	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10550	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10551	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10552	/* Input mixer3 */
10553	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10554	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10555	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10556	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10557
10558	{ }
10559};
10560
10561static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10562	/*
10563	 * Unmute ADC0-2 and set the default input to mic-in
10564	 */
10565	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10566	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10567	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10568	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10569	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10570	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10571
10572	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10573	 * mixer widget
10574	 * Note: PASD motherboards uses the Line In 2 as the input for
10575	 * front panel mic (mic 2)
10576	 */
10577	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10578	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10579	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10580	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10581	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10582	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10583	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10584        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10585
10586	/*
10587	 * Set up output mixers (0x0c - 0x0e)
10588	 */
10589	/* set vol=0 to output mixers */
10590	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10591	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10592	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10593
10594	/* set up input amps for analog loopback */
10595	/* Amp Indices: DAC = 0, mixer = 1 */
10596	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10597	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10598	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10599	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10600	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10601	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10602
10603	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10604	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10605	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10606
10607	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10608	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10609
10610	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10611	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10612
10613	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10614	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10615        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10616	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10617	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10618
10619	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10620	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10621        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10622	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10623	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10624	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10625
10626
10627	/* FIXME: use matrix-type input source selection */
10628	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
10629	/* Input mixer1: only unmute Mic */
10630	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10631	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
10632	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10633	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10634	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10635	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
10636	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
10637	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
10638	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
10639	/* Input mixer2 */
10640	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10641	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
10642	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10643	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10644	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10645	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
10646	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
10647	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
10648	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
10649	/* Input mixer3 */
10650	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10651	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
10652	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10653	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10654	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10655	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
10656	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
10657	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
10658	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
10659
10660	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10661
10662	{ }
10663};
10664
10665static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10666	/*
10667	 * Unmute ADC0-2 and set the default input to mic-in
10668	 */
10669	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10670	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10671	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10672	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10673	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10674	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10675
10676	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10677	 * mixer widget
10678	 * Note: PASD motherboards uses the Line In 2 as the input for front
10679	 * panel mic (mic 2)
10680	 */
10681	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10682	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10683	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10684	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10685	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10686	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10687	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10688	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10689	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10690	/*
10691	 * Set up output mixers (0x0c - 0x0e)
10692	 */
10693	/* set vol=0 to output mixers */
10694	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10695	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10696	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10697
10698	/* set up input amps for analog loopback */
10699	/* Amp Indices: DAC = 0, mixer = 1 */
10700	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10701	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10702	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10703	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10704	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10705	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10706
10707
10708	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },	/* HP */
10709	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Mono */
10710	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* rear MIC */
10711	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* Line in */
10712	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* Front MIC */
10713	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Line out */
10714	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* CD in */
10715
10716	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10717	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10718
10719	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10720	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10721
10722	/* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10723	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10724	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10725	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10726	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10727	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10728
10729	/* FIXME: use matrix-type input source selection */
10730	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10731	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10732	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10733	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10734	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10735	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10736	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10737        /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
10738	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10739	/* Input mixer2 */
10740	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10741	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10742	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10743	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10744	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10745        /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10746	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10747	/* Input mixer3 */
10748	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10749	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10750	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10751	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10752	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10753        /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10754	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10755
10756	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10757
10758	{ }
10759};
10760
10761static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10762
10763	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Front Speaker */
10764	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10765	{0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10766
10767	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* MIC jack */
10768	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* Front MIC */
10769	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10770	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10771
10772	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },	/* HP  jack */
10773	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10774	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10775	{}
10776};
10777
10778
10779#ifdef CONFIG_SND_HDA_POWER_SAVE
10780#define alc262_loopbacks	alc880_loopbacks
10781#endif
10782
10783/* pcm configuration: identical with ALC880 */
10784#define alc262_pcm_analog_playback	alc880_pcm_analog_playback
10785#define alc262_pcm_analog_capture	alc880_pcm_analog_capture
10786#define alc262_pcm_digital_playback	alc880_pcm_digital_playback
10787#define alc262_pcm_digital_capture	alc880_pcm_digital_capture
10788
10789/*
10790 * BIOS auto configuration
10791 */
10792static int alc262_parse_auto_config(struct hda_codec *codec)
10793{
10794	struct alc_spec *spec = codec->spec;
10795	int err;
10796	static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10797
10798	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10799					   alc262_ignore);
10800	if (err < 0)
10801		return err;
10802	if (!spec->autocfg.line_outs) {
10803		if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
10804			spec->multiout.max_channels = 2;
10805			spec->no_analog = 1;
10806			goto dig_only;
10807		}
10808		return 0; /* can't find valid BIOS pin config */
10809	}
10810	err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10811	if (err < 0)
10812		return err;
10813	err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10814	if (err < 0)
10815		return err;
10816
10817	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10818
10819 dig_only:
10820	if (spec->autocfg.dig_outs) {
10821		spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10822		spec->dig_out_type = spec->autocfg.dig_out_type[0];
10823	}
10824	if (spec->autocfg.dig_in_pin)
10825		spec->dig_in_nid = ALC262_DIGIN_NID;
10826
10827	if (spec->kctls.list)
10828		add_mixer(spec, spec->kctls.list);
10829
10830	add_verb(spec, alc262_volume_init_verbs);
10831	spec->num_mux_defs = 1;
10832	spec->input_mux = &spec->private_imux[0];
10833
10834	err = alc_auto_add_mic_boost(codec);
10835	if (err < 0)
10836		return err;
10837
10838	alc_ssid_check(codec, 0x15, 0x14, 0x1b);
10839
10840	return 1;
10841}
10842
10843#define alc262_auto_init_multi_out	alc882_auto_init_multi_out
10844#define alc262_auto_init_hp_out		alc882_auto_init_hp_out
10845#define alc262_auto_init_analog_input	alc882_auto_init_analog_input
10846#define alc262_auto_init_input_src	alc882_auto_init_input_src
10847
10848
10849/* init callback for auto-configuration model -- overriding the default init */
10850static void alc262_auto_init(struct hda_codec *codec)
10851{
10852	struct alc_spec *spec = codec->spec;
10853	alc262_auto_init_multi_out(codec);
10854	alc262_auto_init_hp_out(codec);
10855	alc262_auto_init_analog_input(codec);
10856	alc262_auto_init_input_src(codec);
10857	if (spec->unsol_event)
10858		alc_inithook(codec);
10859}
10860
10861/*
10862 * configuration and preset
10863 */
10864static const char *alc262_models[ALC262_MODEL_LAST] = {
10865	[ALC262_BASIC]		= "basic",
10866	[ALC262_HIPPO]		= "hippo",
10867	[ALC262_HIPPO_1]	= "hippo_1",
10868	[ALC262_FUJITSU]	= "fujitsu",
10869	[ALC262_HP_BPC]		= "hp-bpc",
10870	[ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
10871	[ALC262_HP_TC_T5735]	= "hp-tc-t5735",
10872	[ALC262_HP_RP5700]	= "hp-rp5700",
10873	[ALC262_BENQ_ED8]	= "benq",
10874	[ALC262_BENQ_T31]	= "benq-t31",
10875	[ALC262_SONY_ASSAMD]	= "sony-assamd",
10876	[ALC262_TOSHIBA_S06]	= "toshiba-s06",
10877	[ALC262_TOSHIBA_RX1]	= "toshiba-rx1",
10878	[ALC262_ULTRA]		= "ultra",
10879	[ALC262_LENOVO_3000]	= "lenovo-3000",
10880	[ALC262_NEC]		= "nec",
10881	[ALC262_TYAN]		= "tyan",
10882	[ALC262_AUTO]		= "auto",
10883};
10884
10885static struct snd_pci_quirk alc262_cfg_tbl[] = {
10886	SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10887	SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
10888	SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
10889			   ALC262_HP_BPC),
10890	SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
10891			   ALC262_HP_BPC),
10892	SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
10893			   ALC262_HP_BPC),
10894	SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
10895	SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
10896	SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
10897	SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
10898	SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
10899	SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
10900	SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
10901	SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
10902	SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10903	SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10904	SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
10905	SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10906		      ALC262_HP_TC_T5735),
10907	SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
10908	SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10909	SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
10910	SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10911	SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
10912	SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
10913	SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
10914			   ALC262_SONY_ASSAMD),
10915	SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10916		      ALC262_TOSHIBA_RX1),
10917	SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
10918	SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
10919	SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
10920	SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
10921	SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
10922			   ALC262_ULTRA),
10923	SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
10924	SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
10925	SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10926	SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10927	SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
10928	{}
10929};
10930
10931static struct alc_config_preset alc262_presets[] = {
10932	[ALC262_BASIC] = {
10933		.mixers = { alc262_base_mixer },
10934		.init_verbs = { alc262_init_verbs },
10935		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10936		.dac_nids = alc262_dac_nids,
10937		.hp_nid = 0x03,
10938		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10939		.channel_mode = alc262_modes,
10940		.input_mux = &alc262_capture_source,
10941	},
10942	[ALC262_HIPPO] = {
10943		.mixers = { alc262_hippo_mixer },
10944		.init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10945		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10946		.dac_nids = alc262_dac_nids,
10947		.hp_nid = 0x03,
10948		.dig_out_nid = ALC262_DIGOUT_NID,
10949		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10950		.channel_mode = alc262_modes,
10951		.input_mux = &alc262_capture_source,
10952		.unsol_event = alc262_hippo_unsol_event,
10953		.init_hook = alc262_hippo_init_hook,
10954	},
10955	[ALC262_HIPPO_1] = {
10956		.mixers = { alc262_hippo1_mixer },
10957		.init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10958		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10959		.dac_nids = alc262_dac_nids,
10960		.hp_nid = 0x02,
10961		.dig_out_nid = ALC262_DIGOUT_NID,
10962		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10963		.channel_mode = alc262_modes,
10964		.input_mux = &alc262_capture_source,
10965		.unsol_event = alc262_hippo_unsol_event,
10966		.init_hook = alc262_hippo1_init_hook,
10967	},
10968	[ALC262_FUJITSU] = {
10969		.mixers = { alc262_fujitsu_mixer },
10970		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10971				alc262_fujitsu_unsol_verbs },
10972		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10973		.dac_nids = alc262_dac_nids,
10974		.hp_nid = 0x03,
10975		.dig_out_nid = ALC262_DIGOUT_NID,
10976		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10977		.channel_mode = alc262_modes,
10978		.input_mux = &alc262_fujitsu_capture_source,
10979		.unsol_event = alc262_fujitsu_unsol_event,
10980		.init_hook = alc262_fujitsu_init_hook,
10981	},
10982	[ALC262_HP_BPC] = {
10983		.mixers = { alc262_HP_BPC_mixer },
10984		.init_verbs = { alc262_HP_BPC_init_verbs },
10985		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10986		.dac_nids = alc262_dac_nids,
10987		.hp_nid = 0x03,
10988		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10989		.channel_mode = alc262_modes,
10990		.input_mux = &alc262_HP_capture_source,
10991		.unsol_event = alc262_hp_bpc_unsol_event,
10992		.init_hook = alc262_hp_bpc_automute,
10993	},
10994	[ALC262_HP_BPC_D7000_WF] = {
10995		.mixers = { alc262_HP_BPC_WildWest_mixer },
10996		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10997		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10998		.dac_nids = alc262_dac_nids,
10999		.hp_nid = 0x03,
11000		.num_channel_mode = ARRAY_SIZE(alc262_modes),
11001		.channel_mode = alc262_modes,
11002		.input_mux = &alc262_HP_D7000_capture_source,
11003		.unsol_event = alc262_hp_wildwest_unsol_event,
11004		.init_hook = alc262_hp_wildwest_automute,
11005	},
11006	[ALC262_HP_BPC_D7000_WL] = {
11007		.mixers = { alc262_HP_BPC_WildWest_mixer,
11008			    alc262_HP_BPC_WildWest_option_mixer },
11009		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11010		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
11011		.dac_nids = alc262_dac_nids,
11012		.hp_nid = 0x03,
11013		.num_channel_mode = ARRAY_SIZE(alc262_modes),
11014		.channel_mode = alc262_modes,
11015		.input_mux = &alc262_HP_D7000_capture_source,
11016		.unsol_event = alc262_hp_wildwest_unsol_event,
11017		.init_hook = alc262_hp_wildwest_automute,
11018	},
11019	[ALC262_HP_TC_T5735] = {
11020		.mixers = { alc262_hp_t5735_mixer },
11021		.init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
11022		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
11023		.dac_nids = alc262_dac_nids,
11024		.hp_nid = 0x03,
11025		.num_channel_mode = ARRAY_SIZE(alc262_modes),
11026		.channel_mode = alc262_modes,
11027		.input_mux = &alc262_capture_source,
11028		.unsol_event = alc_automute_amp_unsol_event,
11029		.init_hook = alc262_hp_t5735_init_hook,
11030	},
11031	[ALC262_HP_RP5700] = {
11032		.mixers = { alc262_hp_rp5700_mixer },
11033		.init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
11034		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
11035		.dac_nids = alc262_dac_nids,
11036		.num_channel_mode = ARRAY_SIZE(alc262_modes),
11037		.channel_mode = alc262_modes,
11038		.input_mux = &alc262_hp_rp5700_capture_source,
11039        },
11040	[ALC262_BENQ_ED8] = {
11041		.mixers = { alc262_base_mixer },
11042		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
11043		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
11044		.dac_nids = alc262_dac_nids,
11045		.hp_nid = 0x03,
11046		.num_channel_mode = ARRAY_SIZE(alc262_modes),
11047		.channel_mode = alc262_modes,
11048		.input_mux = &alc262_capture_source,
11049	},
11050	[ALC262_SONY_ASSAMD] = {
11051		.mixers = { alc262_sony_mixer },
11052		.init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
11053		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
11054		.dac_nids = alc262_dac_nids,
11055		.hp_nid = 0x02,
11056		.num_channel_mode = ARRAY_SIZE(alc262_modes),
11057		.channel_mode = alc262_modes,
11058		.input_mux = &alc262_capture_source,
11059		.unsol_event = alc262_hippo_unsol_event,
11060		.init_hook = alc262_hippo_init_hook,
11061	},
11062	[ALC262_BENQ_T31] = {
11063		.mixers = { alc262_benq_t31_mixer },
11064		.init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
11065		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
11066		.dac_nids = alc262_dac_nids,
11067		.hp_nid = 0x03,
11068		.num_channel_mode = ARRAY_SIZE(alc262_modes),
11069		.channel_mode = alc262_modes,
11070		.input_mux = &alc262_capture_source,
11071		.unsol_event = alc262_hippo_unsol_event,
11072		.init_hook = alc262_hippo_init_hook,
11073	},
11074	[ALC262_ULTRA] = {
11075		.mixers = { alc262_ultra_mixer },
11076		.cap_mixer = alc262_ultra_capture_mixer,
11077		.init_verbs = { alc262_ultra_verbs },
11078		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
11079		.dac_nids = alc262_dac_nids,
11080		.num_channel_mode = ARRAY_SIZE(alc262_modes),
11081		.channel_mode = alc262_modes,
11082		.input_mux = &alc262_ultra_capture_source,
11083		.adc_nids = alc262_adc_nids, /* ADC0 */
11084		.capsrc_nids = alc262_capsrc_nids,
11085		.num_adc_nids = 1, /* single ADC */
11086		.unsol_event = alc262_ultra_unsol_event,
11087		.init_hook = alc262_ultra_automute,
11088	},
11089	[ALC262_LENOVO_3000] = {
11090		.mixers = { alc262_lenovo_3000_mixer },
11091		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11092				alc262_lenovo_3000_unsol_verbs },
11093		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
11094		.dac_nids = alc262_dac_nids,
11095		.hp_nid = 0x03,
11096		.dig_out_nid = ALC262_DIGOUT_NID,
11097		.num_channel_mode = ARRAY_SIZE(alc262_modes),
11098		.channel_mode = alc262_modes,
11099		.input_mux = &alc262_fujitsu_capture_source,
11100		.unsol_event = alc262_lenovo_3000_unsol_event,
11101	},
11102	[ALC262_NEC] = {
11103		.mixers = { alc262_nec_mixer },
11104		.init_verbs = { alc262_nec_verbs },
11105		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
11106		.dac_nids = alc262_dac_nids,
11107		.hp_nid = 0x03,
11108		.num_channel_mode = ARRAY_SIZE(alc262_modes),
11109		.channel_mode = alc262_modes,
11110		.input_mux = &alc262_capture_source,
11111	},
11112	[ALC262_TOSHIBA_S06] = {
11113		.mixers = { alc262_toshiba_s06_mixer },
11114		.init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
11115							alc262_eapd_verbs },
11116		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
11117		.capsrc_nids = alc262_dmic_capsrc_nids,
11118		.dac_nids = alc262_dac_nids,
11119		.adc_nids = alc262_dmic_adc_nids, /* ADC0 */
11120		.num_adc_nids = 1, /* single ADC */
11121		.dig_out_nid = ALC262_DIGOUT_NID,
11122		.num_channel_mode = ARRAY_SIZE(alc262_modes),
11123		.channel_mode = alc262_modes,
11124		.input_mux = &alc262_dmic_capture_source,
11125		.unsol_event = alc262_toshiba_s06_unsol_event,
11126		.init_hook = alc262_toshiba_s06_init_hook,
11127	},
11128	[ALC262_TOSHIBA_RX1] = {
11129		.mixers = { alc262_toshiba_rx1_mixer },
11130		.init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
11131		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
11132		.dac_nids = alc262_dac_nids,
11133		.hp_nid = 0x03,
11134		.num_channel_mode = ARRAY_SIZE(alc262_modes),
11135		.channel_mode = alc262_modes,
11136		.input_mux = &alc262_capture_source,
11137		.unsol_event = alc262_hippo_unsol_event,
11138		.init_hook = alc262_hippo_init_hook,
11139	},
11140	[ALC262_TYAN] = {
11141		.mixers = { alc262_tyan_mixer },
11142		.init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
11143		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
11144		.dac_nids = alc262_dac_nids,
11145		.hp_nid = 0x02,
11146		.dig_out_nid = ALC262_DIGOUT_NID,
11147		.num_channel_mode = ARRAY_SIZE(alc262_modes),
11148		.channel_mode = alc262_modes,
11149		.input_mux = &alc262_capture_source,
11150		.unsol_event = alc_automute_amp_unsol_event,
11151		.init_hook = alc262_tyan_init_hook,
11152	},
11153};
11154
11155static int patch_alc262(struct hda_codec *codec)
11156{
11157	struct alc_spec *spec;
11158	int board_config;
11159	int err;
11160
11161	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11162	if (spec == NULL)
11163		return -ENOMEM;
11164
11165	codec->spec = spec;
11166#if 0
11167	/* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
11168	 * under-run
11169	 */
11170	{
11171	int tmp;
11172	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11173	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
11174	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11175	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
11176	}
11177#endif
11178
11179	alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11180
11181	board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
11182						  alc262_models,
11183						  alc262_cfg_tbl);
11184
11185	if (board_config < 0) {
11186		printk(KERN_INFO "hda_codec: Unknown model for %s, "
11187		       "trying auto-probe from BIOS...\n", codec->chip_name);
11188		board_config = ALC262_AUTO;
11189	}
11190
11191	if (board_config == ALC262_AUTO) {
11192		/* automatic parse from the BIOS config */
11193		err = alc262_parse_auto_config(codec);
11194		if (err < 0) {
11195			alc_free(codec);
11196			return err;
11197		} else if (!err) {
11198			printk(KERN_INFO
11199			       "hda_codec: Cannot set up configuration "
11200			       "from BIOS.  Using base mode...\n");
11201			board_config = ALC262_BASIC;
11202		}
11203	}
11204
11205	if (!spec->no_analog) {
11206		err = snd_hda_attach_beep_device(codec, 0x1);
11207		if (err < 0) {
11208			alc_free(codec);
11209			return err;
11210		}
11211	}
11212
11213	if (board_config != ALC262_AUTO)
11214		setup_preset(spec, &alc262_presets[board_config]);
11215
11216	spec->stream_analog_playback = &alc262_pcm_analog_playback;
11217	spec->stream_analog_capture = &alc262_pcm_analog_capture;
11218
11219	spec->stream_digital_playback = &alc262_pcm_digital_playback;
11220	spec->stream_digital_capture = &alc262_pcm_digital_capture;
11221
11222	if (!spec->adc_nids && spec->input_mux) {
11223		int i;
11224		/* check whether the digital-mic has to be supported */
11225		for (i = 0; i < spec->input_mux->num_items; i++) {
11226			if (spec->input_mux->items[i].index >= 9)
11227				break;
11228		}
11229		if (i < spec->input_mux->num_items) {
11230			/* use only ADC0 */
11231			spec->adc_nids = alc262_dmic_adc_nids;
11232			spec->num_adc_nids = 1;
11233			spec->capsrc_nids = alc262_dmic_capsrc_nids;
11234		} else {
11235			/* all analog inputs */
11236			/* check whether NID 0x07 is valid */
11237			unsigned int wcap = get_wcaps(codec, 0x07);
11238
11239			/* get type */
11240			wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11241			if (wcap != AC_WID_AUD_IN) {
11242				spec->adc_nids = alc262_adc_nids_alt;
11243				spec->num_adc_nids =
11244					ARRAY_SIZE(alc262_adc_nids_alt);
11245				spec->capsrc_nids = alc262_capsrc_nids_alt;
11246			} else {
11247				spec->adc_nids = alc262_adc_nids;
11248				spec->num_adc_nids =
11249					ARRAY_SIZE(alc262_adc_nids);
11250				spec->capsrc_nids = alc262_capsrc_nids;
11251			}
11252		}
11253	}
11254	if (!spec->cap_mixer && !spec->no_analog)
11255		set_capture_mixer(spec);
11256	if (!spec->no_analog)
11257		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11258
11259	spec->vmaster_nid = 0x0c;
11260
11261	codec->patch_ops = alc_patch_ops;
11262	if (board_config == ALC262_AUTO)
11263		spec->init_hook = alc262_auto_init;
11264#ifdef CONFIG_SND_HDA_POWER_SAVE
11265	if (!spec->loopback.amplist)
11266		spec->loopback.amplist = alc262_loopbacks;
11267#endif
11268	codec->proc_widget_hook = print_realtek_coef;
11269
11270	return 0;
11271}
11272
11273/*
11274 *  ALC268 channel source setting (2 channel)
11275 */
11276#define ALC268_DIGOUT_NID	ALC880_DIGOUT_NID
11277#define alc268_modes		alc260_modes
11278
11279static hda_nid_t alc268_dac_nids[2] = {
11280	/* front, hp */
11281	0x02, 0x03
11282};
11283
11284static hda_nid_t alc268_adc_nids[2] = {
11285	/* ADC0-1 */
11286	0x08, 0x07
11287};
11288
11289static hda_nid_t alc268_adc_nids_alt[1] = {
11290	/* ADC0 */
11291	0x08
11292};
11293
11294static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
11295
11296static struct snd_kcontrol_new alc268_base_mixer[] = {
11297	/* output mixer control */
11298	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11299	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11300	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11301	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11302	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11303	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11304	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11305	{ }
11306};
11307
11308static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
11309	/* output mixer control */
11310	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11311	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11312	ALC262_HIPPO_MASTER_SWITCH,
11313	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11314	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11315	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11316	{ }
11317};
11318
11319/* bind Beep switches of both NID 0x0f and 0x10 */
11320static struct hda_bind_ctls alc268_bind_beep_sw = {
11321	.ops = &snd_hda_bind_sw,
11322	.values = {
11323		HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
11324		HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
11325		0
11326	},
11327};
11328
11329static struct snd_kcontrol_new alc268_beep_mixer[] = {
11330	HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
11331	HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
11332	{ }
11333};
11334
11335static struct hda_verb alc268_eapd_verbs[] = {
11336	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11337	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11338	{ }
11339};
11340
11341/* Toshiba specific */
11342static struct hda_verb alc268_toshiba_verbs[] = {
11343	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11344	{ } /* end */
11345};
11346
11347static struct hda_input_mux alc268_acer_lc_capture_source = {
11348	.num_items = 2,
11349	.items = {
11350		{ "i-Mic", 0x6 },
11351		{ "E-Mic", 0x0 },
11352	},
11353};
11354
11355/* Acer specific */
11356/* bind volumes of both NID 0x02 and 0x03 */
11357static struct hda_bind_ctls alc268_acer_bind_master_vol = {
11358	.ops = &snd_hda_bind_vol,
11359	.values = {
11360		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11361		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11362		0
11363	},
11364};
11365
11366/* mute/unmute internal speaker according to the hp jack and mute state */
11367static void alc268_acer_automute(struct hda_codec *codec, int force)
11368{
11369	struct alc_spec *spec = codec->spec;
11370	unsigned int mute;
11371
11372	if (force || !spec->sense_updated) {
11373		unsigned int present;
11374		present = snd_hda_codec_read(codec, 0x14, 0,
11375				    	 AC_VERB_GET_PIN_SENSE, 0);
11376		spec->jack_present = (present & 0x80000000) != 0;
11377		spec->sense_updated = 1;
11378	}
11379	if (spec->jack_present)
11380		mute = HDA_AMP_MUTE; /* mute internal speaker */
11381	else /* unmute internal speaker if necessary */
11382		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11383	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11384				 HDA_AMP_MUTE, mute);
11385}
11386
11387
11388/* bind hp and internal speaker mute (with plug check) */
11389static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
11390				     struct snd_ctl_elem_value *ucontrol)
11391{
11392	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11393	long *valp = ucontrol->value.integer.value;
11394	int change;
11395
11396	change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
11397					  HDA_AMP_MUTE,
11398					  valp[0] ? 0 : HDA_AMP_MUTE);
11399	change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
11400					   HDA_AMP_MUTE,
11401					   valp[1] ? 0 : HDA_AMP_MUTE);
11402	if (change)
11403		alc268_acer_automute(codec, 0);
11404	return change;
11405}
11406
11407static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
11408	/* output mixer control */
11409	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11410	{
11411		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11412		.name = "Master Playback Switch",
11413		.info = snd_hda_mixer_amp_switch_info,
11414		.get = snd_hda_mixer_amp_switch_get,
11415		.put = alc268_acer_master_sw_put,
11416		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11417	},
11418	HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
11419	{ }
11420};
11421
11422static struct snd_kcontrol_new alc268_acer_mixer[] = {
11423	/* output mixer control */
11424	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11425	{
11426		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11427		.name = "Master Playback Switch",
11428		.info = snd_hda_mixer_amp_switch_info,
11429		.get = snd_hda_mixer_amp_switch_get,
11430		.put = alc268_acer_master_sw_put,
11431		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11432	},
11433	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11434	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11435	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11436	{ }
11437};
11438
11439static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
11440	/* output mixer control */
11441	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11442	{
11443		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11444		.name = "Master Playback Switch",
11445		.info = snd_hda_mixer_amp_switch_info,
11446		.get = snd_hda_mixer_amp_switch_get,
11447		.put = alc268_acer_master_sw_put,
11448		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11449	},
11450	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11451	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11452	{ }
11453};
11454
11455static struct hda_verb alc268_acer_aspire_one_verbs[] = {
11456	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11457	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11458	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11459	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11460	{0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
11461	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
11462	{ }
11463};
11464
11465static struct hda_verb alc268_acer_verbs[] = {
11466	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
11467	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11468	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11469	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11470	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11471	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11472	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11473	{ }
11474};
11475
11476/* unsolicited event for HP jack sensing */
11477#define alc268_toshiba_unsol_event	alc262_hippo_unsol_event
11478#define alc268_toshiba_init_hook	alc262_hippo_init_hook
11479
11480static void alc268_acer_unsol_event(struct hda_codec *codec,
11481				       unsigned int res)
11482{
11483	if ((res >> 26) != ALC880_HP_EVENT)
11484		return;
11485	alc268_acer_automute(codec, 1);
11486}
11487
11488static void alc268_acer_init_hook(struct hda_codec *codec)
11489{
11490	alc268_acer_automute(codec, 1);
11491}
11492
11493/* toggle speaker-output according to the hp-jack state */
11494static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
11495{
11496	unsigned int present;
11497	unsigned char bits;
11498
11499	present = snd_hda_codec_read(codec, 0x15, 0,
11500				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11501	bits = present ? AMP_IN_MUTE(0) : 0;
11502	snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
11503				AMP_IN_MUTE(0), bits);
11504	snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
11505				AMP_IN_MUTE(0), bits);
11506}
11507
11508
11509static void alc268_acer_mic_automute(struct hda_codec *codec)
11510{
11511	unsigned int present;
11512
11513	present = snd_hda_codec_read(codec, 0x18, 0,
11514				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11515	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
11516			    present ? 0x0 : 0x6);
11517}
11518
11519static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
11520				    unsigned int res)
11521{
11522	if ((res >> 26) == ALC880_HP_EVENT)
11523		alc268_aspire_one_speaker_automute(codec);
11524	if ((res >> 26) == ALC880_MIC_EVENT)
11525		alc268_acer_mic_automute(codec);
11526}
11527
11528static void alc268_acer_lc_init_hook(struct hda_codec *codec)
11529{
11530	alc268_aspire_one_speaker_automute(codec);
11531	alc268_acer_mic_automute(codec);
11532}
11533
11534static struct snd_kcontrol_new alc268_dell_mixer[] = {
11535	/* output mixer control */
11536	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11537	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11538	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11539	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11540	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11541	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11542	{ }
11543};
11544
11545static struct hda_verb alc268_dell_verbs[] = {
11546	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11547	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11548	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11549	{ }
11550};
11551
11552/* mute/unmute internal speaker according to the hp jack and mute state */
11553static void alc268_dell_init_hook(struct hda_codec *codec)
11554{
11555	struct alc_spec *spec = codec->spec;
11556
11557	spec->autocfg.hp_pins[0] = 0x15;
11558	spec->autocfg.speaker_pins[0] = 0x14;
11559	alc_automute_pin(codec);
11560}
11561
11562static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
11563	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11564	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11565	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11566	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11567	HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11568	HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
11569	HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
11570	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11571	{ }
11572};
11573
11574static struct hda_verb alc267_quanta_il1_verbs[] = {
11575	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11576	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
11577	{ }
11578};
11579
11580static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11581{
11582	unsigned int present;
11583
11584	present = snd_hda_codec_read(codec, 0x18, 0,
11585				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11586	snd_hda_codec_write(codec, 0x23, 0,
11587			    AC_VERB_SET_CONNECT_SEL,
11588			    present ? 0x00 : 0x01);
11589}
11590
11591static void alc267_quanta_il1_init_hook(struct hda_codec *codec)
11592{
11593	struct alc_spec *spec = codec->spec;
11594
11595	spec->autocfg.hp_pins[0] = 0x15;
11596	spec->autocfg.speaker_pins[0] = 0x14;
11597	alc_automute_pin(codec);
11598	alc267_quanta_il1_mic_automute(codec);
11599}
11600
11601static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
11602					   unsigned int res)
11603{
11604	switch (res >> 26) {
11605	case ALC880_MIC_EVENT:
11606		alc267_quanta_il1_mic_automute(codec);
11607		break;
11608	default:
11609		alc_sku_unsol_event(codec, res);
11610		break;
11611	}
11612}
11613
11614/*
11615 * generic initialization of ADC, input mixers and output mixers
11616 */
11617static struct hda_verb alc268_base_init_verbs[] = {
11618	/* Unmute DAC0-1 and set vol = 0 */
11619	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11620	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11621
11622	/*
11623	 * Set up output mixers (0x0c - 0x0e)
11624	 */
11625	/* set vol=0 to output mixers */
11626	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11627        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
11628
11629	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11630	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11631
11632	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11633	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11634	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11635	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11636	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11637	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11638	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11639	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11640
11641	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11642	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11643	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11644	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11645	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11646
11647	/* set PCBEEP vol = 0, mute connections */
11648	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11649	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11650	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11651
11652	/* Unmute Selector 23h,24h and set the default input to mic-in */
11653
11654	{0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11655	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11656	{0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11657	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11658
11659	{ }
11660};
11661
11662/*
11663 * generic initialization of ADC, input mixers and output mixers
11664 */
11665static struct hda_verb alc268_volume_init_verbs[] = {
11666	/* set output DAC */
11667	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11668	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11669
11670	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11671	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11672	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11673	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11674	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11675
11676	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11677	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11678	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11679
11680	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11681	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11682
11683	/* set PCBEEP vol = 0, mute connections */
11684	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11685	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11686	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11687
11688	{ }
11689};
11690
11691static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11692	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11693	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11694	{
11695		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11696		/* The multiple "Capture Source" controls confuse alsamixer
11697		 * So call somewhat different..
11698		 */
11699		/* .name = "Capture Source", */
11700		.name = "Input Source",
11701		.count = 1,
11702		.info = alc_mux_enum_info,
11703		.get = alc_mux_enum_get,
11704		.put = alc_mux_enum_put,
11705	},
11706	{ } /* end */
11707};
11708
11709static struct snd_kcontrol_new alc268_capture_mixer[] = {
11710	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11711	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11712	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11713	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11714	{
11715		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11716		/* The multiple "Capture Source" controls confuse alsamixer
11717		 * So call somewhat different..
11718		 */
11719		/* .name = "Capture Source", */
11720		.name = "Input Source",
11721		.count = 2,
11722		.info = alc_mux_enum_info,
11723		.get = alc_mux_enum_get,
11724		.put = alc_mux_enum_put,
11725	},
11726	{ } /* end */
11727};
11728
11729static struct hda_input_mux alc268_capture_source = {
11730	.num_items = 4,
11731	.items = {
11732		{ "Mic", 0x0 },
11733		{ "Front Mic", 0x1 },
11734		{ "Line", 0x2 },
11735		{ "CD", 0x3 },
11736	},
11737};
11738
11739static struct hda_input_mux alc268_acer_capture_source = {
11740	.num_items = 3,
11741	.items = {
11742		{ "Mic", 0x0 },
11743		{ "Internal Mic", 0x1 },
11744		{ "Line", 0x2 },
11745	},
11746};
11747
11748static struct hda_input_mux alc268_acer_dmic_capture_source = {
11749	.num_items = 3,
11750	.items = {
11751		{ "Mic", 0x0 },
11752		{ "Internal Mic", 0x6 },
11753		{ "Line", 0x2 },
11754	},
11755};
11756
11757#ifdef CONFIG_SND_DEBUG
11758static struct snd_kcontrol_new alc268_test_mixer[] = {
11759	/* Volume widgets */
11760	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11761	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11762	HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11763	HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11764	HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11765	HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11766	HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11767	HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11768	HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11769	HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11770	HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11771	HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11772	HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11773	/* The below appears problematic on some hardwares */
11774	/*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11775	HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11776	HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11777	HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11778	HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11779
11780	/* Modes for retasking pin widgets */
11781	ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11782	ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11783	ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11784	ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11785
11786	/* Controls for GPIO pins, assuming they are configured as outputs */
11787	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11788	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11789	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11790	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11791
11792	/* Switches to allow the digital SPDIF output pin to be enabled.
11793	 * The ALC268 does not have an SPDIF input.
11794	 */
11795	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11796
11797	/* A switch allowing EAPD to be enabled.  Some laptops seem to use
11798	 * this output to turn on an external amplifier.
11799	 */
11800	ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11801	ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11802
11803	{ } /* end */
11804};
11805#endif
11806
11807/* create input playback/capture controls for the given pin */
11808static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11809				    const char *ctlname, int idx)
11810{
11811	char name[32];
11812	int err;
11813
11814	sprintf(name, "%s Playback Volume", ctlname);
11815	if (nid == 0x14) {
11816		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11817				  HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11818						      HDA_OUTPUT));
11819		if (err < 0)
11820			return err;
11821	} else if (nid == 0x15) {
11822		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11823				  HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11824						      HDA_OUTPUT));
11825		if (err < 0)
11826			return err;
11827	} else
11828		return -1;
11829	sprintf(name, "%s Playback Switch", ctlname);
11830	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11831			  HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11832	if (err < 0)
11833		return err;
11834	return 0;
11835}
11836
11837/* add playback controls from the parsed DAC table */
11838static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11839					     const struct auto_pin_cfg *cfg)
11840{
11841	hda_nid_t nid;
11842	int err;
11843
11844	spec->multiout.num_dacs = 2;	/* only use one dac */
11845	spec->multiout.dac_nids = spec->private_dac_nids;
11846	spec->multiout.dac_nids[0] = 2;
11847	spec->multiout.dac_nids[1] = 3;
11848
11849	nid = cfg->line_out_pins[0];
11850	if (nid)
11851		alc268_new_analog_output(spec, nid, "Front", 0);
11852
11853	nid = cfg->speaker_pins[0];
11854	if (nid == 0x1d) {
11855		err = add_control(spec, ALC_CTL_WIDGET_VOL,
11856				  "Speaker Playback Volume",
11857				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11858		if (err < 0)
11859			return err;
11860	}
11861	nid = cfg->hp_pins[0];
11862	if (nid)
11863		alc268_new_analog_output(spec, nid, "Headphone", 0);
11864
11865	nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11866	if (nid == 0x16) {
11867		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11868				  "Mono Playback Switch",
11869				  HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11870		if (err < 0)
11871			return err;
11872	}
11873	return 0;
11874}
11875
11876/* create playback/capture controls for input pins */
11877static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11878						const struct auto_pin_cfg *cfg)
11879{
11880	struct hda_input_mux *imux = &spec->private_imux[0];
11881	int i, idx1;
11882
11883	for (i = 0; i < AUTO_PIN_LAST; i++) {
11884		switch(cfg->input_pins[i]) {
11885		case 0x18:
11886			idx1 = 0;	/* Mic 1 */
11887			break;
11888		case 0x19:
11889			idx1 = 1;	/* Mic 2 */
11890			break;
11891		case 0x1a:
11892			idx1 = 2;	/* Line In */
11893			break;
11894		case 0x1c:
11895			idx1 = 3;	/* CD */
11896			break;
11897		case 0x12:
11898		case 0x13:
11899			idx1 = 6;	/* digital mics */
11900			break;
11901		default:
11902			continue;
11903		}
11904		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11905		imux->items[imux->num_items].index = idx1;
11906		imux->num_items++;
11907	}
11908	return 0;
11909}
11910
11911static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11912{
11913	struct alc_spec *spec = codec->spec;
11914	hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11915	hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11916	hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11917	unsigned int	dac_vol1, dac_vol2;
11918
11919	if (speaker_nid) {
11920		snd_hda_codec_write(codec, speaker_nid, 0,
11921				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11922		snd_hda_codec_write(codec, 0x0f, 0,
11923				    AC_VERB_SET_AMP_GAIN_MUTE,
11924				    AMP_IN_UNMUTE(1));
11925		snd_hda_codec_write(codec, 0x10, 0,
11926				    AC_VERB_SET_AMP_GAIN_MUTE,
11927				    AMP_IN_UNMUTE(1));
11928	} else {
11929		snd_hda_codec_write(codec, 0x0f, 0,
11930				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11931		snd_hda_codec_write(codec, 0x10, 0,
11932				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11933	}
11934
11935	dac_vol1 = dac_vol2 = 0xb000 | 0x40;	/* set max volume  */
11936	if (line_nid == 0x14)
11937		dac_vol2 = AMP_OUT_ZERO;
11938	else if (line_nid == 0x15)
11939		dac_vol1 = AMP_OUT_ZERO;
11940	if (hp_nid == 0x14)
11941		dac_vol2 = AMP_OUT_ZERO;
11942	else if (hp_nid == 0x15)
11943		dac_vol1 = AMP_OUT_ZERO;
11944	if (line_nid != 0x16 || hp_nid != 0x16 ||
11945	    spec->autocfg.line_out_pins[1] != 0x16 ||
11946	    spec->autocfg.line_out_pins[2] != 0x16)
11947		dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11948
11949	snd_hda_codec_write(codec, 0x02, 0,
11950			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11951	snd_hda_codec_write(codec, 0x03, 0,
11952			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11953}
11954
11955/* pcm configuration: identical with ALC880 */
11956#define alc268_pcm_analog_playback	alc880_pcm_analog_playback
11957#define alc268_pcm_analog_capture	alc880_pcm_analog_capture
11958#define alc268_pcm_analog_alt_capture	alc880_pcm_analog_alt_capture
11959#define alc268_pcm_digital_playback	alc880_pcm_digital_playback
11960
11961/*
11962 * BIOS auto configuration
11963 */
11964static int alc268_parse_auto_config(struct hda_codec *codec)
11965{
11966	struct alc_spec *spec = codec->spec;
11967	int err;
11968	static hda_nid_t alc268_ignore[] = { 0 };
11969
11970	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11971					   alc268_ignore);
11972	if (err < 0)
11973		return err;
11974	if (!spec->autocfg.line_outs) {
11975		if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
11976			spec->multiout.max_channels = 2;
11977			spec->no_analog = 1;
11978			goto dig_only;
11979		}
11980		return 0; /* can't find valid BIOS pin config */
11981	}
11982	err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11983	if (err < 0)
11984		return err;
11985	err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11986	if (err < 0)
11987		return err;
11988
11989	spec->multiout.max_channels = 2;
11990
11991 dig_only:
11992	/* digital only support output */
11993	if (spec->autocfg.dig_outs) {
11994		spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
11995		spec->dig_out_type = spec->autocfg.dig_out_type[0];
11996	}
11997	if (spec->kctls.list)
11998		add_mixer(spec, spec->kctls.list);
11999
12000	if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
12001		add_mixer(spec, alc268_beep_mixer);
12002
12003	add_verb(spec, alc268_volume_init_verbs);
12004	spec->num_mux_defs = 1;
12005	spec->input_mux = &spec->private_imux[0];
12006
12007	err = alc_auto_add_mic_boost(codec);
12008	if (err < 0)
12009		return err;
12010
12011	alc_ssid_check(codec, 0x15, 0x1b, 0x14);
12012
12013	return 1;
12014}
12015
12016#define alc268_auto_init_multi_out	alc882_auto_init_multi_out
12017#define alc268_auto_init_hp_out		alc882_auto_init_hp_out
12018#define alc268_auto_init_analog_input	alc882_auto_init_analog_input
12019
12020/* init callback for auto-configuration model -- overriding the default init */
12021static void alc268_auto_init(struct hda_codec *codec)
12022{
12023	struct alc_spec *spec = codec->spec;
12024	alc268_auto_init_multi_out(codec);
12025	alc268_auto_init_hp_out(codec);
12026	alc268_auto_init_mono_speaker_out(codec);
12027	alc268_auto_init_analog_input(codec);
12028	if (spec->unsol_event)
12029		alc_inithook(codec);
12030}
12031
12032/*
12033 * configuration and preset
12034 */
12035static const char *alc268_models[ALC268_MODEL_LAST] = {
12036	[ALC267_QUANTA_IL1]	= "quanta-il1",
12037	[ALC268_3ST]		= "3stack",
12038	[ALC268_TOSHIBA]	= "toshiba",
12039	[ALC268_ACER]		= "acer",
12040	[ALC268_ACER_DMIC]	= "acer-dmic",
12041	[ALC268_ACER_ASPIRE_ONE]	= "acer-aspire",
12042	[ALC268_DELL]		= "dell",
12043	[ALC268_ZEPTO]		= "zepto",
12044#ifdef CONFIG_SND_DEBUG
12045	[ALC268_TEST]		= "test",
12046#endif
12047	[ALC268_AUTO]		= "auto",
12048};
12049
12050static struct snd_pci_quirk alc268_cfg_tbl[] = {
12051	SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
12052	SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
12053	SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
12054	SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
12055	SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
12056	SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
12057						ALC268_ACER_ASPIRE_ONE),
12058	SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
12059	SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
12060	SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
12061			   ALC268_TOSHIBA),
12062	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
12063	SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
12064	SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
12065			   ALC268_TOSHIBA),
12066	SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
12067	SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
12068	SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
12069	SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL),
12070	{}
12071};
12072
12073static struct alc_config_preset alc268_presets[] = {
12074	[ALC267_QUANTA_IL1] = {
12075		.mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer },
12076		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12077				alc267_quanta_il1_verbs },
12078		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
12079		.dac_nids = alc268_dac_nids,
12080		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12081		.adc_nids = alc268_adc_nids_alt,
12082		.hp_nid = 0x03,
12083		.num_channel_mode = ARRAY_SIZE(alc268_modes),
12084		.channel_mode = alc268_modes,
12085		.input_mux = &alc268_capture_source,
12086		.unsol_event = alc267_quanta_il1_unsol_event,
12087		.init_hook = alc267_quanta_il1_init_hook,
12088	},
12089	[ALC268_3ST] = {
12090		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12091			    alc268_beep_mixer },
12092		.init_verbs = { alc268_base_init_verbs },
12093		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
12094		.dac_nids = alc268_dac_nids,
12095                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12096                .adc_nids = alc268_adc_nids_alt,
12097		.capsrc_nids = alc268_capsrc_nids,
12098		.hp_nid = 0x03,
12099		.dig_out_nid = ALC268_DIGOUT_NID,
12100		.num_channel_mode = ARRAY_SIZE(alc268_modes),
12101		.channel_mode = alc268_modes,
12102		.input_mux = &alc268_capture_source,
12103	},
12104	[ALC268_TOSHIBA] = {
12105		.mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
12106			    alc268_beep_mixer },
12107		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12108				alc268_toshiba_verbs },
12109		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
12110		.dac_nids = alc268_dac_nids,
12111		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12112		.adc_nids = alc268_adc_nids_alt,
12113		.capsrc_nids = alc268_capsrc_nids,
12114		.hp_nid = 0x03,
12115		.num_channel_mode = ARRAY_SIZE(alc268_modes),
12116		.channel_mode = alc268_modes,
12117		.input_mux = &alc268_capture_source,
12118		.unsol_event = alc268_toshiba_unsol_event,
12119		.init_hook = alc268_toshiba_init_hook,
12120	},
12121	[ALC268_ACER] = {
12122		.mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
12123			    alc268_beep_mixer },
12124		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12125				alc268_acer_verbs },
12126		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
12127		.dac_nids = alc268_dac_nids,
12128		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12129		.adc_nids = alc268_adc_nids_alt,
12130		.capsrc_nids = alc268_capsrc_nids,
12131		.hp_nid = 0x02,
12132		.num_channel_mode = ARRAY_SIZE(alc268_modes),
12133		.channel_mode = alc268_modes,
12134		.input_mux = &alc268_acer_capture_source,
12135		.unsol_event = alc268_acer_unsol_event,
12136		.init_hook = alc268_acer_init_hook,
12137	},
12138	[ALC268_ACER_DMIC] = {
12139		.mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
12140			    alc268_beep_mixer },
12141		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12142				alc268_acer_verbs },
12143		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
12144		.dac_nids = alc268_dac_nids,
12145		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12146		.adc_nids = alc268_adc_nids_alt,
12147		.capsrc_nids = alc268_capsrc_nids,
12148		.hp_nid = 0x02,
12149		.num_channel_mode = ARRAY_SIZE(alc268_modes),
12150		.channel_mode = alc268_modes,
12151		.input_mux = &alc268_acer_dmic_capture_source,
12152		.unsol_event = alc268_acer_unsol_event,
12153		.init_hook = alc268_acer_init_hook,
12154	},
12155	[ALC268_ACER_ASPIRE_ONE] = {
12156		.mixers = { alc268_acer_aspire_one_mixer,
12157			    alc268_beep_mixer,
12158			    alc268_capture_alt_mixer },
12159		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12160				alc268_acer_aspire_one_verbs },
12161		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
12162		.dac_nids = alc268_dac_nids,
12163		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12164		.adc_nids = alc268_adc_nids_alt,
12165		.capsrc_nids = alc268_capsrc_nids,
12166		.hp_nid = 0x03,
12167		.num_channel_mode = ARRAY_SIZE(alc268_modes),
12168		.channel_mode = alc268_modes,
12169		.input_mux = &alc268_acer_lc_capture_source,
12170		.unsol_event = alc268_acer_lc_unsol_event,
12171		.init_hook = alc268_acer_lc_init_hook,
12172	},
12173	[ALC268_DELL] = {
12174		.mixers = { alc268_dell_mixer, alc268_beep_mixer },
12175		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12176				alc268_dell_verbs },
12177		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
12178		.dac_nids = alc268_dac_nids,
12179		.hp_nid = 0x02,
12180		.num_channel_mode = ARRAY_SIZE(alc268_modes),
12181		.channel_mode = alc268_modes,
12182		.unsol_event = alc_sku_unsol_event,
12183		.init_hook = alc268_dell_init_hook,
12184		.input_mux = &alc268_capture_source,
12185	},
12186	[ALC268_ZEPTO] = {
12187		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12188			    alc268_beep_mixer },
12189		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12190				alc268_toshiba_verbs },
12191		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
12192		.dac_nids = alc268_dac_nids,
12193		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12194		.adc_nids = alc268_adc_nids_alt,
12195		.capsrc_nids = alc268_capsrc_nids,
12196		.hp_nid = 0x03,
12197		.dig_out_nid = ALC268_DIGOUT_NID,
12198		.num_channel_mode = ARRAY_SIZE(alc268_modes),
12199		.channel_mode = alc268_modes,
12200		.input_mux = &alc268_capture_source,
12201		.unsol_event = alc268_toshiba_unsol_event,
12202		.init_hook = alc268_toshiba_init_hook
12203	},
12204#ifdef CONFIG_SND_DEBUG
12205	[ALC268_TEST] = {
12206		.mixers = { alc268_test_mixer, alc268_capture_mixer },
12207		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12208				alc268_volume_init_verbs },
12209		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
12210		.dac_nids = alc268_dac_nids,
12211		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12212		.adc_nids = alc268_adc_nids_alt,
12213		.capsrc_nids = alc268_capsrc_nids,
12214		.hp_nid = 0x03,
12215		.dig_out_nid = ALC268_DIGOUT_NID,
12216		.num_channel_mode = ARRAY_SIZE(alc268_modes),
12217		.channel_mode = alc268_modes,
12218		.input_mux = &alc268_capture_source,
12219	},
12220#endif
12221};
12222
12223static int patch_alc268(struct hda_codec *codec)
12224{
12225	struct alc_spec *spec;
12226	int board_config;
12227	int i, has_beep, err;
12228
12229	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
12230	if (spec == NULL)
12231		return -ENOMEM;
12232
12233	codec->spec = spec;
12234
12235	board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
12236						  alc268_models,
12237						  alc268_cfg_tbl);
12238
12239	if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
12240		printk(KERN_INFO "hda_codec: Unknown model for %s, "
12241		       "trying auto-probe from BIOS...\n", codec->chip_name);
12242		board_config = ALC268_AUTO;
12243	}
12244
12245	if (board_config == ALC268_AUTO) {
12246		/* automatic parse from the BIOS config */
12247		err = alc268_parse_auto_config(codec);
12248		if (err < 0) {
12249			alc_free(codec);
12250			return err;
12251		} else if (!err) {
12252			printk(KERN_INFO
12253			       "hda_codec: Cannot set up configuration "
12254			       "from BIOS.  Using base mode...\n");
12255			board_config = ALC268_3ST;
12256		}
12257	}
12258
12259	if (board_config != ALC268_AUTO)
12260		setup_preset(spec, &alc268_presets[board_config]);
12261
12262	spec->stream_analog_playback = &alc268_pcm_analog_playback;
12263	spec->stream_analog_capture = &alc268_pcm_analog_capture;
12264	spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
12265
12266	spec->stream_digital_playback = &alc268_pcm_digital_playback;
12267
12268	has_beep = 0;
12269	for (i = 0; i < spec->num_mixers; i++) {
12270		if (spec->mixers[i] == alc268_beep_mixer) {
12271			has_beep = 1;
12272			break;
12273		}
12274	}
12275
12276	if (has_beep) {
12277		err = snd_hda_attach_beep_device(codec, 0x1);
12278		if (err < 0) {
12279			alc_free(codec);
12280			return err;
12281		}
12282		if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
12283			/* override the amp caps for beep generator */
12284			snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
12285					  (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
12286					  (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
12287					  (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
12288					  (0 << AC_AMPCAP_MUTE_SHIFT));
12289	}
12290
12291	if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
12292		/* check whether NID 0x07 is valid */
12293		unsigned int wcap = get_wcaps(codec, 0x07);
12294		int i;
12295
12296		/* get type */
12297		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
12298		if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
12299			spec->adc_nids = alc268_adc_nids_alt;
12300			spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
12301			add_mixer(spec, alc268_capture_alt_mixer);
12302		} else {
12303			spec->adc_nids = alc268_adc_nids;
12304			spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
12305			add_mixer(spec, alc268_capture_mixer);
12306		}
12307		spec->capsrc_nids = alc268_capsrc_nids;
12308		/* set default input source */
12309		for (i = 0; i < spec->num_adc_nids; i++)
12310			snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
12311				0, AC_VERB_SET_CONNECT_SEL,
12312				spec->input_mux->items[0].index);
12313	}
12314
12315	spec->vmaster_nid = 0x02;
12316
12317	codec->patch_ops = alc_patch_ops;
12318	if (board_config == ALC268_AUTO)
12319		spec->init_hook = alc268_auto_init;
12320
12321	codec->proc_widget_hook = print_realtek_coef;
12322
12323	return 0;
12324}
12325
12326/*
12327 *  ALC269 channel source setting (2 channel)
12328 */
12329#define ALC269_DIGOUT_NID	ALC880_DIGOUT_NID
12330
12331#define alc269_dac_nids		alc260_dac_nids
12332
12333static hda_nid_t alc269_adc_nids[1] = {
12334	/* ADC1 */
12335	0x08,
12336};
12337
12338static hda_nid_t alc269_capsrc_nids[1] = {
12339	0x23,
12340};
12341
12342/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
12343 *       not a mux!
12344 */
12345
12346static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
12347	.num_items = 2,
12348	.items = {
12349		{ "i-Mic", 0x5 },
12350		{ "e-Mic", 0x0 },
12351	},
12352};
12353
12354static struct hda_input_mux alc269_eeepc_amic_capture_source = {
12355	.num_items = 2,
12356	.items = {
12357		{ "i-Mic", 0x1 },
12358		{ "e-Mic", 0x0 },
12359	},
12360};
12361
12362#define alc269_modes		alc260_modes
12363#define alc269_capture_source	alc880_lg_lw_capture_source
12364
12365static struct snd_kcontrol_new alc269_base_mixer[] = {
12366	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12367	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12368	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12369	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12370	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12371	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12372	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12373	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12374	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12375	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12376	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12377	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
12378	{ } /* end */
12379};
12380
12381static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
12382	/* output mixer control */
12383	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12384	{
12385		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12386		.name = "Master Playback Switch",
12387		.info = snd_hda_mixer_amp_switch_info,
12388		.get = snd_hda_mixer_amp_switch_get,
12389		.put = alc268_acer_master_sw_put,
12390		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12391	},
12392	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12393	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12394	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12395	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12396	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12397	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12398	{ }
12399};
12400
12401static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
12402	/* output mixer control */
12403	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12404	{
12405		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12406		.name = "Master Playback Switch",
12407		.info = snd_hda_mixer_amp_switch_info,
12408		.get = snd_hda_mixer_amp_switch_get,
12409		.put = alc268_acer_master_sw_put,
12410		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12411	},
12412	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12413	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12414	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12415	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12416	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12417	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12418	HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
12419	HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
12420	HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
12421	{ }
12422};
12423
12424/* bind volumes of both NID 0x0c and 0x0d */
12425static struct hda_bind_ctls alc269_epc_bind_vol = {
12426	.ops = &snd_hda_bind_vol,
12427	.values = {
12428		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12429		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12430		0
12431	},
12432};
12433
12434static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
12435	HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12436	HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
12437	HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12438	{ } /* end */
12439};
12440
12441/* capture mixer elements */
12442static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
12443	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12444	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12445	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12446	{ } /* end */
12447};
12448
12449/* FSC amilo */
12450static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
12451	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12452	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12453	HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol),
12454	{ } /* end */
12455};
12456
12457static struct hda_verb alc269_quanta_fl1_verbs[] = {
12458	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12459	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12460	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12461	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12462	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12463	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12464	{ }
12465};
12466
12467static struct hda_verb alc269_lifebook_verbs[] = {
12468	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12469	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
12470	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12471	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12472	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12473	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12474	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12475	{0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12476	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12477	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12478	{ }
12479};
12480
12481/* toggle speaker-output according to the hp-jack state */
12482static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
12483{
12484	unsigned int present;
12485	unsigned char bits;
12486
12487	present = snd_hda_codec_read(codec, 0x15, 0,
12488			AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12489	bits = present ? AMP_IN_MUTE(0) : 0;
12490	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12491			AMP_IN_MUTE(0), bits);
12492	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12493			AMP_IN_MUTE(0), bits);
12494
12495	snd_hda_codec_write(codec, 0x20, 0,
12496			AC_VERB_SET_COEF_INDEX, 0x0c);
12497	snd_hda_codec_write(codec, 0x20, 0,
12498			AC_VERB_SET_PROC_COEF, 0x680);
12499
12500	snd_hda_codec_write(codec, 0x20, 0,
12501			AC_VERB_SET_COEF_INDEX, 0x0c);
12502	snd_hda_codec_write(codec, 0x20, 0,
12503			AC_VERB_SET_PROC_COEF, 0x480);
12504}
12505
12506/* toggle speaker-output according to the hp-jacks state */
12507static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
12508{
12509	unsigned int present;
12510	unsigned char bits;
12511
12512	/* Check laptop headphone socket */
12513	present = snd_hda_codec_read(codec, 0x15, 0,
12514			AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12515
12516	/* Check port replicator headphone socket */
12517	present |= snd_hda_codec_read(codec, 0x1a, 0,
12518			AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12519
12520	bits = present ? AMP_IN_MUTE(0) : 0;
12521	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12522			AMP_IN_MUTE(0), bits);
12523	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12524			AMP_IN_MUTE(0), bits);
12525
12526	snd_hda_codec_write(codec, 0x20, 0,
12527			AC_VERB_SET_COEF_INDEX, 0x0c);
12528	snd_hda_codec_write(codec, 0x20, 0,
12529			AC_VERB_SET_PROC_COEF, 0x680);
12530
12531	snd_hda_codec_write(codec, 0x20, 0,
12532			AC_VERB_SET_COEF_INDEX, 0x0c);
12533	snd_hda_codec_write(codec, 0x20, 0,
12534			AC_VERB_SET_PROC_COEF, 0x480);
12535}
12536
12537static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
12538{
12539	unsigned int present;
12540
12541	present = snd_hda_codec_read(codec, 0x18, 0,
12542				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12543	snd_hda_codec_write(codec, 0x23, 0,
12544			    AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
12545}
12546
12547static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
12548{
12549	unsigned int present_laptop;
12550	unsigned int present_dock;
12551
12552	present_laptop = snd_hda_codec_read(codec, 0x18, 0,
12553				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12554
12555	present_dock = snd_hda_codec_read(codec, 0x1b, 0,
12556				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12557
12558	/* Laptop mic port overrides dock mic port, design decision */
12559	if (present_dock)
12560		snd_hda_codec_write(codec, 0x23, 0,
12561				AC_VERB_SET_CONNECT_SEL, 0x3);
12562	if (present_laptop)
12563		snd_hda_codec_write(codec, 0x23, 0,
12564				AC_VERB_SET_CONNECT_SEL, 0x0);
12565	if (!present_dock && !present_laptop)
12566		snd_hda_codec_write(codec, 0x23, 0,
12567				AC_VERB_SET_CONNECT_SEL, 0x1);
12568}
12569
12570static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
12571				    unsigned int res)
12572{
12573	if ((res >> 26) == ALC880_HP_EVENT)
12574		alc269_quanta_fl1_speaker_automute(codec);
12575	if ((res >> 26) == ALC880_MIC_EVENT)
12576		alc269_quanta_fl1_mic_automute(codec);
12577}
12578
12579static void alc269_lifebook_unsol_event(struct hda_codec *codec,
12580					unsigned int res)
12581{
12582	if ((res >> 26) == ALC880_HP_EVENT)
12583		alc269_lifebook_speaker_automute(codec);
12584	if ((res >> 26) == ALC880_MIC_EVENT)
12585		alc269_lifebook_mic_autoswitch(codec);
12586}
12587
12588static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
12589{
12590	alc269_quanta_fl1_speaker_automute(codec);
12591	alc269_quanta_fl1_mic_automute(codec);
12592}
12593
12594static void alc269_lifebook_init_hook(struct hda_codec *codec)
12595{
12596	alc269_lifebook_speaker_automute(codec);
12597	alc269_lifebook_mic_autoswitch(codec);
12598}
12599
12600static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
12601	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12602	{0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
12603	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12604	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
12605	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12606	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12607	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12608	{}
12609};
12610
12611static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
12612	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12613	{0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
12614	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12615	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
12616	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12617	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12618	{}
12619};
12620
12621/* toggle speaker-output according to the hp-jack state */
12622static void alc269_speaker_automute(struct hda_codec *codec)
12623{
12624	unsigned int present;
12625	unsigned char bits;
12626
12627	present = snd_hda_codec_read(codec, 0x15, 0,
12628				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12629	bits = present ? AMP_IN_MUTE(0) : 0;
12630	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12631				AMP_IN_MUTE(0), bits);
12632	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12633				AMP_IN_MUTE(0), bits);
12634}
12635
12636static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
12637{
12638	unsigned int present;
12639
12640	present = snd_hda_codec_read(codec, 0x18, 0,
12641				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12642	snd_hda_codec_write(codec, 0x23, 0,
12643				AC_VERB_SET_CONNECT_SEL,  (present ? 0 : 5));
12644}
12645
12646static void alc269_eeepc_amic_automute(struct hda_codec *codec)
12647{
12648	unsigned int present;
12649
12650	present = snd_hda_codec_read(codec, 0x18, 0,
12651				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12652	snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12653				0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12654	snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12655				0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12656}
12657
12658/* unsolicited event for HP jack sensing */
12659static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
12660				     unsigned int res)
12661{
12662	if ((res >> 26) == ALC880_HP_EVENT)
12663		alc269_speaker_automute(codec);
12664
12665	if ((res >> 26) == ALC880_MIC_EVENT)
12666		alc269_eeepc_dmic_automute(codec);
12667}
12668
12669static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
12670{
12671	alc269_speaker_automute(codec);
12672	alc269_eeepc_dmic_automute(codec);
12673}
12674
12675/* unsolicited event for HP jack sensing */
12676static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
12677				     unsigned int res)
12678{
12679	if ((res >> 26) == ALC880_HP_EVENT)
12680		alc269_speaker_automute(codec);
12681
12682	if ((res >> 26) == ALC880_MIC_EVENT)
12683		alc269_eeepc_amic_automute(codec);
12684}
12685
12686static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
12687{
12688	alc269_speaker_automute(codec);
12689	alc269_eeepc_amic_automute(codec);
12690}
12691
12692/*
12693 * generic initialization of ADC, input mixers and output mixers
12694 */
12695static struct hda_verb alc269_init_verbs[] = {
12696	/*
12697	 * Unmute ADC0 and set the default input to mic-in
12698	 */
12699	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12700
12701	/* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12702	 * analog-loopback mixer widget
12703	 * Note: PASD motherboards uses the Line In 2 as the input for
12704	 * front panel mic (mic 2)
12705	 */
12706	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12707	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12708	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12709	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12710	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12711	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12712
12713	/*
12714	 * Set up output mixers (0x0c - 0x0e)
12715	 */
12716	/* set vol=0 to output mixers */
12717	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12718	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12719
12720	/* set up input amps for analog loopback */
12721	/* Amp Indices: DAC = 0, mixer = 1 */
12722	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12723	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12724	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12725	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12726	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12727	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12728
12729	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12730	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12731	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12732	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12733	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12734	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12735	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12736
12737	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12738	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12739	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12740	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12741	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12742	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12743	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12744
12745	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12746	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12747
12748	/* FIXME: use matrix-type input source selection */
12749	/* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12750	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12751	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12752	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12753	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12754	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12755
12756	/* set EAPD */
12757	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12758	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12759	{ }
12760};
12761
12762/* add playback controls from the parsed DAC table */
12763static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12764					     const struct auto_pin_cfg *cfg)
12765{
12766	hda_nid_t nid;
12767	int err;
12768
12769	spec->multiout.num_dacs = 1;	/* only use one dac */
12770	spec->multiout.dac_nids = spec->private_dac_nids;
12771	spec->multiout.dac_nids[0] = 2;
12772
12773	nid = cfg->line_out_pins[0];
12774	if (nid) {
12775		err = add_control(spec, ALC_CTL_WIDGET_VOL,
12776				  "Front Playback Volume",
12777				  HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12778		if (err < 0)
12779			return err;
12780		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12781				  "Front Playback Switch",
12782				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12783		if (err < 0)
12784			return err;
12785	}
12786
12787	nid = cfg->speaker_pins[0];
12788	if (nid) {
12789		if (!cfg->line_out_pins[0]) {
12790			err = add_control(spec, ALC_CTL_WIDGET_VOL,
12791					  "Speaker Playback Volume",
12792					  HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12793							      HDA_OUTPUT));
12794			if (err < 0)
12795				return err;
12796		}
12797		if (nid == 0x16) {
12798			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12799					  "Speaker Playback Switch",
12800					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12801							      HDA_OUTPUT));
12802			if (err < 0)
12803				return err;
12804		} else {
12805			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12806					  "Speaker Playback Switch",
12807					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12808							      HDA_OUTPUT));
12809			if (err < 0)
12810				return err;
12811		}
12812	}
12813	nid = cfg->hp_pins[0];
12814	if (nid) {
12815		/* spec->multiout.hp_nid = 2; */
12816		if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12817			err = add_control(spec, ALC_CTL_WIDGET_VOL,
12818					  "Headphone Playback Volume",
12819					  HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12820							      HDA_OUTPUT));
12821			if (err < 0)
12822				return err;
12823		}
12824		if (nid == 0x16) {
12825			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12826					  "Headphone Playback Switch",
12827					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12828							      HDA_OUTPUT));
12829			if (err < 0)
12830				return err;
12831		} else {
12832			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12833					  "Headphone Playback Switch",
12834					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12835							      HDA_OUTPUT));
12836			if (err < 0)
12837				return err;
12838		}
12839	}
12840	return 0;
12841}
12842
12843#define alc269_auto_create_analog_input_ctls \
12844	alc262_auto_create_analog_input_ctls
12845
12846#ifdef CONFIG_SND_HDA_POWER_SAVE
12847#define alc269_loopbacks	alc880_loopbacks
12848#endif
12849
12850/* pcm configuration: identical with ALC880 */
12851#define alc269_pcm_analog_playback	alc880_pcm_analog_playback
12852#define alc269_pcm_analog_capture	alc880_pcm_analog_capture
12853#define alc269_pcm_digital_playback	alc880_pcm_digital_playback
12854#define alc269_pcm_digital_capture	alc880_pcm_digital_capture
12855
12856static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
12857	.substreams = 1,
12858	.channels_min = 2,
12859	.channels_max = 8,
12860	.rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12861	/* NID is set in alc_build_pcms */
12862	.ops = {
12863		.open = alc880_playback_pcm_open,
12864		.prepare = alc880_playback_pcm_prepare,
12865		.cleanup = alc880_playback_pcm_cleanup
12866	},
12867};
12868
12869static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
12870	.substreams = 1,
12871	.channels_min = 2,
12872	.channels_max = 2,
12873	.rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12874	/* NID is set in alc_build_pcms */
12875};
12876
12877/*
12878 * BIOS auto configuration
12879 */
12880static int alc269_parse_auto_config(struct hda_codec *codec)
12881{
12882	struct alc_spec *spec = codec->spec;
12883	int err;
12884	static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12885
12886	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12887					   alc269_ignore);
12888	if (err < 0)
12889		return err;
12890
12891	err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12892	if (err < 0)
12893		return err;
12894	err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12895	if (err < 0)
12896		return err;
12897
12898	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12899
12900	if (spec->autocfg.dig_outs)
12901		spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12902
12903	if (spec->kctls.list)
12904		add_mixer(spec, spec->kctls.list);
12905
12906	add_verb(spec, alc269_init_verbs);
12907	spec->num_mux_defs = 1;
12908	spec->input_mux = &spec->private_imux[0];
12909	/* set default input source */
12910	snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12911				  0, AC_VERB_SET_CONNECT_SEL,
12912				  spec->input_mux->items[0].index);
12913
12914	err = alc_auto_add_mic_boost(codec);
12915	if (err < 0)
12916		return err;
12917
12918	if (!spec->cap_mixer && !spec->no_analog)
12919		set_capture_mixer(spec);
12920
12921	alc_ssid_check(codec, 0x15, 0x1b, 0x14);
12922
12923	return 1;
12924}
12925
12926#define alc269_auto_init_multi_out	alc882_auto_init_multi_out
12927#define alc269_auto_init_hp_out		alc882_auto_init_hp_out
12928#define alc269_auto_init_analog_input	alc882_auto_init_analog_input
12929
12930
12931/* init callback for auto-configuration model -- overriding the default init */
12932static void alc269_auto_init(struct hda_codec *codec)
12933{
12934	struct alc_spec *spec = codec->spec;
12935	alc269_auto_init_multi_out(codec);
12936	alc269_auto_init_hp_out(codec);
12937	alc269_auto_init_analog_input(codec);
12938	if (spec->unsol_event)
12939		alc_inithook(codec);
12940}
12941
12942/*
12943 * configuration and preset
12944 */
12945static const char *alc269_models[ALC269_MODEL_LAST] = {
12946	[ALC269_BASIC]			= "basic",
12947	[ALC269_QUANTA_FL1]		= "quanta",
12948	[ALC269_ASUS_EEEPC_P703]	= "eeepc-p703",
12949	[ALC269_ASUS_EEEPC_P901]	= "eeepc-p901",
12950	[ALC269_FUJITSU]		= "fujitsu",
12951	[ALC269_LIFEBOOK]		= "lifebook"
12952};
12953
12954static struct snd_pci_quirk alc269_cfg_tbl[] = {
12955	SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
12956	SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12957		      ALC269_ASUS_EEEPC_P703),
12958        SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703),
12959        SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703),
12960        SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703),
12961        SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703),
12962        SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703),
12963        SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703),
12964	SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12965		      ALC269_ASUS_EEEPC_P901),
12966	SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12967		      ALC269_ASUS_EEEPC_P901),
12968        SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901),
12969	SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
12970	SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
12971	{}
12972};
12973
12974static struct alc_config_preset alc269_presets[] = {
12975	[ALC269_BASIC] = {
12976		.mixers = { alc269_base_mixer },
12977		.init_verbs = { alc269_init_verbs },
12978		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
12979		.dac_nids = alc269_dac_nids,
12980		.hp_nid = 0x03,
12981		.num_channel_mode = ARRAY_SIZE(alc269_modes),
12982		.channel_mode = alc269_modes,
12983		.input_mux = &alc269_capture_source,
12984	},
12985	[ALC269_QUANTA_FL1] = {
12986		.mixers = { alc269_quanta_fl1_mixer },
12987		.init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
12988		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
12989		.dac_nids = alc269_dac_nids,
12990		.hp_nid = 0x03,
12991		.num_channel_mode = ARRAY_SIZE(alc269_modes),
12992		.channel_mode = alc269_modes,
12993		.input_mux = &alc269_capture_source,
12994		.unsol_event = alc269_quanta_fl1_unsol_event,
12995		.init_hook = alc269_quanta_fl1_init_hook,
12996	},
12997	[ALC269_ASUS_EEEPC_P703] = {
12998		.mixers = { alc269_eeepc_mixer },
12999		.cap_mixer = alc269_epc_capture_mixer,
13000		.init_verbs = { alc269_init_verbs,
13001				alc269_eeepc_amic_init_verbs },
13002		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
13003		.dac_nids = alc269_dac_nids,
13004		.hp_nid = 0x03,
13005		.num_channel_mode = ARRAY_SIZE(alc269_modes),
13006		.channel_mode = alc269_modes,
13007		.input_mux = &alc269_eeepc_amic_capture_source,
13008		.unsol_event = alc269_eeepc_amic_unsol_event,
13009		.init_hook = alc269_eeepc_amic_inithook,
13010	},
13011	[ALC269_ASUS_EEEPC_P901] = {
13012		.mixers = { alc269_eeepc_mixer },
13013		.cap_mixer = alc269_epc_capture_mixer,
13014		.init_verbs = { alc269_init_verbs,
13015				alc269_eeepc_dmic_init_verbs },
13016		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
13017		.dac_nids = alc269_dac_nids,
13018		.hp_nid = 0x03,
13019		.num_channel_mode = ARRAY_SIZE(alc269_modes),
13020		.channel_mode = alc269_modes,
13021		.input_mux = &alc269_eeepc_dmic_capture_source,
13022		.unsol_event = alc269_eeepc_dmic_unsol_event,
13023		.init_hook = alc269_eeepc_dmic_inithook,
13024	},
13025	[ALC269_FUJITSU] = {
13026		.mixers = { alc269_fujitsu_mixer },
13027		.cap_mixer = alc269_epc_capture_mixer,
13028		.init_verbs = { alc269_init_verbs,
13029				alc269_eeepc_dmic_init_verbs },
13030		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
13031		.dac_nids = alc269_dac_nids,
13032		.hp_nid = 0x03,
13033		.num_channel_mode = ARRAY_SIZE(alc269_modes),
13034		.channel_mode = alc269_modes,
13035		.input_mux = &alc269_eeepc_dmic_capture_source,
13036		.unsol_event = alc269_eeepc_dmic_unsol_event,
13037		.init_hook = alc269_eeepc_dmic_inithook,
13038	},
13039	[ALC269_LIFEBOOK] = {
13040		.mixers = { alc269_lifebook_mixer },
13041		.init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
13042		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
13043		.dac_nids = alc269_dac_nids,
13044		.hp_nid = 0x03,
13045		.num_channel_mode = ARRAY_SIZE(alc269_modes),
13046		.channel_mode = alc269_modes,
13047		.input_mux = &alc269_capture_source,
13048		.unsol_event = alc269_lifebook_unsol_event,
13049		.init_hook = alc269_lifebook_init_hook,
13050	},
13051};
13052
13053static int patch_alc269(struct hda_codec *codec)
13054{
13055	struct alc_spec *spec;
13056	int board_config;
13057	int err;
13058
13059	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13060	if (spec == NULL)
13061		return -ENOMEM;
13062
13063	codec->spec = spec;
13064
13065	alc_fix_pll_init(codec, 0x20, 0x04, 15);
13066
13067	board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
13068						  alc269_models,
13069						  alc269_cfg_tbl);
13070
13071	if (board_config < 0) {
13072		printk(KERN_INFO "hda_codec: Unknown model for %s, "
13073		       "trying auto-probe from BIOS...\n", codec->chip_name);
13074		board_config = ALC269_AUTO;
13075	}
13076
13077	if (board_config == ALC269_AUTO) {
13078		/* automatic parse from the BIOS config */
13079		err = alc269_parse_auto_config(codec);
13080		if (err < 0) {
13081			alc_free(codec);
13082			return err;
13083		} else if (!err) {
13084			printk(KERN_INFO
13085			       "hda_codec: Cannot set up configuration "
13086			       "from BIOS.  Using base mode...\n");
13087			board_config = ALC269_BASIC;
13088		}
13089	}
13090
13091	err = snd_hda_attach_beep_device(codec, 0x1);
13092	if (err < 0) {
13093		alc_free(codec);
13094		return err;
13095	}
13096
13097	if (board_config != ALC269_AUTO)
13098		setup_preset(spec, &alc269_presets[board_config]);
13099
13100	if (codec->subsystem_id == 0x17aa3bf8) {
13101		/* Due to a hardware problem on Lenovo Ideadpad, we need to
13102		 * fix the sample rate of analog I/O to 44.1kHz
13103		 */
13104		spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
13105		spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
13106	} else {
13107		spec->stream_analog_playback = &alc269_pcm_analog_playback;
13108		spec->stream_analog_capture = &alc269_pcm_analog_capture;
13109	}
13110	spec->stream_digital_playback = &alc269_pcm_digital_playback;
13111	spec->stream_digital_capture = &alc269_pcm_digital_capture;
13112
13113	spec->adc_nids = alc269_adc_nids;
13114	spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
13115	spec->capsrc_nids = alc269_capsrc_nids;
13116	if (!spec->cap_mixer)
13117		set_capture_mixer(spec);
13118	set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
13119
13120	codec->patch_ops = alc_patch_ops;
13121	if (board_config == ALC269_AUTO)
13122		spec->init_hook = alc269_auto_init;
13123#ifdef CONFIG_SND_HDA_POWER_SAVE
13124	if (!spec->loopback.amplist)
13125		spec->loopback.amplist = alc269_loopbacks;
13126#endif
13127	codec->proc_widget_hook = print_realtek_coef;
13128
13129	return 0;
13130}
13131
13132/*
13133 *  ALC861 channel source setting (2/6 channel selection for 3-stack)
13134 */
13135
13136/*
13137 * set the path ways for 2 channel output
13138 * need to set the codec line out and mic 1 pin widgets to inputs
13139 */
13140static struct hda_verb alc861_threestack_ch2_init[] = {
13141	/* set pin widget 1Ah (line in) for input */
13142	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13143	/* set pin widget 18h (mic1/2) for input, for mic also enable
13144	 * the vref
13145	 */
13146	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13147
13148	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13149#if 0
13150	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13151	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13152#endif
13153	{ } /* end */
13154};
13155/*
13156 * 6ch mode
13157 * need to set the codec line out and mic 1 pin widgets to outputs
13158 */
13159static struct hda_verb alc861_threestack_ch6_init[] = {
13160	/* set pin widget 1Ah (line in) for output (Back Surround)*/
13161	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13162	/* set pin widget 18h (mic1) for output (CLFE)*/
13163	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13164
13165	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13166	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13167
13168	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13169#if 0
13170	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13171	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13172#endif
13173	{ } /* end */
13174};
13175
13176static struct hda_channel_mode alc861_threestack_modes[2] = {
13177	{ 2, alc861_threestack_ch2_init },
13178	{ 6, alc861_threestack_ch6_init },
13179};
13180/* Set mic1 as input and unmute the mixer */
13181static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
13182	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13183	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13184	{ } /* end */
13185};
13186/* Set mic1 as output and mute mixer */
13187static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
13188	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13189	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13190	{ } /* end */
13191};
13192
13193static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
13194	{ 2, alc861_uniwill_m31_ch2_init },
13195	{ 4, alc861_uniwill_m31_ch4_init },
13196};
13197
13198/* Set mic1 and line-in as input and unmute the mixer */
13199static struct hda_verb alc861_asus_ch2_init[] = {
13200	/* set pin widget 1Ah (line in) for input */
13201	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13202	/* set pin widget 18h (mic1/2) for input, for mic also enable
13203	 * the vref
13204	 */
13205	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13206
13207	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13208#if 0
13209	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13210	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13211#endif
13212	{ } /* end */
13213};
13214/* Set mic1 nad line-in as output and mute mixer */
13215static struct hda_verb alc861_asus_ch6_init[] = {
13216	/* set pin widget 1Ah (line in) for output (Back Surround)*/
13217	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13218	/* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13219	/* set pin widget 18h (mic1) for output (CLFE)*/
13220	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13221	/* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13222	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13223	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13224
13225	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13226#if 0
13227	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13228	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13229#endif
13230	{ } /* end */
13231};
13232
13233static struct hda_channel_mode alc861_asus_modes[2] = {
13234	{ 2, alc861_asus_ch2_init },
13235	{ 6, alc861_asus_ch6_init },
13236};
13237
13238/* patch-ALC861 */
13239
13240static struct snd_kcontrol_new alc861_base_mixer[] = {
13241        /* output mixer control */
13242	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13243	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13244	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13245	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13246	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13247
13248        /*Input mixer control */
13249	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13250	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13251	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13252	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13253	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13254	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13255	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13256	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13257	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13258	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13259
13260	{ } /* end */
13261};
13262
13263static struct snd_kcontrol_new alc861_3ST_mixer[] = {
13264        /* output mixer control */
13265	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13266	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13267	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13268	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13269	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13270
13271	/* Input mixer control */
13272	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13273	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13274	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13275	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13276	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13277	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13278	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13279	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13280	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13281	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13282
13283	{
13284		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13285		.name = "Channel Mode",
13286		.info = alc_ch_mode_info,
13287		.get = alc_ch_mode_get,
13288		.put = alc_ch_mode_put,
13289                .private_value = ARRAY_SIZE(alc861_threestack_modes),
13290	},
13291	{ } /* end */
13292};
13293
13294static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
13295        /* output mixer control */
13296	HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13297	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13298	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13299
13300	{ } /* end */
13301};
13302
13303static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
13304        /* output mixer control */
13305	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13306	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13307	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13308	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13309	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13310
13311	/* Input mixer control */
13312	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13313	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13314	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13315	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13316	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13317	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13318	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13319	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13320	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13321	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13322
13323	{
13324		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13325		.name = "Channel Mode",
13326		.info = alc_ch_mode_info,
13327		.get = alc_ch_mode_get,
13328		.put = alc_ch_mode_put,
13329                .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
13330	},
13331	{ } /* end */
13332};
13333
13334static struct snd_kcontrol_new alc861_asus_mixer[] = {
13335        /* output mixer control */
13336	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13337	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13338	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13339	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13340	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13341
13342	/* Input mixer control */
13343	HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13344	HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13345	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13346	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13347	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13348	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13349	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13350	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13351	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13352	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
13353
13354	{
13355		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13356		.name = "Channel Mode",
13357		.info = alc_ch_mode_info,
13358		.get = alc_ch_mode_get,
13359		.put = alc_ch_mode_put,
13360                .private_value = ARRAY_SIZE(alc861_asus_modes),
13361	},
13362	{ }
13363};
13364
13365/* additional mixer */
13366static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
13367	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13368	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13369	{ }
13370};
13371
13372/*
13373 * generic initialization of ADC, input mixers and output mixers
13374 */
13375static struct hda_verb alc861_base_init_verbs[] = {
13376	/*
13377	 * Unmute ADC0 and set the default input to mic-in
13378	 */
13379	/* port-A for surround (rear panel) */
13380	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13381	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
13382	/* port-B for mic-in (rear panel) with vref */
13383	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13384	/* port-C for line-in (rear panel) */
13385	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13386	/* port-D for Front */
13387	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13388	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13389	/* port-E for HP out (front panel) */
13390	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13391	/* route front PCM to HP */
13392	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13393	/* port-F for mic-in (front panel) with vref */
13394	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13395	/* port-G for CLFE (rear panel) */
13396	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13397	{ 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13398	/* port-H for side (rear panel) */
13399	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13400	{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
13401	/* CD-in */
13402	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13403	/* route front mic to ADC1*/
13404	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13405	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13406
13407	/* Unmute DAC0~3 & spdif out*/
13408	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13409	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13410	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13411	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13412	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13413
13414	/* Unmute Mixer 14 (mic) 1c (Line in)*/
13415	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13416        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13417	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13418        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13419
13420	/* Unmute Stereo Mixer 15 */
13421	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13422	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13423	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13424	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13425
13426	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13427	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13428	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13429	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13430	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13431	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13432	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13433	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13434	/* hp used DAC 3 (Front) */
13435	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13436        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13437
13438	{ }
13439};
13440
13441static struct hda_verb alc861_threestack_init_verbs[] = {
13442	/*
13443	 * Unmute ADC0 and set the default input to mic-in
13444	 */
13445	/* port-A for surround (rear panel) */
13446	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13447	/* port-B for mic-in (rear panel) with vref */
13448	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13449	/* port-C for line-in (rear panel) */
13450	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13451	/* port-D for Front */
13452	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13453	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13454	/* port-E for HP out (front panel) */
13455	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13456	/* route front PCM to HP */
13457	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13458	/* port-F for mic-in (front panel) with vref */
13459	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13460	/* port-G for CLFE (rear panel) */
13461	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13462	/* port-H for side (rear panel) */
13463	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13464	/* CD-in */
13465	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13466	/* route front mic to ADC1*/
13467	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13468	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13469	/* Unmute DAC0~3 & spdif out*/
13470	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13471	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13472	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13473	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13474	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13475
13476	/* Unmute Mixer 14 (mic) 1c (Line in)*/
13477	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13478        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13479	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13480        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13481
13482	/* Unmute Stereo Mixer 15 */
13483	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13484	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13485	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13486	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13487
13488	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13489	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13490	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13491	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13492	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13493	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13494	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13495	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13496	/* hp used DAC 3 (Front) */
13497	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13498        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13499	{ }
13500};
13501
13502static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
13503	/*
13504	 * Unmute ADC0 and set the default input to mic-in
13505	 */
13506	/* port-A for surround (rear panel) */
13507	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13508	/* port-B for mic-in (rear panel) with vref */
13509	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13510	/* port-C for line-in (rear panel) */
13511	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13512	/* port-D for Front */
13513	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13514	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13515	/* port-E for HP out (front panel) */
13516	/* this has to be set to VREF80 */
13517	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13518	/* route front PCM to HP */
13519	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13520	/* port-F for mic-in (front panel) with vref */
13521	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13522	/* port-G for CLFE (rear panel) */
13523	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13524	/* port-H for side (rear panel) */
13525	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13526	/* CD-in */
13527	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13528	/* route front mic to ADC1*/
13529	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13530	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13531	/* Unmute DAC0~3 & spdif out*/
13532	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13533	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13534	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13535	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13536	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13537
13538	/* Unmute Mixer 14 (mic) 1c (Line in)*/
13539	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13540        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13541	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13542        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13543
13544	/* Unmute Stereo Mixer 15 */
13545	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13546	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13547	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13548	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13549
13550	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13551	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13552	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13553	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13554	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13555	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13556	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13557	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13558	/* hp used DAC 3 (Front) */
13559	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13560        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13561	{ }
13562};
13563
13564static struct hda_verb alc861_asus_init_verbs[] = {
13565	/*
13566	 * Unmute ADC0 and set the default input to mic-in
13567	 */
13568	/* port-A for surround (rear panel)
13569	 * according to codec#0 this is the HP jack
13570	 */
13571	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
13572	/* route front PCM to HP */
13573	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
13574	/* port-B for mic-in (rear panel) with vref */
13575	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13576	/* port-C for line-in (rear panel) */
13577	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13578	/* port-D for Front */
13579	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13580	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13581	/* port-E for HP out (front panel) */
13582	/* this has to be set to VREF80 */
13583	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13584	/* route front PCM to HP */
13585	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13586	/* port-F for mic-in (front panel) with vref */
13587	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13588	/* port-G for CLFE (rear panel) */
13589	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13590	/* port-H for side (rear panel) */
13591	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13592	/* CD-in */
13593	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13594	/* route front mic to ADC1*/
13595	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13596	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13597	/* Unmute DAC0~3 & spdif out*/
13598	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13599	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13600	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13601	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13602	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13603	/* Unmute Mixer 14 (mic) 1c (Line in)*/
13604	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13605        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13606	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13607        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13608
13609	/* Unmute Stereo Mixer 15 */
13610	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13611	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13612	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13613	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13614
13615	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13616	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13617	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13618	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13619	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13620	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13621	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13622	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13623	/* hp used DAC 3 (Front) */
13624	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13625	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13626	{ }
13627};
13628
13629/* additional init verbs for ASUS laptops */
13630static struct hda_verb alc861_asus_laptop_init_verbs[] = {
13631	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
13632	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
13633	{ }
13634};
13635
13636/*
13637 * generic initialization of ADC, input mixers and output mixers
13638 */
13639static struct hda_verb alc861_auto_init_verbs[] = {
13640	/*
13641	 * Unmute ADC0 and set the default input to mic-in
13642	 */
13643	/* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
13644	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13645
13646	/* Unmute DAC0~3 & spdif out*/
13647	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13648	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13649	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13650	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13651	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13652
13653	/* Unmute Mixer 14 (mic) 1c (Line in)*/
13654	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13655	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13656	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13657	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13658
13659	/* Unmute Stereo Mixer 15 */
13660	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13661	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13662	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13663	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
13664
13665	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13666	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13667	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13668	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13669	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13670	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13671	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13672	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13673
13674	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13675	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13676	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13677	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13678	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13679	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13680	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13681	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13682
13683	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},	/* set Mic 1 */
13684
13685	{ }
13686};
13687
13688static struct hda_verb alc861_toshiba_init_verbs[] = {
13689	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13690
13691	{ }
13692};
13693
13694/* toggle speaker-output according to the hp-jack state */
13695static void alc861_toshiba_automute(struct hda_codec *codec)
13696{
13697	unsigned int present;
13698
13699	present = snd_hda_codec_read(codec, 0x0f, 0,
13700				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13701	snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
13702				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13703	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
13704				 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
13705}
13706
13707static void alc861_toshiba_unsol_event(struct hda_codec *codec,
13708				       unsigned int res)
13709{
13710	if ((res >> 26) == ALC880_HP_EVENT)
13711		alc861_toshiba_automute(codec);
13712}
13713
13714/* pcm configuration: identical with ALC880 */
13715#define alc861_pcm_analog_playback	alc880_pcm_analog_playback
13716#define alc861_pcm_analog_capture	alc880_pcm_analog_capture
13717#define alc861_pcm_digital_playback	alc880_pcm_digital_playback
13718#define alc861_pcm_digital_capture	alc880_pcm_digital_capture
13719
13720
13721#define ALC861_DIGOUT_NID	0x07
13722
13723static struct hda_channel_mode alc861_8ch_modes[1] = {
13724	{ 8, NULL }
13725};
13726
13727static hda_nid_t alc861_dac_nids[4] = {
13728	/* front, surround, clfe, side */
13729	0x03, 0x06, 0x05, 0x04
13730};
13731
13732static hda_nid_t alc660_dac_nids[3] = {
13733	/* front, clfe, surround */
13734	0x03, 0x05, 0x06
13735};
13736
13737static hda_nid_t alc861_adc_nids[1] = {
13738	/* ADC0-2 */
13739	0x08,
13740};
13741
13742static struct hda_input_mux alc861_capture_source = {
13743	.num_items = 5,
13744	.items = {
13745		{ "Mic", 0x0 },
13746		{ "Front Mic", 0x3 },
13747		{ "Line", 0x1 },
13748		{ "CD", 0x4 },
13749		{ "Mixer", 0x5 },
13750	},
13751};
13752
13753/* fill in the dac_nids table from the parsed pin configuration */
13754static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
13755				     const struct auto_pin_cfg *cfg)
13756{
13757	int i;
13758	hda_nid_t nid;
13759
13760	spec->multiout.dac_nids = spec->private_dac_nids;
13761	for (i = 0; i < cfg->line_outs; i++) {
13762		nid = cfg->line_out_pins[i];
13763		if (nid) {
13764			if (i >= ARRAY_SIZE(alc861_dac_nids))
13765				continue;
13766			spec->multiout.dac_nids[i] = alc861_dac_nids[i];
13767		}
13768	}
13769	spec->multiout.num_dacs = cfg->line_outs;
13770	return 0;
13771}
13772
13773/* add playback controls from the parsed DAC table */
13774static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
13775					     const struct auto_pin_cfg *cfg)
13776{
13777	char name[32];
13778	static const char *chname[4] = {
13779		"Front", "Surround", NULL /*CLFE*/, "Side"
13780	};
13781	hda_nid_t nid;
13782	int i, idx, err;
13783
13784	for (i = 0; i < cfg->line_outs; i++) {
13785		nid = spec->multiout.dac_nids[i];
13786		if (!nid)
13787			continue;
13788		if (nid == 0x05) {
13789			/* Center/LFE */
13790			err = add_control(spec, ALC_CTL_BIND_MUTE,
13791					  "Center Playback Switch",
13792					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13793							      HDA_OUTPUT));
13794			if (err < 0)
13795				return err;
13796			err = add_control(spec, ALC_CTL_BIND_MUTE,
13797					  "LFE Playback Switch",
13798					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13799							      HDA_OUTPUT));
13800			if (err < 0)
13801				return err;
13802		} else {
13803			for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13804			     idx++)
13805				if (nid == alc861_dac_nids[idx])
13806					break;
13807			sprintf(name, "%s Playback Switch", chname[idx]);
13808			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13809					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13810							      HDA_OUTPUT));
13811			if (err < 0)
13812				return err;
13813		}
13814	}
13815	return 0;
13816}
13817
13818static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13819{
13820	int err;
13821	hda_nid_t nid;
13822
13823	if (!pin)
13824		return 0;
13825
13826	if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13827		nid = 0x03;
13828		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13829				  "Headphone Playback Switch",
13830				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13831		if (err < 0)
13832			return err;
13833		spec->multiout.hp_nid = nid;
13834	}
13835	return 0;
13836}
13837
13838/* create playback/capture controls for input pins */
13839static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13840						const struct auto_pin_cfg *cfg)
13841{
13842	struct hda_input_mux *imux = &spec->private_imux[0];
13843	int i, err, idx, idx1;
13844
13845	for (i = 0; i < AUTO_PIN_LAST; i++) {
13846		switch (cfg->input_pins[i]) {
13847		case 0x0c:
13848			idx1 = 1;
13849			idx = 2;	/* Line In */
13850			break;
13851		case 0x0f:
13852			idx1 = 2;
13853			idx = 2;	/* Line In */
13854			break;
13855		case 0x0d:
13856			idx1 = 0;
13857			idx = 1;	/* Mic In */
13858			break;
13859		case 0x10:
13860			idx1 = 3;
13861			idx = 1;	/* Mic In */
13862			break;
13863		case 0x11:
13864			idx1 = 4;
13865			idx = 0;	/* CD */
13866			break;
13867		default:
13868			continue;
13869		}
13870
13871		err = new_analog_input(spec, cfg->input_pins[i],
13872				       auto_pin_cfg_labels[i], idx, 0x15);
13873		if (err < 0)
13874			return err;
13875
13876		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
13877		imux->items[imux->num_items].index = idx1;
13878		imux->num_items++;
13879	}
13880	return 0;
13881}
13882
13883static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13884					      hda_nid_t nid,
13885					      int pin_type, int dac_idx)
13886{
13887	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13888			    pin_type);
13889	snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13890			    AMP_OUT_UNMUTE);
13891}
13892
13893static void alc861_auto_init_multi_out(struct hda_codec *codec)
13894{
13895	struct alc_spec *spec = codec->spec;
13896	int i;
13897
13898	for (i = 0; i < spec->autocfg.line_outs; i++) {
13899		hda_nid_t nid = spec->autocfg.line_out_pins[i];
13900		int pin_type = get_pin_type(spec->autocfg.line_out_type);
13901		if (nid)
13902			alc861_auto_set_output_and_unmute(codec, nid, pin_type,
13903							  spec->multiout.dac_nids[i]);
13904	}
13905}
13906
13907static void alc861_auto_init_hp_out(struct hda_codec *codec)
13908{
13909	struct alc_spec *spec = codec->spec;
13910	hda_nid_t pin;
13911
13912	pin = spec->autocfg.hp_pins[0];
13913	if (pin) /* connect to front */
13914		alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13915						  spec->multiout.dac_nids[0]);
13916	pin = spec->autocfg.speaker_pins[0];
13917	if (pin)
13918		alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13919}
13920
13921static void alc861_auto_init_analog_input(struct hda_codec *codec)
13922{
13923	struct alc_spec *spec = codec->spec;
13924	int i;
13925
13926	for (i = 0; i < AUTO_PIN_LAST; i++) {
13927		hda_nid_t nid = spec->autocfg.input_pins[i];
13928		if (nid >= 0x0c && nid <= 0x11)
13929			alc_set_input_pin(codec, nid, i);
13930	}
13931}
13932
13933/* parse the BIOS configuration and set up the alc_spec */
13934/* return 1 if successful, 0 if the proper config is not found,
13935 * or a negative error code
13936 */
13937static int alc861_parse_auto_config(struct hda_codec *codec)
13938{
13939	struct alc_spec *spec = codec->spec;
13940	int err;
13941	static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13942
13943	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13944					   alc861_ignore);
13945	if (err < 0)
13946		return err;
13947	if (!spec->autocfg.line_outs)
13948		return 0; /* can't find valid BIOS pin config */
13949
13950	err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13951	if (err < 0)
13952		return err;
13953	err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13954	if (err < 0)
13955		return err;
13956	err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13957	if (err < 0)
13958		return err;
13959	err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13960	if (err < 0)
13961		return err;
13962
13963	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13964
13965	if (spec->autocfg.dig_outs)
13966		spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13967
13968	if (spec->kctls.list)
13969		add_mixer(spec, spec->kctls.list);
13970
13971	add_verb(spec, alc861_auto_init_verbs);
13972
13973	spec->num_mux_defs = 1;
13974	spec->input_mux = &spec->private_imux[0];
13975
13976	spec->adc_nids = alc861_adc_nids;
13977	spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
13978	set_capture_mixer(spec);
13979
13980	alc_ssid_check(codec, 0x0e, 0x0f, 0x0b);
13981
13982	return 1;
13983}
13984
13985/* additional initialization for auto-configuration model */
13986static void alc861_auto_init(struct hda_codec *codec)
13987{
13988	struct alc_spec *spec = codec->spec;
13989	alc861_auto_init_multi_out(codec);
13990	alc861_auto_init_hp_out(codec);
13991	alc861_auto_init_analog_input(codec);
13992	if (spec->unsol_event)
13993		alc_inithook(codec);
13994}
13995
13996#ifdef CONFIG_SND_HDA_POWER_SAVE
13997static struct hda_amp_list alc861_loopbacks[] = {
13998	{ 0x15, HDA_INPUT, 0 },
13999	{ 0x15, HDA_INPUT, 1 },
14000	{ 0x15, HDA_INPUT, 2 },
14001	{ 0x15, HDA_INPUT, 3 },
14002	{ } /* end */
14003};
14004#endif
14005
14006
14007/*
14008 * configuration and preset
14009 */
14010static const char *alc861_models[ALC861_MODEL_LAST] = {
14011	[ALC861_3ST]		= "3stack",
14012	[ALC660_3ST]		= "3stack-660",
14013	[ALC861_3ST_DIG]	= "3stack-dig",
14014	[ALC861_6ST_DIG]	= "6stack-dig",
14015	[ALC861_UNIWILL_M31]	= "uniwill-m31",
14016	[ALC861_TOSHIBA]	= "toshiba",
14017	[ALC861_ASUS]		= "asus",
14018	[ALC861_ASUS_LAPTOP]	= "asus-laptop",
14019	[ALC861_AUTO]		= "auto",
14020};
14021
14022static struct snd_pci_quirk alc861_cfg_tbl[] = {
14023	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
14024	SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14025	SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14026	SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
14027	SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
14028	SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
14029	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
14030	/* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
14031	 *        Any other models that need this preset?
14032	 */
14033	/* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
14034	SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
14035	SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
14036	SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
14037	SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
14038	SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
14039	/* FIXME: the below seems conflict */
14040	/* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
14041	SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
14042	SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
14043	{}
14044};
14045
14046static struct alc_config_preset alc861_presets[] = {
14047	[ALC861_3ST] = {
14048		.mixers = { alc861_3ST_mixer },
14049		.init_verbs = { alc861_threestack_init_verbs },
14050		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
14051		.dac_nids = alc861_dac_nids,
14052		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14053		.channel_mode = alc861_threestack_modes,
14054		.need_dac_fix = 1,
14055		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14056		.adc_nids = alc861_adc_nids,
14057		.input_mux = &alc861_capture_source,
14058	},
14059	[ALC861_3ST_DIG] = {
14060		.mixers = { alc861_base_mixer },
14061		.init_verbs = { alc861_threestack_init_verbs },
14062		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
14063		.dac_nids = alc861_dac_nids,
14064		.dig_out_nid = ALC861_DIGOUT_NID,
14065		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14066		.channel_mode = alc861_threestack_modes,
14067		.need_dac_fix = 1,
14068		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14069		.adc_nids = alc861_adc_nids,
14070		.input_mux = &alc861_capture_source,
14071	},
14072	[ALC861_6ST_DIG] = {
14073		.mixers = { alc861_base_mixer },
14074		.init_verbs = { alc861_base_init_verbs },
14075		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
14076		.dac_nids = alc861_dac_nids,
14077		.dig_out_nid = ALC861_DIGOUT_NID,
14078		.num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
14079		.channel_mode = alc861_8ch_modes,
14080		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14081		.adc_nids = alc861_adc_nids,
14082		.input_mux = &alc861_capture_source,
14083	},
14084	[ALC660_3ST] = {
14085		.mixers = { alc861_3ST_mixer },
14086		.init_verbs = { alc861_threestack_init_verbs },
14087		.num_dacs = ARRAY_SIZE(alc660_dac_nids),
14088		.dac_nids = alc660_dac_nids,
14089		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14090		.channel_mode = alc861_threestack_modes,
14091		.need_dac_fix = 1,
14092		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14093		.adc_nids = alc861_adc_nids,
14094		.input_mux = &alc861_capture_source,
14095	},
14096	[ALC861_UNIWILL_M31] = {
14097		.mixers = { alc861_uniwill_m31_mixer },
14098		.init_verbs = { alc861_uniwill_m31_init_verbs },
14099		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
14100		.dac_nids = alc861_dac_nids,
14101		.dig_out_nid = ALC861_DIGOUT_NID,
14102		.num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
14103		.channel_mode = alc861_uniwill_m31_modes,
14104		.need_dac_fix = 1,
14105		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14106		.adc_nids = alc861_adc_nids,
14107		.input_mux = &alc861_capture_source,
14108	},
14109	[ALC861_TOSHIBA] = {
14110		.mixers = { alc861_toshiba_mixer },
14111		.init_verbs = { alc861_base_init_verbs,
14112				alc861_toshiba_init_verbs },
14113		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
14114		.dac_nids = alc861_dac_nids,
14115		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14116		.channel_mode = alc883_3ST_2ch_modes,
14117		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14118		.adc_nids = alc861_adc_nids,
14119		.input_mux = &alc861_capture_source,
14120		.unsol_event = alc861_toshiba_unsol_event,
14121		.init_hook = alc861_toshiba_automute,
14122	},
14123	[ALC861_ASUS] = {
14124		.mixers = { alc861_asus_mixer },
14125		.init_verbs = { alc861_asus_init_verbs },
14126		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
14127		.dac_nids = alc861_dac_nids,
14128		.dig_out_nid = ALC861_DIGOUT_NID,
14129		.num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
14130		.channel_mode = alc861_asus_modes,
14131		.need_dac_fix = 1,
14132		.hp_nid = 0x06,
14133		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14134		.adc_nids = alc861_adc_nids,
14135		.input_mux = &alc861_capture_source,
14136	},
14137	[ALC861_ASUS_LAPTOP] = {
14138		.mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
14139		.init_verbs = { alc861_asus_init_verbs,
14140				alc861_asus_laptop_init_verbs },
14141		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
14142		.dac_nids = alc861_dac_nids,
14143		.dig_out_nid = ALC861_DIGOUT_NID,
14144		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14145		.channel_mode = alc883_3ST_2ch_modes,
14146		.need_dac_fix = 1,
14147		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14148		.adc_nids = alc861_adc_nids,
14149		.input_mux = &alc861_capture_source,
14150	},
14151};
14152
14153
14154static int patch_alc861(struct hda_codec *codec)
14155{
14156	struct alc_spec *spec;
14157	int board_config;
14158	int err;
14159
14160	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14161	if (spec == NULL)
14162		return -ENOMEM;
14163
14164	codec->spec = spec;
14165
14166        board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
14167						  alc861_models,
14168						  alc861_cfg_tbl);
14169
14170	if (board_config < 0) {
14171		printk(KERN_INFO "hda_codec: Unknown model for %s, "
14172		       "trying auto-probe from BIOS...\n", codec->chip_name);
14173		board_config = ALC861_AUTO;
14174	}
14175
14176	if (board_config == ALC861_AUTO) {
14177		/* automatic parse from the BIOS config */
14178		err = alc861_parse_auto_config(codec);
14179		if (err < 0) {
14180			alc_free(codec);
14181			return err;
14182		} else if (!err) {
14183			printk(KERN_INFO
14184			       "hda_codec: Cannot set up configuration "
14185			       "from BIOS.  Using base mode...\n");
14186		   board_config = ALC861_3ST_DIG;
14187		}
14188	}
14189
14190	err = snd_hda_attach_beep_device(codec, 0x23);
14191	if (err < 0) {
14192		alc_free(codec);
14193		return err;
14194	}
14195
14196	if (board_config != ALC861_AUTO)
14197		setup_preset(spec, &alc861_presets[board_config]);
14198
14199	spec->stream_analog_playback = &alc861_pcm_analog_playback;
14200	spec->stream_analog_capture = &alc861_pcm_analog_capture;
14201
14202	spec->stream_digital_playback = &alc861_pcm_digital_playback;
14203	spec->stream_digital_capture = &alc861_pcm_digital_capture;
14204
14205	set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
14206
14207	spec->vmaster_nid = 0x03;
14208
14209	codec->patch_ops = alc_patch_ops;
14210	if (board_config == ALC861_AUTO)
14211		spec->init_hook = alc861_auto_init;
14212#ifdef CONFIG_SND_HDA_POWER_SAVE
14213	if (!spec->loopback.amplist)
14214		spec->loopback.amplist = alc861_loopbacks;
14215#endif
14216	codec->proc_widget_hook = print_realtek_coef;
14217
14218	return 0;
14219}
14220
14221/*
14222 * ALC861-VD support
14223 *
14224 * Based on ALC882
14225 *
14226 * In addition, an independent DAC
14227 */
14228#define ALC861VD_DIGOUT_NID	0x06
14229
14230static hda_nid_t alc861vd_dac_nids[4] = {
14231	/* front, surr, clfe, side surr */
14232	0x02, 0x03, 0x04, 0x05
14233};
14234
14235/* dac_nids for ALC660vd are in a different order - according to
14236 * Realtek's driver.
14237 * This should probably result in a different mixer for 6stack models
14238 * of ALC660vd codecs, but for now there is only 3stack mixer
14239 * - and it is the same as in 861vd.
14240 * adc_nids in ALC660vd are (is) the same as in 861vd
14241 */
14242static hda_nid_t alc660vd_dac_nids[3] = {
14243	/* front, rear, clfe, rear_surr */
14244	0x02, 0x04, 0x03
14245};
14246
14247static hda_nid_t alc861vd_adc_nids[1] = {
14248	/* ADC0 */
14249	0x09,
14250};
14251
14252static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
14253
14254/* input MUX */
14255/* FIXME: should be a matrix-type input source selection */
14256static struct hda_input_mux alc861vd_capture_source = {
14257	.num_items = 4,
14258	.items = {
14259		{ "Mic", 0x0 },
14260		{ "Front Mic", 0x1 },
14261		{ "Line", 0x2 },
14262		{ "CD", 0x4 },
14263	},
14264};
14265
14266static struct hda_input_mux alc861vd_dallas_capture_source = {
14267	.num_items = 2,
14268	.items = {
14269		{ "Ext Mic", 0x0 },
14270		{ "Int Mic", 0x1 },
14271	},
14272};
14273
14274static struct hda_input_mux alc861vd_hp_capture_source = {
14275	.num_items = 2,
14276	.items = {
14277		{ "Front Mic", 0x0 },
14278		{ "ATAPI Mic", 0x1 },
14279	},
14280};
14281
14282/*
14283 * 2ch mode
14284 */
14285static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
14286	{ 2, NULL }
14287};
14288
14289/*
14290 * 6ch mode
14291 */
14292static struct hda_verb alc861vd_6stack_ch6_init[] = {
14293	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14294	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14295	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14296	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14297	{ } /* end */
14298};
14299
14300/*
14301 * 8ch mode
14302 */
14303static struct hda_verb alc861vd_6stack_ch8_init[] = {
14304	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14305	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14306	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14307	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14308	{ } /* end */
14309};
14310
14311static struct hda_channel_mode alc861vd_6stack_modes[2] = {
14312	{ 6, alc861vd_6stack_ch6_init },
14313	{ 8, alc861vd_6stack_ch8_init },
14314};
14315
14316static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
14317	{
14318		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14319		.name = "Channel Mode",
14320		.info = alc_ch_mode_info,
14321		.get = alc_ch_mode_get,
14322		.put = alc_ch_mode_put,
14323	},
14324	{ } /* end */
14325};
14326
14327/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14328 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14329 */
14330static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
14331	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14332	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14333
14334	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14335	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
14336
14337	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
14338				HDA_OUTPUT),
14339	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
14340				HDA_OUTPUT),
14341	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
14342	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
14343
14344	HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
14345	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
14346
14347	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14348
14349	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14350	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14351	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14352
14353	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14354	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14355	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14356
14357	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14358	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14359
14360	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14361	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14362
14363	{ } /* end */
14364};
14365
14366static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
14367	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14368	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14369
14370	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14371
14372	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14373	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14374	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14375
14376	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14377	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14378	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14379
14380	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14381	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14382
14383	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14384	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14385
14386	{ } /* end */
14387};
14388
14389static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
14390	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14391	/*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
14392	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14393
14394	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14395
14396	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14397	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14398	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14399
14400	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14401	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14402	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14403
14404	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14405	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14406
14407	{ } /* end */
14408};
14409
14410/* Pin assignment: Speaker=0x14, HP = 0x15,
14411 *                 Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
14412 */
14413static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
14414	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14415	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
14416	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14417	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14418	HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
14419	HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14420	HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14421	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
14422	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14423	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14424	{ } /* end */
14425};
14426
14427/* Pin assignment: Speaker=0x14, Line-out = 0x15,
14428 *                 Front Mic=0x18, ATAPI Mic = 0x19,
14429 */
14430static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
14431	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14432	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14433	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14434	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14435	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14436	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14437	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14438	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14439
14440	{ } /* end */
14441};
14442
14443/*
14444 * generic initialization of ADC, input mixers and output mixers
14445 */
14446static struct hda_verb alc861vd_volume_init_verbs[] = {
14447	/*
14448	 * Unmute ADC0 and set the default input to mic-in
14449	 */
14450	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14451	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14452
14453	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
14454	 * the analog-loopback mixer widget
14455	 */
14456	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14457	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14458	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14459	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14460	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14461	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14462
14463	/* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
14464	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14465	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14466	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14467	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14468
14469	/*
14470	 * Set up output mixers (0x02 - 0x05)
14471	 */
14472	/* set vol=0 to output mixers */
14473	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14474	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14475	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14476	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14477
14478	/* set up input amps for analog loopback */
14479	/* Amp Indices: DAC = 0, mixer = 1 */
14480	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14481	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14482	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14483	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14484	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14485	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14486	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14487	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14488
14489	{ }
14490};
14491
14492/*
14493 * 3-stack pin configuration:
14494 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
14495 */
14496static struct hda_verb alc861vd_3stack_init_verbs[] = {
14497	/*
14498	 * Set pin mode and muting
14499	 */
14500	/* set front pin widgets 0x14 for output */
14501	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14502	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14503	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14504
14505	/* Mic (rear) pin: input vref at 80% */
14506	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14507	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14508	/* Front Mic pin: input vref at 80% */
14509	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14510	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14511	/* Line In pin: input */
14512	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14513	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14514	/* Line-2 In: Headphone output (output 0 - 0x0c) */
14515	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14516	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14517	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14518	/* CD pin widget for input */
14519	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14520
14521	{ }
14522};
14523
14524/*
14525 * 6-stack pin configuration:
14526 */
14527static struct hda_verb alc861vd_6stack_init_verbs[] = {
14528	/*
14529	 * Set pin mode and muting
14530	 */
14531	/* set front pin widgets 0x14 for output */
14532	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14533	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14534	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14535
14536	/* Rear Pin: output 1 (0x0d) */
14537	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14538	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14539	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14540	/* CLFE Pin: output 2 (0x0e) */
14541	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14542	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14543	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
14544	/* Side Pin: output 3 (0x0f) */
14545	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14546	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14547	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
14548
14549	/* Mic (rear) pin: input vref at 80% */
14550	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14551	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14552	/* Front Mic pin: input vref at 80% */
14553	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14554	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14555	/* Line In pin: input */
14556	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14557	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14558	/* Line-2 In: Headphone output (output 0 - 0x0c) */
14559	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14560	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14561	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14562	/* CD pin widget for input */
14563	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14564
14565	{ }
14566};
14567
14568static struct hda_verb alc861vd_eapd_verbs[] = {
14569	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14570	{ }
14571};
14572
14573static struct hda_verb alc660vd_eapd_verbs[] = {
14574	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14575	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14576	{ }
14577};
14578
14579static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
14580	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14581	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14582	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
14583	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14584	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14585	{}
14586};
14587
14588static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14589{
14590	unsigned int present;
14591	unsigned char bits;
14592
14593	present = snd_hda_codec_read(codec, 0x18, 0,
14594				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14595	bits = present ? HDA_AMP_MUTE : 0;
14596	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
14597				 HDA_AMP_MUTE, bits);
14598}
14599
14600static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
14601{
14602	struct alc_spec *spec = codec->spec;
14603
14604	spec->autocfg.hp_pins[0] = 0x1b;
14605	spec->autocfg.speaker_pins[0] = 0x14;
14606	alc_automute_amp(codec);
14607	alc861vd_lenovo_mic_automute(codec);
14608}
14609
14610static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
14611					unsigned int res)
14612{
14613	switch (res >> 26) {
14614	case ALC880_MIC_EVENT:
14615		alc861vd_lenovo_mic_automute(codec);
14616		break;
14617	default:
14618		alc_automute_amp_unsol_event(codec, res);
14619		break;
14620	}
14621}
14622
14623static struct hda_verb alc861vd_dallas_verbs[] = {
14624	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14625	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14626	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14627	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14628
14629	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14630	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14631	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14632	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14633	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14634	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14635	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14636	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14637
14638	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14639	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14640	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14641	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14642	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14643	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14644	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14645	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14646
14647	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14648	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14649	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14650	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14651	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14652	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14653	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14654	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14655
14656	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14657	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14658	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14659	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14660
14661	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14662	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14663	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14664
14665	{ } /* end */
14666};
14667
14668/* toggle speaker-output according to the hp-jack state */
14669static void alc861vd_dallas_init_hook(struct hda_codec *codec)
14670{
14671	struct alc_spec *spec = codec->spec;
14672
14673	spec->autocfg.hp_pins[0] = 0x15;
14674	spec->autocfg.speaker_pins[0] = 0x14;
14675	alc_automute_amp(codec);
14676}
14677
14678#ifdef CONFIG_SND_HDA_POWER_SAVE
14679#define alc861vd_loopbacks	alc880_loopbacks
14680#endif
14681
14682/* pcm configuration: identical with ALC880 */
14683#define alc861vd_pcm_analog_playback	alc880_pcm_analog_playback
14684#define alc861vd_pcm_analog_capture	alc880_pcm_analog_capture
14685#define alc861vd_pcm_digital_playback	alc880_pcm_digital_playback
14686#define alc861vd_pcm_digital_capture	alc880_pcm_digital_capture
14687
14688/*
14689 * configuration and preset
14690 */
14691static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14692	[ALC660VD_3ST]		= "3stack-660",
14693	[ALC660VD_3ST_DIG]	= "3stack-660-digout",
14694	[ALC660VD_ASUS_V1S]	= "asus-v1s",
14695	[ALC861VD_3ST]		= "3stack",
14696	[ALC861VD_3ST_DIG]	= "3stack-digout",
14697	[ALC861VD_6ST_DIG]	= "6stack-digout",
14698	[ALC861VD_LENOVO]	= "lenovo",
14699	[ALC861VD_DALLAS]	= "dallas",
14700	[ALC861VD_HP]		= "hp",
14701	[ALC861VD_AUTO]		= "auto",
14702};
14703
14704static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
14705	SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14706	SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
14707	SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
14708	SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
14709	SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
14710	SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
14711	SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
14712	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
14713	/*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
14714	SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
14715	SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
14716	SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
14717	SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
14718	SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
14719	SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
14720	{}
14721};
14722
14723static struct alc_config_preset alc861vd_presets[] = {
14724	[ALC660VD_3ST] = {
14725		.mixers = { alc861vd_3st_mixer },
14726		.init_verbs = { alc861vd_volume_init_verbs,
14727				 alc861vd_3stack_init_verbs },
14728		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14729		.dac_nids = alc660vd_dac_nids,
14730		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14731		.channel_mode = alc861vd_3stack_2ch_modes,
14732		.input_mux = &alc861vd_capture_source,
14733	},
14734	[ALC660VD_3ST_DIG] = {
14735		.mixers = { alc861vd_3st_mixer },
14736		.init_verbs = { alc861vd_volume_init_verbs,
14737				 alc861vd_3stack_init_verbs },
14738		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14739		.dac_nids = alc660vd_dac_nids,
14740		.dig_out_nid = ALC861VD_DIGOUT_NID,
14741		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14742		.channel_mode = alc861vd_3stack_2ch_modes,
14743		.input_mux = &alc861vd_capture_source,
14744	},
14745	[ALC861VD_3ST] = {
14746		.mixers = { alc861vd_3st_mixer },
14747		.init_verbs = { alc861vd_volume_init_verbs,
14748				 alc861vd_3stack_init_verbs },
14749		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14750		.dac_nids = alc861vd_dac_nids,
14751		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14752		.channel_mode = alc861vd_3stack_2ch_modes,
14753		.input_mux = &alc861vd_capture_source,
14754	},
14755	[ALC861VD_3ST_DIG] = {
14756		.mixers = { alc861vd_3st_mixer },
14757		.init_verbs = { alc861vd_volume_init_verbs,
14758		 		 alc861vd_3stack_init_verbs },
14759		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14760		.dac_nids = alc861vd_dac_nids,
14761		.dig_out_nid = ALC861VD_DIGOUT_NID,
14762		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14763		.channel_mode = alc861vd_3stack_2ch_modes,
14764		.input_mux = &alc861vd_capture_source,
14765	},
14766	[ALC861VD_6ST_DIG] = {
14767		.mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14768		.init_verbs = { alc861vd_volume_init_verbs,
14769				alc861vd_6stack_init_verbs },
14770		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14771		.dac_nids = alc861vd_dac_nids,
14772		.dig_out_nid = ALC861VD_DIGOUT_NID,
14773		.num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14774		.channel_mode = alc861vd_6stack_modes,
14775		.input_mux = &alc861vd_capture_source,
14776	},
14777	[ALC861VD_LENOVO] = {
14778		.mixers = { alc861vd_lenovo_mixer },
14779		.init_verbs = { alc861vd_volume_init_verbs,
14780				alc861vd_3stack_init_verbs,
14781				alc861vd_eapd_verbs,
14782				alc861vd_lenovo_unsol_verbs },
14783		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14784		.dac_nids = alc660vd_dac_nids,
14785		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14786		.channel_mode = alc861vd_3stack_2ch_modes,
14787		.input_mux = &alc861vd_capture_source,
14788		.unsol_event = alc861vd_lenovo_unsol_event,
14789		.init_hook = alc861vd_lenovo_init_hook,
14790	},
14791	[ALC861VD_DALLAS] = {
14792		.mixers = { alc861vd_dallas_mixer },
14793		.init_verbs = { alc861vd_dallas_verbs },
14794		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14795		.dac_nids = alc861vd_dac_nids,
14796		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14797		.channel_mode = alc861vd_3stack_2ch_modes,
14798		.input_mux = &alc861vd_dallas_capture_source,
14799		.unsol_event = alc_automute_amp_unsol_event,
14800		.init_hook = alc861vd_dallas_init_hook,
14801	},
14802	[ALC861VD_HP] = {
14803		.mixers = { alc861vd_hp_mixer },
14804		.init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14805		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14806		.dac_nids = alc861vd_dac_nids,
14807		.dig_out_nid = ALC861VD_DIGOUT_NID,
14808		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14809		.channel_mode = alc861vd_3stack_2ch_modes,
14810		.input_mux = &alc861vd_hp_capture_source,
14811		.unsol_event = alc_automute_amp_unsol_event,
14812		.init_hook = alc861vd_dallas_init_hook,
14813	},
14814	[ALC660VD_ASUS_V1S] = {
14815		.mixers = { alc861vd_lenovo_mixer },
14816		.init_verbs = { alc861vd_volume_init_verbs,
14817				alc861vd_3stack_init_verbs,
14818				alc861vd_eapd_verbs,
14819				alc861vd_lenovo_unsol_verbs },
14820		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14821		.dac_nids = alc660vd_dac_nids,
14822		.dig_out_nid = ALC861VD_DIGOUT_NID,
14823		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14824		.channel_mode = alc861vd_3stack_2ch_modes,
14825		.input_mux = &alc861vd_capture_source,
14826		.unsol_event = alc861vd_lenovo_unsol_event,
14827		.init_hook = alc861vd_lenovo_init_hook,
14828	},
14829};
14830
14831/*
14832 * BIOS auto configuration
14833 */
14834static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14835				hda_nid_t nid, int pin_type, int dac_idx)
14836{
14837	alc_set_pin_output(codec, nid, pin_type);
14838}
14839
14840static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14841{
14842	struct alc_spec *spec = codec->spec;
14843	int i;
14844
14845	for (i = 0; i <= HDA_SIDE; i++) {
14846		hda_nid_t nid = spec->autocfg.line_out_pins[i];
14847		int pin_type = get_pin_type(spec->autocfg.line_out_type);
14848		if (nid)
14849			alc861vd_auto_set_output_and_unmute(codec, nid,
14850							    pin_type, i);
14851	}
14852}
14853
14854
14855static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14856{
14857	struct alc_spec *spec = codec->spec;
14858	hda_nid_t pin;
14859
14860	pin = spec->autocfg.hp_pins[0];
14861	if (pin) /* connect to front and use dac 0 */
14862		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
14863	pin = spec->autocfg.speaker_pins[0];
14864	if (pin)
14865		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14866}
14867
14868#define alc861vd_is_input_pin(nid)	alc880_is_input_pin(nid)
14869#define ALC861VD_PIN_CD_NID		ALC880_PIN_CD_NID
14870
14871static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14872{
14873	struct alc_spec *spec = codec->spec;
14874	int i;
14875
14876	for (i = 0; i < AUTO_PIN_LAST; i++) {
14877		hda_nid_t nid = spec->autocfg.input_pins[i];
14878		if (alc861vd_is_input_pin(nid)) {
14879			alc_set_input_pin(codec, nid, i);
14880			if (nid != ALC861VD_PIN_CD_NID &&
14881			    (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
14882				snd_hda_codec_write(codec, nid, 0,
14883						AC_VERB_SET_AMP_GAIN_MUTE,
14884						AMP_OUT_MUTE);
14885		}
14886	}
14887}
14888
14889#define alc861vd_auto_init_input_src	alc882_auto_init_input_src
14890
14891#define alc861vd_idx_to_mixer_vol(nid)		((nid) + 0x02)
14892#define alc861vd_idx_to_mixer_switch(nid)	((nid) + 0x0c)
14893
14894/* add playback controls from the parsed DAC table */
14895/* Based on ALC880 version. But ALC861VD has separate,
14896 * different NIDs for mute/unmute switch and volume control */
14897static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14898					     const struct auto_pin_cfg *cfg)
14899{
14900	char name[32];
14901	static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14902	hda_nid_t nid_v, nid_s;
14903	int i, err;
14904
14905	for (i = 0; i < cfg->line_outs; i++) {
14906		if (!spec->multiout.dac_nids[i])
14907			continue;
14908		nid_v = alc861vd_idx_to_mixer_vol(
14909				alc880_dac_to_idx(
14910					spec->multiout.dac_nids[i]));
14911		nid_s = alc861vd_idx_to_mixer_switch(
14912				alc880_dac_to_idx(
14913					spec->multiout.dac_nids[i]));
14914
14915		if (i == 2) {
14916			/* Center/LFE */
14917			err = add_control(spec, ALC_CTL_WIDGET_VOL,
14918					  "Center Playback Volume",
14919					  HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14920							      HDA_OUTPUT));
14921			if (err < 0)
14922				return err;
14923			err = add_control(spec, ALC_CTL_WIDGET_VOL,
14924					  "LFE Playback Volume",
14925					  HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14926							      HDA_OUTPUT));
14927			if (err < 0)
14928				return err;
14929			err = add_control(spec, ALC_CTL_BIND_MUTE,
14930					  "Center Playback Switch",
14931					  HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14932							      HDA_INPUT));
14933			if (err < 0)
14934				return err;
14935			err = add_control(spec, ALC_CTL_BIND_MUTE,
14936					  "LFE Playback Switch",
14937					  HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14938							      HDA_INPUT));
14939			if (err < 0)
14940				return err;
14941		} else {
14942			sprintf(name, "%s Playback Volume", chname[i]);
14943			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14944					  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14945							      HDA_OUTPUT));
14946			if (err < 0)
14947				return err;
14948			sprintf(name, "%s Playback Switch", chname[i]);
14949			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14950					  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
14951							      HDA_INPUT));
14952			if (err < 0)
14953				return err;
14954		}
14955	}
14956	return 0;
14957}
14958
14959/* add playback controls for speaker and HP outputs */
14960/* Based on ALC880 version. But ALC861VD has separate,
14961 * different NIDs for mute/unmute switch and volume control */
14962static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
14963					hda_nid_t pin, const char *pfx)
14964{
14965	hda_nid_t nid_v, nid_s;
14966	int err;
14967	char name[32];
14968
14969	if (!pin)
14970		return 0;
14971
14972	if (alc880_is_fixed_pin(pin)) {
14973		nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14974		/* specify the DAC as the extra output */
14975		if (!spec->multiout.hp_nid)
14976			spec->multiout.hp_nid = nid_v;
14977		else
14978			spec->multiout.extra_out_nid[0] = nid_v;
14979		/* control HP volume/switch on the output mixer amp */
14980		nid_v = alc861vd_idx_to_mixer_vol(
14981				alc880_fixed_pin_idx(pin));
14982		nid_s = alc861vd_idx_to_mixer_switch(
14983				alc880_fixed_pin_idx(pin));
14984
14985		sprintf(name, "%s Playback Volume", pfx);
14986		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14987				  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
14988		if (err < 0)
14989			return err;
14990		sprintf(name, "%s Playback Switch", pfx);
14991		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14992				  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
14993		if (err < 0)
14994			return err;
14995	} else if (alc880_is_multi_pin(pin)) {
14996		/* set manual connection */
14997		/* we have only a switch on HP-out PIN */
14998		sprintf(name, "%s Playback Switch", pfx);
14999		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15000				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
15001		if (err < 0)
15002			return err;
15003	}
15004	return 0;
15005}
15006
15007/* parse the BIOS configuration and set up the alc_spec
15008 * return 1 if successful, 0 if the proper config is not found,
15009 * or a negative error code
15010 * Based on ALC880 version - had to change it to override
15011 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
15012static int alc861vd_parse_auto_config(struct hda_codec *codec)
15013{
15014	struct alc_spec *spec = codec->spec;
15015	int err;
15016	static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
15017
15018	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15019					   alc861vd_ignore);
15020	if (err < 0)
15021		return err;
15022	if (!spec->autocfg.line_outs)
15023		return 0; /* can't find valid BIOS pin config */
15024
15025	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
15026	if (err < 0)
15027		return err;
15028	err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
15029	if (err < 0)
15030		return err;
15031	err = alc861vd_auto_create_extra_out(spec,
15032					     spec->autocfg.speaker_pins[0],
15033					     "Speaker");
15034	if (err < 0)
15035		return err;
15036	err = alc861vd_auto_create_extra_out(spec,
15037					     spec->autocfg.hp_pins[0],
15038					     "Headphone");
15039	if (err < 0)
15040		return err;
15041	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
15042	if (err < 0)
15043		return err;
15044
15045	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15046
15047	if (spec->autocfg.dig_outs)
15048		spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
15049
15050	if (spec->kctls.list)
15051		add_mixer(spec, spec->kctls.list);
15052
15053	add_verb(spec, alc861vd_volume_init_verbs);
15054
15055	spec->num_mux_defs = 1;
15056	spec->input_mux = &spec->private_imux[0];
15057
15058	err = alc_auto_add_mic_boost(codec);
15059	if (err < 0)
15060		return err;
15061
15062	alc_ssid_check(codec, 0x15, 0x1b, 0x14);
15063
15064	return 1;
15065}
15066
15067/* additional initialization for auto-configuration model */
15068static void alc861vd_auto_init(struct hda_codec *codec)
15069{
15070	struct alc_spec *spec = codec->spec;
15071	alc861vd_auto_init_multi_out(codec);
15072	alc861vd_auto_init_hp_out(codec);
15073	alc861vd_auto_init_analog_input(codec);
15074	alc861vd_auto_init_input_src(codec);
15075	if (spec->unsol_event)
15076		alc_inithook(codec);
15077}
15078
15079static int patch_alc861vd(struct hda_codec *codec)
15080{
15081	struct alc_spec *spec;
15082	int err, board_config;
15083
15084	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15085	if (spec == NULL)
15086		return -ENOMEM;
15087
15088	codec->spec = spec;
15089
15090	board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
15091						  alc861vd_models,
15092						  alc861vd_cfg_tbl);
15093
15094	if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
15095		printk(KERN_INFO "hda_codec: Unknown model for %s, "
15096		       "trying auto-probe from BIOS...\n", codec->chip_name);
15097		board_config = ALC861VD_AUTO;
15098	}
15099
15100	if (board_config == ALC861VD_AUTO) {
15101		/* automatic parse from the BIOS config */
15102		err = alc861vd_parse_auto_config(codec);
15103		if (err < 0) {
15104			alc_free(codec);
15105			return err;
15106		} else if (!err) {
15107			printk(KERN_INFO
15108			       "hda_codec: Cannot set up configuration "
15109			       "from BIOS.  Using base mode...\n");
15110			board_config = ALC861VD_3ST;
15111		}
15112	}
15113
15114	err = snd_hda_attach_beep_device(codec, 0x23);
15115	if (err < 0) {
15116		alc_free(codec);
15117		return err;
15118	}
15119
15120	if (board_config != ALC861VD_AUTO)
15121		setup_preset(spec, &alc861vd_presets[board_config]);
15122
15123	if (codec->vendor_id == 0x10ec0660) {
15124		/* always turn on EAPD */
15125		add_verb(spec, alc660vd_eapd_verbs);
15126	}
15127
15128	spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
15129	spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
15130
15131	spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
15132	spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
15133
15134	spec->adc_nids = alc861vd_adc_nids;
15135	spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
15136	spec->capsrc_nids = alc861vd_capsrc_nids;
15137
15138	set_capture_mixer(spec);
15139	set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
15140
15141	spec->vmaster_nid = 0x02;
15142
15143	codec->patch_ops = alc_patch_ops;
15144
15145	if (board_config == ALC861VD_AUTO)
15146		spec->init_hook = alc861vd_auto_init;
15147#ifdef CONFIG_SND_HDA_POWER_SAVE
15148	if (!spec->loopback.amplist)
15149		spec->loopback.amplist = alc861vd_loopbacks;
15150#endif
15151	codec->proc_widget_hook = print_realtek_coef;
15152
15153	return 0;
15154}
15155
15156/*
15157 * ALC662 support
15158 *
15159 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
15160 * configuration.  Each pin widget can choose any input DACs and a mixer.
15161 * Each ADC is connected from a mixer of all inputs.  This makes possible
15162 * 6-channel independent captures.
15163 *
15164 * In addition, an independent DAC for the multi-playback (not used in this
15165 * driver yet).
15166 */
15167#define ALC662_DIGOUT_NID	0x06
15168#define ALC662_DIGIN_NID	0x0a
15169
15170static hda_nid_t alc662_dac_nids[4] = {
15171	/* front, rear, clfe, rear_surr */
15172	0x02, 0x03, 0x04
15173};
15174
15175static hda_nid_t alc272_dac_nids[2] = {
15176	0x02, 0x03
15177};
15178
15179static hda_nid_t alc662_adc_nids[1] = {
15180	/* ADC1-2 */
15181	0x09,
15182};
15183
15184static hda_nid_t alc272_adc_nids[1] = {
15185	/* ADC1-2 */
15186	0x08,
15187};
15188
15189static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
15190static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
15191
15192
15193/* input MUX */
15194/* FIXME: should be a matrix-type input source selection */
15195static struct hda_input_mux alc662_capture_source = {
15196	.num_items = 4,
15197	.items = {
15198		{ "Mic", 0x0 },
15199		{ "Front Mic", 0x1 },
15200		{ "Line", 0x2 },
15201		{ "CD", 0x4 },
15202	},
15203};
15204
15205static struct hda_input_mux alc662_lenovo_101e_capture_source = {
15206	.num_items = 2,
15207	.items = {
15208		{ "Mic", 0x1 },
15209		{ "Line", 0x2 },
15210	},
15211};
15212
15213static struct hda_input_mux alc662_eeepc_capture_source = {
15214	.num_items = 2,
15215	.items = {
15216		{ "i-Mic", 0x1 },
15217		{ "e-Mic", 0x0 },
15218	},
15219};
15220
15221static struct hda_input_mux alc663_capture_source = {
15222	.num_items = 3,
15223	.items = {
15224		{ "Mic", 0x0 },
15225		{ "Front Mic", 0x1 },
15226		{ "Line", 0x2 },
15227	},
15228};
15229
15230static struct hda_input_mux alc663_m51va_capture_source = {
15231	.num_items = 2,
15232	.items = {
15233		{ "Ext-Mic", 0x0 },
15234		{ "D-Mic", 0x9 },
15235	},
15236};
15237
15238#if 1 /* set to 0 for testing other input sources below */
15239static struct hda_input_mux alc272_nc10_capture_source = {
15240	.num_items = 2,
15241	.items = {
15242		{ "Autoselect Mic", 0x0 },
15243		{ "Internal Mic", 0x1 },
15244	},
15245};
15246#else
15247static struct hda_input_mux alc272_nc10_capture_source = {
15248	.num_items = 16,
15249	.items = {
15250		{ "Autoselect Mic", 0x0 },
15251		{ "Internal Mic", 0x1 },
15252		{ "In-0x02", 0x2 },
15253		{ "In-0x03", 0x3 },
15254		{ "In-0x04", 0x4 },
15255		{ "In-0x05", 0x5 },
15256		{ "In-0x06", 0x6 },
15257		{ "In-0x07", 0x7 },
15258		{ "In-0x08", 0x8 },
15259		{ "In-0x09", 0x9 },
15260		{ "In-0x0a", 0x0a },
15261		{ "In-0x0b", 0x0b },
15262		{ "In-0x0c", 0x0c },
15263		{ "In-0x0d", 0x0d },
15264		{ "In-0x0e", 0x0e },
15265		{ "In-0x0f", 0x0f },
15266	},
15267};
15268#endif
15269
15270/*
15271 * 2ch mode
15272 */
15273static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
15274	{ 2, NULL }
15275};
15276
15277/*
15278 * 2ch mode
15279 */
15280static struct hda_verb alc662_3ST_ch2_init[] = {
15281	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
15282	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15283	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
15284	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15285	{ } /* end */
15286};
15287
15288/*
15289 * 6ch mode
15290 */
15291static struct hda_verb alc662_3ST_ch6_init[] = {
15292	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15293	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15294	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
15295	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15296	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15297	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
15298	{ } /* end */
15299};
15300
15301static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
15302	{ 2, alc662_3ST_ch2_init },
15303	{ 6, alc662_3ST_ch6_init },
15304};
15305
15306/*
15307 * 2ch mode
15308 */
15309static struct hda_verb alc662_sixstack_ch6_init[] = {
15310	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15311	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15312	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15313	{ } /* end */
15314};
15315
15316/*
15317 * 6ch mode
15318 */
15319static struct hda_verb alc662_sixstack_ch8_init[] = {
15320	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15321	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15322	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15323	{ } /* end */
15324};
15325
15326static struct hda_channel_mode alc662_5stack_modes[2] = {
15327	{ 2, alc662_sixstack_ch6_init },
15328	{ 6, alc662_sixstack_ch8_init },
15329};
15330
15331/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15332 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15333 */
15334
15335static struct snd_kcontrol_new alc662_base_mixer[] = {
15336	/* output mixer control */
15337	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
15338	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15339	HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
15340	HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15341	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15342	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15343	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15344	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15345	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15346
15347	/*Input mixer control */
15348	HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
15349	HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
15350	HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
15351	HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
15352	HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
15353	HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
15354	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
15355	HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
15356	{ } /* end */
15357};
15358
15359static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
15360	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15361	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15362	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15363	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15364	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15365	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15366	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15367	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15368	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15369	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15370	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15371	{ } /* end */
15372};
15373
15374static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
15375	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15376	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15377	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15378	HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15379	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15380	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15381	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15382	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15383	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15384	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15385	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15386	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15387	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15388	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15389	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15390	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15391	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15392	{ } /* end */
15393};
15394
15395static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
15396	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15397	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
15398	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15399	HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
15400	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15401	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15402	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15403	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15404	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15405	{ } /* end */
15406};
15407
15408static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
15409	HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15410	ALC262_HIPPO_MASTER_SWITCH,
15411
15412	HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
15413	HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15414	HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15415
15416	HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15417	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15418	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15419	{ } /* end */
15420};
15421
15422static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
15423	ALC262_HIPPO_MASTER_SWITCH,
15424	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15425	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15426	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15427	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15428	HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
15429	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15430	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15431	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15432	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15433	{ } /* end */
15434};
15435
15436static struct hda_bind_ctls alc663_asus_bind_master_vol = {
15437	.ops = &snd_hda_bind_vol,
15438	.values = {
15439		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15440		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
15441		0
15442	},
15443};
15444
15445static struct hda_bind_ctls alc663_asus_one_bind_switch = {
15446	.ops = &snd_hda_bind_sw,
15447	.values = {
15448		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15449		HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15450		0
15451	},
15452};
15453
15454static struct snd_kcontrol_new alc663_m51va_mixer[] = {
15455	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15456	HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
15457	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15458	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15459	{ } /* end */
15460};
15461
15462static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
15463	.ops = &snd_hda_bind_sw,
15464	.values = {
15465		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15466		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15467		HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15468		0
15469	},
15470};
15471
15472static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
15473	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15474	HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
15475	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15476	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15477	HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15478	HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15479
15480	{ } /* end */
15481};
15482
15483static struct hda_bind_ctls alc663_asus_four_bind_switch = {
15484	.ops = &snd_hda_bind_sw,
15485	.values = {
15486		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15487		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15488		HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15489		0
15490	},
15491};
15492
15493static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
15494	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15495	HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
15496	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15497	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15498	HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15499	HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15500	{ } /* end */
15501};
15502
15503static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
15504	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15505	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15506	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15507	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15508	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15509	HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15510	HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15511	{ } /* end */
15512};
15513
15514static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
15515	.ops = &snd_hda_bind_vol,
15516	.values = {
15517		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15518		HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
15519		0
15520	},
15521};
15522
15523static struct hda_bind_ctls alc663_asus_two_bind_switch = {
15524	.ops = &snd_hda_bind_sw,
15525	.values = {
15526		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15527		HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
15528		0
15529	},
15530};
15531
15532static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
15533	HDA_BIND_VOL("Master Playback Volume",
15534				&alc663_asus_two_bind_master_vol),
15535	HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15536	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15537	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15538	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15539	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15540	{ } /* end */
15541};
15542
15543static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
15544	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15545	HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15546	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15547	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15548	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15549	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15550	{ } /* end */
15551};
15552
15553static struct snd_kcontrol_new alc663_g71v_mixer[] = {
15554	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15555	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15556	HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15557	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15558	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15559
15560	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15561	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15562	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15563	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15564	{ } /* end */
15565};
15566
15567static struct snd_kcontrol_new alc663_g50v_mixer[] = {
15568	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15569	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15570	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15571
15572	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15573	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15574	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15575	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15576	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15577	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15578	{ } /* end */
15579};
15580
15581static struct snd_kcontrol_new alc662_chmode_mixer[] = {
15582	{
15583		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15584		.name = "Channel Mode",
15585		.info = alc_ch_mode_info,
15586		.get = alc_ch_mode_get,
15587		.put = alc_ch_mode_put,
15588	},
15589	{ } /* end */
15590};
15591
15592static struct hda_verb alc662_init_verbs[] = {
15593	/* ADC: mute amp left and right */
15594	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15595	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15596	/* Front mixer: unmute input/output amp left and right (volume = 0) */
15597
15598	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15599	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15600	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15601	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15602	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15603
15604	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15605	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15606	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15607	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15608	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15609	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15610
15611	/* Front Pin: output 0 (0x0c) */
15612	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15613	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15614
15615	/* Rear Pin: output 1 (0x0d) */
15616	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15617	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15618
15619	/* CLFE Pin: output 2 (0x0e) */
15620	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15621	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15622
15623	/* Mic (rear) pin: input vref at 80% */
15624	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15625	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15626	/* Front Mic pin: input vref at 80% */
15627	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15628	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15629	/* Line In pin: input */
15630	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15631	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15632	/* Line-2 In: Headphone output (output 0 - 0x0c) */
15633	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15634	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15635	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15636	/* CD pin widget for input */
15637	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15638
15639	/* FIXME: use matrix-type input source selection */
15640	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15641	/* Input mixer */
15642	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15643	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15644
15645	/* always trun on EAPD */
15646	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15647	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15648
15649	{ }
15650};
15651
15652static struct hda_verb alc662_sue_init_verbs[] = {
15653	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15654	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15655	{}
15656};
15657
15658static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
15659	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15660	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15661	{}
15662};
15663
15664/* Set Unsolicited Event*/
15665static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
15666	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15667	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15668	{}
15669};
15670
15671/*
15672 * generic initialization of ADC, input mixers and output mixers
15673 */
15674static struct hda_verb alc662_auto_init_verbs[] = {
15675	/*
15676	 * Unmute ADC and set the default input to mic-in
15677	 */
15678	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15679	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15680
15681	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
15682	 * mixer widget
15683	 * Note: PASD motherboards uses the Line In 2 as the input for front
15684	 * panel mic (mic 2)
15685	 */
15686	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
15687	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15688	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15689	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15690	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15691	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15692
15693	/*
15694	 * Set up output mixers (0x0c - 0x0f)
15695	 */
15696	/* set vol=0 to output mixers */
15697	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15698	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15699	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15700
15701	/* set up input amps for analog loopback */
15702	/* Amp Indices: DAC = 0, mixer = 1 */
15703	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15704	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15705	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15706	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15707	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15708	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15709
15710
15711	/* FIXME: use matrix-type input source selection */
15712	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15713	/* Input mixer */
15714	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15715	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15716	{ }
15717};
15718
15719/* additional verbs for ALC663 */
15720static struct hda_verb alc663_auto_init_verbs[] = {
15721	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15722	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15723	{ }
15724};
15725
15726static struct hda_verb alc663_m51va_init_verbs[] = {
15727	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15728	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15729	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15730	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15731	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
15732	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15733	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15734	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15735	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15736	{}
15737};
15738
15739static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15740	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15741	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15742	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
15743	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15744	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15745	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15746	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15747	{}
15748};
15749
15750static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15751	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15752	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15753	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15754	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
15755	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15756	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15757	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15758	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15759	{}
15760};
15761
15762static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15763	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15764	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15765	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
15766	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15767	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15768	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15769	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15770	{}
15771};
15772
15773static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15774	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15775	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15776	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15777	{0x21, AC_VERB_SET_CONNECT_SEL, 0x0},	/* Headphone */
15778	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15779	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15780	{0x15, AC_VERB_SET_CONNECT_SEL, 0x0},	/* Headphone */
15781	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15782	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15783	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15784	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15785	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15786	{}
15787};
15788
15789static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15790	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15791	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15792	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15793	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
15794	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15795	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15796	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
15797	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15798	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15799	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15800	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15801	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15802	{}
15803};
15804
15805static struct hda_verb alc663_g71v_init_verbs[] = {
15806	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15807	/* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15808	/* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15809
15810	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15811	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15812	{0x21, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
15813
15814	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15815	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15816	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15817	{}
15818};
15819
15820static struct hda_verb alc663_g50v_init_verbs[] = {
15821	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15822	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15823	{0x21, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
15824
15825	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15826	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15827	{}
15828};
15829
15830static struct hda_verb alc662_ecs_init_verbs[] = {
15831	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15832	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15833	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15834	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15835	{}
15836};
15837
15838static struct hda_verb alc272_dell_zm1_init_verbs[] = {
15839	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15840	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15841	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15842	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15843	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15844	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15845	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
15846	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15847	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15848	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15849	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15850	{}
15851};
15852
15853static struct hda_verb alc272_dell_init_verbs[] = {
15854	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15855	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15856	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15857	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15858	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15859	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15860	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
15861	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15862	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15863	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15864	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15865	{}
15866};
15867
15868static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15869	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15870	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15871	{ } /* end */
15872};
15873
15874static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
15875	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
15876	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
15877	{ } /* end */
15878};
15879
15880static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15881{
15882	unsigned int present;
15883	unsigned char bits;
15884
15885	present = snd_hda_codec_read(codec, 0x14, 0,
15886				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15887	bits = present ? HDA_AMP_MUTE : 0;
15888	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15889				 HDA_AMP_MUTE, bits);
15890}
15891
15892static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15893{
15894	unsigned int present;
15895	unsigned char bits;
15896
15897 	present = snd_hda_codec_read(codec, 0x1b, 0,
15898				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15899	bits = present ? HDA_AMP_MUTE : 0;
15900	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15901				 HDA_AMP_MUTE, bits);
15902	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15903				 HDA_AMP_MUTE, bits);
15904}
15905
15906static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15907					   unsigned int res)
15908{
15909	if ((res >> 26) == ALC880_HP_EVENT)
15910		alc662_lenovo_101e_all_automute(codec);
15911	if ((res >> 26) == ALC880_FRONT_EVENT)
15912		alc662_lenovo_101e_ispeaker_automute(codec);
15913}
15914
15915static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15916{
15917	unsigned int present;
15918
15919	present = snd_hda_codec_read(codec, 0x18, 0,
15920				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15921	snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15922			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15923	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15924			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15925	snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15926			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15927	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15928			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15929}
15930
15931/* unsolicited event for HP jack sensing */
15932static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15933				     unsigned int res)
15934{
15935	if ((res >> 26) == ALC880_MIC_EVENT)
15936		alc662_eeepc_mic_automute(codec);
15937	else
15938		alc262_hippo_unsol_event(codec, res);
15939}
15940
15941static void alc662_eeepc_inithook(struct hda_codec *codec)
15942{
15943	alc262_hippo1_init_hook(codec);
15944	alc662_eeepc_mic_automute(codec);
15945}
15946
15947static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
15948{
15949	struct alc_spec *spec = codec->spec;
15950
15951	spec->autocfg.hp_pins[0] = 0x14;
15952	spec->autocfg.speaker_pins[0] = 0x1b;
15953	alc262_hippo_master_update(codec);
15954}
15955
15956static void alc663_m51va_speaker_automute(struct hda_codec *codec)
15957{
15958	unsigned int present;
15959	unsigned char bits;
15960
15961	present = snd_hda_codec_read(codec, 0x21, 0,
15962			AC_VERB_GET_PIN_SENSE, 0)
15963			& AC_PINSENSE_PRESENCE;
15964	bits = present ? HDA_AMP_MUTE : 0;
15965	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15966				AMP_IN_MUTE(0), bits);
15967	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15968				AMP_IN_MUTE(0), bits);
15969}
15970
15971static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
15972{
15973	unsigned int present;
15974	unsigned char bits;
15975
15976	present = snd_hda_codec_read(codec, 0x21, 0,
15977			AC_VERB_GET_PIN_SENSE, 0)
15978			& AC_PINSENSE_PRESENCE;
15979	bits = present ? HDA_AMP_MUTE : 0;
15980	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15981				AMP_IN_MUTE(0), bits);
15982	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15983				AMP_IN_MUTE(0), bits);
15984	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15985				AMP_IN_MUTE(0), bits);
15986	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15987				AMP_IN_MUTE(0), bits);
15988}
15989
15990static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
15991{
15992	unsigned int present;
15993	unsigned char bits;
15994
15995	present = snd_hda_codec_read(codec, 0x15, 0,
15996			AC_VERB_GET_PIN_SENSE, 0)
15997			& AC_PINSENSE_PRESENCE;
15998	bits = present ? HDA_AMP_MUTE : 0;
15999	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16000				AMP_IN_MUTE(0), bits);
16001	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16002				AMP_IN_MUTE(0), bits);
16003	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16004				AMP_IN_MUTE(0), bits);
16005	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16006				AMP_IN_MUTE(0), bits);
16007}
16008
16009static void alc662_f5z_speaker_automute(struct hda_codec *codec)
16010{
16011	unsigned int present;
16012	unsigned char bits;
16013
16014	present = snd_hda_codec_read(codec, 0x1b, 0,
16015			AC_VERB_GET_PIN_SENSE, 0)
16016			& AC_PINSENSE_PRESENCE;
16017	bits = present ? 0 : PIN_OUT;
16018	snd_hda_codec_write(codec, 0x14, 0,
16019			 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
16020}
16021
16022static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
16023{
16024	unsigned int present1, present2;
16025
16026	present1 = snd_hda_codec_read(codec, 0x21, 0,
16027			AC_VERB_GET_PIN_SENSE, 0)
16028			& AC_PINSENSE_PRESENCE;
16029	present2 = snd_hda_codec_read(codec, 0x15, 0,
16030			AC_VERB_GET_PIN_SENSE, 0)
16031			& AC_PINSENSE_PRESENCE;
16032
16033	if (present1 || present2) {
16034		snd_hda_codec_write_cache(codec, 0x14, 0,
16035			AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
16036	} else {
16037		snd_hda_codec_write_cache(codec, 0x14, 0,
16038			AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
16039	}
16040}
16041
16042static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
16043{
16044	unsigned int present1, present2;
16045
16046	present1 = snd_hda_codec_read(codec, 0x1b, 0,
16047				AC_VERB_GET_PIN_SENSE, 0)
16048				& AC_PINSENSE_PRESENCE;
16049	present2 = snd_hda_codec_read(codec, 0x15, 0,
16050				AC_VERB_GET_PIN_SENSE, 0)
16051				& AC_PINSENSE_PRESENCE;
16052
16053	if (present1 || present2) {
16054		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16055				AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16056		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16057				AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16058	} else {
16059		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16060				AMP_IN_MUTE(0), 0);
16061		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16062				AMP_IN_MUTE(0), 0);
16063	}
16064}
16065
16066static void alc663_m51va_mic_automute(struct hda_codec *codec)
16067{
16068	unsigned int present;
16069
16070	present = snd_hda_codec_read(codec, 0x18, 0,
16071			AC_VERB_GET_PIN_SENSE, 0)
16072			& AC_PINSENSE_PRESENCE;
16073	snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16074			0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16075	snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16076			0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16077	snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16078			0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
16079	snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16080			0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
16081}
16082
16083static void alc663_m51va_unsol_event(struct hda_codec *codec,
16084					   unsigned int res)
16085{
16086	switch (res >> 26) {
16087	case ALC880_HP_EVENT:
16088		alc663_m51va_speaker_automute(codec);
16089		break;
16090	case ALC880_MIC_EVENT:
16091		alc663_m51va_mic_automute(codec);
16092		break;
16093	}
16094}
16095
16096static void alc663_m51va_inithook(struct hda_codec *codec)
16097{
16098	alc663_m51va_speaker_automute(codec);
16099	alc663_m51va_mic_automute(codec);
16100}
16101
16102/* ***************** Mode1 ******************************/
16103static void alc663_mode1_unsol_event(struct hda_codec *codec,
16104					   unsigned int res)
16105{
16106	switch (res >> 26) {
16107	case ALC880_HP_EVENT:
16108		alc663_m51va_speaker_automute(codec);
16109		break;
16110	case ALC880_MIC_EVENT:
16111		alc662_eeepc_mic_automute(codec);
16112		break;
16113	}
16114}
16115
16116static void alc663_mode1_inithook(struct hda_codec *codec)
16117{
16118	alc663_m51va_speaker_automute(codec);
16119	alc662_eeepc_mic_automute(codec);
16120}
16121/* ***************** Mode2 ******************************/
16122static void alc662_mode2_unsol_event(struct hda_codec *codec,
16123					   unsigned int res)
16124{
16125	switch (res >> 26) {
16126	case ALC880_HP_EVENT:
16127		alc662_f5z_speaker_automute(codec);
16128		break;
16129	case ALC880_MIC_EVENT:
16130		alc662_eeepc_mic_automute(codec);
16131		break;
16132	}
16133}
16134
16135static void alc662_mode2_inithook(struct hda_codec *codec)
16136{
16137	alc662_f5z_speaker_automute(codec);
16138	alc662_eeepc_mic_automute(codec);
16139}
16140/* ***************** Mode3 ******************************/
16141static void alc663_mode3_unsol_event(struct hda_codec *codec,
16142					   unsigned int res)
16143{
16144	switch (res >> 26) {
16145	case ALC880_HP_EVENT:
16146		alc663_two_hp_m1_speaker_automute(codec);
16147		break;
16148	case ALC880_MIC_EVENT:
16149		alc662_eeepc_mic_automute(codec);
16150		break;
16151	}
16152}
16153
16154static void alc663_mode3_inithook(struct hda_codec *codec)
16155{
16156	alc663_two_hp_m1_speaker_automute(codec);
16157	alc662_eeepc_mic_automute(codec);
16158}
16159/* ***************** Mode4 ******************************/
16160static void alc663_mode4_unsol_event(struct hda_codec *codec,
16161					   unsigned int res)
16162{
16163	switch (res >> 26) {
16164	case ALC880_HP_EVENT:
16165		alc663_21jd_two_speaker_automute(codec);
16166		break;
16167	case ALC880_MIC_EVENT:
16168		alc662_eeepc_mic_automute(codec);
16169		break;
16170	}
16171}
16172
16173static void alc663_mode4_inithook(struct hda_codec *codec)
16174{
16175	alc663_21jd_two_speaker_automute(codec);
16176	alc662_eeepc_mic_automute(codec);
16177}
16178/* ***************** Mode5 ******************************/
16179static void alc663_mode5_unsol_event(struct hda_codec *codec,
16180					   unsigned int res)
16181{
16182	switch (res >> 26) {
16183	case ALC880_HP_EVENT:
16184		alc663_15jd_two_speaker_automute(codec);
16185		break;
16186	case ALC880_MIC_EVENT:
16187		alc662_eeepc_mic_automute(codec);
16188		break;
16189	}
16190}
16191
16192static void alc663_mode5_inithook(struct hda_codec *codec)
16193{
16194	alc663_15jd_two_speaker_automute(codec);
16195	alc662_eeepc_mic_automute(codec);
16196}
16197/* ***************** Mode6 ******************************/
16198static void alc663_mode6_unsol_event(struct hda_codec *codec,
16199					   unsigned int res)
16200{
16201	switch (res >> 26) {
16202	case ALC880_HP_EVENT:
16203		alc663_two_hp_m2_speaker_automute(codec);
16204		break;
16205	case ALC880_MIC_EVENT:
16206		alc662_eeepc_mic_automute(codec);
16207		break;
16208	}
16209}
16210
16211static void alc663_mode6_inithook(struct hda_codec *codec)
16212{
16213	alc663_two_hp_m2_speaker_automute(codec);
16214	alc662_eeepc_mic_automute(codec);
16215}
16216
16217static void alc663_g71v_hp_automute(struct hda_codec *codec)
16218{
16219	unsigned int present;
16220	unsigned char bits;
16221
16222	present = snd_hda_codec_read(codec, 0x21, 0,
16223				     AC_VERB_GET_PIN_SENSE, 0)
16224		& AC_PINSENSE_PRESENCE;
16225	bits = present ? HDA_AMP_MUTE : 0;
16226	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16227				 HDA_AMP_MUTE, bits);
16228	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16229				 HDA_AMP_MUTE, bits);
16230}
16231
16232static void alc663_g71v_front_automute(struct hda_codec *codec)
16233{
16234	unsigned int present;
16235	unsigned char bits;
16236
16237	present = snd_hda_codec_read(codec, 0x15, 0,
16238				     AC_VERB_GET_PIN_SENSE, 0)
16239		& AC_PINSENSE_PRESENCE;
16240	bits = present ? HDA_AMP_MUTE : 0;
16241	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16242				 HDA_AMP_MUTE, bits);
16243}
16244
16245static void alc663_g71v_unsol_event(struct hda_codec *codec,
16246					   unsigned int res)
16247{
16248	switch (res >> 26) {
16249	case ALC880_HP_EVENT:
16250		alc663_g71v_hp_automute(codec);
16251		break;
16252	case ALC880_FRONT_EVENT:
16253		alc663_g71v_front_automute(codec);
16254		break;
16255	case ALC880_MIC_EVENT:
16256		alc662_eeepc_mic_automute(codec);
16257		break;
16258	}
16259}
16260
16261static void alc663_g71v_inithook(struct hda_codec *codec)
16262{
16263	alc663_g71v_front_automute(codec);
16264	alc663_g71v_hp_automute(codec);
16265	alc662_eeepc_mic_automute(codec);
16266}
16267
16268static void alc663_g50v_unsol_event(struct hda_codec *codec,
16269					   unsigned int res)
16270{
16271	switch (res >> 26) {
16272	case ALC880_HP_EVENT:
16273		alc663_m51va_speaker_automute(codec);
16274		break;
16275	case ALC880_MIC_EVENT:
16276		alc662_eeepc_mic_automute(codec);
16277		break;
16278	}
16279}
16280
16281static void alc663_g50v_inithook(struct hda_codec *codec)
16282{
16283	alc663_m51va_speaker_automute(codec);
16284	alc662_eeepc_mic_automute(codec);
16285}
16286
16287static struct snd_kcontrol_new alc662_ecs_mixer[] = {
16288	HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16289	ALC262_HIPPO_MASTER_SWITCH,
16290
16291	HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
16292	HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
16293	HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
16294
16295	HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16296	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16297	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16298	{ } /* end */
16299};
16300
16301static struct snd_kcontrol_new alc272_nc10_mixer[] = {
16302	/* Master Playback automatically created from Speaker and Headphone */
16303	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16304	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16305	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16306	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16307
16308	HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16309	HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16310	HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
16311
16312	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16313	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16314	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
16315	{ } /* end */
16316};
16317
16318#ifdef CONFIG_SND_HDA_POWER_SAVE
16319#define alc662_loopbacks	alc880_loopbacks
16320#endif
16321
16322
16323/* pcm configuration: identical with ALC880 */
16324#define alc662_pcm_analog_playback	alc880_pcm_analog_playback
16325#define alc662_pcm_analog_capture	alc880_pcm_analog_capture
16326#define alc662_pcm_digital_playback	alc880_pcm_digital_playback
16327#define alc662_pcm_digital_capture	alc880_pcm_digital_capture
16328
16329/*
16330 * configuration and preset
16331 */
16332static const char *alc662_models[ALC662_MODEL_LAST] = {
16333	[ALC662_3ST_2ch_DIG]	= "3stack-dig",
16334	[ALC662_3ST_6ch_DIG]	= "3stack-6ch-dig",
16335	[ALC662_3ST_6ch]	= "3stack-6ch",
16336	[ALC662_5ST_DIG]	= "6stack-dig",
16337	[ALC662_LENOVO_101E]	= "lenovo-101e",
16338	[ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
16339	[ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
16340	[ALC662_ECS] = "ecs",
16341	[ALC663_ASUS_M51VA] = "m51va",
16342	[ALC663_ASUS_G71V] = "g71v",
16343	[ALC663_ASUS_H13] = "h13",
16344	[ALC663_ASUS_G50V] = "g50v",
16345	[ALC663_ASUS_MODE1] = "asus-mode1",
16346	[ALC662_ASUS_MODE2] = "asus-mode2",
16347	[ALC663_ASUS_MODE3] = "asus-mode3",
16348	[ALC663_ASUS_MODE4] = "asus-mode4",
16349	[ALC663_ASUS_MODE5] = "asus-mode5",
16350	[ALC663_ASUS_MODE6] = "asus-mode6",
16351	[ALC272_DELL]		= "dell",
16352	[ALC272_DELL_ZM1]	= "dell-zm1",
16353	[ALC272_SAMSUNG_NC10]	= "samsung-nc10",
16354	[ALC662_AUTO]		= "auto",
16355};
16356
16357static struct snd_pci_quirk alc662_cfg_tbl[] = {
16358	SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
16359	SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
16360	SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
16361	SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
16362	SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
16363	SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
16364	SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
16365	SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
16366	SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
16367	SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
16368	SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
16369	SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
16370	SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
16371	SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
16372	SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
16373	SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
16374	SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
16375	SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
16376	SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
16377	SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
16378	SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
16379	SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
16380	SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
16381	SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
16382	SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
16383	SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
16384	/*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
16385	SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
16386	SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
16387	SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
16388	SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
16389	SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
16390	SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
16391	SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
16392	SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
16393	SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
16394	SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
16395	SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
16396	SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
16397	SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
16398	SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
16399	/*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
16400	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
16401	SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
16402	SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
16403	SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
16404	SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
16405	SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
16406	SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
16407	SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
16408	SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
16409	SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16410		      ALC662_3ST_6ch_DIG),
16411	SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
16412	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16413		      ALC662_3ST_6ch_DIG),
16414	SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
16415	SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
16416	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
16417	SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
16418					ALC662_3ST_6ch_DIG),
16419	SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
16420			   ALC663_ASUS_H13),
16421	{}
16422};
16423
16424static struct alc_config_preset alc662_presets[] = {
16425	[ALC662_3ST_2ch_DIG] = {
16426		.mixers = { alc662_3ST_2ch_mixer },
16427		.init_verbs = { alc662_init_verbs },
16428		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16429		.dac_nids = alc662_dac_nids,
16430		.dig_out_nid = ALC662_DIGOUT_NID,
16431		.dig_in_nid = ALC662_DIGIN_NID,
16432		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16433		.channel_mode = alc662_3ST_2ch_modes,
16434		.input_mux = &alc662_capture_source,
16435	},
16436	[ALC662_3ST_6ch_DIG] = {
16437		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16438		.init_verbs = { alc662_init_verbs },
16439		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16440		.dac_nids = alc662_dac_nids,
16441		.dig_out_nid = ALC662_DIGOUT_NID,
16442		.dig_in_nid = ALC662_DIGIN_NID,
16443		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16444		.channel_mode = alc662_3ST_6ch_modes,
16445		.need_dac_fix = 1,
16446		.input_mux = &alc662_capture_source,
16447	},
16448	[ALC662_3ST_6ch] = {
16449		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16450		.init_verbs = { alc662_init_verbs },
16451		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16452		.dac_nids = alc662_dac_nids,
16453		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16454		.channel_mode = alc662_3ST_6ch_modes,
16455		.need_dac_fix = 1,
16456		.input_mux = &alc662_capture_source,
16457	},
16458	[ALC662_5ST_DIG] = {
16459		.mixers = { alc662_base_mixer, alc662_chmode_mixer },
16460		.init_verbs = { alc662_init_verbs },
16461		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16462		.dac_nids = alc662_dac_nids,
16463		.dig_out_nid = ALC662_DIGOUT_NID,
16464		.dig_in_nid = ALC662_DIGIN_NID,
16465		.num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
16466		.channel_mode = alc662_5stack_modes,
16467		.input_mux = &alc662_capture_source,
16468	},
16469	[ALC662_LENOVO_101E] = {
16470		.mixers = { alc662_lenovo_101e_mixer },
16471		.init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
16472		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16473		.dac_nids = alc662_dac_nids,
16474		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16475		.channel_mode = alc662_3ST_2ch_modes,
16476		.input_mux = &alc662_lenovo_101e_capture_source,
16477		.unsol_event = alc662_lenovo_101e_unsol_event,
16478		.init_hook = alc662_lenovo_101e_all_automute,
16479	},
16480	[ALC662_ASUS_EEEPC_P701] = {
16481		.mixers = { alc662_eeepc_p701_mixer },
16482		.init_verbs = { alc662_init_verbs,
16483				alc662_eeepc_sue_init_verbs },
16484		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16485		.dac_nids = alc662_dac_nids,
16486		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16487		.channel_mode = alc662_3ST_2ch_modes,
16488		.input_mux = &alc662_eeepc_capture_source,
16489		.unsol_event = alc662_eeepc_unsol_event,
16490		.init_hook = alc662_eeepc_inithook,
16491	},
16492	[ALC662_ASUS_EEEPC_EP20] = {
16493		.mixers = { alc662_eeepc_ep20_mixer,
16494			    alc662_chmode_mixer },
16495		.init_verbs = { alc662_init_verbs,
16496				alc662_eeepc_ep20_sue_init_verbs },
16497		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16498		.dac_nids = alc662_dac_nids,
16499		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16500		.channel_mode = alc662_3ST_6ch_modes,
16501		.input_mux = &alc662_lenovo_101e_capture_source,
16502		.unsol_event = alc662_eeepc_unsol_event,
16503		.init_hook = alc662_eeepc_ep20_inithook,
16504	},
16505	[ALC662_ECS] = {
16506		.mixers = { alc662_ecs_mixer },
16507		.init_verbs = { alc662_init_verbs,
16508				alc662_ecs_init_verbs },
16509		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16510		.dac_nids = alc662_dac_nids,
16511		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16512		.channel_mode = alc662_3ST_2ch_modes,
16513		.input_mux = &alc662_eeepc_capture_source,
16514		.unsol_event = alc662_eeepc_unsol_event,
16515		.init_hook = alc662_eeepc_inithook,
16516	},
16517	[ALC663_ASUS_M51VA] = {
16518		.mixers = { alc663_m51va_mixer },
16519		.init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16520		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16521		.dac_nids = alc662_dac_nids,
16522		.dig_out_nid = ALC662_DIGOUT_NID,
16523		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16524		.channel_mode = alc662_3ST_2ch_modes,
16525		.input_mux = &alc663_m51va_capture_source,
16526		.unsol_event = alc663_m51va_unsol_event,
16527		.init_hook = alc663_m51va_inithook,
16528	},
16529	[ALC663_ASUS_G71V] = {
16530		.mixers = { alc663_g71v_mixer },
16531		.init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
16532		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16533		.dac_nids = alc662_dac_nids,
16534		.dig_out_nid = ALC662_DIGOUT_NID,
16535		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16536		.channel_mode = alc662_3ST_2ch_modes,
16537		.input_mux = &alc662_eeepc_capture_source,
16538		.unsol_event = alc663_g71v_unsol_event,
16539		.init_hook = alc663_g71v_inithook,
16540	},
16541	[ALC663_ASUS_H13] = {
16542		.mixers = { alc663_m51va_mixer },
16543		.init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16544		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16545		.dac_nids = alc662_dac_nids,
16546		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16547		.channel_mode = alc662_3ST_2ch_modes,
16548		.input_mux = &alc663_m51va_capture_source,
16549		.unsol_event = alc663_m51va_unsol_event,
16550		.init_hook = alc663_m51va_inithook,
16551	},
16552	[ALC663_ASUS_G50V] = {
16553		.mixers = { alc663_g50v_mixer },
16554		.init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
16555		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16556		.dac_nids = alc662_dac_nids,
16557		.dig_out_nid = ALC662_DIGOUT_NID,
16558		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16559		.channel_mode = alc662_3ST_6ch_modes,
16560		.input_mux = &alc663_capture_source,
16561		.unsol_event = alc663_g50v_unsol_event,
16562		.init_hook = alc663_g50v_inithook,
16563	},
16564	[ALC663_ASUS_MODE1] = {
16565		.mixers = { alc663_m51va_mixer },
16566		.cap_mixer = alc662_auto_capture_mixer,
16567		.init_verbs = { alc662_init_verbs,
16568				alc663_21jd_amic_init_verbs },
16569		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16570		.hp_nid = 0x03,
16571		.dac_nids = alc662_dac_nids,
16572		.dig_out_nid = ALC662_DIGOUT_NID,
16573		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16574		.channel_mode = alc662_3ST_2ch_modes,
16575		.input_mux = &alc662_eeepc_capture_source,
16576		.unsol_event = alc663_mode1_unsol_event,
16577		.init_hook = alc663_mode1_inithook,
16578	},
16579	[ALC662_ASUS_MODE2] = {
16580		.mixers = { alc662_1bjd_mixer },
16581		.cap_mixer = alc662_auto_capture_mixer,
16582		.init_verbs = { alc662_init_verbs,
16583				alc662_1bjd_amic_init_verbs },
16584		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16585		.dac_nids = alc662_dac_nids,
16586		.dig_out_nid = ALC662_DIGOUT_NID,
16587		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16588		.channel_mode = alc662_3ST_2ch_modes,
16589		.input_mux = &alc662_eeepc_capture_source,
16590		.unsol_event = alc662_mode2_unsol_event,
16591		.init_hook = alc662_mode2_inithook,
16592	},
16593	[ALC663_ASUS_MODE3] = {
16594		.mixers = { alc663_two_hp_m1_mixer },
16595		.cap_mixer = alc662_auto_capture_mixer,
16596		.init_verbs = { alc662_init_verbs,
16597				alc663_two_hp_amic_m1_init_verbs },
16598		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16599		.hp_nid = 0x03,
16600		.dac_nids = alc662_dac_nids,
16601		.dig_out_nid = ALC662_DIGOUT_NID,
16602		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16603		.channel_mode = alc662_3ST_2ch_modes,
16604		.input_mux = &alc662_eeepc_capture_source,
16605		.unsol_event = alc663_mode3_unsol_event,
16606		.init_hook = alc663_mode3_inithook,
16607	},
16608	[ALC663_ASUS_MODE4] = {
16609		.mixers = { alc663_asus_21jd_clfe_mixer },
16610		.cap_mixer = alc662_auto_capture_mixer,
16611		.init_verbs = { alc662_init_verbs,
16612				alc663_21jd_amic_init_verbs},
16613		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16614		.hp_nid = 0x03,
16615		.dac_nids = alc662_dac_nids,
16616		.dig_out_nid = ALC662_DIGOUT_NID,
16617		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16618		.channel_mode = alc662_3ST_2ch_modes,
16619		.input_mux = &alc662_eeepc_capture_source,
16620		.unsol_event = alc663_mode4_unsol_event,
16621		.init_hook = alc663_mode4_inithook,
16622	},
16623	[ALC663_ASUS_MODE5] = {
16624		.mixers = { alc663_asus_15jd_clfe_mixer },
16625		.cap_mixer = alc662_auto_capture_mixer,
16626		.init_verbs = { alc662_init_verbs,
16627				alc663_15jd_amic_init_verbs },
16628		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16629		.hp_nid = 0x03,
16630		.dac_nids = alc662_dac_nids,
16631		.dig_out_nid = ALC662_DIGOUT_NID,
16632		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16633		.channel_mode = alc662_3ST_2ch_modes,
16634		.input_mux = &alc662_eeepc_capture_source,
16635		.unsol_event = alc663_mode5_unsol_event,
16636		.init_hook = alc663_mode5_inithook,
16637	},
16638	[ALC663_ASUS_MODE6] = {
16639		.mixers = { alc663_two_hp_m2_mixer },
16640		.cap_mixer = alc662_auto_capture_mixer,
16641		.init_verbs = { alc662_init_verbs,
16642				alc663_two_hp_amic_m2_init_verbs },
16643		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16644		.hp_nid = 0x03,
16645		.dac_nids = alc662_dac_nids,
16646		.dig_out_nid = ALC662_DIGOUT_NID,
16647		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16648		.channel_mode = alc662_3ST_2ch_modes,
16649		.input_mux = &alc662_eeepc_capture_source,
16650		.unsol_event = alc663_mode6_unsol_event,
16651		.init_hook = alc663_mode6_inithook,
16652	},
16653	[ALC272_DELL] = {
16654		.mixers = { alc663_m51va_mixer },
16655		.cap_mixer = alc272_auto_capture_mixer,
16656		.init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
16657		.num_dacs = ARRAY_SIZE(alc272_dac_nids),
16658		.dac_nids = alc662_dac_nids,
16659		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16660		.adc_nids = alc272_adc_nids,
16661		.num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
16662		.capsrc_nids = alc272_capsrc_nids,
16663		.channel_mode = alc662_3ST_2ch_modes,
16664		.input_mux = &alc663_m51va_capture_source,
16665		.unsol_event = alc663_m51va_unsol_event,
16666		.init_hook = alc663_m51va_inithook,
16667	},
16668	[ALC272_DELL_ZM1] = {
16669		.mixers = { alc663_m51va_mixer },
16670		.cap_mixer = alc662_auto_capture_mixer,
16671		.init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
16672		.num_dacs = ARRAY_SIZE(alc272_dac_nids),
16673		.dac_nids = alc662_dac_nids,
16674		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16675		.adc_nids = alc662_adc_nids,
16676		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
16677		.capsrc_nids = alc662_capsrc_nids,
16678		.channel_mode = alc662_3ST_2ch_modes,
16679		.input_mux = &alc663_m51va_capture_source,
16680		.unsol_event = alc663_m51va_unsol_event,
16681		.init_hook = alc663_m51va_inithook,
16682	},
16683	[ALC272_SAMSUNG_NC10] = {
16684		.mixers = { alc272_nc10_mixer },
16685		.init_verbs = { alc662_init_verbs,
16686				alc663_21jd_amic_init_verbs },
16687		.num_dacs = ARRAY_SIZE(alc272_dac_nids),
16688		.dac_nids = alc272_dac_nids,
16689		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16690		.channel_mode = alc662_3ST_2ch_modes,
16691		.input_mux = &alc272_nc10_capture_source,
16692		.unsol_event = alc663_mode4_unsol_event,
16693		.init_hook = alc663_mode4_inithook,
16694	},
16695};
16696
16697
16698/*
16699 * BIOS auto configuration
16700 */
16701
16702/* add playback controls from the parsed DAC table */
16703static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
16704					     const struct auto_pin_cfg *cfg)
16705{
16706	char name[32];
16707	static const char *chname[4] = {
16708		"Front", "Surround", NULL /*CLFE*/, "Side"
16709	};
16710	hda_nid_t nid;
16711	int i, err;
16712
16713	for (i = 0; i < cfg->line_outs; i++) {
16714		if (!spec->multiout.dac_nids[i])
16715			continue;
16716		nid = alc880_idx_to_dac(i);
16717		if (i == 2) {
16718			/* Center/LFE */
16719			err = add_control(spec, ALC_CTL_WIDGET_VOL,
16720					  "Center Playback Volume",
16721					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
16722							      HDA_OUTPUT));
16723			if (err < 0)
16724				return err;
16725			err = add_control(spec, ALC_CTL_WIDGET_VOL,
16726					  "LFE Playback Volume",
16727					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
16728							      HDA_OUTPUT));
16729			if (err < 0)
16730				return err;
16731			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16732					  "Center Playback Switch",
16733					  HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
16734							      HDA_INPUT));
16735			if (err < 0)
16736				return err;
16737			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16738					  "LFE Playback Switch",
16739					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
16740							      HDA_INPUT));
16741			if (err < 0)
16742				return err;
16743		} else {
16744			sprintf(name, "%s Playback Volume", chname[i]);
16745			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16746					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
16747							      HDA_OUTPUT));
16748			if (err < 0)
16749				return err;
16750			sprintf(name, "%s Playback Switch", chname[i]);
16751			err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16752				HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16753						    3, 0, HDA_INPUT));
16754			if (err < 0)
16755				return err;
16756		}
16757	}
16758	return 0;
16759}
16760
16761/* add playback controls for speaker and HP outputs */
16762static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16763					const char *pfx)
16764{
16765	hda_nid_t nid;
16766	int err;
16767	char name[32];
16768
16769	if (!pin)
16770		return 0;
16771
16772	if (pin == 0x17) {
16773		/* ALC663 has a mono output pin on 0x17 */
16774		sprintf(name, "%s Playback Switch", pfx);
16775		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16776				  HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16777		return err;
16778	}
16779
16780	if (alc880_is_fixed_pin(pin)) {
16781		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16782		/* printk(KERN_DEBUG "DAC nid=%x\n",nid); */
16783		/* specify the DAC as the extra output */
16784		if (!spec->multiout.hp_nid)
16785			spec->multiout.hp_nid = nid;
16786		else
16787			spec->multiout.extra_out_nid[0] = nid;
16788		/* control HP volume/switch on the output mixer amp */
16789		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16790		sprintf(name, "%s Playback Volume", pfx);
16791		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16792				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16793		if (err < 0)
16794			return err;
16795		sprintf(name, "%s Playback Switch", pfx);
16796		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
16797				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
16798		if (err < 0)
16799			return err;
16800	} else if (alc880_is_multi_pin(pin)) {
16801		/* set manual connection */
16802		/* we have only a switch on HP-out PIN */
16803		sprintf(name, "%s Playback Switch", pfx);
16804		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16805				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16806		if (err < 0)
16807			return err;
16808	}
16809	return 0;
16810}
16811
16812/* return the index of the src widget from the connection list of the nid.
16813 * return -1 if not found
16814 */
16815static int alc662_input_pin_idx(struct hda_codec *codec, hda_nid_t nid,
16816				hda_nid_t src)
16817{
16818	hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
16819	int i, conns;
16820
16821	conns = snd_hda_get_connections(codec, nid, conn_list,
16822					ARRAY_SIZE(conn_list));
16823	if (conns < 0)
16824		return -1;
16825	for (i = 0; i < conns; i++)
16826		if (conn_list[i] == src)
16827			return i;
16828	return -1;
16829}
16830
16831static int alc662_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
16832{
16833	unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
16834	return (pincap & AC_PINCAP_IN) != 0;
16835}
16836
16837/* create playback/capture controls for input pins */
16838static int alc662_auto_create_analog_input_ctls(struct hda_codec *codec,
16839						const struct auto_pin_cfg *cfg)
16840{
16841	struct alc_spec *spec = codec->spec;
16842	struct hda_input_mux *imux = &spec->private_imux[0];
16843	int i, err, idx;
16844
16845	for (i = 0; i < AUTO_PIN_LAST; i++) {
16846		if (alc662_is_input_pin(codec, cfg->input_pins[i])) {
16847			idx = alc662_input_pin_idx(codec, 0x0b,
16848						   cfg->input_pins[i]);
16849			if (idx >= 0) {
16850				err = new_analog_input(spec, cfg->input_pins[i],
16851						       auto_pin_cfg_labels[i],
16852						       idx, 0x0b);
16853				if (err < 0)
16854					return err;
16855			}
16856			idx = alc662_input_pin_idx(codec, 0x22,
16857						   cfg->input_pins[i]);
16858			if (idx >= 0) {
16859				imux->items[imux->num_items].label =
16860					auto_pin_cfg_labels[i];
16861				imux->items[imux->num_items].index = idx;
16862				imux->num_items++;
16863			}
16864		}
16865	}
16866	return 0;
16867}
16868
16869static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16870					      hda_nid_t nid, int pin_type,
16871					      int dac_idx)
16872{
16873	alc_set_pin_output(codec, nid, pin_type);
16874	/* need the manual connection? */
16875	if (alc880_is_multi_pin(nid)) {
16876		struct alc_spec *spec = codec->spec;
16877		int idx = alc880_multi_pin_idx(nid);
16878		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16879				    AC_VERB_SET_CONNECT_SEL,
16880				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16881	}
16882}
16883
16884static void alc662_auto_init_multi_out(struct hda_codec *codec)
16885{
16886	struct alc_spec *spec = codec->spec;
16887	int i;
16888
16889	for (i = 0; i <= HDA_SIDE; i++) {
16890		hda_nid_t nid = spec->autocfg.line_out_pins[i];
16891		int pin_type = get_pin_type(spec->autocfg.line_out_type);
16892		if (nid)
16893			alc662_auto_set_output_and_unmute(codec, nid, pin_type,
16894							  i);
16895	}
16896}
16897
16898static void alc662_auto_init_hp_out(struct hda_codec *codec)
16899{
16900	struct alc_spec *spec = codec->spec;
16901	hda_nid_t pin;
16902
16903	pin = spec->autocfg.hp_pins[0];
16904	if (pin) /* connect to front */
16905		/* use dac 0 */
16906		alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
16907	pin = spec->autocfg.speaker_pins[0];
16908	if (pin)
16909		alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
16910}
16911
16912#define ALC662_PIN_CD_NID		ALC880_PIN_CD_NID
16913
16914static void alc662_auto_init_analog_input(struct hda_codec *codec)
16915{
16916	struct alc_spec *spec = codec->spec;
16917	int i;
16918
16919	for (i = 0; i < AUTO_PIN_LAST; i++) {
16920		hda_nid_t nid = spec->autocfg.input_pins[i];
16921		if (alc662_is_input_pin(codec, nid)) {
16922			alc_set_input_pin(codec, nid, i);
16923			if (nid != ALC662_PIN_CD_NID &&
16924			    (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
16925				snd_hda_codec_write(codec, nid, 0,
16926						    AC_VERB_SET_AMP_GAIN_MUTE,
16927						    AMP_OUT_MUTE);
16928		}
16929	}
16930}
16931
16932#define alc662_auto_init_input_src	alc882_auto_init_input_src
16933
16934static int alc662_parse_auto_config(struct hda_codec *codec)
16935{
16936	struct alc_spec *spec = codec->spec;
16937	int err;
16938	static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
16939
16940	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16941					   alc662_ignore);
16942	if (err < 0)
16943		return err;
16944	if (!spec->autocfg.line_outs)
16945		return 0; /* can't find valid BIOS pin config */
16946
16947	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16948	if (err < 0)
16949		return err;
16950	err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
16951	if (err < 0)
16952		return err;
16953	err = alc662_auto_create_extra_out(spec,
16954					   spec->autocfg.speaker_pins[0],
16955					   "Speaker");
16956	if (err < 0)
16957		return err;
16958	err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
16959					   "Headphone");
16960	if (err < 0)
16961		return err;
16962	err = alc662_auto_create_analog_input_ctls(codec, &spec->autocfg);
16963	if (err < 0)
16964		return err;
16965
16966	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16967
16968	if (spec->autocfg.dig_outs)
16969		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
16970
16971	if (spec->kctls.list)
16972		add_mixer(spec, spec->kctls.list);
16973
16974	spec->num_mux_defs = 1;
16975	spec->input_mux = &spec->private_imux[0];
16976
16977	add_verb(spec, alc662_auto_init_verbs);
16978	if (codec->vendor_id == 0x10ec0663)
16979		add_verb(spec, alc663_auto_init_verbs);
16980
16981	err = alc_auto_add_mic_boost(codec);
16982	if (err < 0)
16983		return err;
16984
16985	alc_ssid_check(codec, 0x15, 0x1b, 0x14);
16986
16987	return 1;
16988}
16989
16990/* additional initialization for auto-configuration model */
16991static void alc662_auto_init(struct hda_codec *codec)
16992{
16993	struct alc_spec *spec = codec->spec;
16994	alc662_auto_init_multi_out(codec);
16995	alc662_auto_init_hp_out(codec);
16996	alc662_auto_init_analog_input(codec);
16997	alc662_auto_init_input_src(codec);
16998	if (spec->unsol_event)
16999		alc_inithook(codec);
17000}
17001
17002static int patch_alc662(struct hda_codec *codec)
17003{
17004	struct alc_spec *spec;
17005	int err, board_config;
17006
17007	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17008	if (!spec)
17009		return -ENOMEM;
17010
17011	codec->spec = spec;
17012
17013	alc_fix_pll_init(codec, 0x20, 0x04, 15);
17014
17015	board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
17016						  alc662_models,
17017			  	                  alc662_cfg_tbl);
17018	if (board_config < 0) {
17019		printk(KERN_INFO "hda_codec: Unknown model for %s, "
17020		       "trying auto-probe from BIOS...\n", codec->chip_name);
17021		board_config = ALC662_AUTO;
17022	}
17023
17024	if (board_config == ALC662_AUTO) {
17025		/* automatic parse from the BIOS config */
17026		err = alc662_parse_auto_config(codec);
17027		if (err < 0) {
17028			alc_free(codec);
17029			return err;
17030		} else if (!err) {
17031			printk(KERN_INFO
17032			       "hda_codec: Cannot set up configuration "
17033			       "from BIOS.  Using base mode...\n");
17034			board_config = ALC662_3ST_2ch_DIG;
17035		}
17036	}
17037
17038	err = snd_hda_attach_beep_device(codec, 0x1);
17039	if (err < 0) {
17040		alc_free(codec);
17041		return err;
17042	}
17043
17044	if (board_config != ALC662_AUTO)
17045		setup_preset(spec, &alc662_presets[board_config]);
17046
17047	spec->stream_analog_playback = &alc662_pcm_analog_playback;
17048	spec->stream_analog_capture = &alc662_pcm_analog_capture;
17049
17050	spec->stream_digital_playback = &alc662_pcm_digital_playback;
17051	spec->stream_digital_capture = &alc662_pcm_digital_capture;
17052
17053	spec->adc_nids = alc662_adc_nids;
17054	spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
17055	spec->capsrc_nids = alc662_capsrc_nids;
17056
17057	if (!spec->cap_mixer)
17058		set_capture_mixer(spec);
17059	if (codec->vendor_id == 0x10ec0662)
17060		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17061	else
17062		set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
17063
17064	spec->vmaster_nid = 0x02;
17065
17066	codec->patch_ops = alc_patch_ops;
17067	if (board_config == ALC662_AUTO)
17068		spec->init_hook = alc662_auto_init;
17069#ifdef CONFIG_SND_HDA_POWER_SAVE
17070	if (!spec->loopback.amplist)
17071		spec->loopback.amplist = alc662_loopbacks;
17072#endif
17073	codec->proc_widget_hook = print_realtek_coef;
17074
17075	return 0;
17076}
17077
17078/*
17079 * patch entries
17080 */
17081static struct hda_codec_preset snd_hda_preset_realtek[] = {
17082	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
17083	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
17084	{ .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
17085	{ .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
17086	{ .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
17087	{ .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
17088	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
17089	  .patch = patch_alc861 },
17090	{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
17091	{ .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
17092	{ .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
17093	{ .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
17094	  .patch = patch_alc882 },
17095	{ .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
17096	  .patch = patch_alc662 },
17097	{ .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
17098	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
17099	{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
17100	{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
17101	{ .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
17102	  .patch = patch_alc882 },
17103	{ .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
17104	  .patch = patch_alc882 },
17105	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
17106	{ .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
17107	{ .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
17108	  .patch = patch_alc882 },
17109	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 },
17110	{ .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
17111	{} /* terminator */
17112};
17113
17114MODULE_ALIAS("snd-hda-codec-id:10ec*");
17115
17116MODULE_LICENSE("GPL");
17117MODULE_DESCRIPTION("Realtek HD-audio codec");
17118
17119static struct hda_codec_preset_list realtek_list = {
17120	.preset = snd_hda_preset_realtek,
17121	.owner = THIS_MODULE,
17122};
17123
17124static int __init patch_realtek_init(void)
17125{
17126	return snd_hda_add_codec_preset(&realtek_list);
17127}
17128
17129static void __exit patch_realtek_exit(void)
17130{
17131	snd_hda_delete_codec_preset(&realtek_list);
17132}
17133
17134module_init(patch_realtek_init)
17135module_exit(patch_realtek_exit)
17136