patch_realtek.c revision 3ab909351a3c653a879a35b3342979ac483c0460
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_patch.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#ifdef CONFIG_SND_DEBUG
82	ALC260_TEST,
83#endif
84	ALC260_AUTO,
85	ALC260_MODEL_LAST /* last tag */
86};
87
88/* ALC262 models */
89enum {
90	ALC262_BASIC,
91	ALC262_HIPPO,
92	ALC262_HIPPO_1,
93	ALC262_FUJITSU,
94	ALC262_HP_BPC,
95	ALC262_HP_BPC_D7000_WL,
96	ALC262_HP_BPC_D7000_WF,
97	ALC262_HP_TC_T5735,
98	ALC262_HP_RP5700,
99	ALC262_BENQ_ED8,
100	ALC262_SONY_ASSAMD,
101	ALC262_BENQ_T31,
102	ALC262_ULTRA,
103	ALC262_LENOVO_3000,
104	ALC262_NEC,
105	ALC262_TOSHIBA_S06,
106	ALC262_TOSHIBA_RX1,
107	ALC262_AUTO,
108	ALC262_MODEL_LAST /* last tag */
109};
110
111/* ALC268 models */
112enum {
113	ALC267_QUANTA_IL1,
114	ALC268_3ST,
115	ALC268_TOSHIBA,
116	ALC268_ACER,
117	ALC268_ACER_DMIC,
118	ALC268_ACER_ASPIRE_ONE,
119	ALC268_DELL,
120	ALC268_ZEPTO,
121#ifdef CONFIG_SND_DEBUG
122	ALC268_TEST,
123#endif
124	ALC268_AUTO,
125	ALC268_MODEL_LAST /* last tag */
126};
127
128/* ALC269 models */
129enum {
130	ALC269_BASIC,
131	ALC269_QUANTA_FL1,
132	ALC269_ASUS_EEEPC_P703,
133	ALC269_ASUS_EEEPC_P901,
134	ALC269_FUJITSU,
135	ALC269_LIFEBOOK,
136	ALC269_AUTO,
137	ALC269_MODEL_LAST /* last tag */
138};
139
140/* ALC861 models */
141enum {
142	ALC861_3ST,
143	ALC660_3ST,
144	ALC861_3ST_DIG,
145	ALC861_6ST_DIG,
146	ALC861_UNIWILL_M31,
147	ALC861_TOSHIBA,
148	ALC861_ASUS,
149	ALC861_ASUS_LAPTOP,
150	ALC861_AUTO,
151	ALC861_MODEL_LAST,
152};
153
154/* ALC861-VD models */
155enum {
156	ALC660VD_3ST,
157	ALC660VD_3ST_DIG,
158	ALC660VD_ASUS_V1S,
159	ALC861VD_3ST,
160	ALC861VD_3ST_DIG,
161	ALC861VD_6ST_DIG,
162	ALC861VD_LENOVO,
163	ALC861VD_DALLAS,
164	ALC861VD_HP,
165	ALC861VD_AUTO,
166	ALC861VD_MODEL_LAST,
167};
168
169/* ALC662 models */
170enum {
171	ALC662_3ST_2ch_DIG,
172	ALC662_3ST_6ch_DIG,
173	ALC662_3ST_6ch,
174	ALC662_5ST_DIG,
175	ALC662_LENOVO_101E,
176	ALC662_ASUS_EEEPC_P701,
177	ALC662_ASUS_EEEPC_EP20,
178	ALC663_ASUS_M51VA,
179	ALC663_ASUS_G71V,
180	ALC663_ASUS_H13,
181	ALC663_ASUS_G50V,
182	ALC662_ECS,
183	ALC663_ASUS_MODE1,
184	ALC662_ASUS_MODE2,
185	ALC663_ASUS_MODE3,
186	ALC663_ASUS_MODE4,
187	ALC663_ASUS_MODE5,
188	ALC663_ASUS_MODE6,
189	ALC662_AUTO,
190	ALC662_MODEL_LAST,
191};
192
193/* ALC882 models */
194enum {
195	ALC882_3ST_DIG,
196	ALC882_6ST_DIG,
197	ALC882_ARIMA,
198	ALC882_W2JC,
199	ALC882_TARGA,
200	ALC882_ASUS_A7J,
201	ALC882_ASUS_A7M,
202	ALC885_MACPRO,
203	ALC885_MBP3,
204	ALC885_IMAC24,
205	ALC882_AUTO,
206	ALC882_MODEL_LAST,
207};
208
209/* ALC883 models */
210enum {
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_ACER,
218	ALC883_ACER_ASPIRE,
219	ALC883_MEDION,
220	ALC883_MEDION_MD2,
221	ALC883_LAPTOP_EAPD,
222	ALC883_LENOVO_101E_2ch,
223	ALC883_LENOVO_NB0763,
224	ALC888_LENOVO_MS7195_DIG,
225	ALC888_LENOVO_SKY,
226	ALC883_HAIER_W66,
227	ALC888_3ST_HP,
228	ALC888_6ST_DELL,
229	ALC883_MITAC,
230	ALC883_CLEVO_M720,
231	ALC883_FUJITSU_PI2515,
232	ALC883_3ST_6ch_INTEL,
233	ALC888_ASUS_M90V,
234	ALC888_ASUS_EEE1601,
235	ALC1200_ASUS_P5Q,
236	ALC883_AUTO,
237	ALC883_MODEL_LAST,
238};
239
240/* for GPIO Poll */
241#define GPIO_MASK	0x03
242
243struct alc_spec {
244	/* codec parameterization */
245	struct snd_kcontrol_new *mixers[5];	/* mixer arrays */
246	unsigned int num_mixers;
247	struct snd_kcontrol_new *cap_mixer;	/* capture mixer */
248
249	const struct hda_verb *init_verbs[5];	/* initialization verbs
250						 * don't forget NULL
251						 * termination!
252						 */
253	unsigned int num_init_verbs;
254
255	char *stream_name_analog;	/* analog PCM stream */
256	struct hda_pcm_stream *stream_analog_playback;
257	struct hda_pcm_stream *stream_analog_capture;
258	struct hda_pcm_stream *stream_analog_alt_playback;
259	struct hda_pcm_stream *stream_analog_alt_capture;
260
261	char *stream_name_digital;	/* digital PCM stream */
262	struct hda_pcm_stream *stream_digital_playback;
263	struct hda_pcm_stream *stream_digital_capture;
264
265	/* playback */
266	struct hda_multi_out multiout;	/* playback set-up
267					 * max_channels, dacs must be set
268					 * dig_out_nid and hp_nid are optional
269					 */
270	hda_nid_t alt_dac_nid;
271
272	/* capture */
273	unsigned int num_adc_nids;
274	hda_nid_t *adc_nids;
275	hda_nid_t *capsrc_nids;
276	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
277	unsigned char is_mix_capture;	/* matrix-style capture (non-mux) */
278
279	/* capture source */
280	unsigned int num_mux_defs;
281	const struct hda_input_mux *input_mux;
282	unsigned int cur_mux[3];
283
284	/* channel model */
285	const struct hda_channel_mode *channel_mode;
286	int num_channel_mode;
287	int need_dac_fix;
288
289	/* PCM information */
290	struct hda_pcm pcm_rec[3];	/* used in alc_build_pcms() */
291
292	/* dynamic controls, init_verbs and input_mux */
293	struct auto_pin_cfg autocfg;
294	struct snd_array kctls;
295	struct hda_input_mux private_imux;
296	hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
297
298	/* hooks */
299	void (*init_hook)(struct hda_codec *codec);
300	void (*unsol_event)(struct hda_codec *codec, unsigned int res);
301
302	/* for pin sensing */
303	unsigned int sense_updated: 1;
304	unsigned int jack_present: 1;
305	unsigned int master_sw: 1;
306
307	/* for virtual master */
308	hda_nid_t vmaster_nid;
309#ifdef CONFIG_SND_HDA_POWER_SAVE
310	struct hda_loopback_check loopback;
311#endif
312
313	/* for PLL fix */
314	hda_nid_t pll_nid;
315	unsigned int pll_coef_idx, pll_coef_bit;
316
317#ifdef SND_HDA_NEEDS_RESUME
318#define ALC_MAX_PINS	16
319	unsigned int num_pins;
320	hda_nid_t pin_nids[ALC_MAX_PINS];
321	unsigned int pin_cfgs[ALC_MAX_PINS];
322#endif
323};
324
325/*
326 * configuration template - to be copied to the spec instance
327 */
328struct alc_config_preset {
329	struct snd_kcontrol_new *mixers[5]; /* should be identical size
330					     * with spec
331					     */
332	struct snd_kcontrol_new *cap_mixer; /* capture mixer */
333	const struct hda_verb *init_verbs[5];
334	unsigned int num_dacs;
335	hda_nid_t *dac_nids;
336	hda_nid_t dig_out_nid;		/* optional */
337	hda_nid_t hp_nid;		/* optional */
338	unsigned int num_adc_nids;
339	hda_nid_t *adc_nids;
340	hda_nid_t *capsrc_nids;
341	hda_nid_t dig_in_nid;
342	unsigned int num_channel_mode;
343	const struct hda_channel_mode *channel_mode;
344	int need_dac_fix;
345	unsigned int num_mux_defs;
346	const struct hda_input_mux *input_mux;
347	void (*unsol_event)(struct hda_codec *, unsigned int);
348	void (*init_hook)(struct hda_codec *);
349#ifdef CONFIG_SND_HDA_POWER_SAVE
350	struct hda_amp_list *loopbacks;
351#endif
352};
353
354
355/*
356 * input MUX handling
357 */
358static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
359			     struct snd_ctl_elem_info *uinfo)
360{
361	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
362	struct alc_spec *spec = codec->spec;
363	unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
364	if (mux_idx >= spec->num_mux_defs)
365		mux_idx = 0;
366	return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
367}
368
369static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
370			    struct snd_ctl_elem_value *ucontrol)
371{
372	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
373	struct alc_spec *spec = codec->spec;
374	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
375
376	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
377	return 0;
378}
379
380static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
381			    struct snd_ctl_elem_value *ucontrol)
382{
383	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
384	struct alc_spec *spec = codec->spec;
385	const struct hda_input_mux *imux = spec->input_mux;
386	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
387	hda_nid_t nid = spec->capsrc_nids ?
388		spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
389
390	if (spec->is_mix_capture) {
391		/* Matrix-mixer style (e.g. ALC882) */
392		unsigned int *cur_val = &spec->cur_mux[adc_idx];
393		unsigned int i, idx;
394
395		idx = ucontrol->value.enumerated.item[0];
396		if (idx >= imux->num_items)
397			idx = imux->num_items - 1;
398		if (*cur_val == idx)
399			return 0;
400		for (i = 0; i < imux->num_items; i++) {
401			unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
402			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
403						 imux->items[i].index,
404						 HDA_AMP_MUTE, v);
405		}
406		*cur_val = idx;
407		return 1;
408	} else {
409		/* MUX style (e.g. ALC880) */
410		unsigned int mux_idx;
411		mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
412		return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx],
413					     ucontrol, nid,
414					     &spec->cur_mux[adc_idx]);
415	}
416}
417
418/*
419 * channel mode setting
420 */
421static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
422			    struct snd_ctl_elem_info *uinfo)
423{
424	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
425	struct alc_spec *spec = codec->spec;
426	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
427				    spec->num_channel_mode);
428}
429
430static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
431			   struct snd_ctl_elem_value *ucontrol)
432{
433	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
434	struct alc_spec *spec = codec->spec;
435	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
436				   spec->num_channel_mode,
437				   spec->multiout.max_channels);
438}
439
440static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
441			   struct snd_ctl_elem_value *ucontrol)
442{
443	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
444	struct alc_spec *spec = codec->spec;
445	int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
446				      spec->num_channel_mode,
447				      &spec->multiout.max_channels);
448	if (err >= 0 && spec->need_dac_fix)
449		spec->multiout.num_dacs = spec->multiout.max_channels / 2;
450	return err;
451}
452
453/*
454 * Control the mode of pin widget settings via the mixer.  "pc" is used
455 * instead of "%" to avoid consequences of accidently treating the % as
456 * being part of a format specifier.  Maximum allowed length of a value is
457 * 63 characters plus NULL terminator.
458 *
459 * Note: some retasking pin complexes seem to ignore requests for input
460 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
461 * are requested.  Therefore order this list so that this behaviour will not
462 * cause problems when mixer clients move through the enum sequentially.
463 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
464 * March 2006.
465 */
466static char *alc_pin_mode_names[] = {
467	"Mic 50pc bias", "Mic 80pc bias",
468	"Line in", "Line out", "Headphone out",
469};
470static unsigned char alc_pin_mode_values[] = {
471	PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
472};
473/* The control can present all 5 options, or it can limit the options based
474 * in the pin being assumed to be exclusively an input or an output pin.  In
475 * addition, "input" pins may or may not process the mic bias option
476 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
477 * accept requests for bias as of chip versions up to March 2006) and/or
478 * wiring in the computer.
479 */
480#define ALC_PIN_DIR_IN              0x00
481#define ALC_PIN_DIR_OUT             0x01
482#define ALC_PIN_DIR_INOUT           0x02
483#define ALC_PIN_DIR_IN_NOMICBIAS    0x03
484#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
485
486/* Info about the pin modes supported by the different pin direction modes.
487 * For each direction the minimum and maximum values are given.
488 */
489static signed char alc_pin_mode_dir_info[5][2] = {
490	{ 0, 2 },    /* ALC_PIN_DIR_IN */
491	{ 3, 4 },    /* ALC_PIN_DIR_OUT */
492	{ 0, 4 },    /* ALC_PIN_DIR_INOUT */
493	{ 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
494	{ 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
495};
496#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
497#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
498#define alc_pin_mode_n_items(_dir) \
499	(alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
500
501static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
502			     struct snd_ctl_elem_info *uinfo)
503{
504	unsigned int item_num = uinfo->value.enumerated.item;
505	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
506
507	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
508	uinfo->count = 1;
509	uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
510
511	if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
512		item_num = alc_pin_mode_min(dir);
513	strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
514	return 0;
515}
516
517static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
518			    struct snd_ctl_elem_value *ucontrol)
519{
520	unsigned int i;
521	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
522	hda_nid_t nid = kcontrol->private_value & 0xffff;
523	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
524	long *valp = ucontrol->value.integer.value;
525	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
526						 AC_VERB_GET_PIN_WIDGET_CONTROL,
527						 0x00);
528
529	/* Find enumerated value for current pinctl setting */
530	i = alc_pin_mode_min(dir);
531	while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
532		i++;
533	*valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
534	return 0;
535}
536
537static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
538			    struct snd_ctl_elem_value *ucontrol)
539{
540	signed int change;
541	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
542	hda_nid_t nid = kcontrol->private_value & 0xffff;
543	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
544	long val = *ucontrol->value.integer.value;
545	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
546						 AC_VERB_GET_PIN_WIDGET_CONTROL,
547						 0x00);
548
549	if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
550		val = alc_pin_mode_min(dir);
551
552	change = pinctl != alc_pin_mode_values[val];
553	if (change) {
554		/* Set pin mode to that requested */
555		snd_hda_codec_write_cache(codec, nid, 0,
556					  AC_VERB_SET_PIN_WIDGET_CONTROL,
557					  alc_pin_mode_values[val]);
558
559		/* Also enable the retasking pin's input/output as required
560		 * for the requested pin mode.  Enum values of 2 or less are
561		 * input modes.
562		 *
563		 * Dynamically switching the input/output buffers probably
564		 * reduces noise slightly (particularly on input) so we'll
565		 * do it.  However, having both input and output buffers
566		 * enabled simultaneously doesn't seem to be problematic if
567		 * this turns out to be necessary in the future.
568		 */
569		if (val <= 2) {
570			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
571						 HDA_AMP_MUTE, HDA_AMP_MUTE);
572			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
573						 HDA_AMP_MUTE, 0);
574		} else {
575			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
576						 HDA_AMP_MUTE, HDA_AMP_MUTE);
577			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
578						 HDA_AMP_MUTE, 0);
579		}
580	}
581	return change;
582}
583
584#define ALC_PIN_MODE(xname, nid, dir) \
585	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
586	  .info = alc_pin_mode_info, \
587	  .get = alc_pin_mode_get, \
588	  .put = alc_pin_mode_put, \
589	  .private_value = nid | (dir<<16) }
590
591/* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
592 * together using a mask with more than one bit set.  This control is
593 * currently used only by the ALC260 test model.  At this stage they are not
594 * needed for any "production" models.
595 */
596#ifdef CONFIG_SND_DEBUG
597#define alc_gpio_data_info	snd_ctl_boolean_mono_info
598
599static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
600			     struct snd_ctl_elem_value *ucontrol)
601{
602	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
603	hda_nid_t nid = kcontrol->private_value & 0xffff;
604	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
605	long *valp = ucontrol->value.integer.value;
606	unsigned int val = snd_hda_codec_read(codec, nid, 0,
607					      AC_VERB_GET_GPIO_DATA, 0x00);
608
609	*valp = (val & mask) != 0;
610	return 0;
611}
612static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
613			     struct snd_ctl_elem_value *ucontrol)
614{
615	signed int change;
616	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
617	hda_nid_t nid = kcontrol->private_value & 0xffff;
618	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
619	long val = *ucontrol->value.integer.value;
620	unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
621						    AC_VERB_GET_GPIO_DATA,
622						    0x00);
623
624	/* Set/unset the masked GPIO bit(s) as needed */
625	change = (val == 0 ? 0 : mask) != (gpio_data & mask);
626	if (val == 0)
627		gpio_data &= ~mask;
628	else
629		gpio_data |= mask;
630	snd_hda_codec_write_cache(codec, nid, 0,
631				  AC_VERB_SET_GPIO_DATA, gpio_data);
632
633	return change;
634}
635#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
636	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
637	  .info = alc_gpio_data_info, \
638	  .get = alc_gpio_data_get, \
639	  .put = alc_gpio_data_put, \
640	  .private_value = nid | (mask<<16) }
641#endif   /* CONFIG_SND_DEBUG */
642
643/* A switch control to allow the enabling of the digital IO pins on the
644 * ALC260.  This is incredibly simplistic; the intention of this control is
645 * to provide something in the test model allowing digital outputs to be
646 * identified if present.  If models are found which can utilise these
647 * outputs a more complete mixer control can be devised for those models if
648 * necessary.
649 */
650#ifdef CONFIG_SND_DEBUG
651#define alc_spdif_ctrl_info	snd_ctl_boolean_mono_info
652
653static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
654			      struct snd_ctl_elem_value *ucontrol)
655{
656	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
657	hda_nid_t nid = kcontrol->private_value & 0xffff;
658	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
659	long *valp = ucontrol->value.integer.value;
660	unsigned int val = snd_hda_codec_read(codec, nid, 0,
661					      AC_VERB_GET_DIGI_CONVERT_1, 0x00);
662
663	*valp = (val & mask) != 0;
664	return 0;
665}
666static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
667			      struct snd_ctl_elem_value *ucontrol)
668{
669	signed int change;
670	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
671	hda_nid_t nid = kcontrol->private_value & 0xffff;
672	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
673	long val = *ucontrol->value.integer.value;
674	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
675						    AC_VERB_GET_DIGI_CONVERT_1,
676						    0x00);
677
678	/* Set/unset the masked control bit(s) as needed */
679	change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
680	if (val==0)
681		ctrl_data &= ~mask;
682	else
683		ctrl_data |= mask;
684	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
685				  ctrl_data);
686
687	return change;
688}
689#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
690	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
691	  .info = alc_spdif_ctrl_info, \
692	  .get = alc_spdif_ctrl_get, \
693	  .put = alc_spdif_ctrl_put, \
694	  .private_value = nid | (mask<<16) }
695#endif   /* CONFIG_SND_DEBUG */
696
697/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
698 * Again, this is only used in the ALC26x test models to help identify when
699 * the EAPD line must be asserted for features to work.
700 */
701#ifdef CONFIG_SND_DEBUG
702#define alc_eapd_ctrl_info	snd_ctl_boolean_mono_info
703
704static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
705			      struct snd_ctl_elem_value *ucontrol)
706{
707	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
708	hda_nid_t nid = kcontrol->private_value & 0xffff;
709	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
710	long *valp = ucontrol->value.integer.value;
711	unsigned int val = snd_hda_codec_read(codec, nid, 0,
712					      AC_VERB_GET_EAPD_BTLENABLE, 0x00);
713
714	*valp = (val & mask) != 0;
715	return 0;
716}
717
718static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
719			      struct snd_ctl_elem_value *ucontrol)
720{
721	int change;
722	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
723	hda_nid_t nid = kcontrol->private_value & 0xffff;
724	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
725	long val = *ucontrol->value.integer.value;
726	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
727						    AC_VERB_GET_EAPD_BTLENABLE,
728						    0x00);
729
730	/* Set/unset the masked control bit(s) as needed */
731	change = (!val ? 0 : mask) != (ctrl_data & mask);
732	if (!val)
733		ctrl_data &= ~mask;
734	else
735		ctrl_data |= mask;
736	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
737				  ctrl_data);
738
739	return change;
740}
741
742#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
743	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
744	  .info = alc_eapd_ctrl_info, \
745	  .get = alc_eapd_ctrl_get, \
746	  .put = alc_eapd_ctrl_put, \
747	  .private_value = nid | (mask<<16) }
748#endif   /* CONFIG_SND_DEBUG */
749
750/*
751 */
752static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
753{
754	if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
755		return;
756	spec->mixers[spec->num_mixers++] = mix;
757}
758
759static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
760{
761	if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
762		return;
763	spec->init_verbs[spec->num_init_verbs++] = verb;
764}
765
766/*
767 * set up from the preset table
768 */
769static void setup_preset(struct alc_spec *spec,
770			 const struct alc_config_preset *preset)
771{
772	int i;
773
774	for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
775		add_mixer(spec, preset->mixers[i]);
776	spec->cap_mixer = preset->cap_mixer;
777	for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
778	     i++)
779		add_verb(spec, preset->init_verbs[i]);
780
781	spec->channel_mode = preset->channel_mode;
782	spec->num_channel_mode = preset->num_channel_mode;
783	spec->need_dac_fix = preset->need_dac_fix;
784
785	spec->multiout.max_channels = spec->channel_mode[0].channels;
786
787	spec->multiout.num_dacs = preset->num_dacs;
788	spec->multiout.dac_nids = preset->dac_nids;
789	spec->multiout.dig_out_nid = preset->dig_out_nid;
790	spec->multiout.hp_nid = preset->hp_nid;
791
792	spec->num_mux_defs = preset->num_mux_defs;
793	if (!spec->num_mux_defs)
794		spec->num_mux_defs = 1;
795	spec->input_mux = preset->input_mux;
796
797	spec->num_adc_nids = preset->num_adc_nids;
798	spec->adc_nids = preset->adc_nids;
799	spec->capsrc_nids = preset->capsrc_nids;
800	spec->dig_in_nid = preset->dig_in_nid;
801
802	spec->unsol_event = preset->unsol_event;
803	spec->init_hook = preset->init_hook;
804#ifdef CONFIG_SND_HDA_POWER_SAVE
805	spec->loopback.amplist = preset->loopbacks;
806#endif
807}
808
809/* Enable GPIO mask and set output */
810static struct hda_verb alc_gpio1_init_verbs[] = {
811	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
812	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
813	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
814	{ }
815};
816
817static struct hda_verb alc_gpio2_init_verbs[] = {
818	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
819	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
820	{0x01, AC_VERB_SET_GPIO_DATA, 0x02},
821	{ }
822};
823
824static struct hda_verb alc_gpio3_init_verbs[] = {
825	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
826	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
827	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
828	{ }
829};
830
831/*
832 * Fix hardware PLL issue
833 * On some codecs, the analog PLL gating control must be off while
834 * the default value is 1.
835 */
836static void alc_fix_pll(struct hda_codec *codec)
837{
838	struct alc_spec *spec = codec->spec;
839	unsigned int val;
840
841	if (!spec->pll_nid)
842		return;
843	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
844			    spec->pll_coef_idx);
845	val = snd_hda_codec_read(codec, spec->pll_nid, 0,
846				 AC_VERB_GET_PROC_COEF, 0);
847	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
848			    spec->pll_coef_idx);
849	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
850			    val & ~(1 << spec->pll_coef_bit));
851}
852
853static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
854			     unsigned int coef_idx, unsigned int coef_bit)
855{
856	struct alc_spec *spec = codec->spec;
857	spec->pll_nid = nid;
858	spec->pll_coef_idx = coef_idx;
859	spec->pll_coef_bit = coef_bit;
860	alc_fix_pll(codec);
861}
862
863static void alc_sku_automute(struct hda_codec *codec)
864{
865	struct alc_spec *spec = codec->spec;
866	unsigned int present;
867	unsigned int hp_nid = spec->autocfg.hp_pins[0];
868	unsigned int sp_nid = spec->autocfg.speaker_pins[0];
869
870	/* need to execute and sync at first */
871	snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
872	present = snd_hda_codec_read(codec, hp_nid, 0,
873				     AC_VERB_GET_PIN_SENSE, 0);
874	spec->jack_present = (present & 0x80000000) != 0;
875	snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
876			    spec->jack_present ? 0 : PIN_OUT);
877}
878
879#if 0 /* it's broken in some acses -- temporarily disabled */
880static void alc_mic_automute(struct hda_codec *codec)
881{
882	struct alc_spec *spec = codec->spec;
883	unsigned int present;
884	unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
885	unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
886	unsigned int mix_nid = spec->capsrc_nids[0];
887	unsigned int capsrc_idx_mic, capsrc_idx_fmic;
888
889	capsrc_idx_mic = mic_nid - 0x18;
890	capsrc_idx_fmic = fmic_nid - 0x18;
891	present = snd_hda_codec_read(codec, mic_nid, 0,
892				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
893	snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
894		    0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
895	snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
896		    0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
897	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
898			 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
899}
900#else
901#define alc_mic_automute(codec) /* NOP */
902#endif /* disabled */
903
904/* unsolicited event for HP jack sensing */
905static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
906{
907	if (codec->vendor_id == 0x10ec0880)
908		res >>= 28;
909	else
910		res >>= 26;
911	if (res == ALC880_HP_EVENT)
912		alc_sku_automute(codec);
913
914	if (res == ALC880_MIC_EVENT)
915		alc_mic_automute(codec);
916}
917
918static void alc_inithook(struct hda_codec *codec)
919{
920	alc_sku_automute(codec);
921	alc_mic_automute(codec);
922}
923
924/* additional initialization for ALC888 variants */
925static void alc888_coef_init(struct hda_codec *codec)
926{
927	unsigned int tmp;
928
929	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
930	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
931	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
932	if ((tmp & 0xf0) == 2)
933		/* alc888S-VC */
934		snd_hda_codec_read(codec, 0x20, 0,
935				   AC_VERB_SET_PROC_COEF, 0x830);
936	 else
937		 /* alc888-VB */
938		 snd_hda_codec_read(codec, 0x20, 0,
939				    AC_VERB_SET_PROC_COEF, 0x3030);
940}
941
942/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
943 *	31 ~ 16 :	Manufacture ID
944 *	15 ~ 8	:	SKU ID
945 *	7  ~ 0	:	Assembly ID
946 *	port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
947 */
948static void alc_subsystem_id(struct hda_codec *codec,
949			     unsigned int porta, unsigned int porte,
950			     unsigned int portd)
951{
952	unsigned int ass, tmp, i;
953	unsigned nid;
954	struct alc_spec *spec = codec->spec;
955
956	ass = codec->subsystem_id & 0xffff;
957	if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
958		goto do_sku;
959
960	/*
961	 * 31~30	: port conetcivity
962	 * 29~21	: reserve
963	 * 20		: PCBEEP input
964	 * 19~16	: Check sum (15:1)
965	 * 15~1		: Custom
966	 * 0		: override
967	*/
968	nid = 0x1d;
969	if (codec->vendor_id == 0x10ec0260)
970		nid = 0x17;
971	ass = snd_hda_codec_read(codec, nid, 0,
972				 AC_VERB_GET_CONFIG_DEFAULT, 0);
973	if (!(ass & 1) && !(ass & 0x100000))
974		return;
975	if ((ass >> 30) != 1)	/* no physical connection */
976		return;
977
978	/* check sum */
979	tmp = 0;
980	for (i = 1; i < 16; i++) {
981		if ((ass >> i) & 1)
982			tmp++;
983	}
984	if (((ass >> 16) & 0xf) != tmp)
985		return;
986do_sku:
987	/*
988	 * 0 : override
989	 * 1 :	Swap Jack
990	 * 2 : 0 --> Desktop, 1 --> Laptop
991	 * 3~5 : External Amplifier control
992	 * 7~6 : Reserved
993	*/
994	tmp = (ass & 0x38) >> 3;	/* external Amp control */
995	switch (tmp) {
996	case 1:
997		snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
998		break;
999	case 3:
1000		snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1001		break;
1002	case 7:
1003		snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1004		break;
1005	case 5:	/* set EAPD output high */
1006		switch (codec->vendor_id) {
1007		case 0x10ec0260:
1008			snd_hda_codec_write(codec, 0x0f, 0,
1009					    AC_VERB_SET_EAPD_BTLENABLE, 2);
1010			snd_hda_codec_write(codec, 0x10, 0,
1011					    AC_VERB_SET_EAPD_BTLENABLE, 2);
1012			break;
1013		case 0x10ec0262:
1014		case 0x10ec0267:
1015		case 0x10ec0268:
1016		case 0x10ec0269:
1017		case 0x10ec0660:
1018		case 0x10ec0662:
1019		case 0x10ec0663:
1020		case 0x10ec0862:
1021		case 0x10ec0889:
1022			snd_hda_codec_write(codec, 0x14, 0,
1023					    AC_VERB_SET_EAPD_BTLENABLE, 2);
1024			snd_hda_codec_write(codec, 0x15, 0,
1025					    AC_VERB_SET_EAPD_BTLENABLE, 2);
1026			break;
1027		}
1028		switch (codec->vendor_id) {
1029		case 0x10ec0260:
1030			snd_hda_codec_write(codec, 0x1a, 0,
1031					    AC_VERB_SET_COEF_INDEX, 7);
1032			tmp = snd_hda_codec_read(codec, 0x1a, 0,
1033						 AC_VERB_GET_PROC_COEF, 0);
1034			snd_hda_codec_write(codec, 0x1a, 0,
1035					    AC_VERB_SET_COEF_INDEX, 7);
1036			snd_hda_codec_write(codec, 0x1a, 0,
1037					    AC_VERB_SET_PROC_COEF,
1038					    tmp | 0x2010);
1039			break;
1040		case 0x10ec0262:
1041		case 0x10ec0880:
1042		case 0x10ec0882:
1043		case 0x10ec0883:
1044		case 0x10ec0885:
1045		case 0x10ec0889:
1046			snd_hda_codec_write(codec, 0x20, 0,
1047					    AC_VERB_SET_COEF_INDEX, 7);
1048			tmp = snd_hda_codec_read(codec, 0x20, 0,
1049						 AC_VERB_GET_PROC_COEF, 0);
1050			snd_hda_codec_write(codec, 0x20, 0,
1051					    AC_VERB_SET_COEF_INDEX, 7);
1052			snd_hda_codec_write(codec, 0x20, 0,
1053					    AC_VERB_SET_PROC_COEF,
1054					    tmp | 0x2010);
1055			break;
1056		case 0x10ec0888:
1057			/*alc888_coef_init(codec);*/ /* called in alc_init() */
1058			break;
1059		case 0x10ec0267:
1060		case 0x10ec0268:
1061			snd_hda_codec_write(codec, 0x20, 0,
1062					    AC_VERB_SET_COEF_INDEX, 7);
1063			tmp = snd_hda_codec_read(codec, 0x20, 0,
1064						 AC_VERB_GET_PROC_COEF, 0);
1065			snd_hda_codec_write(codec, 0x20, 0,
1066					    AC_VERB_SET_COEF_INDEX, 7);
1067			snd_hda_codec_write(codec, 0x20, 0,
1068					    AC_VERB_SET_PROC_COEF,
1069					    tmp | 0x3000);
1070			break;
1071		}
1072	default:
1073		break;
1074	}
1075
1076	/* is laptop or Desktop and enable the function "Mute internal speaker
1077	 * when the external headphone out jack is plugged"
1078	 */
1079	if (!(ass & 0x8000))
1080		return;
1081	/*
1082	 * 10~8 : Jack location
1083	 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1084	 * 14~13: Resvered
1085	 * 15   : 1 --> enable the function "Mute internal speaker
1086	 *	        when the external headphone out jack is plugged"
1087	 */
1088	if (!spec->autocfg.speaker_pins[0]) {
1089		if (spec->autocfg.line_out_pins[0])
1090			spec->autocfg.speaker_pins[0] =
1091				spec->autocfg.line_out_pins[0];
1092		else
1093			return;
1094	}
1095
1096	if (!spec->autocfg.hp_pins[0]) {
1097		tmp = (ass >> 11) & 0x3;	/* HP to chassis */
1098		if (tmp == 0)
1099			spec->autocfg.hp_pins[0] = porta;
1100		else if (tmp == 1)
1101			spec->autocfg.hp_pins[0] = porte;
1102		else if (tmp == 2)
1103			spec->autocfg.hp_pins[0] = portd;
1104		else
1105			return;
1106	}
1107	if (spec->autocfg.hp_pins[0])
1108		snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
1109			AC_VERB_SET_UNSOLICITED_ENABLE,
1110			AC_USRSP_EN | ALC880_HP_EVENT);
1111
1112#if 0 /* it's broken in some acses -- temporarily disabled */
1113	if (spec->autocfg.input_pins[AUTO_PIN_MIC] &&
1114		spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC])
1115		snd_hda_codec_write(codec,
1116			spec->autocfg.input_pins[AUTO_PIN_MIC], 0,
1117			AC_VERB_SET_UNSOLICITED_ENABLE,
1118			AC_USRSP_EN | ALC880_MIC_EVENT);
1119#endif /* disabled */
1120
1121	spec->unsol_event = alc_sku_unsol_event;
1122}
1123
1124/*
1125 * Fix-up pin default configurations
1126 */
1127
1128struct alc_pincfg {
1129	hda_nid_t nid;
1130	u32 val;
1131};
1132
1133static void alc_fix_pincfg(struct hda_codec *codec,
1134			   const struct snd_pci_quirk *quirk,
1135			   const struct alc_pincfg **pinfix)
1136{
1137	const struct alc_pincfg *cfg;
1138
1139	quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1140	if (!quirk)
1141		return;
1142
1143	cfg = pinfix[quirk->value];
1144	for (; cfg->nid; cfg++) {
1145		int i;
1146		u32 val = cfg->val;
1147		for (i = 0; i < 4; i++) {
1148			snd_hda_codec_write(codec, cfg->nid, 0,
1149				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
1150				    val & 0xff);
1151			val >>= 8;
1152		}
1153	}
1154}
1155
1156/*
1157 * ALC880 3-stack model
1158 *
1159 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1160 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1161 *                 F-Mic = 0x1b, HP = 0x19
1162 */
1163
1164static hda_nid_t alc880_dac_nids[4] = {
1165	/* front, rear, clfe, rear_surr */
1166	0x02, 0x05, 0x04, 0x03
1167};
1168
1169static hda_nid_t alc880_adc_nids[3] = {
1170	/* ADC0-2 */
1171	0x07, 0x08, 0x09,
1172};
1173
1174/* The datasheet says the node 0x07 is connected from inputs,
1175 * but it shows zero connection in the real implementation on some devices.
1176 * Note: this is a 915GAV bug, fixed on 915GLV
1177 */
1178static hda_nid_t alc880_adc_nids_alt[2] = {
1179	/* ADC1-2 */
1180	0x08, 0x09,
1181};
1182
1183#define ALC880_DIGOUT_NID	0x06
1184#define ALC880_DIGIN_NID	0x0a
1185
1186static struct hda_input_mux alc880_capture_source = {
1187	.num_items = 4,
1188	.items = {
1189		{ "Mic", 0x0 },
1190		{ "Front Mic", 0x3 },
1191		{ "Line", 0x2 },
1192		{ "CD", 0x4 },
1193	},
1194};
1195
1196/* channel source setting (2/6 channel selection for 3-stack) */
1197/* 2ch mode */
1198static struct hda_verb alc880_threestack_ch2_init[] = {
1199	/* set line-in to input, mute it */
1200	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1201	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1202	/* set mic-in to input vref 80%, mute it */
1203	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1204	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1205	{ } /* end */
1206};
1207
1208/* 6ch mode */
1209static struct hda_verb alc880_threestack_ch6_init[] = {
1210	/* set line-in to output, unmute it */
1211	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1212	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1213	/* set mic-in to output, unmute it */
1214	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1215	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1216	{ } /* end */
1217};
1218
1219static struct hda_channel_mode alc880_threestack_modes[2] = {
1220	{ 2, alc880_threestack_ch2_init },
1221	{ 6, alc880_threestack_ch6_init },
1222};
1223
1224static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1225	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1226	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1227	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1228	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1229	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1230	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1231	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1232	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1233	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1234	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1235	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1236	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1237	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1238	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1239	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1240	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1241	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1242	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1243	HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1244	{
1245		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1246		.name = "Channel Mode",
1247		.info = alc_ch_mode_info,
1248		.get = alc_ch_mode_get,
1249		.put = alc_ch_mode_put,
1250	},
1251	{ } /* end */
1252};
1253
1254/* capture mixer elements */
1255static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1256			    struct snd_ctl_elem_info *uinfo)
1257{
1258	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1259	struct alc_spec *spec = codec->spec;
1260	int err;
1261
1262	mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
1263	kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1264						      HDA_INPUT);
1265	err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1266	mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */
1267	return err;
1268}
1269
1270static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1271			   unsigned int size, unsigned int __user *tlv)
1272{
1273	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1274	struct alc_spec *spec = codec->spec;
1275	int err;
1276
1277	mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
1278	kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1279						      HDA_INPUT);
1280	err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1281	mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */
1282	return err;
1283}
1284
1285typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1286			     struct snd_ctl_elem_value *ucontrol);
1287
1288static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1289				 struct snd_ctl_elem_value *ucontrol,
1290				 getput_call_t func)
1291{
1292	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1293	struct alc_spec *spec = codec->spec;
1294	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1295	int err;
1296
1297	mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
1298	kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1299						      3, 0, HDA_INPUT);
1300	err = func(kcontrol, ucontrol);
1301	mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */
1302	return err;
1303}
1304
1305static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1306			   struct snd_ctl_elem_value *ucontrol)
1307{
1308	return alc_cap_getput_caller(kcontrol, ucontrol,
1309				     snd_hda_mixer_amp_volume_get);
1310}
1311
1312static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1313			   struct snd_ctl_elem_value *ucontrol)
1314{
1315	return alc_cap_getput_caller(kcontrol, ucontrol,
1316				     snd_hda_mixer_amp_volume_put);
1317}
1318
1319/* capture mixer elements */
1320#define alc_cap_sw_info		snd_ctl_boolean_stereo_info
1321
1322static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1323			  struct snd_ctl_elem_value *ucontrol)
1324{
1325	return alc_cap_getput_caller(kcontrol, ucontrol,
1326				     snd_hda_mixer_amp_switch_get);
1327}
1328
1329static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1330			  struct snd_ctl_elem_value *ucontrol)
1331{
1332	return alc_cap_getput_caller(kcontrol, ucontrol,
1333				     snd_hda_mixer_amp_switch_put);
1334}
1335
1336#define DEFINE_CAPMIX(num) \
1337static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
1338	{ \
1339		.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1340		.name = "Capture Switch", \
1341		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1342		.count = num, \
1343		.info = alc_cap_sw_info, \
1344		.get = alc_cap_sw_get, \
1345		.put = alc_cap_sw_put, \
1346	}, \
1347	{ \
1348		.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1349		.name = "Capture Volume", \
1350		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1351			   SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1352			   SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1353		.count = num, \
1354		.info = alc_cap_vol_info, \
1355		.get = alc_cap_vol_get, \
1356		.put = alc_cap_vol_put, \
1357		.tlv = { .c = alc_cap_vol_tlv }, \
1358	}, \
1359	{ \
1360		.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1361		/* .name = "Capture Source", */ \
1362		.name = "Input Source", \
1363		.count = num, \
1364		.info = alc_mux_enum_info, \
1365		.get = alc_mux_enum_get, \
1366		.put = alc_mux_enum_put, \
1367	}, \
1368	{ } /* end */ \
1369}
1370
1371/* up to three ADCs */
1372DEFINE_CAPMIX(1);
1373DEFINE_CAPMIX(2);
1374DEFINE_CAPMIX(3);
1375
1376
1377/*
1378 * ALC880 5-stack model
1379 *
1380 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1381 *      Side = 0x02 (0xd)
1382 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1383 *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1384 */
1385
1386/* additional mixers to alc880_three_stack_mixer */
1387static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1388	HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1389	HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1390	{ } /* end */
1391};
1392
1393/* channel source setting (6/8 channel selection for 5-stack) */
1394/* 6ch mode */
1395static struct hda_verb alc880_fivestack_ch6_init[] = {
1396	/* set line-in to input, mute it */
1397	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1398	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1399	{ } /* end */
1400};
1401
1402/* 8ch mode */
1403static struct hda_verb alc880_fivestack_ch8_init[] = {
1404	/* set line-in to output, unmute it */
1405	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1406	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1407	{ } /* end */
1408};
1409
1410static struct hda_channel_mode alc880_fivestack_modes[2] = {
1411	{ 6, alc880_fivestack_ch6_init },
1412	{ 8, alc880_fivestack_ch8_init },
1413};
1414
1415
1416/*
1417 * ALC880 6-stack model
1418 *
1419 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1420 *      Side = 0x05 (0x0f)
1421 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1422 *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1423 */
1424
1425static hda_nid_t alc880_6st_dac_nids[4] = {
1426	/* front, rear, clfe, rear_surr */
1427	0x02, 0x03, 0x04, 0x05
1428};
1429
1430static struct hda_input_mux alc880_6stack_capture_source = {
1431	.num_items = 4,
1432	.items = {
1433		{ "Mic", 0x0 },
1434		{ "Front Mic", 0x1 },
1435		{ "Line", 0x2 },
1436		{ "CD", 0x4 },
1437	},
1438};
1439
1440/* fixed 8-channels */
1441static struct hda_channel_mode alc880_sixstack_modes[1] = {
1442	{ 8, NULL },
1443};
1444
1445static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1446	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1447	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1448	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1449	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1450	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1451	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1452	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1453	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1454	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1455	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1456	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1457	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1458	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1459	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1460	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1461	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1462	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1463	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1464	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1465	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1466	{
1467		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1468		.name = "Channel Mode",
1469		.info = alc_ch_mode_info,
1470		.get = alc_ch_mode_get,
1471		.put = alc_ch_mode_put,
1472	},
1473	{ } /* end */
1474};
1475
1476
1477/*
1478 * ALC880 W810 model
1479 *
1480 * W810 has rear IO for:
1481 * Front (DAC 02)
1482 * Surround (DAC 03)
1483 * Center/LFE (DAC 04)
1484 * Digital out (06)
1485 *
1486 * The system also has a pair of internal speakers, and a headphone jack.
1487 * These are both connected to Line2 on the codec, hence to DAC 02.
1488 *
1489 * There is a variable resistor to control the speaker or headphone
1490 * volume. This is a hardware-only device without a software API.
1491 *
1492 * Plugging headphones in will disable the internal speakers. This is
1493 * implemented in hardware, not via the driver using jack sense. In
1494 * a similar fashion, plugging into the rear socket marked "front" will
1495 * disable both the speakers and headphones.
1496 *
1497 * For input, there's a microphone jack, and an "audio in" jack.
1498 * These may not do anything useful with this driver yet, because I
1499 * haven't setup any initialization verbs for these yet...
1500 */
1501
1502static hda_nid_t alc880_w810_dac_nids[3] = {
1503	/* front, rear/surround, clfe */
1504	0x02, 0x03, 0x04
1505};
1506
1507/* fixed 6 channels */
1508static struct hda_channel_mode alc880_w810_modes[1] = {
1509	{ 6, NULL }
1510};
1511
1512/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1513static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1514	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1515	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1516	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1517	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1518	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1519	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1520	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1521	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1522	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1523	{ } /* end */
1524};
1525
1526
1527/*
1528 * Z710V model
1529 *
1530 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1531 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1532 *                 Line = 0x1a
1533 */
1534
1535static hda_nid_t alc880_z71v_dac_nids[1] = {
1536	0x02
1537};
1538#define ALC880_Z71V_HP_DAC	0x03
1539
1540/* fixed 2 channels */
1541static struct hda_channel_mode alc880_2_jack_modes[1] = {
1542	{ 2, NULL }
1543};
1544
1545static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1546	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1547	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1548	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1549	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1550	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1551	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1552	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1553	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1554	{ } /* end */
1555};
1556
1557
1558/*
1559 * ALC880 F1734 model
1560 *
1561 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1562 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1563 */
1564
1565static hda_nid_t alc880_f1734_dac_nids[1] = {
1566	0x03
1567};
1568#define ALC880_F1734_HP_DAC	0x02
1569
1570static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1571	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1572	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1573	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1574	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1575	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1576	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1577	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1578	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1579	{ } /* end */
1580};
1581
1582static struct hda_input_mux alc880_f1734_capture_source = {
1583	.num_items = 2,
1584	.items = {
1585		{ "Mic", 0x1 },
1586		{ "CD", 0x4 },
1587	},
1588};
1589
1590
1591/*
1592 * ALC880 ASUS model
1593 *
1594 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1595 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1596 *  Mic = 0x18, Line = 0x1a
1597 */
1598
1599#define alc880_asus_dac_nids	alc880_w810_dac_nids	/* identical with w810 */
1600#define alc880_asus_modes	alc880_threestack_modes	/* 2/6 channel mode */
1601
1602static struct snd_kcontrol_new alc880_asus_mixer[] = {
1603	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1604	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1605	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1606	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1607	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1608	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1609	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1610	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1611	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1612	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1613	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1614	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1615	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1616	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1617	{
1618		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1619		.name = "Channel Mode",
1620		.info = alc_ch_mode_info,
1621		.get = alc_ch_mode_get,
1622		.put = alc_ch_mode_put,
1623	},
1624	{ } /* end */
1625};
1626
1627/*
1628 * ALC880 ASUS W1V model
1629 *
1630 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1631 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1632 *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1633 */
1634
1635/* additional mixers to alc880_asus_mixer */
1636static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1637	HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1638	HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1639	{ } /* end */
1640};
1641
1642/* additional mixers to alc880_asus_mixer */
1643static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1644	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1645	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1646	{ } /* end */
1647};
1648
1649/* TCL S700 */
1650static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1651	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1652	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1653	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1654	HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1655	HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1656	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1657	HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1658	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1659	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1660	{ } /* end */
1661};
1662
1663/* Uniwill */
1664static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1665	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1666	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1667	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1668	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1669	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1670	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1671	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1672	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1673	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1674	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1675	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1676	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1677	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1678	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1679	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1680	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1681	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1682	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1683	{
1684		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1685		.name = "Channel Mode",
1686		.info = alc_ch_mode_info,
1687		.get = alc_ch_mode_get,
1688		.put = alc_ch_mode_put,
1689	},
1690	{ } /* end */
1691};
1692
1693static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1694	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1695	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1696	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1697	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1698	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1699	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1700	HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1701	HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1702	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1703	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1704	{ } /* end */
1705};
1706
1707static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1708	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1709	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1710	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1711	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1712	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1713	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1714	{ } /* end */
1715};
1716
1717/*
1718 * virtual master controls
1719 */
1720
1721/*
1722 * slave controls for virtual master
1723 */
1724static const char *alc_slave_vols[] = {
1725	"Front Playback Volume",
1726	"Surround Playback Volume",
1727	"Center Playback Volume",
1728	"LFE Playback Volume",
1729	"Side Playback Volume",
1730	"Headphone Playback Volume",
1731	"Speaker Playback Volume",
1732	"Mono Playback Volume",
1733	"Line-Out Playback Volume",
1734	"PCM Playback Volume",
1735	NULL,
1736};
1737
1738static const char *alc_slave_sws[] = {
1739	"Front Playback Switch",
1740	"Surround Playback Switch",
1741	"Center Playback Switch",
1742	"LFE Playback Switch",
1743	"Side Playback Switch",
1744	"Headphone Playback Switch",
1745	"Speaker Playback Switch",
1746	"Mono Playback Switch",
1747	"IEC958 Playback Switch",
1748	NULL,
1749};
1750
1751/*
1752 * build control elements
1753 */
1754
1755static void alc_free_kctls(struct hda_codec *codec);
1756
1757static int alc_build_controls(struct hda_codec *codec)
1758{
1759	struct alc_spec *spec = codec->spec;
1760	int err;
1761	int i;
1762
1763	for (i = 0; i < spec->num_mixers; i++) {
1764		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1765		if (err < 0)
1766			return err;
1767	}
1768	if (spec->cap_mixer) {
1769		err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
1770		if (err < 0)
1771			return err;
1772	}
1773	if (spec->multiout.dig_out_nid) {
1774		err = snd_hda_create_spdif_out_ctls(codec,
1775						    spec->multiout.dig_out_nid);
1776		if (err < 0)
1777			return err;
1778		err = snd_hda_create_spdif_share_sw(codec,
1779						    &spec->multiout);
1780		if (err < 0)
1781			return err;
1782		spec->multiout.share_spdif = 1;
1783	}
1784	if (spec->dig_in_nid) {
1785		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1786		if (err < 0)
1787			return err;
1788	}
1789
1790	/* if we have no master control, let's create it */
1791	if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1792		unsigned int vmaster_tlv[4];
1793		snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1794					HDA_OUTPUT, vmaster_tlv);
1795		err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1796					  vmaster_tlv, alc_slave_vols);
1797		if (err < 0)
1798			return err;
1799	}
1800	if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1801		err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1802					  NULL, alc_slave_sws);
1803		if (err < 0)
1804			return err;
1805	}
1806
1807	alc_free_kctls(codec); /* no longer needed */
1808	return 0;
1809}
1810
1811
1812/*
1813 * initialize the codec volumes, etc
1814 */
1815
1816/*
1817 * generic initialization of ADC, input mixers and output mixers
1818 */
1819static struct hda_verb alc880_volume_init_verbs[] = {
1820	/*
1821	 * Unmute ADC0-2 and set the default input to mic-in
1822	 */
1823	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1824	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1825	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1826	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1827	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1828	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1829
1830	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1831	 * mixer widget
1832	 * Note: PASD motherboards uses the Line In 2 as the input for front
1833	 * panel mic (mic 2)
1834	 */
1835	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1836	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1837	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1838	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1839	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1840	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1841	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1842	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1843
1844	/*
1845	 * Set up output mixers (0x0c - 0x0f)
1846	 */
1847	/* set vol=0 to output mixers */
1848	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1849	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1850	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1851	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1852	/* set up input amps for analog loopback */
1853	/* Amp Indices: DAC = 0, mixer = 1 */
1854	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1855	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1856	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1857	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1858	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1859	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1860	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1861	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1862
1863	{ }
1864};
1865
1866/*
1867 * 3-stack pin configuration:
1868 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1869 */
1870static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1871	/*
1872	 * preset connection lists of input pins
1873	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1874	 */
1875	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1876	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1877	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1878
1879	/*
1880	 * Set pin mode and muting
1881	 */
1882	/* set front pin widgets 0x14 for output */
1883	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1884	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1885	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1886	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1887	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1888	/* Mic2 (as headphone out) for HP output */
1889	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1890	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1891	/* Line In pin widget for input */
1892	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1893	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1894	/* Line2 (as front mic) pin widget for input and vref at 80% */
1895	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1896	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1897	/* CD pin widget for input */
1898	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1899
1900	{ }
1901};
1902
1903/*
1904 * 5-stack pin configuration:
1905 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1906 * line-in/side = 0x1a, f-mic = 0x1b
1907 */
1908static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1909	/*
1910	 * preset connection lists of input pins
1911	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1912	 */
1913	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1914	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1915
1916	/*
1917	 * Set pin mode and muting
1918	 */
1919	/* set pin widgets 0x14-0x17 for output */
1920	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1921	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1922	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1923	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1924	/* unmute pins for output (no gain on this amp) */
1925	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1926	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1927	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1928	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1929
1930	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1931	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1932	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1933	/* Mic2 (as headphone out) for HP output */
1934	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1935	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1936	/* Line In pin widget for input */
1937	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1938	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1939	/* Line2 (as front mic) pin widget for input and vref at 80% */
1940	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1941	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1942	/* CD pin widget for input */
1943	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1944
1945	{ }
1946};
1947
1948/*
1949 * W810 pin configuration:
1950 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1951 */
1952static struct hda_verb alc880_pin_w810_init_verbs[] = {
1953	/* hphone/speaker input selector: front DAC */
1954	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1955
1956	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1957	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1958	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1959	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1960	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1961	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1962
1963	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1964	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1965
1966	{ }
1967};
1968
1969/*
1970 * Z71V pin configuration:
1971 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1972 */
1973static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1974	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1975	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1976	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1977	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1978
1979	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1980	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1981	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1982	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1983
1984	{ }
1985};
1986
1987/*
1988 * 6-stack pin configuration:
1989 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1990 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1991 */
1992static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1993	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1994
1995	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1996	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1997	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1998	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1999	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2000	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2001	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2002	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2003
2004	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2005	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2006	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2007	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2008	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2009	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2010	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2011	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2012	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2013
2014	{ }
2015};
2016
2017/*
2018 * Uniwill pin configuration:
2019 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2020 * line = 0x1a
2021 */
2022static struct hda_verb alc880_uniwill_init_verbs[] = {
2023	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2024
2025	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2026	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2027	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2028	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2029	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2030	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2031	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2032	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2033	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2034	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2035	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2036	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2037	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2038	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2039
2040	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2041	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2042	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2043	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2044	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2045	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2046	/* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2047	/* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2048	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2049
2050	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2051	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2052
2053	{ }
2054};
2055
2056/*
2057* Uniwill P53
2058* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
2059 */
2060static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2061	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2062
2063	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2064	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2065	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2066	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2067	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2068	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2069	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2070	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2071	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2072	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2073	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2074	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2075
2076	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2077	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2078	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2079	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2080	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2081	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2082
2083	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2084	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2085
2086	{ }
2087};
2088
2089static struct hda_verb alc880_beep_init_verbs[] = {
2090	{ 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2091	{ }
2092};
2093
2094/* toggle speaker-output according to the hp-jack state */
2095static void alc880_uniwill_hp_automute(struct hda_codec *codec)
2096{
2097 	unsigned int present;
2098	unsigned char bits;
2099
2100 	present = snd_hda_codec_read(codec, 0x14, 0,
2101				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2102	bits = present ? HDA_AMP_MUTE : 0;
2103	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
2104				 HDA_AMP_MUTE, bits);
2105	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
2106				 HDA_AMP_MUTE, bits);
2107}
2108
2109/* auto-toggle front mic */
2110static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2111{
2112 	unsigned int present;
2113	unsigned char bits;
2114
2115	present = snd_hda_codec_read(codec, 0x18, 0,
2116				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2117	bits = present ? HDA_AMP_MUTE : 0;
2118	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2119}
2120
2121static void alc880_uniwill_automute(struct hda_codec *codec)
2122{
2123	alc880_uniwill_hp_automute(codec);
2124	alc880_uniwill_mic_automute(codec);
2125}
2126
2127static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2128				       unsigned int res)
2129{
2130	/* Looks like the unsol event is incompatible with the standard
2131	 * definition.  4bit tag is placed at 28 bit!
2132	 */
2133	switch (res >> 28) {
2134	case ALC880_HP_EVENT:
2135		alc880_uniwill_hp_automute(codec);
2136		break;
2137	case ALC880_MIC_EVENT:
2138		alc880_uniwill_mic_automute(codec);
2139		break;
2140	}
2141}
2142
2143static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
2144{
2145 	unsigned int present;
2146	unsigned char bits;
2147
2148 	present = snd_hda_codec_read(codec, 0x14, 0,
2149				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2150	bits = present ? HDA_AMP_MUTE : 0;
2151	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
2152}
2153
2154static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2155{
2156	unsigned int present;
2157
2158	present = snd_hda_codec_read(codec, 0x21, 0,
2159				     AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2160	present &= HDA_AMP_VOLMASK;
2161	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2162				 HDA_AMP_VOLMASK, present);
2163	snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2164				 HDA_AMP_VOLMASK, present);
2165}
2166
2167static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2168					   unsigned int res)
2169{
2170	/* Looks like the unsol event is incompatible with the standard
2171	 * definition.  4bit tag is placed at 28 bit!
2172	 */
2173	if ((res >> 28) == ALC880_HP_EVENT)
2174		alc880_uniwill_p53_hp_automute(codec);
2175	if ((res >> 28) == ALC880_DCVOL_EVENT)
2176		alc880_uniwill_p53_dcvol_automute(codec);
2177}
2178
2179/*
2180 * F1734 pin configuration:
2181 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2182 */
2183static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2184	{0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2185	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2186	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2187	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2188	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2189
2190	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2191	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2192	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2193	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2194
2195	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2196	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2197	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2198	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2199	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2200	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2201	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2202	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2203	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2204
2205	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2206	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2207
2208	{ }
2209};
2210
2211/*
2212 * ASUS pin configuration:
2213 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2214 */
2215static struct hda_verb alc880_pin_asus_init_verbs[] = {
2216	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2217	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2218	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2219	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2220
2221	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2222	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2223	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2224	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2225	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2226	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2227	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2228	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2229
2230	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2231	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2232	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2233	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2234	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2235	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2236	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2237	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2238	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2239
2240	{ }
2241};
2242
2243/* Enable GPIO mask and set output */
2244#define alc880_gpio1_init_verbs	alc_gpio1_init_verbs
2245#define alc880_gpio2_init_verbs	alc_gpio2_init_verbs
2246
2247/* Clevo m520g init */
2248static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2249	/* headphone output */
2250	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2251	/* line-out */
2252	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2253	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2254	/* Line-in */
2255	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2256	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2257	/* CD */
2258	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2259	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2260	/* Mic1 (rear panel) */
2261	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2262	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2263	/* Mic2 (front panel) */
2264	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2265	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2266	/* headphone */
2267	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2268	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2269        /* change to EAPD mode */
2270	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2271	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2272
2273	{ }
2274};
2275
2276static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2277	/* change to EAPD mode */
2278	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2279	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2280
2281	/* Headphone output */
2282	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2283	/* Front output*/
2284	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2285	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2286
2287	/* Line In pin widget for input */
2288	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2289	/* CD pin widget for input */
2290	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2291	/* Mic1 (rear panel) pin widget for input and vref at 80% */
2292	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2293
2294	/* change to EAPD mode */
2295	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2296	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
2297
2298	{ }
2299};
2300
2301/*
2302 * LG m1 express dual
2303 *
2304 * Pin assignment:
2305 *   Rear Line-In/Out (blue): 0x14
2306 *   Build-in Mic-In: 0x15
2307 *   Speaker-out: 0x17
2308 *   HP-Out (green): 0x1b
2309 *   Mic-In/Out (red): 0x19
2310 *   SPDIF-Out: 0x1e
2311 */
2312
2313/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2314static hda_nid_t alc880_lg_dac_nids[3] = {
2315	0x05, 0x02, 0x03
2316};
2317
2318/* seems analog CD is not working */
2319static struct hda_input_mux alc880_lg_capture_source = {
2320	.num_items = 3,
2321	.items = {
2322		{ "Mic", 0x1 },
2323		{ "Line", 0x5 },
2324		{ "Internal Mic", 0x6 },
2325	},
2326};
2327
2328/* 2,4,6 channel modes */
2329static struct hda_verb alc880_lg_ch2_init[] = {
2330	/* set line-in and mic-in to input */
2331	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2332	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2333	{ }
2334};
2335
2336static struct hda_verb alc880_lg_ch4_init[] = {
2337	/* set line-in to out and mic-in to input */
2338	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2339	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2340	{ }
2341};
2342
2343static struct hda_verb alc880_lg_ch6_init[] = {
2344	/* set line-in and mic-in to output */
2345	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2346	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2347	{ }
2348};
2349
2350static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2351	{ 2, alc880_lg_ch2_init },
2352	{ 4, alc880_lg_ch4_init },
2353	{ 6, alc880_lg_ch6_init },
2354};
2355
2356static struct snd_kcontrol_new alc880_lg_mixer[] = {
2357	HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2358	HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2359	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2360	HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2361	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2362	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2363	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2364	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2365	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2366	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2367	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2368	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2369	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2370	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2371	{
2372		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2373		.name = "Channel Mode",
2374		.info = alc_ch_mode_info,
2375		.get = alc_ch_mode_get,
2376		.put = alc_ch_mode_put,
2377	},
2378	{ } /* end */
2379};
2380
2381static struct hda_verb alc880_lg_init_verbs[] = {
2382	/* set capture source to mic-in */
2383	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2384	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2385	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2386	/* mute all amp mixer inputs */
2387	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2388	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2389	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2390	/* line-in to input */
2391	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2392	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2393	/* built-in mic */
2394	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2395	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2396	/* speaker-out */
2397	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2398	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2399	/* mic-in to input */
2400	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2401	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2402	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2403	/* HP-out */
2404	{0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2405	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2406	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2407	/* jack sense */
2408	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2409	{ }
2410};
2411
2412/* toggle speaker-output according to the hp-jack state */
2413static void alc880_lg_automute(struct hda_codec *codec)
2414{
2415	unsigned int present;
2416	unsigned char bits;
2417
2418	present = snd_hda_codec_read(codec, 0x1b, 0,
2419				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2420	bits = present ? HDA_AMP_MUTE : 0;
2421	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2422				 HDA_AMP_MUTE, bits);
2423}
2424
2425static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2426{
2427	/* Looks like the unsol event is incompatible with the standard
2428	 * definition.  4bit tag is placed at 28 bit!
2429	 */
2430	if ((res >> 28) == 0x01)
2431		alc880_lg_automute(codec);
2432}
2433
2434/*
2435 * LG LW20
2436 *
2437 * Pin assignment:
2438 *   Speaker-out: 0x14
2439 *   Mic-In: 0x18
2440 *   Built-in Mic-In: 0x19
2441 *   Line-In: 0x1b
2442 *   HP-Out: 0x1a
2443 *   SPDIF-Out: 0x1e
2444 */
2445
2446static struct hda_input_mux alc880_lg_lw_capture_source = {
2447	.num_items = 3,
2448	.items = {
2449		{ "Mic", 0x0 },
2450		{ "Internal Mic", 0x1 },
2451		{ "Line In", 0x2 },
2452	},
2453};
2454
2455#define alc880_lg_lw_modes alc880_threestack_modes
2456
2457static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2458	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2459	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2460	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2461	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2462	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2463	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2464	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2465	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2466	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2467	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2468	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2469	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2470	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2471	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2472	{
2473		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2474		.name = "Channel Mode",
2475		.info = alc_ch_mode_info,
2476		.get = alc_ch_mode_get,
2477		.put = alc_ch_mode_put,
2478	},
2479	{ } /* end */
2480};
2481
2482static struct hda_verb alc880_lg_lw_init_verbs[] = {
2483	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2484	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2485	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2486
2487	/* set capture source to mic-in */
2488	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2489	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2490	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2491	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2492	/* speaker-out */
2493	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2494	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2495	/* HP-out */
2496	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2497	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2498	/* mic-in to input */
2499	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2500	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2501	/* built-in mic */
2502	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2503	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2504	/* jack sense */
2505	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2506	{ }
2507};
2508
2509/* toggle speaker-output according to the hp-jack state */
2510static void alc880_lg_lw_automute(struct hda_codec *codec)
2511{
2512	unsigned int present;
2513	unsigned char bits;
2514
2515	present = snd_hda_codec_read(codec, 0x1b, 0,
2516				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2517	bits = present ? HDA_AMP_MUTE : 0;
2518	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2519				 HDA_AMP_MUTE, bits);
2520}
2521
2522static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2523{
2524	/* Looks like the unsol event is incompatible with the standard
2525	 * definition.  4bit tag is placed at 28 bit!
2526	 */
2527	if ((res >> 28) == 0x01)
2528		alc880_lg_lw_automute(codec);
2529}
2530
2531static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2532	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2533	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2534	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2535	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2536	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2537	HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2538	{ } /* end */
2539};
2540
2541static struct hda_input_mux alc880_medion_rim_capture_source = {
2542	.num_items = 2,
2543	.items = {
2544		{ "Mic", 0x0 },
2545		{ "Internal Mic", 0x1 },
2546	},
2547};
2548
2549static struct hda_verb alc880_medion_rim_init_verbs[] = {
2550	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2551
2552	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2553	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2554
2555	/* Mic1 (rear panel) pin widget for input and vref at 80% */
2556	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2557	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2558	/* Mic2 (as headphone out) for HP output */
2559	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2560	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2561	/* Internal Speaker */
2562	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2563	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2564
2565	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2566	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2567
2568	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2569	{ }
2570};
2571
2572/* toggle speaker-output according to the hp-jack state */
2573static void alc880_medion_rim_automute(struct hda_codec *codec)
2574{
2575	unsigned int present;
2576	unsigned char bits;
2577
2578	present = snd_hda_codec_read(codec, 0x14, 0,
2579				     AC_VERB_GET_PIN_SENSE, 0)
2580		& AC_PINSENSE_PRESENCE;
2581	bits = present ? HDA_AMP_MUTE : 0;
2582	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
2583				 HDA_AMP_MUTE, bits);
2584	if (present)
2585		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2586	else
2587		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2588}
2589
2590static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2591					  unsigned int res)
2592{
2593	/* Looks like the unsol event is incompatible with the standard
2594	 * definition.  4bit tag is placed at 28 bit!
2595	 */
2596	if ((res >> 28) == ALC880_HP_EVENT)
2597		alc880_medion_rim_automute(codec);
2598}
2599
2600#ifdef CONFIG_SND_HDA_POWER_SAVE
2601static struct hda_amp_list alc880_loopbacks[] = {
2602	{ 0x0b, HDA_INPUT, 0 },
2603	{ 0x0b, HDA_INPUT, 1 },
2604	{ 0x0b, HDA_INPUT, 2 },
2605	{ 0x0b, HDA_INPUT, 3 },
2606	{ 0x0b, HDA_INPUT, 4 },
2607	{ } /* end */
2608};
2609
2610static struct hda_amp_list alc880_lg_loopbacks[] = {
2611	{ 0x0b, HDA_INPUT, 1 },
2612	{ 0x0b, HDA_INPUT, 6 },
2613	{ 0x0b, HDA_INPUT, 7 },
2614	{ } /* end */
2615};
2616#endif
2617
2618/*
2619 * Common callbacks
2620 */
2621
2622static int alc_init(struct hda_codec *codec)
2623{
2624	struct alc_spec *spec = codec->spec;
2625	unsigned int i;
2626
2627	alc_fix_pll(codec);
2628	if (codec->vendor_id == 0x10ec0888)
2629		alc888_coef_init(codec);
2630
2631	for (i = 0; i < spec->num_init_verbs; i++)
2632		snd_hda_sequence_write(codec, spec->init_verbs[i]);
2633
2634	if (spec->init_hook)
2635		spec->init_hook(codec);
2636
2637	return 0;
2638}
2639
2640static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2641{
2642	struct alc_spec *spec = codec->spec;
2643
2644	if (spec->unsol_event)
2645		spec->unsol_event(codec, res);
2646}
2647
2648#ifdef CONFIG_SND_HDA_POWER_SAVE
2649static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2650{
2651	struct alc_spec *spec = codec->spec;
2652	return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2653}
2654#endif
2655
2656/*
2657 * Analog playback callbacks
2658 */
2659static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2660				    struct hda_codec *codec,
2661				    struct snd_pcm_substream *substream)
2662{
2663	struct alc_spec *spec = codec->spec;
2664	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2665					     hinfo);
2666}
2667
2668static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2669				       struct hda_codec *codec,
2670				       unsigned int stream_tag,
2671				       unsigned int format,
2672				       struct snd_pcm_substream *substream)
2673{
2674	struct alc_spec *spec = codec->spec;
2675	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2676						stream_tag, format, substream);
2677}
2678
2679static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2680				       struct hda_codec *codec,
2681				       struct snd_pcm_substream *substream)
2682{
2683	struct alc_spec *spec = codec->spec;
2684	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2685}
2686
2687/*
2688 * Digital out
2689 */
2690static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2691					struct hda_codec *codec,
2692					struct snd_pcm_substream *substream)
2693{
2694	struct alc_spec *spec = codec->spec;
2695	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2696}
2697
2698static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2699					   struct hda_codec *codec,
2700					   unsigned int stream_tag,
2701					   unsigned int format,
2702					   struct snd_pcm_substream *substream)
2703{
2704	struct alc_spec *spec = codec->spec;
2705	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2706					     stream_tag, format, substream);
2707}
2708
2709static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2710					 struct hda_codec *codec,
2711					 struct snd_pcm_substream *substream)
2712{
2713	struct alc_spec *spec = codec->spec;
2714	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2715}
2716
2717/*
2718 * Analog capture
2719 */
2720static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2721				      struct hda_codec *codec,
2722				      unsigned int stream_tag,
2723				      unsigned int format,
2724				      struct snd_pcm_substream *substream)
2725{
2726	struct alc_spec *spec = codec->spec;
2727
2728	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
2729				   stream_tag, 0, format);
2730	return 0;
2731}
2732
2733static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2734				      struct hda_codec *codec,
2735				      struct snd_pcm_substream *substream)
2736{
2737	struct alc_spec *spec = codec->spec;
2738
2739	snd_hda_codec_cleanup_stream(codec,
2740				     spec->adc_nids[substream->number + 1]);
2741	return 0;
2742}
2743
2744
2745/*
2746 */
2747static struct hda_pcm_stream alc880_pcm_analog_playback = {
2748	.substreams = 1,
2749	.channels_min = 2,
2750	.channels_max = 8,
2751	/* NID is set in alc_build_pcms */
2752	.ops = {
2753		.open = alc880_playback_pcm_open,
2754		.prepare = alc880_playback_pcm_prepare,
2755		.cleanup = alc880_playback_pcm_cleanup
2756	},
2757};
2758
2759static struct hda_pcm_stream alc880_pcm_analog_capture = {
2760	.substreams = 1,
2761	.channels_min = 2,
2762	.channels_max = 2,
2763	/* NID is set in alc_build_pcms */
2764};
2765
2766static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
2767	.substreams = 1,
2768	.channels_min = 2,
2769	.channels_max = 2,
2770	/* NID is set in alc_build_pcms */
2771};
2772
2773static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
2774	.substreams = 2, /* can be overridden */
2775	.channels_min = 2,
2776	.channels_max = 2,
2777	/* NID is set in alc_build_pcms */
2778	.ops = {
2779		.prepare = alc880_alt_capture_pcm_prepare,
2780		.cleanup = alc880_alt_capture_pcm_cleanup
2781	},
2782};
2783
2784static struct hda_pcm_stream alc880_pcm_digital_playback = {
2785	.substreams = 1,
2786	.channels_min = 2,
2787	.channels_max = 2,
2788	/* NID is set in alc_build_pcms */
2789	.ops = {
2790		.open = alc880_dig_playback_pcm_open,
2791		.close = alc880_dig_playback_pcm_close,
2792		.prepare = alc880_dig_playback_pcm_prepare
2793	},
2794};
2795
2796static struct hda_pcm_stream alc880_pcm_digital_capture = {
2797	.substreams = 1,
2798	.channels_min = 2,
2799	.channels_max = 2,
2800	/* NID is set in alc_build_pcms */
2801};
2802
2803/* Used by alc_build_pcms to flag that a PCM has no playback stream */
2804static struct hda_pcm_stream alc_pcm_null_stream = {
2805	.substreams = 0,
2806	.channels_min = 0,
2807	.channels_max = 0,
2808};
2809
2810static int alc_build_pcms(struct hda_codec *codec)
2811{
2812	struct alc_spec *spec = codec->spec;
2813	struct hda_pcm *info = spec->pcm_rec;
2814	int i;
2815
2816	codec->num_pcms = 1;
2817	codec->pcm_info = info;
2818
2819	info->name = spec->stream_name_analog;
2820	if (spec->stream_analog_playback) {
2821		if (snd_BUG_ON(!spec->multiout.dac_nids))
2822			return -EINVAL;
2823		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2824		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2825	}
2826	if (spec->stream_analog_capture) {
2827		if (snd_BUG_ON(!spec->adc_nids))
2828			return -EINVAL;
2829		info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2830		info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2831	}
2832
2833	if (spec->channel_mode) {
2834		info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2835		for (i = 0; i < spec->num_channel_mode; i++) {
2836			if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2837				info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2838			}
2839		}
2840	}
2841
2842	/* SPDIF for stream index #1 */
2843	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2844		codec->num_pcms = 2;
2845		info = spec->pcm_rec + 1;
2846		info->name = spec->stream_name_digital;
2847		info->pcm_type = HDA_PCM_TYPE_SPDIF;
2848		if (spec->multiout.dig_out_nid &&
2849		    spec->stream_digital_playback) {
2850			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2851			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2852		}
2853		if (spec->dig_in_nid &&
2854		    spec->stream_digital_capture) {
2855			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2856			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2857		}
2858		/* FIXME: do we need this for all Realtek codec models? */
2859		codec->spdif_status_reset = 1;
2860	}
2861
2862	/* If the use of more than one ADC is requested for the current
2863	 * model, configure a second analog capture-only PCM.
2864	 */
2865	/* Additional Analaog capture for index #2 */
2866	if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
2867	    (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
2868		codec->num_pcms = 3;
2869		info = spec->pcm_rec + 2;
2870		info->name = spec->stream_name_analog;
2871		if (spec->alt_dac_nid) {
2872			info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2873				*spec->stream_analog_alt_playback;
2874			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2875				spec->alt_dac_nid;
2876		} else {
2877			info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2878				alc_pcm_null_stream;
2879			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2880		}
2881		if (spec->num_adc_nids > 1) {
2882			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2883				*spec->stream_analog_alt_capture;
2884			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
2885				spec->adc_nids[1];
2886			info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
2887				spec->num_adc_nids - 1;
2888		} else {
2889			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2890				alc_pcm_null_stream;
2891			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
2892		}
2893	}
2894
2895	return 0;
2896}
2897
2898static void alc_free_kctls(struct hda_codec *codec)
2899{
2900	struct alc_spec *spec = codec->spec;
2901
2902	if (spec->kctls.list) {
2903		struct snd_kcontrol_new *kctl = spec->kctls.list;
2904		int i;
2905		for (i = 0; i < spec->kctls.used; i++)
2906			kfree(kctl[i].name);
2907	}
2908	snd_array_free(&spec->kctls);
2909}
2910
2911static void alc_free(struct hda_codec *codec)
2912{
2913	struct alc_spec *spec = codec->spec;
2914
2915	if (!spec)
2916		return;
2917
2918	alc_free_kctls(codec);
2919	kfree(spec);
2920	codec->spec = NULL; /* to be sure */
2921}
2922
2923#ifdef SND_HDA_NEEDS_RESUME
2924static void store_pin_configs(struct hda_codec *codec)
2925{
2926	struct alc_spec *spec = codec->spec;
2927	hda_nid_t nid, end_nid;
2928
2929	end_nid = codec->start_nid + codec->num_nodes;
2930	for (nid = codec->start_nid; nid < end_nid; nid++) {
2931		unsigned int wid_caps = get_wcaps(codec, nid);
2932		unsigned int wid_type =
2933			(wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
2934		if (wid_type != AC_WID_PIN)
2935			continue;
2936		if (spec->num_pins >= ARRAY_SIZE(spec->pin_nids))
2937			break;
2938		spec->pin_nids[spec->num_pins] = nid;
2939		spec->pin_cfgs[spec->num_pins] =
2940			snd_hda_codec_read(codec, nid, 0,
2941					   AC_VERB_GET_CONFIG_DEFAULT, 0);
2942		spec->num_pins++;
2943	}
2944}
2945
2946static void resume_pin_configs(struct hda_codec *codec)
2947{
2948	struct alc_spec *spec = codec->spec;
2949	int i;
2950
2951	for (i = 0; i < spec->num_pins; i++) {
2952		hda_nid_t pin_nid = spec->pin_nids[i];
2953		unsigned int pin_config = spec->pin_cfgs[i];
2954		snd_hda_codec_write(codec, pin_nid, 0,
2955				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
2956				    pin_config & 0x000000ff);
2957		snd_hda_codec_write(codec, pin_nid, 0,
2958				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
2959				    (pin_config & 0x0000ff00) >> 8);
2960		snd_hda_codec_write(codec, pin_nid, 0,
2961				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
2962				    (pin_config & 0x00ff0000) >> 16);
2963		snd_hda_codec_write(codec, pin_nid, 0,
2964				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
2965				    pin_config >> 24);
2966	}
2967}
2968
2969static int alc_resume(struct hda_codec *codec)
2970{
2971	resume_pin_configs(codec);
2972	codec->patch_ops.init(codec);
2973	snd_hda_codec_resume_amp(codec);
2974	snd_hda_codec_resume_cache(codec);
2975	return 0;
2976}
2977#else
2978#define store_pin_configs(codec)
2979#endif
2980
2981/*
2982 */
2983static struct hda_codec_ops alc_patch_ops = {
2984	.build_controls = alc_build_controls,
2985	.build_pcms = alc_build_pcms,
2986	.init = alc_init,
2987	.free = alc_free,
2988	.unsol_event = alc_unsol_event,
2989#ifdef SND_HDA_NEEDS_RESUME
2990	.resume = alc_resume,
2991#endif
2992#ifdef CONFIG_SND_HDA_POWER_SAVE
2993	.check_power_status = alc_check_power_status,
2994#endif
2995};
2996
2997
2998/*
2999 * Test configuration for debugging
3000 *
3001 * Almost all inputs/outputs are enabled.  I/O pins can be configured via
3002 * enum controls.
3003 */
3004#ifdef CONFIG_SND_DEBUG
3005static hda_nid_t alc880_test_dac_nids[4] = {
3006	0x02, 0x03, 0x04, 0x05
3007};
3008
3009static struct hda_input_mux alc880_test_capture_source = {
3010	.num_items = 7,
3011	.items = {
3012		{ "In-1", 0x0 },
3013		{ "In-2", 0x1 },
3014		{ "In-3", 0x2 },
3015		{ "In-4", 0x3 },
3016		{ "CD", 0x4 },
3017		{ "Front", 0x5 },
3018		{ "Surround", 0x6 },
3019	},
3020};
3021
3022static struct hda_channel_mode alc880_test_modes[4] = {
3023	{ 2, NULL },
3024	{ 4, NULL },
3025	{ 6, NULL },
3026	{ 8, NULL },
3027};
3028
3029static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3030				 struct snd_ctl_elem_info *uinfo)
3031{
3032	static char *texts[] = {
3033		"N/A", "Line Out", "HP Out",
3034		"In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3035	};
3036	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3037	uinfo->count = 1;
3038	uinfo->value.enumerated.items = 8;
3039	if (uinfo->value.enumerated.item >= 8)
3040		uinfo->value.enumerated.item = 7;
3041	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3042	return 0;
3043}
3044
3045static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3046				struct snd_ctl_elem_value *ucontrol)
3047{
3048	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3049	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3050	unsigned int pin_ctl, item = 0;
3051
3052	pin_ctl = snd_hda_codec_read(codec, nid, 0,
3053				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3054	if (pin_ctl & AC_PINCTL_OUT_EN) {
3055		if (pin_ctl & AC_PINCTL_HP_EN)
3056			item = 2;
3057		else
3058			item = 1;
3059	} else if (pin_ctl & AC_PINCTL_IN_EN) {
3060		switch (pin_ctl & AC_PINCTL_VREFEN) {
3061		case AC_PINCTL_VREF_HIZ: item = 3; break;
3062		case AC_PINCTL_VREF_50:  item = 4; break;
3063		case AC_PINCTL_VREF_GRD: item = 5; break;
3064		case AC_PINCTL_VREF_80:  item = 6; break;
3065		case AC_PINCTL_VREF_100: item = 7; break;
3066		}
3067	}
3068	ucontrol->value.enumerated.item[0] = item;
3069	return 0;
3070}
3071
3072static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3073				struct snd_ctl_elem_value *ucontrol)
3074{
3075	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3076	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3077	static unsigned int ctls[] = {
3078		0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3079		AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3080		AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3081		AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3082		AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3083		AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3084	};
3085	unsigned int old_ctl, new_ctl;
3086
3087	old_ctl = snd_hda_codec_read(codec, nid, 0,
3088				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3089	new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3090	if (old_ctl != new_ctl) {
3091		int val;
3092		snd_hda_codec_write_cache(codec, nid, 0,
3093					  AC_VERB_SET_PIN_WIDGET_CONTROL,
3094					  new_ctl);
3095		val = ucontrol->value.enumerated.item[0] >= 3 ?
3096			HDA_AMP_MUTE : 0;
3097		snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3098					 HDA_AMP_MUTE, val);
3099		return 1;
3100	}
3101	return 0;
3102}
3103
3104static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3105				 struct snd_ctl_elem_info *uinfo)
3106{
3107	static char *texts[] = {
3108		"Front", "Surround", "CLFE", "Side"
3109	};
3110	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3111	uinfo->count = 1;
3112	uinfo->value.enumerated.items = 4;
3113	if (uinfo->value.enumerated.item >= 4)
3114		uinfo->value.enumerated.item = 3;
3115	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3116	return 0;
3117}
3118
3119static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3120				struct snd_ctl_elem_value *ucontrol)
3121{
3122	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3123	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3124	unsigned int sel;
3125
3126	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3127	ucontrol->value.enumerated.item[0] = sel & 3;
3128	return 0;
3129}
3130
3131static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3132				struct snd_ctl_elem_value *ucontrol)
3133{
3134	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3135	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3136	unsigned int sel;
3137
3138	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3139	if (ucontrol->value.enumerated.item[0] != sel) {
3140		sel = ucontrol->value.enumerated.item[0] & 3;
3141		snd_hda_codec_write_cache(codec, nid, 0,
3142					  AC_VERB_SET_CONNECT_SEL, sel);
3143		return 1;
3144	}
3145	return 0;
3146}
3147
3148#define PIN_CTL_TEST(xname,nid) {			\
3149		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
3150			.name = xname,		       \
3151			.info = alc_test_pin_ctl_info, \
3152			.get = alc_test_pin_ctl_get,   \
3153			.put = alc_test_pin_ctl_put,   \
3154			.private_value = nid	       \
3155			}
3156
3157#define PIN_SRC_TEST(xname,nid) {			\
3158		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
3159			.name = xname,		       \
3160			.info = alc_test_pin_src_info, \
3161			.get = alc_test_pin_src_get,   \
3162			.put = alc_test_pin_src_put,   \
3163			.private_value = nid	       \
3164			}
3165
3166static struct snd_kcontrol_new alc880_test_mixer[] = {
3167	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3168	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3169	HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3170	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3171	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3172	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3173	HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3174	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
3175	PIN_CTL_TEST("Front Pin Mode", 0x14),
3176	PIN_CTL_TEST("Surround Pin Mode", 0x15),
3177	PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3178	PIN_CTL_TEST("Side Pin Mode", 0x17),
3179	PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3180	PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3181	PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3182	PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3183	PIN_SRC_TEST("In-1 Pin Source", 0x18),
3184	PIN_SRC_TEST("In-2 Pin Source", 0x19),
3185	PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3186	PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3187	HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3188	HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3189	HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3190	HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3191	HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3192	HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3193	HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3194	HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3195	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3196	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
3197	{
3198		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3199		.name = "Channel Mode",
3200		.info = alc_ch_mode_info,
3201		.get = alc_ch_mode_get,
3202		.put = alc_ch_mode_put,
3203	},
3204	{ } /* end */
3205};
3206
3207static struct hda_verb alc880_test_init_verbs[] = {
3208	/* Unmute inputs of 0x0c - 0x0f */
3209	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3210	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3211	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3212	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3213	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3214	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3215	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3216	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3217	/* Vol output for 0x0c-0x0f */
3218	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3219	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3220	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3221	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3222	/* Set output pins 0x14-0x17 */
3223	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3224	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3225	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3226	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3227	/* Unmute output pins 0x14-0x17 */
3228	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3229	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3230	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3231	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3232	/* Set input pins 0x18-0x1c */
3233	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3234	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3235	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3236	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3237	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3238	/* Mute input pins 0x18-0x1b */
3239	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3240	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3241	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3242	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3243	/* ADC set up */
3244	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3245	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3246	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3247	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3248	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3249	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3250	/* Analog input/passthru */
3251	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3252	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3253	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3254	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3255	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3256	{ }
3257};
3258#endif
3259
3260/*
3261 */
3262
3263static const char *alc880_models[ALC880_MODEL_LAST] = {
3264	[ALC880_3ST]		= "3stack",
3265	[ALC880_TCL_S700]	= "tcl",
3266	[ALC880_3ST_DIG]	= "3stack-digout",
3267	[ALC880_CLEVO]		= "clevo",
3268	[ALC880_5ST]		= "5stack",
3269	[ALC880_5ST_DIG]	= "5stack-digout",
3270	[ALC880_W810]		= "w810",
3271	[ALC880_Z71V]		= "z71v",
3272	[ALC880_6ST]		= "6stack",
3273	[ALC880_6ST_DIG]	= "6stack-digout",
3274	[ALC880_ASUS]		= "asus",
3275	[ALC880_ASUS_W1V]	= "asus-w1v",
3276	[ALC880_ASUS_DIG]	= "asus-dig",
3277	[ALC880_ASUS_DIG2]	= "asus-dig2",
3278	[ALC880_UNIWILL_DIG]	= "uniwill",
3279	[ALC880_UNIWILL_P53]	= "uniwill-p53",
3280	[ALC880_FUJITSU]	= "fujitsu",
3281	[ALC880_F1734]		= "F1734",
3282	[ALC880_LG]		= "lg",
3283	[ALC880_LG_LW]		= "lg-lw",
3284	[ALC880_MEDION_RIM]	= "medion",
3285#ifdef CONFIG_SND_DEBUG
3286	[ALC880_TEST]		= "test",
3287#endif
3288	[ALC880_AUTO]		= "auto",
3289};
3290
3291static struct snd_pci_quirk alc880_cfg_tbl[] = {
3292	SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3293	SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3294	SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3295	SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3296	SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3297	SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3298	SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3299	SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3300	SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3301	SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3302	SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3303	SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3304	SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3305	SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3306	SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3307	SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3308	SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3309	SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3310	/* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3311	SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3312	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3313	SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3314	SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3315	SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3316	SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3317	SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
3318	SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3319	SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3320	SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3321	SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3322	SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3323	SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3324	SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3325	SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3326	SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3327	SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3328	SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3329	SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3330	SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3331	SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3332	SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3333	SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3334	SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3335	SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3336	SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3337	SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3338	SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3339	SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3340	SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3341	SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3342	SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3343	SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3344	SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3345	SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3346	SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3347	SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3348	SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3349	SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3350	SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3351	SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3352	SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3353	SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3354	SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3355	SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3356	SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3357	SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3358	SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3359	SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3360	SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
3361	SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3362	SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3363	{}
3364};
3365
3366/*
3367 * ALC880 codec presets
3368 */
3369static struct alc_config_preset alc880_presets[] = {
3370	[ALC880_3ST] = {
3371		.mixers = { alc880_three_stack_mixer },
3372		.init_verbs = { alc880_volume_init_verbs,
3373				alc880_pin_3stack_init_verbs },
3374		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3375		.dac_nids = alc880_dac_nids,
3376		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3377		.channel_mode = alc880_threestack_modes,
3378		.need_dac_fix = 1,
3379		.input_mux = &alc880_capture_source,
3380	},
3381	[ALC880_3ST_DIG] = {
3382		.mixers = { alc880_three_stack_mixer },
3383		.init_verbs = { alc880_volume_init_verbs,
3384				alc880_pin_3stack_init_verbs },
3385		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3386		.dac_nids = alc880_dac_nids,
3387		.dig_out_nid = ALC880_DIGOUT_NID,
3388		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3389		.channel_mode = alc880_threestack_modes,
3390		.need_dac_fix = 1,
3391		.input_mux = &alc880_capture_source,
3392	},
3393	[ALC880_TCL_S700] = {
3394		.mixers = { alc880_tcl_s700_mixer },
3395		.init_verbs = { alc880_volume_init_verbs,
3396				alc880_pin_tcl_S700_init_verbs,
3397				alc880_gpio2_init_verbs },
3398		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3399		.dac_nids = alc880_dac_nids,
3400		.adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
3401		.num_adc_nids = 1, /* single ADC */
3402		.hp_nid = 0x03,
3403		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3404		.channel_mode = alc880_2_jack_modes,
3405		.input_mux = &alc880_capture_source,
3406	},
3407	[ALC880_5ST] = {
3408		.mixers = { alc880_three_stack_mixer,
3409			    alc880_five_stack_mixer},
3410		.init_verbs = { alc880_volume_init_verbs,
3411				alc880_pin_5stack_init_verbs },
3412		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3413		.dac_nids = alc880_dac_nids,
3414		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3415		.channel_mode = alc880_fivestack_modes,
3416		.input_mux = &alc880_capture_source,
3417	},
3418	[ALC880_5ST_DIG] = {
3419		.mixers = { alc880_three_stack_mixer,
3420			    alc880_five_stack_mixer },
3421		.init_verbs = { alc880_volume_init_verbs,
3422				alc880_pin_5stack_init_verbs },
3423		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3424		.dac_nids = alc880_dac_nids,
3425		.dig_out_nid = ALC880_DIGOUT_NID,
3426		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3427		.channel_mode = alc880_fivestack_modes,
3428		.input_mux = &alc880_capture_source,
3429	},
3430	[ALC880_6ST] = {
3431		.mixers = { alc880_six_stack_mixer },
3432		.init_verbs = { alc880_volume_init_verbs,
3433				alc880_pin_6stack_init_verbs },
3434		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3435		.dac_nids = alc880_6st_dac_nids,
3436		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3437		.channel_mode = alc880_sixstack_modes,
3438		.input_mux = &alc880_6stack_capture_source,
3439	},
3440	[ALC880_6ST_DIG] = {
3441		.mixers = { alc880_six_stack_mixer },
3442		.init_verbs = { alc880_volume_init_verbs,
3443				alc880_pin_6stack_init_verbs },
3444		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3445		.dac_nids = alc880_6st_dac_nids,
3446		.dig_out_nid = ALC880_DIGOUT_NID,
3447		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3448		.channel_mode = alc880_sixstack_modes,
3449		.input_mux = &alc880_6stack_capture_source,
3450	},
3451	[ALC880_W810] = {
3452		.mixers = { alc880_w810_base_mixer },
3453		.init_verbs = { alc880_volume_init_verbs,
3454				alc880_pin_w810_init_verbs,
3455				alc880_gpio2_init_verbs },
3456		.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3457		.dac_nids = alc880_w810_dac_nids,
3458		.dig_out_nid = ALC880_DIGOUT_NID,
3459		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3460		.channel_mode = alc880_w810_modes,
3461		.input_mux = &alc880_capture_source,
3462	},
3463	[ALC880_Z71V] = {
3464		.mixers = { alc880_z71v_mixer },
3465		.init_verbs = { alc880_volume_init_verbs,
3466				alc880_pin_z71v_init_verbs },
3467		.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3468		.dac_nids = alc880_z71v_dac_nids,
3469		.dig_out_nid = ALC880_DIGOUT_NID,
3470		.hp_nid = 0x03,
3471		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3472		.channel_mode = alc880_2_jack_modes,
3473		.input_mux = &alc880_capture_source,
3474	},
3475	[ALC880_F1734] = {
3476		.mixers = { alc880_f1734_mixer },
3477		.init_verbs = { alc880_volume_init_verbs,
3478				alc880_pin_f1734_init_verbs },
3479		.num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3480		.dac_nids = alc880_f1734_dac_nids,
3481		.hp_nid = 0x02,
3482		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3483		.channel_mode = alc880_2_jack_modes,
3484		.input_mux = &alc880_f1734_capture_source,
3485		.unsol_event = alc880_uniwill_p53_unsol_event,
3486		.init_hook = alc880_uniwill_p53_hp_automute,
3487	},
3488	[ALC880_ASUS] = {
3489		.mixers = { alc880_asus_mixer },
3490		.init_verbs = { alc880_volume_init_verbs,
3491				alc880_pin_asus_init_verbs,
3492				alc880_gpio1_init_verbs },
3493		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3494		.dac_nids = alc880_asus_dac_nids,
3495		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3496		.channel_mode = alc880_asus_modes,
3497		.need_dac_fix = 1,
3498		.input_mux = &alc880_capture_source,
3499	},
3500	[ALC880_ASUS_DIG] = {
3501		.mixers = { alc880_asus_mixer },
3502		.init_verbs = { alc880_volume_init_verbs,
3503				alc880_pin_asus_init_verbs,
3504				alc880_gpio1_init_verbs },
3505		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3506		.dac_nids = alc880_asus_dac_nids,
3507		.dig_out_nid = ALC880_DIGOUT_NID,
3508		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3509		.channel_mode = alc880_asus_modes,
3510		.need_dac_fix = 1,
3511		.input_mux = &alc880_capture_source,
3512	},
3513	[ALC880_ASUS_DIG2] = {
3514		.mixers = { alc880_asus_mixer },
3515		.init_verbs = { alc880_volume_init_verbs,
3516				alc880_pin_asus_init_verbs,
3517				alc880_gpio2_init_verbs }, /* use GPIO2 */
3518		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3519		.dac_nids = alc880_asus_dac_nids,
3520		.dig_out_nid = ALC880_DIGOUT_NID,
3521		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3522		.channel_mode = alc880_asus_modes,
3523		.need_dac_fix = 1,
3524		.input_mux = &alc880_capture_source,
3525	},
3526	[ALC880_ASUS_W1V] = {
3527		.mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3528		.init_verbs = { alc880_volume_init_verbs,
3529				alc880_pin_asus_init_verbs,
3530				alc880_gpio1_init_verbs },
3531		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3532		.dac_nids = alc880_asus_dac_nids,
3533		.dig_out_nid = ALC880_DIGOUT_NID,
3534		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3535		.channel_mode = alc880_asus_modes,
3536		.need_dac_fix = 1,
3537		.input_mux = &alc880_capture_source,
3538	},
3539	[ALC880_UNIWILL_DIG] = {
3540		.mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
3541		.init_verbs = { alc880_volume_init_verbs,
3542				alc880_pin_asus_init_verbs },
3543		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3544		.dac_nids = alc880_asus_dac_nids,
3545		.dig_out_nid = ALC880_DIGOUT_NID,
3546		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3547		.channel_mode = alc880_asus_modes,
3548		.need_dac_fix = 1,
3549		.input_mux = &alc880_capture_source,
3550	},
3551	[ALC880_UNIWILL] = {
3552		.mixers = { alc880_uniwill_mixer },
3553		.init_verbs = { alc880_volume_init_verbs,
3554				alc880_uniwill_init_verbs },
3555		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3556		.dac_nids = alc880_asus_dac_nids,
3557		.dig_out_nid = ALC880_DIGOUT_NID,
3558		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3559		.channel_mode = alc880_threestack_modes,
3560		.need_dac_fix = 1,
3561		.input_mux = &alc880_capture_source,
3562		.unsol_event = alc880_uniwill_unsol_event,
3563		.init_hook = alc880_uniwill_automute,
3564	},
3565	[ALC880_UNIWILL_P53] = {
3566		.mixers = { alc880_uniwill_p53_mixer },
3567		.init_verbs = { alc880_volume_init_verbs,
3568				alc880_uniwill_p53_init_verbs },
3569		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3570		.dac_nids = alc880_asus_dac_nids,
3571		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3572		.channel_mode = alc880_threestack_modes,
3573		.input_mux = &alc880_capture_source,
3574		.unsol_event = alc880_uniwill_p53_unsol_event,
3575		.init_hook = alc880_uniwill_p53_hp_automute,
3576	},
3577	[ALC880_FUJITSU] = {
3578		.mixers = { alc880_fujitsu_mixer,
3579			    alc880_pcbeep_mixer, },
3580		.init_verbs = { alc880_volume_init_verbs,
3581				alc880_uniwill_p53_init_verbs,
3582	       			alc880_beep_init_verbs },
3583		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3584		.dac_nids = alc880_dac_nids,
3585		.dig_out_nid = ALC880_DIGOUT_NID,
3586		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3587		.channel_mode = alc880_2_jack_modes,
3588		.input_mux = &alc880_capture_source,
3589		.unsol_event = alc880_uniwill_p53_unsol_event,
3590		.init_hook = alc880_uniwill_p53_hp_automute,
3591	},
3592	[ALC880_CLEVO] = {
3593		.mixers = { alc880_three_stack_mixer },
3594		.init_verbs = { alc880_volume_init_verbs,
3595				alc880_pin_clevo_init_verbs },
3596		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3597		.dac_nids = alc880_dac_nids,
3598		.hp_nid = 0x03,
3599		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3600		.channel_mode = alc880_threestack_modes,
3601		.need_dac_fix = 1,
3602		.input_mux = &alc880_capture_source,
3603	},
3604	[ALC880_LG] = {
3605		.mixers = { alc880_lg_mixer },
3606		.init_verbs = { alc880_volume_init_verbs,
3607				alc880_lg_init_verbs },
3608		.num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3609		.dac_nids = alc880_lg_dac_nids,
3610		.dig_out_nid = ALC880_DIGOUT_NID,
3611		.num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3612		.channel_mode = alc880_lg_ch_modes,
3613		.need_dac_fix = 1,
3614		.input_mux = &alc880_lg_capture_source,
3615		.unsol_event = alc880_lg_unsol_event,
3616		.init_hook = alc880_lg_automute,
3617#ifdef CONFIG_SND_HDA_POWER_SAVE
3618		.loopbacks = alc880_lg_loopbacks,
3619#endif
3620	},
3621	[ALC880_LG_LW] = {
3622		.mixers = { alc880_lg_lw_mixer },
3623		.init_verbs = { alc880_volume_init_verbs,
3624				alc880_lg_lw_init_verbs },
3625		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3626		.dac_nids = alc880_dac_nids,
3627		.dig_out_nid = ALC880_DIGOUT_NID,
3628		.num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3629		.channel_mode = alc880_lg_lw_modes,
3630		.input_mux = &alc880_lg_lw_capture_source,
3631		.unsol_event = alc880_lg_lw_unsol_event,
3632		.init_hook = alc880_lg_lw_automute,
3633	},
3634	[ALC880_MEDION_RIM] = {
3635		.mixers = { alc880_medion_rim_mixer },
3636		.init_verbs = { alc880_volume_init_verbs,
3637				alc880_medion_rim_init_verbs,
3638				alc_gpio2_init_verbs },
3639		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3640		.dac_nids = alc880_dac_nids,
3641		.dig_out_nid = ALC880_DIGOUT_NID,
3642		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3643		.channel_mode = alc880_2_jack_modes,
3644		.input_mux = &alc880_medion_rim_capture_source,
3645		.unsol_event = alc880_medion_rim_unsol_event,
3646		.init_hook = alc880_medion_rim_automute,
3647	},
3648#ifdef CONFIG_SND_DEBUG
3649	[ALC880_TEST] = {
3650		.mixers = { alc880_test_mixer },
3651		.init_verbs = { alc880_test_init_verbs },
3652		.num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3653		.dac_nids = alc880_test_dac_nids,
3654		.dig_out_nid = ALC880_DIGOUT_NID,
3655		.num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3656		.channel_mode = alc880_test_modes,
3657		.input_mux = &alc880_test_capture_source,
3658	},
3659#endif
3660};
3661
3662/*
3663 * Automatic parse of I/O pins from the BIOS configuration
3664 */
3665
3666enum {
3667	ALC_CTL_WIDGET_VOL,
3668	ALC_CTL_WIDGET_MUTE,
3669	ALC_CTL_BIND_MUTE,
3670};
3671static struct snd_kcontrol_new alc880_control_templates[] = {
3672	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3673	HDA_CODEC_MUTE(NULL, 0, 0, 0),
3674	HDA_BIND_MUTE(NULL, 0, 0, 0),
3675};
3676
3677/* add dynamic controls */
3678static int add_control(struct alc_spec *spec, int type, const char *name,
3679		       unsigned long val)
3680{
3681	struct snd_kcontrol_new *knew;
3682
3683	snd_array_init(&spec->kctls, sizeof(*knew), 32);
3684	knew = snd_array_new(&spec->kctls);
3685	if (!knew)
3686		return -ENOMEM;
3687	*knew = alc880_control_templates[type];
3688	knew->name = kstrdup(name, GFP_KERNEL);
3689	if (!knew->name)
3690		return -ENOMEM;
3691	knew->private_value = val;
3692	return 0;
3693}
3694
3695#define alc880_is_fixed_pin(nid)	((nid) >= 0x14 && (nid) <= 0x17)
3696#define alc880_fixed_pin_idx(nid)	((nid) - 0x14)
3697#define alc880_is_multi_pin(nid)	((nid) >= 0x18)
3698#define alc880_multi_pin_idx(nid)	((nid) - 0x18)
3699#define alc880_is_input_pin(nid)	((nid) >= 0x18)
3700#define alc880_input_pin_idx(nid)	((nid) - 0x18)
3701#define alc880_idx_to_dac(nid)		((nid) + 0x02)
3702#define alc880_dac_to_idx(nid)		((nid) - 0x02)
3703#define alc880_idx_to_mixer(nid)	((nid) + 0x0c)
3704#define alc880_idx_to_selector(nid)	((nid) + 0x10)
3705#define ALC880_PIN_CD_NID		0x1c
3706
3707/* fill in the dac_nids table from the parsed pin configuration */
3708static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3709				     const struct auto_pin_cfg *cfg)
3710{
3711	hda_nid_t nid;
3712	int assigned[4];
3713	int i, j;
3714
3715	memset(assigned, 0, sizeof(assigned));
3716	spec->multiout.dac_nids = spec->private_dac_nids;
3717
3718	/* check the pins hardwired to audio widget */
3719	for (i = 0; i < cfg->line_outs; i++) {
3720		nid = cfg->line_out_pins[i];
3721		if (alc880_is_fixed_pin(nid)) {
3722			int idx = alc880_fixed_pin_idx(nid);
3723			spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3724			assigned[idx] = 1;
3725		}
3726	}
3727	/* left pins can be connect to any audio widget */
3728	for (i = 0; i < cfg->line_outs; i++) {
3729		nid = cfg->line_out_pins[i];
3730		if (alc880_is_fixed_pin(nid))
3731			continue;
3732		/* search for an empty channel */
3733		for (j = 0; j < cfg->line_outs; j++) {
3734			if (!assigned[j]) {
3735				spec->multiout.dac_nids[i] =
3736					alc880_idx_to_dac(j);
3737				assigned[j] = 1;
3738				break;
3739			}
3740		}
3741	}
3742	spec->multiout.num_dacs = cfg->line_outs;
3743	return 0;
3744}
3745
3746/* add playback controls from the parsed DAC table */
3747static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3748					     const struct auto_pin_cfg *cfg)
3749{
3750	char name[32];
3751	static const char *chname[4] = {
3752		"Front", "Surround", NULL /*CLFE*/, "Side"
3753	};
3754	hda_nid_t nid;
3755	int i, err;
3756
3757	for (i = 0; i < cfg->line_outs; i++) {
3758		if (!spec->multiout.dac_nids[i])
3759			continue;
3760		nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3761		if (i == 2) {
3762			/* Center/LFE */
3763			err = add_control(spec, ALC_CTL_WIDGET_VOL,
3764					  "Center Playback Volume",
3765					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3766							      HDA_OUTPUT));
3767			if (err < 0)
3768				return err;
3769			err = add_control(spec, ALC_CTL_WIDGET_VOL,
3770					  "LFE Playback Volume",
3771					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3772							      HDA_OUTPUT));
3773			if (err < 0)
3774				return err;
3775			err = add_control(spec, ALC_CTL_BIND_MUTE,
3776					  "Center Playback Switch",
3777					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3778							      HDA_INPUT));
3779			if (err < 0)
3780				return err;
3781			err = add_control(spec, ALC_CTL_BIND_MUTE,
3782					  "LFE Playback Switch",
3783					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3784							      HDA_INPUT));
3785			if (err < 0)
3786				return err;
3787		} else {
3788			sprintf(name, "%s Playback Volume", chname[i]);
3789			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3790					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3791							      HDA_OUTPUT));
3792			if (err < 0)
3793				return err;
3794			sprintf(name, "%s Playback Switch", chname[i]);
3795			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3796					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3797							      HDA_INPUT));
3798			if (err < 0)
3799				return err;
3800		}
3801	}
3802	return 0;
3803}
3804
3805/* add playback controls for speaker and HP outputs */
3806static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3807					const char *pfx)
3808{
3809	hda_nid_t nid;
3810	int err;
3811	char name[32];
3812
3813	if (!pin)
3814		return 0;
3815
3816	if (alc880_is_fixed_pin(pin)) {
3817		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3818		/* specify the DAC as the extra output */
3819		if (!spec->multiout.hp_nid)
3820			spec->multiout.hp_nid = nid;
3821		else
3822			spec->multiout.extra_out_nid[0] = nid;
3823		/* control HP volume/switch on the output mixer amp */
3824		nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3825		sprintf(name, "%s Playback Volume", pfx);
3826		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3827				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3828		if (err < 0)
3829			return err;
3830		sprintf(name, "%s Playback Switch", pfx);
3831		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3832				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3833		if (err < 0)
3834			return err;
3835	} else if (alc880_is_multi_pin(pin)) {
3836		/* set manual connection */
3837		/* we have only a switch on HP-out PIN */
3838		sprintf(name, "%s Playback Switch", pfx);
3839		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3840				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3841		if (err < 0)
3842			return err;
3843	}
3844	return 0;
3845}
3846
3847/* create input playback/capture controls for the given pin */
3848static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3849			    const char *ctlname,
3850			    int idx, hda_nid_t mix_nid)
3851{
3852	char name[32];
3853	int err;
3854
3855	sprintf(name, "%s Playback Volume", ctlname);
3856	err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3857			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3858	if (err < 0)
3859		return err;
3860	sprintf(name, "%s Playback Switch", ctlname);
3861	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3862			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3863	if (err < 0)
3864		return err;
3865	return 0;
3866}
3867
3868/* create playback/capture controls for input pins */
3869static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3870						const struct auto_pin_cfg *cfg)
3871{
3872	struct hda_input_mux *imux = &spec->private_imux;
3873	int i, err, idx;
3874
3875	for (i = 0; i < AUTO_PIN_LAST; i++) {
3876		if (alc880_is_input_pin(cfg->input_pins[i])) {
3877			idx = alc880_input_pin_idx(cfg->input_pins[i]);
3878			err = new_analog_input(spec, cfg->input_pins[i],
3879					       auto_pin_cfg_labels[i],
3880					       idx, 0x0b);
3881			if (err < 0)
3882				return err;
3883			imux->items[imux->num_items].label =
3884				auto_pin_cfg_labels[i];
3885			imux->items[imux->num_items].index =
3886				alc880_input_pin_idx(cfg->input_pins[i]);
3887			imux->num_items++;
3888		}
3889	}
3890	return 0;
3891}
3892
3893static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
3894			       unsigned int pin_type)
3895{
3896	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3897			    pin_type);
3898	/* unmute pin */
3899	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3900			    AMP_OUT_UNMUTE);
3901}
3902
3903static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3904					      hda_nid_t nid, int pin_type,
3905					      int dac_idx)
3906{
3907	alc_set_pin_output(codec, nid, pin_type);
3908	/* need the manual connection? */
3909	if (alc880_is_multi_pin(nid)) {
3910		struct alc_spec *spec = codec->spec;
3911		int idx = alc880_multi_pin_idx(nid);
3912		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3913				    AC_VERB_SET_CONNECT_SEL,
3914				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3915	}
3916}
3917
3918static int get_pin_type(int line_out_type)
3919{
3920	if (line_out_type == AUTO_PIN_HP_OUT)
3921		return PIN_HP;
3922	else
3923		return PIN_OUT;
3924}
3925
3926static void alc880_auto_init_multi_out(struct hda_codec *codec)
3927{
3928	struct alc_spec *spec = codec->spec;
3929	int i;
3930
3931	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3932	for (i = 0; i < spec->autocfg.line_outs; i++) {
3933		hda_nid_t nid = spec->autocfg.line_out_pins[i];
3934		int pin_type = get_pin_type(spec->autocfg.line_out_type);
3935		alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3936	}
3937}
3938
3939static void alc880_auto_init_extra_out(struct hda_codec *codec)
3940{
3941	struct alc_spec *spec = codec->spec;
3942	hda_nid_t pin;
3943
3944	pin = spec->autocfg.speaker_pins[0];
3945	if (pin) /* connect to front */
3946		alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3947	pin = spec->autocfg.hp_pins[0];
3948	if (pin) /* connect to front */
3949		alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3950}
3951
3952static void alc880_auto_init_analog_input(struct hda_codec *codec)
3953{
3954	struct alc_spec *spec = codec->spec;
3955	int i;
3956
3957	for (i = 0; i < AUTO_PIN_LAST; i++) {
3958		hda_nid_t nid = spec->autocfg.input_pins[i];
3959		if (alc880_is_input_pin(nid)) {
3960			snd_hda_codec_write(codec, nid, 0,
3961					    AC_VERB_SET_PIN_WIDGET_CONTROL,
3962					    i <= AUTO_PIN_FRONT_MIC ?
3963					    PIN_VREF80 : PIN_IN);
3964			if (nid != ALC880_PIN_CD_NID)
3965				snd_hda_codec_write(codec, nid, 0,
3966						    AC_VERB_SET_AMP_GAIN_MUTE,
3967						    AMP_OUT_MUTE);
3968		}
3969	}
3970}
3971
3972/* parse the BIOS configuration and set up the alc_spec */
3973/* return 1 if successful, 0 if the proper config is not found,
3974 * or a negative error code
3975 */
3976static int alc880_parse_auto_config(struct hda_codec *codec)
3977{
3978	struct alc_spec *spec = codec->spec;
3979	int err;
3980	static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3981
3982	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3983					   alc880_ignore);
3984	if (err < 0)
3985		return err;
3986	if (!spec->autocfg.line_outs)
3987		return 0; /* can't find valid BIOS pin config */
3988
3989	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3990	if (err < 0)
3991		return err;
3992	err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3993	if (err < 0)
3994		return err;
3995	err = alc880_auto_create_extra_out(spec,
3996					   spec->autocfg.speaker_pins[0],
3997					   "Speaker");
3998	if (err < 0)
3999		return err;
4000	err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4001					   "Headphone");
4002	if (err < 0)
4003		return err;
4004	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
4005	if (err < 0)
4006		return err;
4007
4008	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4009
4010	if (spec->autocfg.dig_out_pin)
4011		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
4012	if (spec->autocfg.dig_in_pin)
4013		spec->dig_in_nid = ALC880_DIGIN_NID;
4014
4015	if (spec->kctls.list)
4016		add_mixer(spec, spec->kctls.list);
4017
4018	add_verb(spec, alc880_volume_init_verbs);
4019
4020	spec->num_mux_defs = 1;
4021	spec->input_mux = &spec->private_imux;
4022
4023	store_pin_configs(codec);
4024	return 1;
4025}
4026
4027/* additional initialization for auto-configuration model */
4028static void alc880_auto_init(struct hda_codec *codec)
4029{
4030	struct alc_spec *spec = codec->spec;
4031	alc880_auto_init_multi_out(codec);
4032	alc880_auto_init_extra_out(codec);
4033	alc880_auto_init_analog_input(codec);
4034	if (spec->unsol_event)
4035		alc_inithook(codec);
4036}
4037
4038/*
4039 * OK, here we have finally the patch for ALC880
4040 */
4041
4042static void set_capture_mixer(struct alc_spec *spec)
4043{
4044	static struct snd_kcontrol_new *caps[3] = {
4045		alc_capture_mixer1,
4046		alc_capture_mixer2,
4047		alc_capture_mixer3,
4048	};
4049	if (spec->num_adc_nids > 0 && spec->num_adc_nids < 3)
4050		spec->cap_mixer = caps[spec->num_adc_nids - 1];
4051}
4052
4053static int patch_alc880(struct hda_codec *codec)
4054{
4055	struct alc_spec *spec;
4056	int board_config;
4057	int err;
4058
4059	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4060	if (spec == NULL)
4061		return -ENOMEM;
4062
4063	codec->spec = spec;
4064
4065	board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4066						  alc880_models,
4067						  alc880_cfg_tbl);
4068	if (board_config < 0) {
4069		printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
4070		       "trying auto-probe from BIOS...\n");
4071		board_config = ALC880_AUTO;
4072	}
4073
4074	if (board_config == ALC880_AUTO) {
4075		/* automatic parse from the BIOS config */
4076		err = alc880_parse_auto_config(codec);
4077		if (err < 0) {
4078			alc_free(codec);
4079			return err;
4080		} else if (!err) {
4081			printk(KERN_INFO
4082			       "hda_codec: Cannot set up configuration "
4083			       "from BIOS.  Using 3-stack mode...\n");
4084			board_config = ALC880_3ST;
4085		}
4086	}
4087
4088	if (board_config != ALC880_AUTO)
4089		setup_preset(spec, &alc880_presets[board_config]);
4090
4091	spec->stream_name_analog = "ALC880 Analog";
4092	spec->stream_analog_playback = &alc880_pcm_analog_playback;
4093	spec->stream_analog_capture = &alc880_pcm_analog_capture;
4094	spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
4095
4096	spec->stream_name_digital = "ALC880 Digital";
4097	spec->stream_digital_playback = &alc880_pcm_digital_playback;
4098	spec->stream_digital_capture = &alc880_pcm_digital_capture;
4099
4100	if (!spec->adc_nids && spec->input_mux) {
4101		/* check whether NID 0x07 is valid */
4102		unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
4103		/* get type */
4104		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
4105		if (wcap != AC_WID_AUD_IN) {
4106			spec->adc_nids = alc880_adc_nids_alt;
4107			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
4108		} else {
4109			spec->adc_nids = alc880_adc_nids;
4110			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
4111		}
4112	}
4113	set_capture_mixer(spec);
4114
4115	spec->vmaster_nid = 0x0c;
4116
4117	codec->patch_ops = alc_patch_ops;
4118	if (board_config == ALC880_AUTO)
4119		spec->init_hook = alc880_auto_init;
4120#ifdef CONFIG_SND_HDA_POWER_SAVE
4121	if (!spec->loopback.amplist)
4122		spec->loopback.amplist = alc880_loopbacks;
4123#endif
4124
4125	return 0;
4126}
4127
4128
4129/*
4130 * ALC260 support
4131 */
4132
4133static hda_nid_t alc260_dac_nids[1] = {
4134	/* front */
4135	0x02,
4136};
4137
4138static hda_nid_t alc260_adc_nids[1] = {
4139	/* ADC0 */
4140	0x04,
4141};
4142
4143static hda_nid_t alc260_adc_nids_alt[1] = {
4144	/* ADC1 */
4145	0x05,
4146};
4147
4148/* NIDs used when simultaneous access to both ADCs makes sense.  Note that
4149 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4150 */
4151static hda_nid_t alc260_dual_adc_nids[2] = {
4152	/* ADC0, ADC1 */
4153	0x04, 0x05
4154};
4155
4156#define ALC260_DIGOUT_NID	0x03
4157#define ALC260_DIGIN_NID	0x06
4158
4159static struct hda_input_mux alc260_capture_source = {
4160	.num_items = 4,
4161	.items = {
4162		{ "Mic", 0x0 },
4163		{ "Front Mic", 0x1 },
4164		{ "Line", 0x2 },
4165		{ "CD", 0x4 },
4166	},
4167};
4168
4169/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
4170 * headphone jack and the internal CD lines since these are the only pins at
4171 * which audio can appear.  For flexibility, also allow the option of
4172 * recording the mixer output on the second ADC (ADC0 doesn't have a
4173 * connection to the mixer output).
4174 */
4175static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4176	{
4177		.num_items = 3,
4178		.items = {
4179			{ "Mic/Line", 0x0 },
4180			{ "CD", 0x4 },
4181			{ "Headphone", 0x2 },
4182		},
4183	},
4184	{
4185		.num_items = 4,
4186		.items = {
4187			{ "Mic/Line", 0x0 },
4188			{ "CD", 0x4 },
4189			{ "Headphone", 0x2 },
4190			{ "Mixer", 0x5 },
4191		},
4192	},
4193
4194};
4195
4196/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4197 * the Fujitsu S702x, but jacks are marked differently.
4198 */
4199static struct hda_input_mux alc260_acer_capture_sources[2] = {
4200	{
4201		.num_items = 4,
4202		.items = {
4203			{ "Mic", 0x0 },
4204			{ "Line", 0x2 },
4205			{ "CD", 0x4 },
4206			{ "Headphone", 0x5 },
4207		},
4208	},
4209	{
4210		.num_items = 5,
4211		.items = {
4212			{ "Mic", 0x0 },
4213			{ "Line", 0x2 },
4214			{ "CD", 0x4 },
4215			{ "Headphone", 0x6 },
4216			{ "Mixer", 0x5 },
4217		},
4218	},
4219};
4220/*
4221 * This is just place-holder, so there's something for alc_build_pcms to look
4222 * at when it calculates the maximum number of channels. ALC260 has no mixer
4223 * element which allows changing the channel mode, so the verb list is
4224 * never used.
4225 */
4226static struct hda_channel_mode alc260_modes[1] = {
4227	{ 2, NULL },
4228};
4229
4230
4231/* Mixer combinations
4232 *
4233 * basic: base_output + input + pc_beep + capture
4234 * HP: base_output + input + capture_alt
4235 * HP_3013: hp_3013 + input + capture
4236 * fujitsu: fujitsu + capture
4237 * acer: acer + capture
4238 */
4239
4240static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4241	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4242	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4243	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4244	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4245	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4246	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4247	{ } /* end */
4248};
4249
4250static struct snd_kcontrol_new alc260_input_mixer[] = {
4251	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4252	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4253	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4254	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4255	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4256	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4257	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4258	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4259	{ } /* end */
4260};
4261
4262static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
4263	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
4264	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
4265	{ } /* end */
4266};
4267
4268/* update HP, line and mono out pins according to the master switch */
4269static void alc260_hp_master_update(struct hda_codec *codec,
4270				    hda_nid_t hp, hda_nid_t line,
4271				    hda_nid_t mono)
4272{
4273	struct alc_spec *spec = codec->spec;
4274	unsigned int val = spec->master_sw ? PIN_HP : 0;
4275	/* change HP and line-out pins */
4276	snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4277			    val);
4278	snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4279			    val);
4280	/* mono (speaker) depending on the HP jack sense */
4281	val = (val && !spec->jack_present) ? PIN_OUT : 0;
4282	snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4283			    val);
4284}
4285
4286static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4287				   struct snd_ctl_elem_value *ucontrol)
4288{
4289	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4290	struct alc_spec *spec = codec->spec;
4291	*ucontrol->value.integer.value = spec->master_sw;
4292	return 0;
4293}
4294
4295static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4296				   struct snd_ctl_elem_value *ucontrol)
4297{
4298	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4299	struct alc_spec *spec = codec->spec;
4300	int val = !!*ucontrol->value.integer.value;
4301	hda_nid_t hp, line, mono;
4302
4303	if (val == spec->master_sw)
4304		return 0;
4305	spec->master_sw = val;
4306	hp = (kcontrol->private_value >> 16) & 0xff;
4307	line = (kcontrol->private_value >> 8) & 0xff;
4308	mono = kcontrol->private_value & 0xff;
4309	alc260_hp_master_update(codec, hp, line, mono);
4310	return 1;
4311}
4312
4313static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4314	{
4315		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4316		.name = "Master Playback Switch",
4317		.info = snd_ctl_boolean_mono_info,
4318		.get = alc260_hp_master_sw_get,
4319		.put = alc260_hp_master_sw_put,
4320		.private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4321	},
4322	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4323	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4324	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4325	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4326	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4327			      HDA_OUTPUT),
4328	HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4329	{ } /* end */
4330};
4331
4332static struct hda_verb alc260_hp_unsol_verbs[] = {
4333	{0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4334	{},
4335};
4336
4337static void alc260_hp_automute(struct hda_codec *codec)
4338{
4339	struct alc_spec *spec = codec->spec;
4340	unsigned int present;
4341
4342	present = snd_hda_codec_read(codec, 0x10, 0,
4343				     AC_VERB_GET_PIN_SENSE, 0);
4344	spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4345	alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4346}
4347
4348static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4349{
4350	if ((res >> 26) == ALC880_HP_EVENT)
4351		alc260_hp_automute(codec);
4352}
4353
4354static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4355	{
4356		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4357		.name = "Master Playback Switch",
4358		.info = snd_ctl_boolean_mono_info,
4359		.get = alc260_hp_master_sw_get,
4360		.put = alc260_hp_master_sw_put,
4361		.private_value = (0x15 << 16) | (0x10 << 8) | 0x11
4362	},
4363	HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4364	HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4365	HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4366	HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4367	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4368	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4369	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4370	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4371	{ } /* end */
4372};
4373
4374static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4375	.ops = &snd_hda_bind_vol,
4376	.values = {
4377		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4378		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4379		HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4380		0
4381	},
4382};
4383
4384static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4385	.ops = &snd_hda_bind_sw,
4386	.values = {
4387		HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4388		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4389		0
4390	},
4391};
4392
4393static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4394	HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4395	HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4396	HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4397	HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4398	{ } /* end */
4399};
4400
4401static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4402	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4403	{},
4404};
4405
4406static void alc260_hp_3013_automute(struct hda_codec *codec)
4407{
4408	struct alc_spec *spec = codec->spec;
4409	unsigned int present;
4410
4411	present = snd_hda_codec_read(codec, 0x15, 0,
4412				     AC_VERB_GET_PIN_SENSE, 0);
4413	spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4414	alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
4415}
4416
4417static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4418				       unsigned int res)
4419{
4420	if ((res >> 26) == ALC880_HP_EVENT)
4421		alc260_hp_3013_automute(codec);
4422}
4423
4424static void alc260_hp_3012_automute(struct hda_codec *codec)
4425{
4426	unsigned int present, bits;
4427
4428	present = snd_hda_codec_read(codec, 0x10, 0,
4429			AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4430
4431	bits = present ? 0 : PIN_OUT;
4432	snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4433			    bits);
4434	snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4435			    bits);
4436	snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4437			    bits);
4438}
4439
4440static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4441				       unsigned int res)
4442{
4443	if ((res >> 26) == ALC880_HP_EVENT)
4444		alc260_hp_3012_automute(codec);
4445}
4446
4447/* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12,
4448 * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
4449 */
4450static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4451	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4452	HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4453	ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4454	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4455	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4456	HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4457	HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4458	ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4459	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4460	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4461	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4462	HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4463	{ } /* end */
4464};
4465
4466/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
4467 * versions of the ALC260 don't act on requests to enable mic bias from NID
4468 * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
4469 * datasheet doesn't mention this restriction.  At this stage it's not clear
4470 * whether this behaviour is intentional or is a hardware bug in chip
4471 * revisions available in early 2006.  Therefore for now allow the
4472 * "Headphone Jack Mode" control to span all choices, but if it turns out
4473 * that the lack of mic bias for this NID is intentional we could change the
4474 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4475 *
4476 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4477 * don't appear to make the mic bias available from the "line" jack, even
4478 * though the NID used for this jack (0x14) can supply it.  The theory is
4479 * that perhaps Acer have included blocking capacitors between the ALC260
4480 * and the output jack.  If this turns out to be the case for all such
4481 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4482 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4483 *
4484 * The C20x Tablet series have a mono internal speaker which is controlled
4485 * via the chip's Mono sum widget and pin complex, so include the necessary
4486 * controls for such models.  On models without a "mono speaker" the control
4487 * won't do anything.
4488 */
4489static struct snd_kcontrol_new alc260_acer_mixer[] = {
4490	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4491	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4492	ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4493	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4494			      HDA_OUTPUT),
4495	HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4496			   HDA_INPUT),
4497	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4498	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4499	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4500	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4501	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4502	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4503	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4504	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4505	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4506	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4507	{ } /* end */
4508};
4509
4510/* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4511 * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
4512 */
4513static struct snd_kcontrol_new alc260_will_mixer[] = {
4514	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4515	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4516	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4517	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4518	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4519	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4520	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4521	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4522	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4523	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4524	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4525	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4526	{ } /* end */
4527};
4528
4529/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4530 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4531 */
4532static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4533	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4534	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4535	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4536	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4537	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4538	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4539	HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4540	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4541	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4542	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4543	{ } /* end */
4544};
4545
4546/*
4547 * initialization verbs
4548 */
4549static struct hda_verb alc260_init_verbs[] = {
4550	/* Line In pin widget for input */
4551	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4552	/* CD pin widget for input */
4553	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4554	/* Mic1 (rear panel) pin widget for input and vref at 80% */
4555	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4556	/* Mic2 (front panel) pin widget for input and vref at 80% */
4557	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4558	/* LINE-2 is used for line-out in rear */
4559	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4560	/* select line-out */
4561	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4562	/* LINE-OUT pin */
4563	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4564	/* enable HP */
4565	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4566	/* enable Mono */
4567	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4568	/* mute capture amp left and right */
4569	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4570	/* set connection select to line in (default select for this ADC) */
4571	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4572	/* mute capture amp left and right */
4573	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4574	/* set connection select to line in (default select for this ADC) */
4575	{0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4576	/* set vol=0 Line-Out mixer amp left and right */
4577	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4578	/* unmute pin widget amp left and right (no gain on this amp) */
4579	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4580	/* set vol=0 HP mixer amp left and right */
4581	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4582	/* unmute pin widget amp left and right (no gain on this amp) */
4583	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4584	/* set vol=0 Mono mixer amp left and right */
4585	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4586	/* unmute pin widget amp left and right (no gain on this amp) */
4587	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4588	/* unmute LINE-2 out pin */
4589	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4590	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4591	 * Line In 2 = 0x03
4592	 */
4593	/* mute analog inputs */
4594	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4595	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4596	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4597	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4598	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4599	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4600	/* mute Front out path */
4601	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4602	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4603	/* mute Headphone out path */
4604	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4605	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4606	/* mute Mono out path */
4607	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4608	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4609	{ }
4610};
4611
4612#if 0 /* should be identical with alc260_init_verbs? */
4613static struct hda_verb alc260_hp_init_verbs[] = {
4614	/* Headphone and output */
4615	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4616	/* mono output */
4617	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4618	/* Mic1 (rear panel) pin widget for input and vref at 80% */
4619	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4620	/* Mic2 (front panel) pin widget for input and vref at 80% */
4621	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4622	/* Line In pin widget for input */
4623	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4624	/* Line-2 pin widget for output */
4625	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4626	/* CD pin widget for input */
4627	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4628	/* unmute amp left and right */
4629	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4630	/* set connection select to line in (default select for this ADC) */
4631	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4632	/* unmute Line-Out mixer amp left and right (volume = 0) */
4633	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4634	/* mute pin widget amp left and right (no gain on this amp) */
4635	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4636	/* unmute HP mixer amp left and right (volume = 0) */
4637	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4638	/* mute pin widget amp left and right (no gain on this amp) */
4639	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4640	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4641	 * Line In 2 = 0x03
4642	 */
4643	/* mute analog inputs */
4644	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4645	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4646	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4647	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4648	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4649	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4650	/* Unmute Front out path */
4651	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4652	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4653	/* Unmute Headphone out path */
4654	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4655	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4656	/* Unmute Mono out path */
4657	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4658	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4659	{ }
4660};
4661#endif
4662
4663static struct hda_verb alc260_hp_3013_init_verbs[] = {
4664	/* Line out and output */
4665	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4666	/* mono output */
4667	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4668	/* Mic1 (rear panel) pin widget for input and vref at 80% */
4669	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4670	/* Mic2 (front panel) pin widget for input and vref at 80% */
4671	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4672	/* Line In pin widget for input */
4673	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4674	/* Headphone pin widget for output */
4675	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4676	/* CD pin widget for input */
4677	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4678	/* unmute amp left and right */
4679	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4680	/* set connection select to line in (default select for this ADC) */
4681	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4682	/* unmute Line-Out mixer amp left and right (volume = 0) */
4683	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4684	/* mute pin widget amp left and right (no gain on this amp) */
4685	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4686	/* unmute HP mixer amp left and right (volume = 0) */
4687	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4688	/* mute pin widget amp left and right (no gain on this amp) */
4689	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4690	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4691	 * Line In 2 = 0x03
4692	 */
4693	/* mute analog inputs */
4694	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4695	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4696	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4697	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4698	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4699	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4700	/* Unmute Front out path */
4701	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4702	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4703	/* Unmute Headphone out path */
4704	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4705	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4706	/* Unmute Mono out path */
4707	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4708	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4709	{ }
4710};
4711
4712/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4713 * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4714 * audio = 0x16, internal speaker = 0x10.
4715 */
4716static struct hda_verb alc260_fujitsu_init_verbs[] = {
4717	/* Disable all GPIOs */
4718	{0x01, AC_VERB_SET_GPIO_MASK, 0},
4719	/* Internal speaker is connected to headphone pin */
4720	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4721	/* Headphone/Line-out jack connects to Line1 pin; make it an output */
4722	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4723	/* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4724	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4725	/* Ensure all other unused pins are disabled and muted. */
4726	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4727	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4728	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4729	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4730	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4731	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4732	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4733	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4734
4735	/* Disable digital (SPDIF) pins */
4736	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4737	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4738
4739	/* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4740	 * when acting as an output.
4741	 */
4742	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4743
4744	/* Start with output sum widgets muted and their output gains at min */
4745	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4746	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4747	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4748	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4749	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4750	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4751	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4752	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4753	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4754
4755	/* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4756	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4757	/* Unmute Line1 pin widget output buffer since it starts as an output.
4758	 * If the pin mode is changed by the user the pin mode control will
4759	 * take care of enabling the pin's input/output buffers as needed.
4760	 * Therefore there's no need to enable the input buffer at this
4761	 * stage.
4762	 */
4763	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4764	/* Unmute input buffer of pin widget used for Line-in (no equiv
4765	 * mixer ctrl)
4766	 */
4767	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4768
4769	/* Mute capture amp left and right */
4770	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4771	/* Set ADC connection select to match default mixer setting - line
4772	 * in (on mic1 pin)
4773	 */
4774	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4775
4776	/* Do the same for the second ADC: mute capture input amp and
4777	 * set ADC connection to line in (on mic1 pin)
4778	 */
4779	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4780	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4781
4782	/* Mute all inputs to mixer widget (even unconnected ones) */
4783	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4784	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4785	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4786	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4787	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4788	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4789	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4790	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4791
4792	{ }
4793};
4794
4795/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4796 * similar laptops (adapted from Fujitsu init verbs).
4797 */
4798static struct hda_verb alc260_acer_init_verbs[] = {
4799	/* On TravelMate laptops, GPIO 0 enables the internal speaker and
4800	 * the headphone jack.  Turn this on and rely on the standard mute
4801	 * methods whenever the user wants to turn these outputs off.
4802	 */
4803	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4804	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4805	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4806	/* Internal speaker/Headphone jack is connected to Line-out pin */
4807	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4808	/* Internal microphone/Mic jack is connected to Mic1 pin */
4809	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4810	/* Line In jack is connected to Line1 pin */
4811	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4812	/* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4813	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4814	/* Ensure all other unused pins are disabled and muted. */
4815	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4816	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4817	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4818	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4819	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4820	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4821	/* Disable digital (SPDIF) pins */
4822	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4823	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4824
4825	/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4826	 * bus when acting as outputs.
4827	 */
4828	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4829	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4830
4831	/* Start with output sum widgets muted and their output gains at min */
4832	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4833	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4834	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4835	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4836	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4837	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4838	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4839	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4840	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4841
4842	/* Unmute Line-out pin widget amp left and right
4843	 * (no equiv mixer ctrl)
4844	 */
4845	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4846	/* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4847	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4848	/* Unmute Mic1 and Line1 pin widget input buffers since they start as
4849	 * inputs. If the pin mode is changed by the user the pin mode control
4850	 * will take care of enabling the pin's input/output buffers as needed.
4851	 * Therefore there's no need to enable the input buffer at this
4852	 * stage.
4853	 */
4854	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4855	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4856
4857	/* Mute capture amp left and right */
4858	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4859	/* Set ADC connection select to match default mixer setting - mic
4860	 * (on mic1 pin)
4861	 */
4862	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4863
4864	/* Do similar with the second ADC: mute capture input amp and
4865	 * set ADC connection to mic to match ALSA's default state.
4866	 */
4867	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4868	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4869
4870	/* Mute all inputs to mixer widget (even unconnected ones) */
4871	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4872	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4873	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4874	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4875	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4876	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4877	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4878	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4879
4880	{ }
4881};
4882
4883static struct hda_verb alc260_will_verbs[] = {
4884	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4885	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4886	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4887	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4888	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4889	{0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4890	{}
4891};
4892
4893static struct hda_verb alc260_replacer_672v_verbs[] = {
4894	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4895	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4896	{0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4897
4898	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4899	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4900	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4901
4902	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4903	{}
4904};
4905
4906/* toggle speaker-output according to the hp-jack state */
4907static void alc260_replacer_672v_automute(struct hda_codec *codec)
4908{
4909        unsigned int present;
4910
4911	/* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4912        present = snd_hda_codec_read(codec, 0x0f, 0,
4913                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4914	if (present) {
4915		snd_hda_codec_write_cache(codec, 0x01, 0,
4916					  AC_VERB_SET_GPIO_DATA, 1);
4917		snd_hda_codec_write_cache(codec, 0x0f, 0,
4918					  AC_VERB_SET_PIN_WIDGET_CONTROL,
4919					  PIN_HP);
4920	} else {
4921		snd_hda_codec_write_cache(codec, 0x01, 0,
4922					  AC_VERB_SET_GPIO_DATA, 0);
4923		snd_hda_codec_write_cache(codec, 0x0f, 0,
4924					  AC_VERB_SET_PIN_WIDGET_CONTROL,
4925					  PIN_OUT);
4926	}
4927}
4928
4929static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4930                                       unsigned int res)
4931{
4932        if ((res >> 26) == ALC880_HP_EVENT)
4933                alc260_replacer_672v_automute(codec);
4934}
4935
4936static struct hda_verb alc260_hp_dc7600_verbs[] = {
4937	{0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
4938	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
4939	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4940	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4941	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4942	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4943	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4944	{0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4945	{0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4946	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4947	{}
4948};
4949
4950/* Test configuration for debugging, modelled after the ALC880 test
4951 * configuration.
4952 */
4953#ifdef CONFIG_SND_DEBUG
4954static hda_nid_t alc260_test_dac_nids[1] = {
4955	0x02,
4956};
4957static hda_nid_t alc260_test_adc_nids[2] = {
4958	0x04, 0x05,
4959};
4960/* For testing the ALC260, each input MUX needs its own definition since
4961 * the signal assignments are different.  This assumes that the first ADC
4962 * is NID 0x04.
4963 */
4964static struct hda_input_mux alc260_test_capture_sources[2] = {
4965	{
4966		.num_items = 7,
4967		.items = {
4968			{ "MIC1 pin", 0x0 },
4969			{ "MIC2 pin", 0x1 },
4970			{ "LINE1 pin", 0x2 },
4971			{ "LINE2 pin", 0x3 },
4972			{ "CD pin", 0x4 },
4973			{ "LINE-OUT pin", 0x5 },
4974			{ "HP-OUT pin", 0x6 },
4975		},
4976        },
4977	{
4978		.num_items = 8,
4979		.items = {
4980			{ "MIC1 pin", 0x0 },
4981			{ "MIC2 pin", 0x1 },
4982			{ "LINE1 pin", 0x2 },
4983			{ "LINE2 pin", 0x3 },
4984			{ "CD pin", 0x4 },
4985			{ "Mixer", 0x5 },
4986			{ "LINE-OUT pin", 0x6 },
4987			{ "HP-OUT pin", 0x7 },
4988		},
4989        },
4990};
4991static struct snd_kcontrol_new alc260_test_mixer[] = {
4992	/* Output driver widgets */
4993	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4994	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4995	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4996	HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4997	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4998	HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4999
5000	/* Modes for retasking pin widgets
5001	 * Note: the ALC260 doesn't seem to act on requests to enable mic
5002         * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
5003         * mention this restriction.  At this stage it's not clear whether
5004         * this behaviour is intentional or is a hardware bug in chip
5005         * revisions available at least up until early 2006.  Therefore for
5006         * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5007         * choices, but if it turns out that the lack of mic bias for these
5008         * NIDs is intentional we could change their modes from
5009         * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5010	 */
5011	ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5012	ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5013	ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5014	ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5015	ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5016	ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5017
5018	/* Loopback mixer controls */
5019	HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5020	HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5021	HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5022	HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5023	HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5024	HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5025	HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5026	HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5027	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5028	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5029	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
5030	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
5031	HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5032	HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5033	HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5034	HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5035
5036	/* Controls for GPIO pins, assuming they are configured as outputs */
5037	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5038	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5039	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5040	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5041
5042	/* Switches to allow the digital IO pins to be enabled.  The datasheet
5043	 * is ambigious as to which NID is which; testing on laptops which
5044	 * make this output available should provide clarification.
5045	 */
5046	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5047	ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5048
5049	/* A switch allowing EAPD to be enabled.  Some laptops seem to use
5050	 * this output to turn on an external amplifier.
5051	 */
5052	ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5053	ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5054
5055	{ } /* end */
5056};
5057static struct hda_verb alc260_test_init_verbs[] = {
5058	/* Enable all GPIOs as outputs with an initial value of 0 */
5059	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5060	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5061	{0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5062
5063	/* Enable retasking pins as output, initially without power amp */
5064	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5065	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5066	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5067	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5068	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5069	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5070
5071	/* Disable digital (SPDIF) pins initially, but users can enable
5072	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
5073	 * payload also sets the generation to 0, output to be in "consumer"
5074	 * PCM format, copyright asserted, no pre-emphasis and no validity
5075	 * control.
5076	 */
5077	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5078	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5079
5080	/* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
5081	 * OUT1 sum bus when acting as an output.
5082	 */
5083	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5084	{0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5085	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5086	{0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5087
5088	/* Start with output sum widgets muted and their output gains at min */
5089	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5090	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5091	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5092	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5093	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5094	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5095	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5096	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5097	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5098
5099	/* Unmute retasking pin widget output buffers since the default
5100	 * state appears to be output.  As the pin mode is changed by the
5101	 * user the pin mode control will take care of enabling the pin's
5102	 * input/output buffers as needed.
5103	 */
5104	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5105	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5106	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5107	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5108	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5109	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5110	/* Also unmute the mono-out pin widget */
5111	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5112
5113	/* Mute capture amp left and right */
5114	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5115	/* Set ADC connection select to match default mixer setting (mic1
5116	 * pin)
5117	 */
5118	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5119
5120	/* Do the same for the second ADC: mute capture input amp and
5121	 * set ADC connection to mic1 pin
5122	 */
5123	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5124	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5125
5126	/* Mute all inputs to mixer widget (even unconnected ones) */
5127	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5128	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5129	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5130	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5131	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5132	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5133	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5134	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5135
5136	{ }
5137};
5138#endif
5139
5140#define alc260_pcm_analog_playback	alc880_pcm_analog_alt_playback
5141#define alc260_pcm_analog_capture	alc880_pcm_analog_capture
5142
5143#define alc260_pcm_digital_playback	alc880_pcm_digital_playback
5144#define alc260_pcm_digital_capture	alc880_pcm_digital_capture
5145
5146/*
5147 * for BIOS auto-configuration
5148 */
5149
5150static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
5151					const char *pfx, int *vol_bits)
5152{
5153	hda_nid_t nid_vol;
5154	unsigned long vol_val, sw_val;
5155	char name[32];
5156	int err;
5157
5158	if (nid >= 0x0f && nid < 0x11) {
5159		nid_vol = nid - 0x7;
5160		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5161		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5162	} else if (nid == 0x11) {
5163		nid_vol = nid - 0x7;
5164		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5165		sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5166	} else if (nid >= 0x12 && nid <= 0x15) {
5167		nid_vol = 0x08;
5168		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5169		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5170	} else
5171		return 0; /* N/A */
5172
5173	if (!(*vol_bits & (1 << nid_vol))) {
5174		/* first control for the volume widget */
5175		snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5176		err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5177		if (err < 0)
5178			return err;
5179		*vol_bits |= (1 << nid_vol);
5180	}
5181	snprintf(name, sizeof(name), "%s Playback Switch", pfx);
5182	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5183	if (err < 0)
5184		return err;
5185	return 1;
5186}
5187
5188/* add playback controls from the parsed DAC table */
5189static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5190					     const struct auto_pin_cfg *cfg)
5191{
5192	hda_nid_t nid;
5193	int err;
5194	int vols = 0;
5195
5196	spec->multiout.num_dacs = 1;
5197	spec->multiout.dac_nids = spec->private_dac_nids;
5198	spec->multiout.dac_nids[0] = 0x02;
5199
5200	nid = cfg->line_out_pins[0];
5201	if (nid) {
5202		err = alc260_add_playback_controls(spec, nid, "Front", &vols);
5203		if (err < 0)
5204			return err;
5205	}
5206
5207	nid = cfg->speaker_pins[0];
5208	if (nid) {
5209		err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
5210		if (err < 0)
5211			return err;
5212	}
5213
5214	nid = cfg->hp_pins[0];
5215	if (nid) {
5216		err = alc260_add_playback_controls(spec, nid, "Headphone",
5217						   &vols);
5218		if (err < 0)
5219			return err;
5220	}
5221	return 0;
5222}
5223
5224/* create playback/capture controls for input pins */
5225static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5226						const struct auto_pin_cfg *cfg)
5227{
5228	struct hda_input_mux *imux = &spec->private_imux;
5229	int i, err, idx;
5230
5231	for (i = 0; i < AUTO_PIN_LAST; i++) {
5232		if (cfg->input_pins[i] >= 0x12) {
5233			idx = cfg->input_pins[i] - 0x12;
5234			err = new_analog_input(spec, cfg->input_pins[i],
5235					       auto_pin_cfg_labels[i], idx,
5236					       0x07);
5237			if (err < 0)
5238				return err;
5239			imux->items[imux->num_items].label =
5240				auto_pin_cfg_labels[i];
5241			imux->items[imux->num_items].index = idx;
5242			imux->num_items++;
5243		}
5244		if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
5245			idx = cfg->input_pins[i] - 0x09;
5246			err = new_analog_input(spec, cfg->input_pins[i],
5247					       auto_pin_cfg_labels[i], idx,
5248					       0x07);
5249			if (err < 0)
5250				return err;
5251			imux->items[imux->num_items].label =
5252				auto_pin_cfg_labels[i];
5253			imux->items[imux->num_items].index = idx;
5254			imux->num_items++;
5255		}
5256	}
5257	return 0;
5258}
5259
5260static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5261					      hda_nid_t nid, int pin_type,
5262					      int sel_idx)
5263{
5264	alc_set_pin_output(codec, nid, pin_type);
5265	/* need the manual connection? */
5266	if (nid >= 0x12) {
5267		int idx = nid - 0x12;
5268		snd_hda_codec_write(codec, idx + 0x0b, 0,
5269				    AC_VERB_SET_CONNECT_SEL, sel_idx);
5270	}
5271}
5272
5273static void alc260_auto_init_multi_out(struct hda_codec *codec)
5274{
5275	struct alc_spec *spec = codec->spec;
5276	hda_nid_t nid;
5277
5278	alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
5279	nid = spec->autocfg.line_out_pins[0];
5280	if (nid) {
5281		int pin_type = get_pin_type(spec->autocfg.line_out_type);
5282		alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5283	}
5284
5285	nid = spec->autocfg.speaker_pins[0];
5286	if (nid)
5287		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5288
5289	nid = spec->autocfg.hp_pins[0];
5290	if (nid)
5291		alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5292}
5293
5294#define ALC260_PIN_CD_NID		0x16
5295static void alc260_auto_init_analog_input(struct hda_codec *codec)
5296{
5297	struct alc_spec *spec = codec->spec;
5298	int i;
5299
5300	for (i = 0; i < AUTO_PIN_LAST; i++) {
5301		hda_nid_t nid = spec->autocfg.input_pins[i];
5302		if (nid >= 0x12) {
5303			snd_hda_codec_write(codec, nid, 0,
5304					    AC_VERB_SET_PIN_WIDGET_CONTROL,
5305					    i <= AUTO_PIN_FRONT_MIC ?
5306					    PIN_VREF80 : PIN_IN);
5307			if (nid != ALC260_PIN_CD_NID)
5308				snd_hda_codec_write(codec, nid, 0,
5309						    AC_VERB_SET_AMP_GAIN_MUTE,
5310						    AMP_OUT_MUTE);
5311		}
5312	}
5313}
5314
5315/*
5316 * generic initialization of ADC, input mixers and output mixers
5317 */
5318static struct hda_verb alc260_volume_init_verbs[] = {
5319	/*
5320	 * Unmute ADC0-1 and set the default input to mic-in
5321	 */
5322	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5323	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5324	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5325	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5326
5327	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5328	 * mixer widget
5329	 * Note: PASD motherboards uses the Line In 2 as the input for
5330	 * front panel mic (mic 2)
5331	 */
5332	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5333	/* mute analog inputs */
5334	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5335	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5336	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5337	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5338	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5339
5340	/*
5341	 * Set up output mixers (0x08 - 0x0a)
5342	 */
5343	/* set vol=0 to output mixers */
5344	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5345	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5346	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5347	/* set up input amps for analog loopback */
5348	/* Amp Indices: DAC = 0, mixer = 1 */
5349	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5350	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5351	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5352	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5353	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5354	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5355
5356	{ }
5357};
5358
5359static int alc260_parse_auto_config(struct hda_codec *codec)
5360{
5361	struct alc_spec *spec = codec->spec;
5362	int err;
5363	static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5364
5365	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5366					   alc260_ignore);
5367	if (err < 0)
5368		return err;
5369	err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5370	if (err < 0)
5371		return err;
5372	if (!spec->kctls.list)
5373		return 0; /* can't find valid BIOS pin config */
5374	err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5375	if (err < 0)
5376		return err;
5377
5378	spec->multiout.max_channels = 2;
5379
5380	if (spec->autocfg.dig_out_pin)
5381		spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5382	if (spec->kctls.list)
5383		add_mixer(spec, spec->kctls.list);
5384
5385	add_verb(spec, alc260_volume_init_verbs);
5386
5387	spec->num_mux_defs = 1;
5388	spec->input_mux = &spec->private_imux;
5389
5390	store_pin_configs(codec);
5391	return 1;
5392}
5393
5394/* additional initialization for auto-configuration model */
5395static void alc260_auto_init(struct hda_codec *codec)
5396{
5397	struct alc_spec *spec = codec->spec;
5398	alc260_auto_init_multi_out(codec);
5399	alc260_auto_init_analog_input(codec);
5400	if (spec->unsol_event)
5401		alc_inithook(codec);
5402}
5403
5404#ifdef CONFIG_SND_HDA_POWER_SAVE
5405static struct hda_amp_list alc260_loopbacks[] = {
5406	{ 0x07, HDA_INPUT, 0 },
5407	{ 0x07, HDA_INPUT, 1 },
5408	{ 0x07, HDA_INPUT, 2 },
5409	{ 0x07, HDA_INPUT, 3 },
5410	{ 0x07, HDA_INPUT, 4 },
5411	{ } /* end */
5412};
5413#endif
5414
5415/*
5416 * ALC260 configurations
5417 */
5418static const char *alc260_models[ALC260_MODEL_LAST] = {
5419	[ALC260_BASIC]		= "basic",
5420	[ALC260_HP]		= "hp",
5421	[ALC260_HP_3013]	= "hp-3013",
5422	[ALC260_HP_DC7600]	= "hp-dc7600",
5423	[ALC260_FUJITSU_S702X]	= "fujitsu",
5424	[ALC260_ACER]		= "acer",
5425	[ALC260_WILL]		= "will",
5426	[ALC260_REPLACER_672V]	= "replacer",
5427#ifdef CONFIG_SND_DEBUG
5428	[ALC260_TEST]		= "test",
5429#endif
5430	[ALC260_AUTO]		= "auto",
5431};
5432
5433static struct snd_pci_quirk alc260_cfg_tbl[] = {
5434	SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5435	SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5436	SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5437	SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5438	SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5439	SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5440	SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
5441	SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5442	SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5443	SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5444	SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5445	SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5446	SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5447	SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5448	SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5449	SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5450	SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5451	SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5452	{}
5453};
5454
5455static struct alc_config_preset alc260_presets[] = {
5456	[ALC260_BASIC] = {
5457		.mixers = { alc260_base_output_mixer,
5458			    alc260_input_mixer,
5459			    alc260_pc_beep_mixer },
5460		.init_verbs = { alc260_init_verbs },
5461		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5462		.dac_nids = alc260_dac_nids,
5463		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5464		.adc_nids = alc260_adc_nids,
5465		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5466		.channel_mode = alc260_modes,
5467		.input_mux = &alc260_capture_source,
5468	},
5469	[ALC260_HP] = {
5470		.mixers = { alc260_hp_output_mixer,
5471			    alc260_input_mixer },
5472		.init_verbs = { alc260_init_verbs,
5473				alc260_hp_unsol_verbs },
5474		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5475		.dac_nids = alc260_dac_nids,
5476		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5477		.adc_nids = alc260_adc_nids_alt,
5478		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5479		.channel_mode = alc260_modes,
5480		.input_mux = &alc260_capture_source,
5481		.unsol_event = alc260_hp_unsol_event,
5482		.init_hook = alc260_hp_automute,
5483	},
5484	[ALC260_HP_DC7600] = {
5485		.mixers = { alc260_hp_dc7600_mixer,
5486			    alc260_input_mixer },
5487		.init_verbs = { alc260_init_verbs,
5488				alc260_hp_dc7600_verbs },
5489		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5490		.dac_nids = alc260_dac_nids,
5491		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5492		.adc_nids = alc260_adc_nids_alt,
5493		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5494		.channel_mode = alc260_modes,
5495		.input_mux = &alc260_capture_source,
5496		.unsol_event = alc260_hp_3012_unsol_event,
5497		.init_hook = alc260_hp_3012_automute,
5498	},
5499	[ALC260_HP_3013] = {
5500		.mixers = { alc260_hp_3013_mixer,
5501			    alc260_input_mixer },
5502		.init_verbs = { alc260_hp_3013_init_verbs,
5503				alc260_hp_3013_unsol_verbs },
5504		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5505		.dac_nids = alc260_dac_nids,
5506		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5507		.adc_nids = alc260_adc_nids_alt,
5508		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5509		.channel_mode = alc260_modes,
5510		.input_mux = &alc260_capture_source,
5511		.unsol_event = alc260_hp_3013_unsol_event,
5512		.init_hook = alc260_hp_3013_automute,
5513	},
5514	[ALC260_FUJITSU_S702X] = {
5515		.mixers = { alc260_fujitsu_mixer },
5516		.init_verbs = { alc260_fujitsu_init_verbs },
5517		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5518		.dac_nids = alc260_dac_nids,
5519		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5520		.adc_nids = alc260_dual_adc_nids,
5521		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5522		.channel_mode = alc260_modes,
5523		.num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5524		.input_mux = alc260_fujitsu_capture_sources,
5525	},
5526	[ALC260_ACER] = {
5527		.mixers = { alc260_acer_mixer },
5528		.init_verbs = { alc260_acer_init_verbs },
5529		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5530		.dac_nids = alc260_dac_nids,
5531		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5532		.adc_nids = alc260_dual_adc_nids,
5533		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5534		.channel_mode = alc260_modes,
5535		.num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5536		.input_mux = alc260_acer_capture_sources,
5537	},
5538	[ALC260_WILL] = {
5539		.mixers = { alc260_will_mixer },
5540		.init_verbs = { alc260_init_verbs, alc260_will_verbs },
5541		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5542		.dac_nids = alc260_dac_nids,
5543		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5544		.adc_nids = alc260_adc_nids,
5545		.dig_out_nid = ALC260_DIGOUT_NID,
5546		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5547		.channel_mode = alc260_modes,
5548		.input_mux = &alc260_capture_source,
5549	},
5550	[ALC260_REPLACER_672V] = {
5551		.mixers = { alc260_replacer_672v_mixer },
5552		.init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5553		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5554		.dac_nids = alc260_dac_nids,
5555		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5556		.adc_nids = alc260_adc_nids,
5557		.dig_out_nid = ALC260_DIGOUT_NID,
5558		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5559		.channel_mode = alc260_modes,
5560		.input_mux = &alc260_capture_source,
5561		.unsol_event = alc260_replacer_672v_unsol_event,
5562		.init_hook = alc260_replacer_672v_automute,
5563	},
5564#ifdef CONFIG_SND_DEBUG
5565	[ALC260_TEST] = {
5566		.mixers = { alc260_test_mixer },
5567		.init_verbs = { alc260_test_init_verbs },
5568		.num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5569		.dac_nids = alc260_test_dac_nids,
5570		.num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5571		.adc_nids = alc260_test_adc_nids,
5572		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5573		.channel_mode = alc260_modes,
5574		.num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5575		.input_mux = alc260_test_capture_sources,
5576	},
5577#endif
5578};
5579
5580static int patch_alc260(struct hda_codec *codec)
5581{
5582	struct alc_spec *spec;
5583	int err, board_config;
5584
5585	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5586	if (spec == NULL)
5587		return -ENOMEM;
5588
5589	codec->spec = spec;
5590
5591	board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5592						  alc260_models,
5593						  alc260_cfg_tbl);
5594	if (board_config < 0) {
5595		snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5596			   "trying auto-probe from BIOS...\n");
5597		board_config = ALC260_AUTO;
5598	}
5599
5600	if (board_config == ALC260_AUTO) {
5601		/* automatic parse from the BIOS config */
5602		err = alc260_parse_auto_config(codec);
5603		if (err < 0) {
5604			alc_free(codec);
5605			return err;
5606		} else if (!err) {
5607			printk(KERN_INFO
5608			       "hda_codec: Cannot set up configuration "
5609			       "from BIOS.  Using base mode...\n");
5610			board_config = ALC260_BASIC;
5611		}
5612	}
5613
5614	if (board_config != ALC260_AUTO)
5615		setup_preset(spec, &alc260_presets[board_config]);
5616
5617	spec->stream_name_analog = "ALC260 Analog";
5618	spec->stream_analog_playback = &alc260_pcm_analog_playback;
5619	spec->stream_analog_capture = &alc260_pcm_analog_capture;
5620
5621	spec->stream_name_digital = "ALC260 Digital";
5622	spec->stream_digital_playback = &alc260_pcm_digital_playback;
5623	spec->stream_digital_capture = &alc260_pcm_digital_capture;
5624
5625	if (!spec->adc_nids && spec->input_mux) {
5626		/* check whether NID 0x04 is valid */
5627		unsigned int wcap = get_wcaps(codec, 0x04);
5628		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
5629		/* get type */
5630		if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
5631			spec->adc_nids = alc260_adc_nids_alt;
5632			spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
5633		} else {
5634			spec->adc_nids = alc260_adc_nids;
5635			spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
5636		}
5637	}
5638	set_capture_mixer(spec);
5639
5640	spec->vmaster_nid = 0x08;
5641
5642	codec->patch_ops = alc_patch_ops;
5643	if (board_config == ALC260_AUTO)
5644		spec->init_hook = alc260_auto_init;
5645#ifdef CONFIG_SND_HDA_POWER_SAVE
5646	if (!spec->loopback.amplist)
5647		spec->loopback.amplist = alc260_loopbacks;
5648#endif
5649
5650	return 0;
5651}
5652
5653
5654/*
5655 * ALC882 support
5656 *
5657 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5658 * configuration.  Each pin widget can choose any input DACs and a mixer.
5659 * Each ADC is connected from a mixer of all inputs.  This makes possible
5660 * 6-channel independent captures.
5661 *
5662 * In addition, an independent DAC for the multi-playback (not used in this
5663 * driver yet).
5664 */
5665#define ALC882_DIGOUT_NID	0x06
5666#define ALC882_DIGIN_NID	0x0a
5667
5668static struct hda_channel_mode alc882_ch_modes[1] = {
5669	{ 8, NULL }
5670};
5671
5672static hda_nid_t alc882_dac_nids[4] = {
5673	/* front, rear, clfe, rear_surr */
5674	0x02, 0x03, 0x04, 0x05
5675};
5676
5677/* identical with ALC880 */
5678#define alc882_adc_nids		alc880_adc_nids
5679#define alc882_adc_nids_alt	alc880_adc_nids_alt
5680
5681static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
5682static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
5683
5684/* input MUX */
5685/* FIXME: should be a matrix-type input source selection */
5686
5687static struct hda_input_mux alc882_capture_source = {
5688	.num_items = 4,
5689	.items = {
5690		{ "Mic", 0x0 },
5691		{ "Front Mic", 0x1 },
5692		{ "Line", 0x2 },
5693		{ "CD", 0x4 },
5694	},
5695};
5696/*
5697 * 2ch mode
5698 */
5699static struct hda_verb alc882_3ST_ch2_init[] = {
5700	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5701	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5702	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5703	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5704	{ } /* end */
5705};
5706
5707/*
5708 * 6ch mode
5709 */
5710static struct hda_verb alc882_3ST_ch6_init[] = {
5711	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5712	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5713	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5714	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5715	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5716	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5717	{ } /* end */
5718};
5719
5720static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5721	{ 2, alc882_3ST_ch2_init },
5722	{ 6, alc882_3ST_ch6_init },
5723};
5724
5725/*
5726 * 6ch mode
5727 */
5728static struct hda_verb alc882_sixstack_ch6_init[] = {
5729	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5730	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5731	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5732	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5733	{ } /* end */
5734};
5735
5736/*
5737 * 8ch mode
5738 */
5739static struct hda_verb alc882_sixstack_ch8_init[] = {
5740	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5741	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5742	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5743	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5744	{ } /* end */
5745};
5746
5747static struct hda_channel_mode alc882_sixstack_modes[2] = {
5748	{ 6, alc882_sixstack_ch6_init },
5749	{ 8, alc882_sixstack_ch8_init },
5750};
5751
5752/*
5753 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5754 */
5755
5756/*
5757 * 2ch mode
5758 */
5759static struct hda_verb alc885_mbp_ch2_init[] = {
5760	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5761	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5762	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5763	{ } /* end */
5764};
5765
5766/*
5767 * 6ch mode
5768 */
5769static struct hda_verb alc885_mbp_ch6_init[] = {
5770	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5771	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5772	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5773	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5774	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5775	{ } /* end */
5776};
5777
5778static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5779	{ 2, alc885_mbp_ch2_init },
5780	{ 6, alc885_mbp_ch6_init },
5781};
5782
5783
5784/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5785 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5786 */
5787static struct snd_kcontrol_new alc882_base_mixer[] = {
5788	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5789	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5790	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5791	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5792	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5793	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5794	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5795	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5796	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5797	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5798	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5799	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5800	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5801	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5802	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5803	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5804	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5805	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5806	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5807	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5808	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5809	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5810	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5811	{ } /* end */
5812};
5813
5814static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5815	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5816	HDA_BIND_MUTE   ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
5817	HDA_CODEC_MUTE  ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
5818	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
5819	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5820	HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5821	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5822	HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5823	HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
5824	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5825	{ } /* end */
5826};
5827static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5828	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5829	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5830	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5831	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5832	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5833	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5834	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5835	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5836	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5837	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5838	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5839	{ } /* end */
5840};
5841
5842static struct snd_kcontrol_new alc882_targa_mixer[] = {
5843	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5844	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5845	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5846	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5847	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5848	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5849	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5850	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5851	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5852	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5853	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5854	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5855	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5856	{ } /* end */
5857};
5858
5859/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5860 *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5861 */
5862static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5863	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5864	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5865	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5866	HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5867	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5868	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5869	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5870	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5871	HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5872	HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5873	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5874	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5875	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5876	{ } /* end */
5877};
5878
5879static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5880	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5881	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5882	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5883	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5884	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5885	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5886	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5887	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5888	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5889	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5890	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5891	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5892	{ } /* end */
5893};
5894
5895static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5896	{
5897		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5898		.name = "Channel Mode",
5899		.info = alc_ch_mode_info,
5900		.get = alc_ch_mode_get,
5901		.put = alc_ch_mode_put,
5902	},
5903	{ } /* end */
5904};
5905
5906static struct hda_verb alc882_init_verbs[] = {
5907	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5908	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5909	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5910	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5911	/* Rear mixer */
5912	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5913	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5914	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5915	/* CLFE mixer */
5916	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5917	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5918	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5919	/* Side mixer */
5920	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5921	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5922	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5923
5924	/* Front Pin: output 0 (0x0c) */
5925	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5926	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5927	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5928	/* Rear Pin: output 1 (0x0d) */
5929	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5930	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5931	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5932	/* CLFE Pin: output 2 (0x0e) */
5933	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5934	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5935	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5936	/* Side Pin: output 3 (0x0f) */
5937	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5938	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5939	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5940	/* Mic (rear) pin: input vref at 80% */
5941	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5942	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5943	/* Front Mic pin: input vref at 80% */
5944	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5945	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5946	/* Line In pin: input */
5947	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5948	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5949	/* Line-2 In: Headphone output (output 0 - 0x0c) */
5950	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5951	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5952	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5953	/* CD pin widget for input */
5954	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5955
5956	/* FIXME: use matrix-type input source selection */
5957	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5958	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5959	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5960	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5961	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5962	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5963	/* Input mixer2 */
5964	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5965	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5966	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5967	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5968	/* Input mixer3 */
5969	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5970	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5971	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5972	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5973	/* ADC1: mute amp left and right */
5974	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5975	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5976	/* ADC2: mute amp left and right */
5977	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5978	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5979	/* ADC3: mute amp left and right */
5980	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5981	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5982
5983	{ }
5984};
5985
5986static struct hda_verb alc882_eapd_verbs[] = {
5987	/* change to EAPD mode */
5988	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5989	{0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5990	{ }
5991};
5992
5993/* Mac Pro test */
5994static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5995	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5996	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5997	HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5998	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5999	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
6000	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
6001	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
6002	{ } /* end */
6003};
6004
6005static struct hda_verb alc882_macpro_init_verbs[] = {
6006	/* Front mixer: unmute input/output amp left and right (volume = 0) */
6007	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6008	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6009	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6010	/* Front Pin: output 0 (0x0c) */
6011	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6012	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6013	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6014	/* Front Mic pin: input vref at 80% */
6015	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6016	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6017	/* Speaker:  output */
6018	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6019	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6020	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
6021	/* Headphone output (output 0 - 0x0c) */
6022	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6023	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6024	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6025
6026	/* FIXME: use matrix-type input source selection */
6027	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6028	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6029	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6030	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6031	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6032	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6033	/* Input mixer2 */
6034	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6035	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6036	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6037	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6038	/* Input mixer3 */
6039	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6040	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6041	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6042	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6043	/* ADC1: mute amp left and right */
6044	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6045	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6046	/* ADC2: mute amp left and right */
6047	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6048	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6049	/* ADC3: mute amp left and right */
6050	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6051	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6052
6053	{ }
6054};
6055
6056/* Macbook Pro rev3 */
6057static struct hda_verb alc885_mbp3_init_verbs[] = {
6058	/* Front mixer: unmute input/output amp left and right (volume = 0) */
6059	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6060	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6061	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6062	/* Rear mixer */
6063	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6064	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6065	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6066	/* Front Pin: output 0 (0x0c) */
6067	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6068	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6069	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6070	/* HP Pin: output 0 (0x0d) */
6071	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
6072	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6073	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6074	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6075	/* Mic (rear) pin: input vref at 80% */
6076	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6077	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6078	/* Front Mic pin: input vref at 80% */
6079	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6080	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6081	/* Line In pin: use output 1 when in LineOut mode */
6082	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6083	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6084	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
6085
6086	/* FIXME: use matrix-type input source selection */
6087	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6088	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6089	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6090	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6091	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6092	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6093	/* Input mixer2 */
6094	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6095	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6096	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6097	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6098	/* Input mixer3 */
6099	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6100	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6101	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6102	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6103	/* ADC1: mute amp left and right */
6104	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6105	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6106	/* ADC2: mute amp left and right */
6107	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6108	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6109	/* ADC3: mute amp left and right */
6110	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6111	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6112
6113	{ }
6114};
6115
6116/* iMac 24 mixer. */
6117static struct snd_kcontrol_new alc885_imac24_mixer[] = {
6118	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6119	HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
6120	{ } /* end */
6121};
6122
6123/* iMac 24 init verbs. */
6124static struct hda_verb alc885_imac24_init_verbs[] = {
6125	/* Internal speakers: output 0 (0x0c) */
6126	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6127	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6128	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6129	/* Internal speakers: output 0 (0x0c) */
6130	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6131	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6132	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
6133	/* Headphone: output 0 (0x0c) */
6134	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6135	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6136	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6137	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6138	/* Front Mic: input vref at 80% */
6139	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6140	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6141	{ }
6142};
6143
6144/* Toggle speaker-output according to the hp-jack state */
6145static void alc885_imac24_automute(struct hda_codec *codec)
6146{
6147 	unsigned int present;
6148
6149 	present = snd_hda_codec_read(codec, 0x14, 0,
6150				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6151	snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
6152				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6153	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
6154				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6155}
6156
6157/* Processes unsolicited events. */
6158static void alc885_imac24_unsol_event(struct hda_codec *codec,
6159				      unsigned int res)
6160{
6161	/* Headphone insertion or removal. */
6162	if ((res >> 26) == ALC880_HP_EVENT)
6163		alc885_imac24_automute(codec);
6164}
6165
6166static void alc885_mbp3_automute(struct hda_codec *codec)
6167{
6168 	unsigned int present;
6169
6170 	present = snd_hda_codec_read(codec, 0x15, 0,
6171				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6172	snd_hda_codec_amp_stereo(codec, 0x14,  HDA_OUTPUT, 0,
6173				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6174	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6175				 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
6176
6177}
6178static void alc885_mbp3_unsol_event(struct hda_codec *codec,
6179				    unsigned int res)
6180{
6181	/* Headphone insertion or removal. */
6182	if ((res >> 26) == ALC880_HP_EVENT)
6183		alc885_mbp3_automute(codec);
6184}
6185
6186
6187static struct hda_verb alc882_targa_verbs[] = {
6188	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6189	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6190
6191	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6192	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6193
6194	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6195	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6196	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6197
6198	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6199	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6200	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6201	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6202	{ } /* end */
6203};
6204
6205/* toggle speaker-output according to the hp-jack state */
6206static void alc882_targa_automute(struct hda_codec *codec)
6207{
6208 	unsigned int present;
6209
6210 	present = snd_hda_codec_read(codec, 0x14, 0,
6211				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6212	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6213				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6214	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6215				  present ? 1 : 3);
6216}
6217
6218static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6219{
6220	/* Looks like the unsol event is incompatible with the standard
6221	 * definition.  4bit tag is placed at 26 bit!
6222	 */
6223	if (((res >> 26) == ALC880_HP_EVENT)) {
6224		alc882_targa_automute(codec);
6225	}
6226}
6227
6228static struct hda_verb alc882_asus_a7j_verbs[] = {
6229	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6230	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6231
6232	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6233	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6234	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6235
6236	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6237	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6238	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6239
6240	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6241	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6242	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6243	{ } /* end */
6244};
6245
6246static struct hda_verb alc882_asus_a7m_verbs[] = {
6247	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6248	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6249
6250	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6251	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6252	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6253
6254	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6255	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6256	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6257
6258	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6259	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6260	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6261 	{ } /* end */
6262};
6263
6264static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6265{
6266	unsigned int gpiostate, gpiomask, gpiodir;
6267
6268	gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6269				       AC_VERB_GET_GPIO_DATA, 0);
6270
6271	if (!muted)
6272		gpiostate |= (1 << pin);
6273	else
6274		gpiostate &= ~(1 << pin);
6275
6276	gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6277				      AC_VERB_GET_GPIO_MASK, 0);
6278	gpiomask |= (1 << pin);
6279
6280	gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6281				     AC_VERB_GET_GPIO_DIRECTION, 0);
6282	gpiodir |= (1 << pin);
6283
6284
6285	snd_hda_codec_write(codec, codec->afg, 0,
6286			    AC_VERB_SET_GPIO_MASK, gpiomask);
6287	snd_hda_codec_write(codec, codec->afg, 0,
6288			    AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6289
6290	msleep(1);
6291
6292	snd_hda_codec_write(codec, codec->afg, 0,
6293			    AC_VERB_SET_GPIO_DATA, gpiostate);
6294}
6295
6296/* set up GPIO at initialization */
6297static void alc885_macpro_init_hook(struct hda_codec *codec)
6298{
6299	alc882_gpio_mute(codec, 0, 0);
6300	alc882_gpio_mute(codec, 1, 0);
6301}
6302
6303/* set up GPIO and update auto-muting at initialization */
6304static void alc885_imac24_init_hook(struct hda_codec *codec)
6305{
6306	alc885_macpro_init_hook(codec);
6307	alc885_imac24_automute(codec);
6308}
6309
6310/*
6311 * generic initialization of ADC, input mixers and output mixers
6312 */
6313static struct hda_verb alc882_auto_init_verbs[] = {
6314	/*
6315	 * Unmute ADC0-2 and set the default input to mic-in
6316	 */
6317	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6318	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6319	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6320	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6321	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6322	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6323
6324	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6325	 * mixer widget
6326	 * Note: PASD motherboards uses the Line In 2 as the input for
6327	 * front panel mic (mic 2)
6328	 */
6329	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6330	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6331	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6332	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6333	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6334	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6335
6336	/*
6337	 * Set up output mixers (0x0c - 0x0f)
6338	 */
6339	/* set vol=0 to output mixers */
6340	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6341	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6342	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6343	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6344	/* set up input amps for analog loopback */
6345	/* Amp Indices: DAC = 0, mixer = 1 */
6346	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6347	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6348	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6349	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6350	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6351	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6352	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6353	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6354	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6355	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6356
6357	/* FIXME: use matrix-type input source selection */
6358	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6359	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6360	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6361	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6362	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6363	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6364	/* Input mixer2 */
6365	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6366	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6367	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6368	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6369	/* Input mixer3 */
6370	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6371	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6372	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6373	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6374
6375	{ }
6376};
6377
6378#ifdef CONFIG_SND_HDA_POWER_SAVE
6379#define alc882_loopbacks	alc880_loopbacks
6380#endif
6381
6382/* pcm configuration: identiacal with ALC880 */
6383#define alc882_pcm_analog_playback	alc880_pcm_analog_playback
6384#define alc882_pcm_analog_capture	alc880_pcm_analog_capture
6385#define alc882_pcm_digital_playback	alc880_pcm_digital_playback
6386#define alc882_pcm_digital_capture	alc880_pcm_digital_capture
6387
6388/*
6389 * configuration and preset
6390 */
6391static const char *alc882_models[ALC882_MODEL_LAST] = {
6392	[ALC882_3ST_DIG]	= "3stack-dig",
6393	[ALC882_6ST_DIG]	= "6stack-dig",
6394	[ALC882_ARIMA]		= "arima",
6395	[ALC882_W2JC]		= "w2jc",
6396	[ALC882_TARGA]		= "targa",
6397	[ALC882_ASUS_A7J]	= "asus-a7j",
6398	[ALC882_ASUS_A7M]	= "asus-a7m",
6399	[ALC885_MACPRO]		= "macpro",
6400	[ALC885_MBP3]		= "mbp3",
6401	[ALC885_IMAC24]		= "imac24",
6402	[ALC882_AUTO]		= "auto",
6403};
6404
6405static struct snd_pci_quirk alc882_cfg_tbl[] = {
6406	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6407	SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6408	SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6409	SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6410	SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6411	SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6412	SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6413	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6414	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6415	SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
6416	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6417	SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6418	{}
6419};
6420
6421static struct alc_config_preset alc882_presets[] = {
6422	[ALC882_3ST_DIG] = {
6423		.mixers = { alc882_base_mixer },
6424		.init_verbs = { alc882_init_verbs },
6425		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6426		.dac_nids = alc882_dac_nids,
6427		.dig_out_nid = ALC882_DIGOUT_NID,
6428		.dig_in_nid = ALC882_DIGIN_NID,
6429		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6430		.channel_mode = alc882_ch_modes,
6431		.need_dac_fix = 1,
6432		.input_mux = &alc882_capture_source,
6433	},
6434	[ALC882_6ST_DIG] = {
6435		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
6436		.init_verbs = { alc882_init_verbs },
6437		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6438		.dac_nids = alc882_dac_nids,
6439		.dig_out_nid = ALC882_DIGOUT_NID,
6440		.dig_in_nid = ALC882_DIGIN_NID,
6441		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6442		.channel_mode = alc882_sixstack_modes,
6443		.input_mux = &alc882_capture_source,
6444	},
6445	[ALC882_ARIMA] = {
6446		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
6447		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6448		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6449		.dac_nids = alc882_dac_nids,
6450		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6451		.channel_mode = alc882_sixstack_modes,
6452		.input_mux = &alc882_capture_source,
6453	},
6454	[ALC882_W2JC] = {
6455		.mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6456		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6457				alc880_gpio1_init_verbs },
6458		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6459		.dac_nids = alc882_dac_nids,
6460		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6461		.channel_mode = alc880_threestack_modes,
6462		.need_dac_fix = 1,
6463		.input_mux = &alc882_capture_source,
6464		.dig_out_nid = ALC882_DIGOUT_NID,
6465	},
6466	[ALC885_MBP3] = {
6467		.mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6468		.init_verbs = { alc885_mbp3_init_verbs,
6469				alc880_gpio1_init_verbs },
6470		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6471		.dac_nids = alc882_dac_nids,
6472		.channel_mode = alc885_mbp_6ch_modes,
6473		.num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6474		.input_mux = &alc882_capture_source,
6475		.dig_out_nid = ALC882_DIGOUT_NID,
6476		.dig_in_nid = ALC882_DIGIN_NID,
6477		.unsol_event = alc885_mbp3_unsol_event,
6478		.init_hook = alc885_mbp3_automute,
6479	},
6480	[ALC885_MACPRO] = {
6481		.mixers = { alc882_macpro_mixer },
6482		.init_verbs = { alc882_macpro_init_verbs },
6483		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6484		.dac_nids = alc882_dac_nids,
6485		.dig_out_nid = ALC882_DIGOUT_NID,
6486		.dig_in_nid = ALC882_DIGIN_NID,
6487		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6488		.channel_mode = alc882_ch_modes,
6489		.input_mux = &alc882_capture_source,
6490		.init_hook = alc885_macpro_init_hook,
6491	},
6492	[ALC885_IMAC24] = {
6493		.mixers = { alc885_imac24_mixer },
6494		.init_verbs = { alc885_imac24_init_verbs },
6495		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6496		.dac_nids = alc882_dac_nids,
6497		.dig_out_nid = ALC882_DIGOUT_NID,
6498		.dig_in_nid = ALC882_DIGIN_NID,
6499		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6500		.channel_mode = alc882_ch_modes,
6501		.input_mux = &alc882_capture_source,
6502		.unsol_event = alc885_imac24_unsol_event,
6503		.init_hook = alc885_imac24_init_hook,
6504	},
6505	[ALC882_TARGA] = {
6506		.mixers = { alc882_targa_mixer, alc882_chmode_mixer },
6507		.init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6508		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6509		.dac_nids = alc882_dac_nids,
6510		.dig_out_nid = ALC882_DIGOUT_NID,
6511		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6512		.adc_nids = alc882_adc_nids,
6513		.capsrc_nids = alc882_capsrc_nids,
6514		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6515		.channel_mode = alc882_3ST_6ch_modes,
6516		.need_dac_fix = 1,
6517		.input_mux = &alc882_capture_source,
6518		.unsol_event = alc882_targa_unsol_event,
6519		.init_hook = alc882_targa_automute,
6520	},
6521	[ALC882_ASUS_A7J] = {
6522		.mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
6523		.init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6524		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6525		.dac_nids = alc882_dac_nids,
6526		.dig_out_nid = ALC882_DIGOUT_NID,
6527		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6528		.adc_nids = alc882_adc_nids,
6529		.capsrc_nids = alc882_capsrc_nids,
6530		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6531		.channel_mode = alc882_3ST_6ch_modes,
6532		.need_dac_fix = 1,
6533		.input_mux = &alc882_capture_source,
6534	},
6535	[ALC882_ASUS_A7M] = {
6536		.mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6537		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6538				alc880_gpio1_init_verbs,
6539				alc882_asus_a7m_verbs },
6540		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6541		.dac_nids = alc882_dac_nids,
6542		.dig_out_nid = ALC882_DIGOUT_NID,
6543		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6544		.channel_mode = alc880_threestack_modes,
6545		.need_dac_fix = 1,
6546		.input_mux = &alc882_capture_source,
6547	},
6548};
6549
6550
6551/*
6552 * Pin config fixes
6553 */
6554enum {
6555	PINFIX_ABIT_AW9D_MAX
6556};
6557
6558static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6559	{ 0x15, 0x01080104 }, /* side */
6560	{ 0x16, 0x01011012 }, /* rear */
6561	{ 0x17, 0x01016011 }, /* clfe */
6562	{ }
6563};
6564
6565static const struct alc_pincfg *alc882_pin_fixes[] = {
6566	[PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6567};
6568
6569static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6570	SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6571	{}
6572};
6573
6574/*
6575 * BIOS auto configuration
6576 */
6577static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6578					      hda_nid_t nid, int pin_type,
6579					      int dac_idx)
6580{
6581	/* set as output */
6582	struct alc_spec *spec = codec->spec;
6583	int idx;
6584
6585	alc_set_pin_output(codec, nid, pin_type);
6586	if (spec->multiout.dac_nids[dac_idx] == 0x25)
6587		idx = 4;
6588	else
6589		idx = spec->multiout.dac_nids[dac_idx] - 2;
6590	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6591
6592}
6593
6594static void alc882_auto_init_multi_out(struct hda_codec *codec)
6595{
6596	struct alc_spec *spec = codec->spec;
6597	int i;
6598
6599	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6600	for (i = 0; i <= HDA_SIDE; i++) {
6601		hda_nid_t nid = spec->autocfg.line_out_pins[i];
6602		int pin_type = get_pin_type(spec->autocfg.line_out_type);
6603		if (nid)
6604			alc882_auto_set_output_and_unmute(codec, nid, pin_type,
6605							  i);
6606	}
6607}
6608
6609static void alc882_auto_init_hp_out(struct hda_codec *codec)
6610{
6611	struct alc_spec *spec = codec->spec;
6612	hda_nid_t pin;
6613
6614	pin = spec->autocfg.hp_pins[0];
6615	if (pin) /* connect to front */
6616		/* use dac 0 */
6617		alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6618	pin = spec->autocfg.speaker_pins[0];
6619	if (pin)
6620		alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
6621}
6622
6623#define alc882_is_input_pin(nid)	alc880_is_input_pin(nid)
6624#define ALC882_PIN_CD_NID		ALC880_PIN_CD_NID
6625
6626static void alc882_auto_init_analog_input(struct hda_codec *codec)
6627{
6628	struct alc_spec *spec = codec->spec;
6629	int i;
6630
6631	for (i = 0; i < AUTO_PIN_LAST; i++) {
6632		hda_nid_t nid = spec->autocfg.input_pins[i];
6633		unsigned int vref;
6634		if (!nid)
6635			continue;
6636		vref = PIN_IN;
6637		if (1 /*i <= AUTO_PIN_FRONT_MIC*/) {
6638			unsigned int pincap;
6639			pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
6640			if ((pincap >> AC_PINCAP_VREF_SHIFT) &
6641			    AC_PINCAP_VREF_80)
6642				vref = PIN_VREF80;
6643		}
6644		snd_hda_codec_write(codec, nid, 0,
6645				    AC_VERB_SET_PIN_WIDGET_CONTROL, vref);
6646		if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
6647			snd_hda_codec_write(codec, nid, 0,
6648					    AC_VERB_SET_AMP_GAIN_MUTE,
6649					    AMP_OUT_MUTE);
6650	}
6651}
6652
6653static void alc882_auto_init_input_src(struct hda_codec *codec)
6654{
6655	struct alc_spec *spec = codec->spec;
6656	const struct hda_input_mux *imux = spec->input_mux;
6657	int c;
6658
6659	for (c = 0; c < spec->num_adc_nids; c++) {
6660		hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
6661		hda_nid_t nid = spec->capsrc_nids[c];
6662		int conns, mute, idx, item;
6663
6664		conns = snd_hda_get_connections(codec, nid, conn_list,
6665						ARRAY_SIZE(conn_list));
6666		if (conns < 0)
6667			continue;
6668		for (idx = 0; idx < conns; idx++) {
6669			/* if the current connection is the selected one,
6670			 * unmute it as default - otherwise mute it
6671			 */
6672			mute = AMP_IN_MUTE(idx);
6673			for (item = 0; item < imux->num_items; item++) {
6674				if (imux->items[item].index == idx) {
6675					if (spec->cur_mux[c] == item)
6676						mute = AMP_IN_UNMUTE(idx);
6677					break;
6678				}
6679			}
6680			snd_hda_codec_write(codec, nid, 0,
6681					    AC_VERB_SET_AMP_GAIN_MUTE, mute);
6682		}
6683	}
6684}
6685
6686/* add mic boosts if needed */
6687static int alc_auto_add_mic_boost(struct hda_codec *codec)
6688{
6689	struct alc_spec *spec = codec->spec;
6690	int err;
6691	hda_nid_t nid;
6692
6693	nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
6694	if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6695		err = add_control(spec, ALC_CTL_WIDGET_VOL,
6696				  "Mic Boost",
6697				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6698		if (err < 0)
6699			return err;
6700	}
6701	nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6702	if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6703		err = add_control(spec, ALC_CTL_WIDGET_VOL,
6704				  "Front Mic Boost",
6705				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6706		if (err < 0)
6707			return err;
6708	}
6709	return 0;
6710}
6711
6712/* almost identical with ALC880 parser... */
6713static int alc882_parse_auto_config(struct hda_codec *codec)
6714{
6715	struct alc_spec *spec = codec->spec;
6716	int err = alc880_parse_auto_config(codec);
6717
6718	if (err < 0)
6719		return err;
6720	else if (!err)
6721		return 0; /* no config found */
6722
6723	err = alc_auto_add_mic_boost(codec);
6724	if (err < 0)
6725		return err;
6726
6727	/* hack - override the init verbs */
6728	spec->init_verbs[0] = alc882_auto_init_verbs;
6729
6730	return 1; /* config found */
6731}
6732
6733/* additional initialization for auto-configuration model */
6734static void alc882_auto_init(struct hda_codec *codec)
6735{
6736	struct alc_spec *spec = codec->spec;
6737	alc882_auto_init_multi_out(codec);
6738	alc882_auto_init_hp_out(codec);
6739	alc882_auto_init_analog_input(codec);
6740	alc882_auto_init_input_src(codec);
6741	if (spec->unsol_event)
6742		alc_inithook(codec);
6743}
6744
6745static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
6746
6747static int patch_alc882(struct hda_codec *codec)
6748{
6749	struct alc_spec *spec;
6750	int err, board_config;
6751
6752	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6753	if (spec == NULL)
6754		return -ENOMEM;
6755
6756	codec->spec = spec;
6757
6758	board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6759						  alc882_models,
6760						  alc882_cfg_tbl);
6761
6762	if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
6763		/* Pick up systems that don't supply PCI SSID */
6764		switch (codec->subsystem_id) {
6765		case 0x106b0c00: /* Mac Pro */
6766			board_config = ALC885_MACPRO;
6767			break;
6768		case 0x106b1000: /* iMac 24 */
6769		case 0x106b2800: /* AppleTV */
6770			board_config = ALC885_IMAC24;
6771			break;
6772		case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
6773		case 0x106b00a4: /* MacbookPro4,1 */
6774		case 0x106b2c00: /* Macbook Pro rev3 */
6775		case 0x106b3600: /* Macbook 3.1 */
6776			board_config = ALC885_MBP3;
6777			break;
6778		default:
6779			/* ALC889A is handled better as ALC888-compatible */
6780			if (codec->revision_id == 0x100101 ||
6781			    codec->revision_id == 0x100103) {
6782				alc_free(codec);
6783				return patch_alc883(codec);
6784			}
6785			printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6786		       			 "trying auto-probe from BIOS...\n");
6787			board_config = ALC882_AUTO;
6788		}
6789	}
6790
6791	alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6792
6793	if (board_config == ALC882_AUTO) {
6794		/* automatic parse from the BIOS config */
6795		err = alc882_parse_auto_config(codec);
6796		if (err < 0) {
6797			alc_free(codec);
6798			return err;
6799		} else if (!err) {
6800			printk(KERN_INFO
6801			       "hda_codec: Cannot set up configuration "
6802			       "from BIOS.  Using base mode...\n");
6803			board_config = ALC882_3ST_DIG;
6804		}
6805	}
6806
6807	if (board_config != ALC882_AUTO)
6808		setup_preset(spec, &alc882_presets[board_config]);
6809
6810	if (codec->vendor_id == 0x10ec0885) {
6811		spec->stream_name_analog = "ALC885 Analog";
6812		spec->stream_name_digital = "ALC885 Digital";
6813	} else {
6814		spec->stream_name_analog = "ALC882 Analog";
6815		spec->stream_name_digital = "ALC882 Digital";
6816	}
6817
6818	spec->stream_analog_playback = &alc882_pcm_analog_playback;
6819	spec->stream_analog_capture = &alc882_pcm_analog_capture;
6820	/* FIXME: setup DAC5 */
6821	/*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
6822	spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
6823
6824	spec->stream_digital_playback = &alc882_pcm_digital_playback;
6825	spec->stream_digital_capture = &alc882_pcm_digital_capture;
6826
6827	spec->is_mix_capture = 1; /* matrix-style capture */
6828	if (!spec->adc_nids && spec->input_mux) {
6829		/* check whether NID 0x07 is valid */
6830		unsigned int wcap = get_wcaps(codec, 0x07);
6831		/* get type */
6832		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6833		if (wcap != AC_WID_AUD_IN) {
6834			spec->adc_nids = alc882_adc_nids_alt;
6835			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6836			spec->capsrc_nids = alc882_capsrc_nids_alt;
6837		} else {
6838			spec->adc_nids = alc882_adc_nids;
6839			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6840			spec->capsrc_nids = alc882_capsrc_nids;
6841		}
6842	}
6843	set_capture_mixer(spec);
6844
6845	spec->vmaster_nid = 0x0c;
6846
6847	codec->patch_ops = alc_patch_ops;
6848	if (board_config == ALC882_AUTO)
6849		spec->init_hook = alc882_auto_init;
6850#ifdef CONFIG_SND_HDA_POWER_SAVE
6851	if (!spec->loopback.amplist)
6852		spec->loopback.amplist = alc882_loopbacks;
6853#endif
6854
6855	return 0;
6856}
6857
6858/*
6859 * ALC883 support
6860 *
6861 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6862 * configuration.  Each pin widget can choose any input DACs and a mixer.
6863 * Each ADC is connected from a mixer of all inputs.  This makes possible
6864 * 6-channel independent captures.
6865 *
6866 * In addition, an independent DAC for the multi-playback (not used in this
6867 * driver yet).
6868 */
6869#define ALC883_DIGOUT_NID	0x06
6870#define ALC883_DIGIN_NID	0x0a
6871
6872#define ALC1200_DIGOUT_NID	0x10
6873
6874static hda_nid_t alc883_dac_nids[4] = {
6875	/* front, rear, clfe, rear_surr */
6876	0x02, 0x03, 0x04, 0x05
6877};
6878
6879static hda_nid_t alc883_adc_nids[2] = {
6880	/* ADC1-2 */
6881	0x08, 0x09,
6882};
6883
6884static hda_nid_t alc883_adc_nids_alt[1] = {
6885	/* ADC1 */
6886	0x08,
6887};
6888
6889static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
6890
6891/* input MUX */
6892/* FIXME: should be a matrix-type input source selection */
6893
6894static struct hda_input_mux alc883_capture_source = {
6895	.num_items = 4,
6896	.items = {
6897		{ "Mic", 0x0 },
6898		{ "Front Mic", 0x1 },
6899		{ "Line", 0x2 },
6900		{ "CD", 0x4 },
6901	},
6902};
6903
6904static struct hda_input_mux alc883_3stack_6ch_intel = {
6905	.num_items = 4,
6906	.items = {
6907		{ "Mic", 0x1 },
6908		{ "Front Mic", 0x0 },
6909		{ "Line", 0x2 },
6910		{ "CD", 0x4 },
6911	},
6912};
6913
6914static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6915	.num_items = 2,
6916	.items = {
6917		{ "Mic", 0x1 },
6918		{ "Line", 0x2 },
6919	},
6920};
6921
6922static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6923	.num_items = 4,
6924	.items = {
6925		{ "Mic", 0x0 },
6926		{ "iMic", 0x1 },
6927		{ "Line", 0x2 },
6928		{ "CD", 0x4 },
6929	},
6930};
6931
6932static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6933	.num_items = 2,
6934	.items = {
6935		{ "Mic", 0x0 },
6936		{ "Int Mic", 0x1 },
6937	},
6938};
6939
6940static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6941	.num_items = 3,
6942	.items = {
6943		{ "Mic", 0x0 },
6944		{ "Front Mic", 0x1 },
6945		{ "Line", 0x4 },
6946	},
6947};
6948
6949static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6950	.num_items = 2,
6951	.items = {
6952		{ "Mic", 0x0 },
6953		{ "Line", 0x2 },
6954	},
6955};
6956
6957/*
6958 * 2ch mode
6959 */
6960static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6961	{ 2, NULL }
6962};
6963
6964/*
6965 * 2ch mode
6966 */
6967static struct hda_verb alc883_3ST_ch2_init[] = {
6968	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6969	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6970	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6971	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6972	{ } /* end */
6973};
6974
6975/*
6976 * 4ch mode
6977 */
6978static struct hda_verb alc883_3ST_ch4_init[] = {
6979	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6980	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6981	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6982	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6983	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6984	{ } /* end */
6985};
6986
6987/*
6988 * 6ch mode
6989 */
6990static struct hda_verb alc883_3ST_ch6_init[] = {
6991	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6992	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6993	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6994	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6995	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6996	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6997	{ } /* end */
6998};
6999
7000static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
7001	{ 2, alc883_3ST_ch2_init },
7002	{ 4, alc883_3ST_ch4_init },
7003	{ 6, alc883_3ST_ch6_init },
7004};
7005
7006/*
7007 * 2ch mode
7008 */
7009static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7010	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7011	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7012	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7013	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7014	{ } /* end */
7015};
7016
7017/*
7018 * 4ch mode
7019 */
7020static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7021	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7022	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7023	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7024	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7025	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7026	{ } /* end */
7027};
7028
7029/*
7030 * 6ch mode
7031 */
7032static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7033	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7034	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7035	{ 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7036	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7037	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7038	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7039	{ } /* end */
7040};
7041
7042static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7043	{ 2, alc883_3ST_ch2_intel_init },
7044	{ 4, alc883_3ST_ch4_intel_init },
7045	{ 6, alc883_3ST_ch6_intel_init },
7046};
7047
7048/*
7049 * 6ch mode
7050 */
7051static struct hda_verb alc883_sixstack_ch6_init[] = {
7052	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7053	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7054	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7055	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7056	{ } /* end */
7057};
7058
7059/*
7060 * 8ch mode
7061 */
7062static struct hda_verb alc883_sixstack_ch8_init[] = {
7063	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7064	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7065	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7066	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7067	{ } /* end */
7068};
7069
7070static struct hda_channel_mode alc883_sixstack_modes[2] = {
7071	{ 6, alc883_sixstack_ch6_init },
7072	{ 8, alc883_sixstack_ch8_init },
7073};
7074
7075static struct hda_verb alc883_medion_eapd_verbs[] = {
7076        /* eanable EAPD on medion laptop */
7077	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7078	{0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7079	{ }
7080};
7081
7082/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7083 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7084 */
7085
7086static struct snd_kcontrol_new alc883_base_mixer[] = {
7087	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7088	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7089	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7090	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7091	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7092	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7093	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7094	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7095	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7096	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7097	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7098	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7099	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7100	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7101	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7102	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7103	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7104	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7105	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7106	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7107	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7108	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7109	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7110	{ } /* end */
7111};
7112
7113static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7114	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7115	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7116	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7117	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7118	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7119	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7120	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7121	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7122	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7123	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7124	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7125	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7126	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7127	{ } /* end */
7128};
7129
7130static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7131	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7132	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7133	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7134	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7135	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7136	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7137	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7138	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7139	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7140	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7141	{ } /* end */
7142};
7143
7144static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7145	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7146	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7147	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7148	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7149	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7150	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7151	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7152	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7153	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7154	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7155	{ } /* end */
7156};
7157
7158static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7159	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7160	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7161	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7162	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7163	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7164	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7165	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7166	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7167	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7168	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7169	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7170	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7171	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7172	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7173	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7174	{ } /* end */
7175};
7176
7177static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7178	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7179	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7180	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7181	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7182	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7183	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7184	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7185	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7186	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7187	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7188	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7189	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7190	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7191	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7192	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7193	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7194	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7195	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7196	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7197	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7198	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7199	{ } /* end */
7200};
7201
7202static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7203	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7204	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7205	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7206	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7207	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7208			      HDA_OUTPUT),
7209	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7210	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7211	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7212	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7213	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7214	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7215	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7216	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7217	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7218	HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7219	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7220	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7221	HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7222	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7223	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7224	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7225	{ } /* end */
7226};
7227
7228static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7229	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7230	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7231	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7232	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7233	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7234	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7235	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7236	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7237	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7238	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7239	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7240	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7241	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7242	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7243	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7244	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7245	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7246	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7247	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7248	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7249	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7250	{ } /* end */
7251};
7252
7253static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7254	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7255	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7256	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7257	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7258	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7259	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7260	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7261	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7262	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7263	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7264	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7265	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7266	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7267	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7268	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7269	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7270	{ } /* end */
7271};
7272
7273static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7274	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7275	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7276	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7277	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7278	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7279	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7280	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7281	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7282	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7283	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7284	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7285	{ } /* end */
7286};
7287
7288static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7289	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7290	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7291	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7292	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7293	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7294	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7295	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7296	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7297	{ } /* end */
7298};
7299
7300static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7301	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7302	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7303	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7304	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7305	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7306	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7307	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7308	HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7309	HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7310	{ } /* end */
7311};
7312
7313static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7314	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7315	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7316	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7317	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7318	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7319	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7320	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7321	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7322	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7323	{ } /* end */
7324};
7325
7326static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7327	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7328	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7329	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7330	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7331	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7332	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7333	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7334	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7335	{ } /* end */
7336};
7337
7338static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7339	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7340	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7341	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7342	HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7343	HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7344						0x0d, 1, 0x0, HDA_OUTPUT),
7345	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7346	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7347	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7348	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7349	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7350	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7351	HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
7352	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7353	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7354	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7355	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7356	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7357	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7358	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7359	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7360	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7361	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7362	{ } /* end */
7363};
7364
7365static struct hda_bind_ctls alc883_bind_cap_vol = {
7366	.ops = &snd_hda_bind_vol,
7367	.values = {
7368		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7369		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7370		0
7371	},
7372};
7373
7374static struct hda_bind_ctls alc883_bind_cap_switch = {
7375	.ops = &snd_hda_bind_sw,
7376	.values = {
7377		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7378		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7379		0
7380	},
7381};
7382
7383static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7384	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7385	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7386	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7387	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7388	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7389	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7390	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7391	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7392	{ } /* end */
7393};
7394
7395static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
7396	HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7397	HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7398	{
7399		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7400		/* .name = "Capture Source", */
7401		.name = "Input Source",
7402		.count = 1,
7403		.info = alc_mux_enum_info,
7404		.get = alc_mux_enum_get,
7405		.put = alc_mux_enum_put,
7406	},
7407	{ } /* end */
7408};
7409
7410static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7411	{
7412		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7413		.name = "Channel Mode",
7414		.info = alc_ch_mode_info,
7415		.get = alc_ch_mode_get,
7416		.put = alc_ch_mode_put,
7417	},
7418	{ } /* end */
7419};
7420
7421static struct hda_verb alc883_init_verbs[] = {
7422	/* ADC1: mute amp left and right */
7423	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7424	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7425	/* ADC2: mute amp left and right */
7426	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7427	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7428	/* Front mixer: unmute input/output amp left and right (volume = 0) */
7429	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7430	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7431	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7432	/* Rear mixer */
7433	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7434	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7435	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7436	/* CLFE mixer */
7437	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7438	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7439	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7440	/* Side mixer */
7441	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7442	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7443	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7444
7445	/* mute analog input loopbacks */
7446	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7447	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7448	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7449	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7450	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7451
7452	/* Front Pin: output 0 (0x0c) */
7453	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7454	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7455	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7456	/* Rear Pin: output 1 (0x0d) */
7457	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7458	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7459	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7460	/* CLFE Pin: output 2 (0x0e) */
7461	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7462	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7463	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7464	/* Side Pin: output 3 (0x0f) */
7465	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7466	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7467	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7468	/* Mic (rear) pin: input vref at 80% */
7469	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7470	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7471	/* Front Mic pin: input vref at 80% */
7472	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7473	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7474	/* Line In pin: input */
7475	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7476	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7477	/* Line-2 In: Headphone output (output 0 - 0x0c) */
7478	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7479	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7480	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7481	/* CD pin widget for input */
7482	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7483
7484	/* FIXME: use matrix-type input source selection */
7485	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7486	/* Input mixer2 */
7487	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7488	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7489	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7490	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7491	/* Input mixer3 */
7492	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7493	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7494	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7495	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7496	{ }
7497};
7498
7499/* toggle speaker-output according to the hp-jack state */
7500static void alc883_mitac_hp_automute(struct hda_codec *codec)
7501{
7502	unsigned int present;
7503
7504	present = snd_hda_codec_read(codec, 0x15, 0,
7505				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7506	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7507				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7508	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7509				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7510}
7511
7512/* auto-toggle front mic */
7513/*
7514static void alc883_mitac_mic_automute(struct hda_codec *codec)
7515{
7516	unsigned int present;
7517	unsigned char bits;
7518
7519	present = snd_hda_codec_read(codec, 0x18, 0,
7520				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7521	bits = present ? HDA_AMP_MUTE : 0;
7522	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7523}
7524*/
7525
7526static void alc883_mitac_automute(struct hda_codec *codec)
7527{
7528	alc883_mitac_hp_automute(codec);
7529	/* alc883_mitac_mic_automute(codec); */
7530}
7531
7532static void alc883_mitac_unsol_event(struct hda_codec *codec,
7533					   unsigned int res)
7534{
7535	switch (res >> 26) {
7536	case ALC880_HP_EVENT:
7537		alc883_mitac_hp_automute(codec);
7538		break;
7539	case ALC880_MIC_EVENT:
7540		/* alc883_mitac_mic_automute(codec); */
7541		break;
7542	}
7543}
7544
7545static struct hda_verb alc883_mitac_verbs[] = {
7546	/* HP */
7547	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7548	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7549	/* Subwoofer */
7550	{0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7551	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7552
7553	/* enable unsolicited event */
7554	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7555	/* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7556
7557	{ } /* end */
7558};
7559
7560static struct hda_verb alc883_clevo_m720_verbs[] = {
7561	/* HP */
7562	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7563	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7564	/* Int speaker */
7565	{0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
7566	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7567
7568	/* enable unsolicited event */
7569	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7570	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
7571
7572	{ } /* end */
7573};
7574
7575static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
7576	/* HP */
7577	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7578	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7579	/* Subwoofer */
7580	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7581	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7582
7583	/* enable unsolicited event */
7584	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7585
7586	{ } /* end */
7587};
7588
7589static struct hda_verb alc883_tagra_verbs[] = {
7590	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7591	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7592
7593	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7594	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7595
7596	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7597	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7598	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7599
7600	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7601	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7602	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7603	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
7604
7605	{ } /* end */
7606};
7607
7608static struct hda_verb alc883_lenovo_101e_verbs[] = {
7609	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7610	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7611        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7612	{ } /* end */
7613};
7614
7615static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7616        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7617	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7618        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7619        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7620	{ } /* end */
7621};
7622
7623static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7624	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7625	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7626	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7627	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7628	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
7629	{ } /* end */
7630};
7631
7632static struct hda_verb alc883_haier_w66_verbs[] = {
7633	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7634	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7635
7636	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7637
7638	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7639	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7640	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7641	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7642	{ } /* end */
7643};
7644
7645static struct hda_verb alc888_lenovo_sky_verbs[] = {
7646	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7647	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7648	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7649	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7650	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7651	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7652	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7653	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7654	{ } /* end */
7655};
7656
7657static struct hda_verb alc888_3st_hp_verbs[] = {
7658	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Front: output 0 (0x0c) */
7659	{0x16, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Rear : output 1 (0x0d) */
7660	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02},	/* CLFE : output 2 (0x0e) */
7661	{ }
7662};
7663
7664static struct hda_verb alc888_6st_dell_verbs[] = {
7665	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7666	{ }
7667};
7668
7669static struct hda_verb alc888_3st_hp_2ch_init[] = {
7670	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7671	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7672	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7673	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7674	{ }
7675};
7676
7677static struct hda_verb alc888_3st_hp_6ch_init[] = {
7678	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7679	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7680	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7681	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7682	{ }
7683};
7684
7685static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7686	{ 2, alc888_3st_hp_2ch_init },
7687	{ 6, alc888_3st_hp_6ch_init },
7688};
7689
7690/* toggle front-jack and RCA according to the hp-jack state */
7691static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7692{
7693 	unsigned int present;
7694
7695 	present = snd_hda_codec_read(codec, 0x1b, 0,
7696				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7697	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7698				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7699	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7700				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7701}
7702
7703/* toggle RCA according to the front-jack state */
7704static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7705{
7706 	unsigned int present;
7707
7708 	present = snd_hda_codec_read(codec, 0x14, 0,
7709				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7710	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7711				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7712}
7713
7714static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7715					     unsigned int res)
7716{
7717	if ((res >> 26) == ALC880_HP_EVENT)
7718		alc888_lenovo_ms7195_front_automute(codec);
7719	if ((res >> 26) == ALC880_FRONT_EVENT)
7720		alc888_lenovo_ms7195_rca_automute(codec);
7721}
7722
7723static struct hda_verb alc883_medion_md2_verbs[] = {
7724	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7725	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7726
7727	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7728
7729	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7730	{ } /* end */
7731};
7732
7733/* toggle speaker-output according to the hp-jack state */
7734static void alc883_medion_md2_automute(struct hda_codec *codec)
7735{
7736 	unsigned int present;
7737
7738 	present = snd_hda_codec_read(codec, 0x14, 0,
7739				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7740	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7741				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7742}
7743
7744static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7745					  unsigned int res)
7746{
7747	if ((res >> 26) == ALC880_HP_EVENT)
7748		alc883_medion_md2_automute(codec);
7749}
7750
7751/* toggle speaker-output according to the hp-jack state */
7752static void alc883_tagra_automute(struct hda_codec *codec)
7753{
7754 	unsigned int present;
7755	unsigned char bits;
7756
7757 	present = snd_hda_codec_read(codec, 0x14, 0,
7758				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7759	bits = present ? HDA_AMP_MUTE : 0;
7760	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7761				 HDA_AMP_MUTE, bits);
7762	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7763				  present ? 1 : 3);
7764}
7765
7766static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7767{
7768	if ((res >> 26) == ALC880_HP_EVENT)
7769		alc883_tagra_automute(codec);
7770}
7771
7772/* toggle speaker-output according to the hp-jack state */
7773static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
7774{
7775	unsigned int present;
7776	unsigned char bits;
7777
7778	present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
7779		& AC_PINSENSE_PRESENCE;
7780	bits = present ? HDA_AMP_MUTE : 0;
7781	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7782				 HDA_AMP_MUTE, bits);
7783}
7784
7785static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
7786{
7787	unsigned int present;
7788
7789	present = snd_hda_codec_read(codec, 0x18, 0,
7790				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7791	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
7792				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7793}
7794
7795static void alc883_clevo_m720_automute(struct hda_codec *codec)
7796{
7797	alc883_clevo_m720_hp_automute(codec);
7798	alc883_clevo_m720_mic_automute(codec);
7799}
7800
7801static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
7802					   unsigned int res)
7803{
7804	switch (res >> 26) {
7805	case ALC880_HP_EVENT:
7806		alc883_clevo_m720_hp_automute(codec);
7807		break;
7808	case ALC880_MIC_EVENT:
7809		alc883_clevo_m720_mic_automute(codec);
7810		break;
7811	}
7812}
7813
7814/* toggle speaker-output according to the hp-jack state */
7815static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
7816{
7817 	unsigned int present;
7818	unsigned char bits;
7819
7820 	present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
7821		& AC_PINSENSE_PRESENCE;
7822	bits = present ? HDA_AMP_MUTE : 0;
7823	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7824				 HDA_AMP_MUTE, bits);
7825}
7826
7827static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
7828						  unsigned int res)
7829{
7830	if ((res >> 26) == ALC880_HP_EVENT)
7831		alc883_2ch_fujitsu_pi2515_automute(codec);
7832}
7833
7834static void alc883_haier_w66_automute(struct hda_codec *codec)
7835{
7836	unsigned int present;
7837	unsigned char bits;
7838
7839	present = snd_hda_codec_read(codec, 0x1b, 0,
7840				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7841	bits = present ? 0x80 : 0;
7842	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7843				 0x80, bits);
7844}
7845
7846static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7847					 unsigned int res)
7848{
7849	if ((res >> 26) == ALC880_HP_EVENT)
7850		alc883_haier_w66_automute(codec);
7851}
7852
7853static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7854{
7855 	unsigned int present;
7856	unsigned char bits;
7857
7858 	present = snd_hda_codec_read(codec, 0x14, 0,
7859				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7860	bits = present ? HDA_AMP_MUTE : 0;
7861	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7862				 HDA_AMP_MUTE, bits);
7863}
7864
7865static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7866{
7867 	unsigned int present;
7868	unsigned char bits;
7869
7870 	present = snd_hda_codec_read(codec, 0x1b, 0,
7871				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7872	bits = present ? HDA_AMP_MUTE : 0;
7873	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7874				 HDA_AMP_MUTE, bits);
7875	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7876				 HDA_AMP_MUTE, bits);
7877}
7878
7879static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7880					   unsigned int res)
7881{
7882	if ((res >> 26) == ALC880_HP_EVENT)
7883		alc883_lenovo_101e_all_automute(codec);
7884	if ((res >> 26) == ALC880_FRONT_EVENT)
7885		alc883_lenovo_101e_ispeaker_automute(codec);
7886}
7887
7888/* toggle speaker-output according to the hp-jack state */
7889static void alc883_acer_aspire_automute(struct hda_codec *codec)
7890{
7891 	unsigned int present;
7892
7893 	present = snd_hda_codec_read(codec, 0x14, 0,
7894				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7895	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7896				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7897	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7898				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7899}
7900
7901static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7902					   unsigned int res)
7903{
7904	if ((res >> 26) == ALC880_HP_EVENT)
7905		alc883_acer_aspire_automute(codec);
7906}
7907
7908static struct hda_verb alc883_acer_eapd_verbs[] = {
7909	/* HP Pin: output 0 (0x0c) */
7910	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7911	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7912	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7913	/* Front Pin: output 0 (0x0c) */
7914	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7915	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7916	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7917	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7918        /* eanable EAPD on medion laptop */
7919	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7920	{0x20, AC_VERB_SET_PROC_COEF, 0x3050},
7921	/* enable unsolicited event */
7922	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7923	{ }
7924};
7925
7926static void alc888_6st_dell_front_automute(struct hda_codec *codec)
7927{
7928 	unsigned int present;
7929
7930 	present = snd_hda_codec_read(codec, 0x1b, 0,
7931				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7932	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7933				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7934	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7935				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7936	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7937				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7938	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7939				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7940}
7941
7942static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
7943					     unsigned int res)
7944{
7945	switch (res >> 26) {
7946	case ALC880_HP_EVENT:
7947		printk("hp_event\n");
7948		alc888_6st_dell_front_automute(codec);
7949		break;
7950	}
7951}
7952
7953static void alc888_lenovo_sky_front_automute(struct hda_codec *codec)
7954{
7955	unsigned int mute;
7956	unsigned int present;
7957
7958	snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
7959	present = snd_hda_codec_read(codec, 0x1b, 0,
7960				     AC_VERB_GET_PIN_SENSE, 0);
7961	present = (present & 0x80000000) != 0;
7962	if (present) {
7963		/* mute internal speaker */
7964		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7965					 HDA_AMP_MUTE, HDA_AMP_MUTE);
7966		snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7967					 HDA_AMP_MUTE, HDA_AMP_MUTE);
7968		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7969					 HDA_AMP_MUTE, HDA_AMP_MUTE);
7970		snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7971					 HDA_AMP_MUTE, HDA_AMP_MUTE);
7972		snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
7973					 HDA_AMP_MUTE, HDA_AMP_MUTE);
7974	} else {
7975		/* unmute internal speaker if necessary */
7976		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
7977		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7978					 HDA_AMP_MUTE, mute);
7979		snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7980					 HDA_AMP_MUTE, mute);
7981		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7982					 HDA_AMP_MUTE, mute);
7983		snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7984					 HDA_AMP_MUTE, mute);
7985		snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
7986					 HDA_AMP_MUTE, mute);
7987	}
7988}
7989
7990static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec,
7991					     unsigned int res)
7992{
7993	if ((res >> 26) == ALC880_HP_EVENT)
7994		alc888_lenovo_sky_front_automute(codec);
7995}
7996
7997/*
7998 * generic initialization of ADC, input mixers and output mixers
7999 */
8000static struct hda_verb alc883_auto_init_verbs[] = {
8001	/*
8002	 * Unmute ADC0-2 and set the default input to mic-in
8003	 */
8004	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8005	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8006	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8007	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8008
8009	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8010	 * mixer widget
8011	 * Note: PASD motherboards uses the Line In 2 as the input for
8012	 * front panel mic (mic 2)
8013	 */
8014	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8015	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8016	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8017	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8018	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8019	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8020
8021	/*
8022	 * Set up output mixers (0x0c - 0x0f)
8023	 */
8024	/* set vol=0 to output mixers */
8025	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8026	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8027	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8028	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8029	/* set up input amps for analog loopback */
8030	/* Amp Indices: DAC = 0, mixer = 1 */
8031	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8032	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8033	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8034	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8035	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8036	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8037	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8038	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8039	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8040	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8041
8042	/* FIXME: use matrix-type input source selection */
8043	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8044	/* Input mixer1 */
8045	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8046	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8047	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8048	/* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8049	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8050	/* Input mixer2 */
8051	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8052	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8053	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8054	/* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8055	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8056
8057	{ }
8058};
8059
8060static struct hda_verb alc888_asus_m90v_verbs[] = {
8061	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8062	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8063	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8064	/* enable unsolicited event */
8065	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8066	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8067	{ } /* end */
8068};
8069
8070static void alc883_nb_mic_automute(struct hda_codec *codec)
8071{
8072	unsigned int present;
8073
8074	present = snd_hda_codec_read(codec, 0x18, 0,
8075				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8076	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8077			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8078	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8079			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8080}
8081
8082static void alc883_M90V_speaker_automute(struct hda_codec *codec)
8083{
8084	unsigned int present;
8085	unsigned char bits;
8086
8087	present = snd_hda_codec_read(codec, 0x1b, 0,
8088				     AC_VERB_GET_PIN_SENSE, 0)
8089		& AC_PINSENSE_PRESENCE;
8090	bits = present ? 0 : PIN_OUT;
8091	snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8092			    bits);
8093	snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8094			    bits);
8095	snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8096			    bits);
8097}
8098
8099static void alc883_mode2_unsol_event(struct hda_codec *codec,
8100					   unsigned int res)
8101{
8102	switch (res >> 26) {
8103	case ALC880_HP_EVENT:
8104		alc883_M90V_speaker_automute(codec);
8105		break;
8106	case ALC880_MIC_EVENT:
8107		alc883_nb_mic_automute(codec);
8108		break;
8109	}
8110}
8111
8112static void alc883_mode2_inithook(struct hda_codec *codec)
8113{
8114	alc883_M90V_speaker_automute(codec);
8115	alc883_nb_mic_automute(codec);
8116}
8117
8118static struct hda_verb alc888_asus_eee1601_verbs[] = {
8119	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8120	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8121	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8122	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8123	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8124	{0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8125	{0x20, AC_VERB_SET_PROC_COEF,  0x0838},
8126	/* enable unsolicited event */
8127	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8128	{ } /* end */
8129};
8130
8131static void alc883_eee1601_speaker_automute(struct hda_codec *codec)
8132{
8133	unsigned int present;
8134	unsigned char bits;
8135
8136	present = snd_hda_codec_read(codec, 0x14, 0,
8137				     AC_VERB_GET_PIN_SENSE, 0)
8138		& AC_PINSENSE_PRESENCE;
8139	bits = present ? 0 : PIN_OUT;
8140	snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8141			    bits);
8142}
8143
8144static void alc883_eee1601_unsol_event(struct hda_codec *codec,
8145					   unsigned int res)
8146{
8147	switch (res >> 26) {
8148	case ALC880_HP_EVENT:
8149		alc883_eee1601_speaker_automute(codec);
8150		break;
8151	}
8152}
8153
8154static void alc883_eee1601_inithook(struct hda_codec *codec)
8155{
8156	alc883_eee1601_speaker_automute(codec);
8157}
8158
8159#ifdef CONFIG_SND_HDA_POWER_SAVE
8160#define alc883_loopbacks	alc880_loopbacks
8161#endif
8162
8163/* pcm configuration: identiacal with ALC880 */
8164#define alc883_pcm_analog_playback	alc880_pcm_analog_playback
8165#define alc883_pcm_analog_capture	alc880_pcm_analog_capture
8166#define alc883_pcm_analog_alt_capture	alc880_pcm_analog_alt_capture
8167#define alc883_pcm_digital_playback	alc880_pcm_digital_playback
8168#define alc883_pcm_digital_capture	alc880_pcm_digital_capture
8169
8170/*
8171 * configuration and preset
8172 */
8173static const char *alc883_models[ALC883_MODEL_LAST] = {
8174	[ALC883_3ST_2ch_DIG]	= "3stack-dig",
8175	[ALC883_3ST_6ch_DIG]	= "3stack-6ch-dig",
8176	[ALC883_3ST_6ch]	= "3stack-6ch",
8177	[ALC883_6ST_DIG]	= "6stack-dig",
8178	[ALC883_TARGA_DIG]	= "targa-dig",
8179	[ALC883_TARGA_2ch_DIG]	= "targa-2ch-dig",
8180	[ALC883_ACER]		= "acer",
8181	[ALC883_ACER_ASPIRE]	= "acer-aspire",
8182	[ALC883_MEDION]		= "medion",
8183	[ALC883_MEDION_MD2]	= "medion-md2",
8184	[ALC883_LAPTOP_EAPD]	= "laptop-eapd",
8185	[ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8186	[ALC883_LENOVO_NB0763]	= "lenovo-nb0763",
8187	[ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8188	[ALC888_LENOVO_SKY] = "lenovo-sky",
8189	[ALC883_HAIER_W66] 	= "haier-w66",
8190	[ALC888_3ST_HP]		= "3stack-hp",
8191	[ALC888_6ST_DELL]	= "6stack-dell",
8192	[ALC883_MITAC]		= "mitac",
8193	[ALC883_CLEVO_M720]	= "clevo-m720",
8194	[ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8195	[ALC883_3ST_6ch_INTEL]	= "3stack-6ch-intel",
8196	[ALC1200_ASUS_P5Q]	= "asus-p5q",
8197	[ALC883_AUTO]		= "auto",
8198};
8199
8200static struct snd_pci_quirk alc883_cfg_tbl[] = {
8201	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
8202	SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8203	SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
8204	SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8205	SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8206	SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8207	SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
8208	SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8209	SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8210	SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8211	SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8212	SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8213	SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8214	SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8215	SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
8216	SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8217	SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8218	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
8219	SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8220	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8221	SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8222	SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8223	SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
8224	SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8225	SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8226	SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8227	SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8228	SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8229	SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8230	SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8231	SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8232	SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8233	SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8234	SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8235	SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8236	SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8237	SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8238	SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8239	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8240	SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8241	SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8242	SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8243	SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8244	SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8245	SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8246	SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8247	SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8248	SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8249	SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
8250	SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8251	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8252	SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515),
8253	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8254	SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8255	SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8256	SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8257	SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8258	SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8259	SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
8260	SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8261	SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8262	SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8263	SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8264	SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8265	{}
8266};
8267
8268static struct alc_config_preset alc883_presets[] = {
8269	[ALC883_3ST_2ch_DIG] = {
8270		.mixers = { alc883_3ST_2ch_mixer },
8271		.init_verbs = { alc883_init_verbs },
8272		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8273		.dac_nids = alc883_dac_nids,
8274		.dig_out_nid = ALC883_DIGOUT_NID,
8275		.dig_in_nid = ALC883_DIGIN_NID,
8276		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8277		.channel_mode = alc883_3ST_2ch_modes,
8278		.input_mux = &alc883_capture_source,
8279	},
8280	[ALC883_3ST_6ch_DIG] = {
8281		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8282		.init_verbs = { alc883_init_verbs },
8283		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8284		.dac_nids = alc883_dac_nids,
8285		.dig_out_nid = ALC883_DIGOUT_NID,
8286		.dig_in_nid = ALC883_DIGIN_NID,
8287		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8288		.channel_mode = alc883_3ST_6ch_modes,
8289		.need_dac_fix = 1,
8290		.input_mux = &alc883_capture_source,
8291	},
8292	[ALC883_3ST_6ch] = {
8293		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8294		.init_verbs = { alc883_init_verbs },
8295		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8296		.dac_nids = alc883_dac_nids,
8297		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8298		.channel_mode = alc883_3ST_6ch_modes,
8299		.need_dac_fix = 1,
8300		.input_mux = &alc883_capture_source,
8301	},
8302	[ALC883_3ST_6ch_INTEL] = {
8303		.mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8304		.init_verbs = { alc883_init_verbs },
8305		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8306		.dac_nids = alc883_dac_nids,
8307		.dig_out_nid = ALC883_DIGOUT_NID,
8308		.dig_in_nid = ALC883_DIGIN_NID,
8309		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8310		.channel_mode = alc883_3ST_6ch_intel_modes,
8311		.need_dac_fix = 1,
8312		.input_mux = &alc883_3stack_6ch_intel,
8313	},
8314	[ALC883_6ST_DIG] = {
8315		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
8316		.init_verbs = { alc883_init_verbs },
8317		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8318		.dac_nids = alc883_dac_nids,
8319		.dig_out_nid = ALC883_DIGOUT_NID,
8320		.dig_in_nid = ALC883_DIGIN_NID,
8321		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8322		.channel_mode = alc883_sixstack_modes,
8323		.input_mux = &alc883_capture_source,
8324	},
8325	[ALC883_TARGA_DIG] = {
8326		.mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8327		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8328		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8329		.dac_nids = alc883_dac_nids,
8330		.dig_out_nid = ALC883_DIGOUT_NID,
8331		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8332		.channel_mode = alc883_3ST_6ch_modes,
8333		.need_dac_fix = 1,
8334		.input_mux = &alc883_capture_source,
8335		.unsol_event = alc883_tagra_unsol_event,
8336		.init_hook = alc883_tagra_automute,
8337	},
8338	[ALC883_TARGA_2ch_DIG] = {
8339		.mixers = { alc883_tagra_2ch_mixer},
8340		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8341		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8342		.dac_nids = alc883_dac_nids,
8343		.adc_nids = alc883_adc_nids_alt,
8344		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8345		.dig_out_nid = ALC883_DIGOUT_NID,
8346		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8347		.channel_mode = alc883_3ST_2ch_modes,
8348		.input_mux = &alc883_capture_source,
8349		.unsol_event = alc883_tagra_unsol_event,
8350		.init_hook = alc883_tagra_automute,
8351	},
8352	[ALC883_ACER] = {
8353		.mixers = { alc883_base_mixer },
8354		/* On TravelMate laptops, GPIO 0 enables the internal speaker
8355		 * and the headphone jack.  Turn this on and rely on the
8356		 * standard mute methods whenever the user wants to turn
8357		 * these outputs off.
8358		 */
8359		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8360		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8361		.dac_nids = alc883_dac_nids,
8362		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8363		.channel_mode = alc883_3ST_2ch_modes,
8364		.input_mux = &alc883_capture_source,
8365	},
8366	[ALC883_ACER_ASPIRE] = {
8367		.mixers = { alc883_acer_aspire_mixer },
8368		.init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
8369		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8370		.dac_nids = alc883_dac_nids,
8371		.dig_out_nid = ALC883_DIGOUT_NID,
8372		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8373		.channel_mode = alc883_3ST_2ch_modes,
8374		.input_mux = &alc883_capture_source,
8375		.unsol_event = alc883_acer_aspire_unsol_event,
8376		.init_hook = alc883_acer_aspire_automute,
8377	},
8378	[ALC883_MEDION] = {
8379		.mixers = { alc883_fivestack_mixer,
8380			    alc883_chmode_mixer },
8381		.init_verbs = { alc883_init_verbs,
8382				alc883_medion_eapd_verbs },
8383		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8384		.dac_nids = alc883_dac_nids,
8385		.adc_nids = alc883_adc_nids_alt,
8386		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8387		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8388		.channel_mode = alc883_sixstack_modes,
8389		.input_mux = &alc883_capture_source,
8390	},
8391	[ALC883_MEDION_MD2] = {
8392		.mixers = { alc883_medion_md2_mixer},
8393		.init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8394		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8395		.dac_nids = alc883_dac_nids,
8396		.dig_out_nid = ALC883_DIGOUT_NID,
8397		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8398		.channel_mode = alc883_3ST_2ch_modes,
8399		.input_mux = &alc883_capture_source,
8400		.unsol_event = alc883_medion_md2_unsol_event,
8401		.init_hook = alc883_medion_md2_automute,
8402	},
8403	[ALC883_LAPTOP_EAPD] = {
8404		.mixers = { alc883_base_mixer },
8405		.init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8406		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8407		.dac_nids = alc883_dac_nids,
8408		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8409		.channel_mode = alc883_3ST_2ch_modes,
8410		.input_mux = &alc883_capture_source,
8411	},
8412	[ALC883_CLEVO_M720] = {
8413		.mixers = { alc883_clevo_m720_mixer },
8414		.init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
8415		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8416		.dac_nids = alc883_dac_nids,
8417		.dig_out_nid = ALC883_DIGOUT_NID,
8418		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8419		.channel_mode = alc883_3ST_2ch_modes,
8420		.input_mux = &alc883_capture_source,
8421		.unsol_event = alc883_clevo_m720_unsol_event,
8422		.init_hook = alc883_clevo_m720_automute,
8423	},
8424	[ALC883_LENOVO_101E_2ch] = {
8425		.mixers = { alc883_lenovo_101e_2ch_mixer},
8426		.init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8427		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8428		.dac_nids = alc883_dac_nids,
8429		.adc_nids = alc883_adc_nids_alt,
8430		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8431		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8432		.channel_mode = alc883_3ST_2ch_modes,
8433		.input_mux = &alc883_lenovo_101e_capture_source,
8434		.unsol_event = alc883_lenovo_101e_unsol_event,
8435		.init_hook = alc883_lenovo_101e_all_automute,
8436	},
8437	[ALC883_LENOVO_NB0763] = {
8438		.mixers = { alc883_lenovo_nb0763_mixer },
8439		.init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8440		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8441		.dac_nids = alc883_dac_nids,
8442		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8443		.channel_mode = alc883_3ST_2ch_modes,
8444		.need_dac_fix = 1,
8445		.input_mux = &alc883_lenovo_nb0763_capture_source,
8446		.unsol_event = alc883_medion_md2_unsol_event,
8447		.init_hook = alc883_medion_md2_automute,
8448	},
8449	[ALC888_LENOVO_MS7195_DIG] = {
8450		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8451		.init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8452		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8453		.dac_nids = alc883_dac_nids,
8454		.dig_out_nid = ALC883_DIGOUT_NID,
8455		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8456		.channel_mode = alc883_3ST_6ch_modes,
8457		.need_dac_fix = 1,
8458		.input_mux = &alc883_capture_source,
8459		.unsol_event = alc883_lenovo_ms7195_unsol_event,
8460		.init_hook = alc888_lenovo_ms7195_front_automute,
8461	},
8462	[ALC883_HAIER_W66] = {
8463		.mixers = { alc883_tagra_2ch_mixer},
8464		.init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8465		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8466		.dac_nids = alc883_dac_nids,
8467		.dig_out_nid = ALC883_DIGOUT_NID,
8468		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8469		.channel_mode = alc883_3ST_2ch_modes,
8470		.input_mux = &alc883_capture_source,
8471		.unsol_event = alc883_haier_w66_unsol_event,
8472		.init_hook = alc883_haier_w66_automute,
8473	},
8474	[ALC888_3ST_HP] = {
8475		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8476		.init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8477		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8478		.dac_nids = alc883_dac_nids,
8479		.num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
8480		.channel_mode = alc888_3st_hp_modes,
8481		.need_dac_fix = 1,
8482		.input_mux = &alc883_capture_source,
8483	},
8484	[ALC888_6ST_DELL] = {
8485		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
8486		.init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
8487		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8488		.dac_nids = alc883_dac_nids,
8489		.dig_out_nid = ALC883_DIGOUT_NID,
8490		.dig_in_nid = ALC883_DIGIN_NID,
8491		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8492		.channel_mode = alc883_sixstack_modes,
8493		.input_mux = &alc883_capture_source,
8494		.unsol_event = alc888_6st_dell_unsol_event,
8495		.init_hook = alc888_6st_dell_front_automute,
8496	},
8497	[ALC883_MITAC] = {
8498		.mixers = { alc883_mitac_mixer },
8499		.init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8500		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8501		.dac_nids = alc883_dac_nids,
8502		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8503		.channel_mode = alc883_3ST_2ch_modes,
8504		.input_mux = &alc883_capture_source,
8505		.unsol_event = alc883_mitac_unsol_event,
8506		.init_hook = alc883_mitac_automute,
8507	},
8508	[ALC883_FUJITSU_PI2515] = {
8509		.mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8510		.init_verbs = { alc883_init_verbs,
8511				alc883_2ch_fujitsu_pi2515_verbs},
8512		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8513		.dac_nids = alc883_dac_nids,
8514		.dig_out_nid = ALC883_DIGOUT_NID,
8515		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8516		.channel_mode = alc883_3ST_2ch_modes,
8517		.input_mux = &alc883_fujitsu_pi2515_capture_source,
8518		.unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
8519		.init_hook = alc883_2ch_fujitsu_pi2515_automute,
8520	},
8521	[ALC888_LENOVO_SKY] = {
8522		.mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
8523		.init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
8524		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8525		.dac_nids = alc883_dac_nids,
8526		.dig_out_nid = ALC883_DIGOUT_NID,
8527		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8528		.channel_mode = alc883_sixstack_modes,
8529		.need_dac_fix = 1,
8530		.input_mux = &alc883_lenovo_sky_capture_source,
8531		.unsol_event = alc883_lenovo_sky_unsol_event,
8532		.init_hook = alc888_lenovo_sky_front_automute,
8533	},
8534	[ALC888_ASUS_M90V] = {
8535		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8536		.init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
8537		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8538		.dac_nids = alc883_dac_nids,
8539		.dig_out_nid = ALC883_DIGOUT_NID,
8540		.dig_in_nid = ALC883_DIGIN_NID,
8541		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8542		.channel_mode = alc883_3ST_6ch_modes,
8543		.need_dac_fix = 1,
8544		.input_mux = &alc883_fujitsu_pi2515_capture_source,
8545		.unsol_event = alc883_mode2_unsol_event,
8546		.init_hook = alc883_mode2_inithook,
8547	},
8548	[ALC888_ASUS_EEE1601] = {
8549		.mixers = { alc883_asus_eee1601_mixer },
8550		.cap_mixer = alc883_asus_eee1601_cap_mixer,
8551		.init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
8552		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8553		.dac_nids = alc883_dac_nids,
8554		.dig_out_nid = ALC883_DIGOUT_NID,
8555		.dig_in_nid = ALC883_DIGIN_NID,
8556		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8557		.channel_mode = alc883_3ST_2ch_modes,
8558		.need_dac_fix = 1,
8559		.input_mux = &alc883_asus_eee1601_capture_source,
8560		.unsol_event = alc883_eee1601_unsol_event,
8561		.init_hook = alc883_eee1601_inithook,
8562	},
8563	[ALC1200_ASUS_P5Q] = {
8564		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
8565		.init_verbs = { alc883_init_verbs },
8566		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8567		.dac_nids = alc883_dac_nids,
8568		.dig_out_nid = ALC1200_DIGOUT_NID,
8569		.dig_in_nid = ALC883_DIGIN_NID,
8570		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8571		.channel_mode = alc883_sixstack_modes,
8572		.input_mux = &alc883_capture_source,
8573	},
8574};
8575
8576
8577/*
8578 * BIOS auto configuration
8579 */
8580static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
8581					      hda_nid_t nid, int pin_type,
8582					      int dac_idx)
8583{
8584	/* set as output */
8585	struct alc_spec *spec = codec->spec;
8586	int idx;
8587
8588	alc_set_pin_output(codec, nid, pin_type);
8589	if (spec->multiout.dac_nids[dac_idx] == 0x25)
8590		idx = 4;
8591	else
8592		idx = spec->multiout.dac_nids[dac_idx] - 2;
8593	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
8594
8595}
8596
8597static void alc883_auto_init_multi_out(struct hda_codec *codec)
8598{
8599	struct alc_spec *spec = codec->spec;
8600	int i;
8601
8602	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
8603	for (i = 0; i <= HDA_SIDE; i++) {
8604		hda_nid_t nid = spec->autocfg.line_out_pins[i];
8605		int pin_type = get_pin_type(spec->autocfg.line_out_type);
8606		if (nid)
8607			alc883_auto_set_output_and_unmute(codec, nid, pin_type,
8608							  i);
8609	}
8610}
8611
8612static void alc883_auto_init_hp_out(struct hda_codec *codec)
8613{
8614	struct alc_spec *spec = codec->spec;
8615	hda_nid_t pin;
8616
8617	pin = spec->autocfg.hp_pins[0];
8618	if (pin) /* connect to front */
8619		/* use dac 0 */
8620		alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
8621	pin = spec->autocfg.speaker_pins[0];
8622	if (pin)
8623		alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
8624}
8625
8626#define alc883_is_input_pin(nid)	alc880_is_input_pin(nid)
8627#define ALC883_PIN_CD_NID		ALC880_PIN_CD_NID
8628
8629static void alc883_auto_init_analog_input(struct hda_codec *codec)
8630{
8631	struct alc_spec *spec = codec->spec;
8632	int i;
8633
8634	for (i = 0; i < AUTO_PIN_LAST; i++) {
8635		hda_nid_t nid = spec->autocfg.input_pins[i];
8636		if (alc883_is_input_pin(nid)) {
8637			snd_hda_codec_write(codec, nid, 0,
8638					    AC_VERB_SET_PIN_WIDGET_CONTROL,
8639					    (i <= AUTO_PIN_FRONT_MIC ?
8640					     PIN_VREF80 : PIN_IN));
8641			if (nid != ALC883_PIN_CD_NID)
8642				snd_hda_codec_write(codec, nid, 0,
8643						    AC_VERB_SET_AMP_GAIN_MUTE,
8644						    AMP_OUT_MUTE);
8645		}
8646	}
8647}
8648
8649#define alc883_auto_init_input_src	alc882_auto_init_input_src
8650
8651/* almost identical with ALC880 parser... */
8652static int alc883_parse_auto_config(struct hda_codec *codec)
8653{
8654	struct alc_spec *spec = codec->spec;
8655	int err = alc880_parse_auto_config(codec);
8656
8657	if (err < 0)
8658		return err;
8659	else if (!err)
8660		return 0; /* no config found */
8661
8662	err = alc_auto_add_mic_boost(codec);
8663	if (err < 0)
8664		return err;
8665
8666	/* hack - override the init verbs */
8667	spec->init_verbs[0] = alc883_auto_init_verbs;
8668
8669	return 1; /* config found */
8670}
8671
8672/* additional initialization for auto-configuration model */
8673static void alc883_auto_init(struct hda_codec *codec)
8674{
8675	struct alc_spec *spec = codec->spec;
8676	alc883_auto_init_multi_out(codec);
8677	alc883_auto_init_hp_out(codec);
8678	alc883_auto_init_analog_input(codec);
8679	alc883_auto_init_input_src(codec);
8680	if (spec->unsol_event)
8681		alc_inithook(codec);
8682}
8683
8684static int patch_alc883(struct hda_codec *codec)
8685{
8686	struct alc_spec *spec;
8687	int err, board_config;
8688
8689	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8690	if (spec == NULL)
8691		return -ENOMEM;
8692
8693	codec->spec = spec;
8694
8695	alc_fix_pll_init(codec, 0x20, 0x0a, 10);
8696
8697	board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
8698						  alc883_models,
8699						  alc883_cfg_tbl);
8700	if (board_config < 0) {
8701		printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
8702		       "trying auto-probe from BIOS...\n");
8703		board_config = ALC883_AUTO;
8704	}
8705
8706	if (board_config == ALC883_AUTO) {
8707		/* automatic parse from the BIOS config */
8708		err = alc883_parse_auto_config(codec);
8709		if (err < 0) {
8710			alc_free(codec);
8711			return err;
8712		} else if (!err) {
8713			printk(KERN_INFO
8714			       "hda_codec: Cannot set up configuration "
8715			       "from BIOS.  Using base mode...\n");
8716			board_config = ALC883_3ST_2ch_DIG;
8717		}
8718	}
8719
8720	if (board_config != ALC883_AUTO)
8721		setup_preset(spec, &alc883_presets[board_config]);
8722
8723	switch (codec->vendor_id) {
8724	case 0x10ec0888:
8725		if (codec->revision_id == 0x100101) {
8726			spec->stream_name_analog = "ALC1200 Analog";
8727			spec->stream_name_digital = "ALC1200 Digital";
8728		} else {
8729			spec->stream_name_analog = "ALC888 Analog";
8730			spec->stream_name_digital = "ALC888 Digital";
8731		}
8732		break;
8733	case 0x10ec0889:
8734		spec->stream_name_analog = "ALC889 Analog";
8735		spec->stream_name_digital = "ALC889 Digital";
8736		break;
8737	default:
8738		spec->stream_name_analog = "ALC883 Analog";
8739		spec->stream_name_digital = "ALC883 Digital";
8740		break;
8741	}
8742
8743	spec->stream_analog_playback = &alc883_pcm_analog_playback;
8744	spec->stream_analog_capture = &alc883_pcm_analog_capture;
8745	spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
8746
8747	spec->stream_digital_playback = &alc883_pcm_digital_playback;
8748	spec->stream_digital_capture = &alc883_pcm_digital_capture;
8749
8750	if (!spec->num_adc_nids) {
8751		spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8752		spec->adc_nids = alc883_adc_nids;
8753	}
8754	if (!spec->capsrc_nids)
8755		spec->capsrc_nids = alc883_capsrc_nids;
8756	spec->is_mix_capture = 1; /* matrix-style capture */
8757	if (!spec->cap_mixer)
8758		set_capture_mixer(spec);
8759
8760	spec->vmaster_nid = 0x0c;
8761
8762	codec->patch_ops = alc_patch_ops;
8763	if (board_config == ALC883_AUTO)
8764		spec->init_hook = alc883_auto_init;
8765
8766#ifdef CONFIG_SND_HDA_POWER_SAVE
8767	if (!spec->loopback.amplist)
8768		spec->loopback.amplist = alc883_loopbacks;
8769#endif
8770
8771	return 0;
8772}
8773
8774/*
8775 * ALC262 support
8776 */
8777
8778#define ALC262_DIGOUT_NID	ALC880_DIGOUT_NID
8779#define ALC262_DIGIN_NID	ALC880_DIGIN_NID
8780
8781#define alc262_dac_nids		alc260_dac_nids
8782#define alc262_adc_nids		alc882_adc_nids
8783#define alc262_adc_nids_alt	alc882_adc_nids_alt
8784#define alc262_capsrc_nids	alc882_capsrc_nids
8785#define alc262_capsrc_nids_alt	alc882_capsrc_nids_alt
8786
8787#define alc262_modes		alc260_modes
8788#define alc262_capture_source	alc882_capture_source
8789
8790static hda_nid_t alc262_dmic_adc_nids[1] = {
8791	/* ADC0 */
8792	0x09
8793};
8794
8795static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
8796
8797static struct snd_kcontrol_new alc262_base_mixer[] = {
8798	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8799	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8800	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8801	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8802	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8803	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8804	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8805	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8806	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8807	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8808	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8809	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8810	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8811	   HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8812	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
8813	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8814	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8815	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
8816	{ } /* end */
8817};
8818
8819static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
8820	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8821	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8822	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8823	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8824	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8825	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8826	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8827	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8828	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8829	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8830	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8831	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8832	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8833	   HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8834	/*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
8835	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8836	{ } /* end */
8837};
8838
8839/* update HP, line and mono-out pins according to the master switch */
8840static void alc262_hp_master_update(struct hda_codec *codec)
8841{
8842	struct alc_spec *spec = codec->spec;
8843	int val = spec->master_sw;
8844
8845	/* HP & line-out */
8846	snd_hda_codec_write_cache(codec, 0x1b, 0,
8847				  AC_VERB_SET_PIN_WIDGET_CONTROL,
8848				  val ? PIN_HP : 0);
8849	snd_hda_codec_write_cache(codec, 0x15, 0,
8850				  AC_VERB_SET_PIN_WIDGET_CONTROL,
8851				  val ? PIN_HP : 0);
8852	/* mono (speaker) depending on the HP jack sense */
8853	val = val && !spec->jack_present;
8854	snd_hda_codec_write_cache(codec, 0x16, 0,
8855				  AC_VERB_SET_PIN_WIDGET_CONTROL,
8856				  val ? PIN_OUT : 0);
8857}
8858
8859static void alc262_hp_bpc_automute(struct hda_codec *codec)
8860{
8861	struct alc_spec *spec = codec->spec;
8862	unsigned int presence;
8863	presence = snd_hda_codec_read(codec, 0x1b, 0,
8864				      AC_VERB_GET_PIN_SENSE, 0);
8865	spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8866	alc262_hp_master_update(codec);
8867}
8868
8869static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
8870{
8871	if ((res >> 26) != ALC880_HP_EVENT)
8872		return;
8873	alc262_hp_bpc_automute(codec);
8874}
8875
8876static void alc262_hp_wildwest_automute(struct hda_codec *codec)
8877{
8878	struct alc_spec *spec = codec->spec;
8879	unsigned int presence;
8880	presence = snd_hda_codec_read(codec, 0x15, 0,
8881				      AC_VERB_GET_PIN_SENSE, 0);
8882	spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8883	alc262_hp_master_update(codec);
8884}
8885
8886static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
8887					   unsigned int res)
8888{
8889	if ((res >> 26) != ALC880_HP_EVENT)
8890		return;
8891	alc262_hp_wildwest_automute(codec);
8892}
8893
8894static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
8895				   struct snd_ctl_elem_value *ucontrol)
8896{
8897	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8898	struct alc_spec *spec = codec->spec;
8899	*ucontrol->value.integer.value = spec->master_sw;
8900	return 0;
8901}
8902
8903static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
8904				   struct snd_ctl_elem_value *ucontrol)
8905{
8906	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8907	struct alc_spec *spec = codec->spec;
8908	int val = !!*ucontrol->value.integer.value;
8909
8910	if (val == spec->master_sw)
8911		return 0;
8912	spec->master_sw = val;
8913	alc262_hp_master_update(codec);
8914	return 1;
8915}
8916
8917static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
8918	{
8919		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8920		.name = "Master Playback Switch",
8921		.info = snd_ctl_boolean_mono_info,
8922		.get = alc262_hp_master_sw_get,
8923		.put = alc262_hp_master_sw_put,
8924	},
8925	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8926	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8927	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8928	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8929			      HDA_OUTPUT),
8930	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8931			    HDA_OUTPUT),
8932	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8933	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8934	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8935	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8936	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8937	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8938	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8939	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8940	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8941	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8942	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8943	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8944	HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
8945	HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
8946	{ } /* end */
8947};
8948
8949static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
8950	{
8951		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8952		.name = "Master Playback Switch",
8953		.info = snd_ctl_boolean_mono_info,
8954		.get = alc262_hp_master_sw_get,
8955		.put = alc262_hp_master_sw_put,
8956	},
8957	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8958	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8959	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8960	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8961	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8962			      HDA_OUTPUT),
8963	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8964			    HDA_OUTPUT),
8965	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
8966	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
8967	HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
8968	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8969	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8970	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8971	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8972	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8973	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8974	{ } /* end */
8975};
8976
8977static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
8978	HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8979	HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8980	HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
8981	{ } /* end */
8982};
8983
8984/* mute/unmute internal speaker according to the hp jack and mute state */
8985static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
8986{
8987	struct alc_spec *spec = codec->spec;
8988
8989	if (force || !spec->sense_updated) {
8990		unsigned int present;
8991		present = snd_hda_codec_read(codec, 0x15, 0,
8992					     AC_VERB_GET_PIN_SENSE, 0);
8993		spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
8994		spec->sense_updated = 1;
8995	}
8996	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
8997				 spec->jack_present ? HDA_AMP_MUTE : 0);
8998}
8999
9000static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
9001					unsigned int res)
9002{
9003	if ((res >> 26) != ALC880_HP_EVENT)
9004		return;
9005	alc262_hp_t5735_automute(codec, 1);
9006}
9007
9008static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9009{
9010	alc262_hp_t5735_automute(codec, 1);
9011}
9012
9013static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
9014	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9015	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9016	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9017	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9018	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9019	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9020	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9021	{ } /* end */
9022};
9023
9024static struct hda_verb alc262_hp_t5735_verbs[] = {
9025	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9026	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9027
9028	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9029	{ }
9030};
9031
9032static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
9033	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9034	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9035	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9036	HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
9037	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9038	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9039	{ } /* end */
9040};
9041
9042static struct hda_verb alc262_hp_rp5700_verbs[] = {
9043	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9044	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9045	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9046	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9047	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9048	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9049	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9050	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9051	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9052	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9053	{}
9054};
9055
9056static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9057	.num_items = 1,
9058	.items = {
9059		{ "Line", 0x1 },
9060	},
9061};
9062
9063/* bind hp and internal speaker mute (with plug check) */
9064static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
9065				     struct snd_ctl_elem_value *ucontrol)
9066{
9067	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9068	long *valp = ucontrol->value.integer.value;
9069	int change;
9070
9071	/* change hp mute */
9072	change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
9073					  HDA_AMP_MUTE,
9074					  valp[0] ? 0 : HDA_AMP_MUTE);
9075	change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
9076					   HDA_AMP_MUTE,
9077					   valp[1] ? 0 : HDA_AMP_MUTE);
9078	if (change) {
9079		/* change speaker according to HP jack state */
9080		struct alc_spec *spec = codec->spec;
9081		unsigned int mute;
9082		if (spec->jack_present)
9083			mute = HDA_AMP_MUTE;
9084		else
9085			mute = snd_hda_codec_amp_read(codec, 0x15, 0,
9086						      HDA_OUTPUT, 0);
9087		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9088					 HDA_AMP_MUTE, mute);
9089	}
9090	return change;
9091}
9092
9093static struct snd_kcontrol_new alc262_sony_mixer[] = {
9094	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9095	{
9096		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9097		.name = "Master Playback Switch",
9098		.info = snd_hda_mixer_amp_switch_info,
9099		.get = snd_hda_mixer_amp_switch_get,
9100		.put = alc262_sony_master_sw_put,
9101		.private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9102	},
9103	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9104	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9105	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9106	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9107	{ } /* end */
9108};
9109
9110static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9111	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9112	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9113	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9114	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9115	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9116	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9117	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9118	{ } /* end */
9119};
9120
9121#define alc262_capture_mixer		alc882_capture_mixer
9122#define alc262_capture_alt_mixer	alc882_capture_alt_mixer
9123
9124/*
9125 * generic initialization of ADC, input mixers and output mixers
9126 */
9127static struct hda_verb alc262_init_verbs[] = {
9128	/*
9129	 * Unmute ADC0-2 and set the default input to mic-in
9130	 */
9131	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9132	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9133	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9134	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9135	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9136	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9137
9138	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9139	 * mixer widget
9140	 * Note: PASD motherboards uses the Line In 2 as the input for
9141	 * front panel mic (mic 2)
9142	 */
9143	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9144	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9145	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9146	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9147	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9148	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9149
9150	/*
9151	 * Set up output mixers (0x0c - 0x0e)
9152	 */
9153	/* set vol=0 to output mixers */
9154	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9155	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9156	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9157	/* set up input amps for analog loopback */
9158	/* Amp Indices: DAC = 0, mixer = 1 */
9159	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9160	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9161	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9162	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9163	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9164	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9165
9166	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9167	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9168	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9169	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9170	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9171	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9172
9173	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9174	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9175	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9176	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9177	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9178
9179	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9180	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9181
9182	/* FIXME: use matrix-type input source selection */
9183	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9184	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9185	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9186	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9187	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9188	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9189	/* Input mixer2 */
9190	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9191	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9192	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9193	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9194	/* Input mixer3 */
9195	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9196	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9197	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9198	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9199
9200	{ }
9201};
9202
9203static struct hda_verb alc262_eapd_verbs[] = {
9204	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9205	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9206	{ }
9207};
9208
9209static struct hda_verb alc262_hippo_unsol_verbs[] = {
9210	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9211	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9212	{}
9213};
9214
9215static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9216	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9217	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9218	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9219
9220	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9221	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9222	{}
9223};
9224
9225static struct hda_verb alc262_sony_unsol_verbs[] = {
9226	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9227	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9228	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},	// Front Mic
9229
9230	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9231	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9232	{}
9233};
9234
9235static struct hda_input_mux alc262_dmic_capture_source = {
9236	.num_items = 2,
9237	.items = {
9238		{ "Int DMic", 0x9 },
9239		{ "Mic", 0x0 },
9240	},
9241};
9242
9243static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9244	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9245	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9246	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9247	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9248	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9249	{ } /* end */
9250};
9251
9252static struct hda_verb alc262_toshiba_s06_verbs[] = {
9253	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9254	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9255	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9256	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9257	{0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9258	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9259	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9260	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9261	{}
9262};
9263
9264static void alc262_dmic_automute(struct hda_codec *codec)
9265{
9266	unsigned int present;
9267
9268	present = snd_hda_codec_read(codec, 0x18, 0,
9269					AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9270	snd_hda_codec_write(codec, 0x22, 0,
9271				AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9272}
9273
9274/* toggle speaker-output according to the hp-jack state */
9275static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
9276{
9277	unsigned int present;
9278	unsigned char bits;
9279
9280	present = snd_hda_codec_read(codec, 0x15, 0,
9281					AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9282	bits = present ? 0 : PIN_OUT;
9283	snd_hda_codec_write(codec, 0x14, 0,
9284					AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
9285}
9286
9287
9288
9289/* unsolicited event for HP jack sensing */
9290static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9291				       unsigned int res)
9292{
9293	if ((res >> 26) == ALC880_HP_EVENT)
9294		alc262_toshiba_s06_speaker_automute(codec);
9295	if ((res >> 26) == ALC880_MIC_EVENT)
9296		alc262_dmic_automute(codec);
9297
9298}
9299
9300static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9301{
9302	alc262_toshiba_s06_speaker_automute(codec);
9303	alc262_dmic_automute(codec);
9304}
9305
9306/* mute/unmute internal speaker according to the hp jack and mute state */
9307static void alc262_hippo_automute(struct hda_codec *codec)
9308{
9309	struct alc_spec *spec = codec->spec;
9310	unsigned int mute;
9311	unsigned int present;
9312
9313	/* need to execute and sync at first */
9314	snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9315	present = snd_hda_codec_read(codec, 0x15, 0,
9316				     AC_VERB_GET_PIN_SENSE, 0);
9317	spec->jack_present = (present & 0x80000000) != 0;
9318	if (spec->jack_present) {
9319		/* mute internal speaker */
9320		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9321					 HDA_AMP_MUTE, HDA_AMP_MUTE);
9322	} else {
9323		/* unmute internal speaker if necessary */
9324		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
9325		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9326					 HDA_AMP_MUTE, mute);
9327	}
9328}
9329
9330/* unsolicited event for HP jack sensing */
9331static void alc262_hippo_unsol_event(struct hda_codec *codec,
9332				       unsigned int res)
9333{
9334	if ((res >> 26) != ALC880_HP_EVENT)
9335		return;
9336	alc262_hippo_automute(codec);
9337}
9338
9339static void alc262_hippo1_automute(struct hda_codec *codec)
9340{
9341	unsigned int mute;
9342	unsigned int present;
9343
9344	snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9345	present = snd_hda_codec_read(codec, 0x1b, 0,
9346				     AC_VERB_GET_PIN_SENSE, 0);
9347	present = (present & 0x80000000) != 0;
9348	if (present) {
9349		/* mute internal speaker */
9350		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9351					 HDA_AMP_MUTE, HDA_AMP_MUTE);
9352	} else {
9353		/* unmute internal speaker if necessary */
9354		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9355		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9356					 HDA_AMP_MUTE, mute);
9357	}
9358}
9359
9360/* unsolicited event for HP jack sensing */
9361static void alc262_hippo1_unsol_event(struct hda_codec *codec,
9362				       unsigned int res)
9363{
9364	if ((res >> 26) != ALC880_HP_EVENT)
9365		return;
9366	alc262_hippo1_automute(codec);
9367}
9368
9369/*
9370 * nec model
9371 *  0x15 = headphone
9372 *  0x16 = internal speaker
9373 *  0x18 = external mic
9374 */
9375
9376static struct snd_kcontrol_new alc262_nec_mixer[] = {
9377	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9378	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
9379
9380	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9381	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9382	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9383
9384	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9385	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9386	{ } /* end */
9387};
9388
9389static struct hda_verb alc262_nec_verbs[] = {
9390	/* Unmute Speaker */
9391	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9392
9393	/* Headphone */
9394	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9395	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9396
9397	/* External mic to headphone */
9398	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9399	/* External mic to speaker */
9400	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9401	{}
9402};
9403
9404/*
9405 * fujitsu model
9406 *  0x14 = headphone/spdif-out, 0x15 = internal speaker,
9407 *  0x1b = port replicator headphone out
9408 */
9409
9410#define ALC_HP_EVENT	0x37
9411
9412static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
9413	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9414	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9415	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9416	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9417	{}
9418};
9419
9420static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
9421	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9422	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9423	{}
9424};
9425
9426static struct hda_input_mux alc262_fujitsu_capture_source = {
9427	.num_items = 3,
9428	.items = {
9429		{ "Mic", 0x0 },
9430		{ "Int Mic", 0x1 },
9431		{ "CD", 0x4 },
9432	},
9433};
9434
9435static struct hda_input_mux alc262_HP_capture_source = {
9436	.num_items = 5,
9437	.items = {
9438		{ "Mic", 0x0 },
9439		{ "Front Mic", 0x1 },
9440		{ "Line", 0x2 },
9441		{ "CD", 0x4 },
9442		{ "AUX IN", 0x6 },
9443	},
9444};
9445
9446static struct hda_input_mux alc262_HP_D7000_capture_source = {
9447	.num_items = 4,
9448	.items = {
9449		{ "Mic", 0x0 },
9450		{ "Front Mic", 0x2 },
9451		{ "Line", 0x1 },
9452		{ "CD", 0x4 },
9453	},
9454};
9455
9456/* mute/unmute internal speaker according to the hp jacks and mute state */
9457static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
9458{
9459	struct alc_spec *spec = codec->spec;
9460	unsigned int mute;
9461
9462	if (force || !spec->sense_updated) {
9463		unsigned int present;
9464		/* need to execute and sync at first */
9465		snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
9466		/* check laptop HP jack */
9467		present = snd_hda_codec_read(codec, 0x14, 0,
9468					     AC_VERB_GET_PIN_SENSE, 0);
9469		/* need to execute and sync at first */
9470		snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9471		/* check docking HP jack */
9472		present |= snd_hda_codec_read(codec, 0x1b, 0,
9473					      AC_VERB_GET_PIN_SENSE, 0);
9474		if (present & AC_PINSENSE_PRESENCE)
9475			spec->jack_present = 1;
9476		else
9477			spec->jack_present = 0;
9478		spec->sense_updated = 1;
9479	}
9480	/* unmute internal speaker only if both HPs are unplugged and
9481	 * master switch is on
9482	 */
9483	if (spec->jack_present)
9484		mute = HDA_AMP_MUTE;
9485	else
9486		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9487	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9488				 HDA_AMP_MUTE, mute);
9489}
9490
9491/* unsolicited event for HP jack sensing */
9492static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
9493				       unsigned int res)
9494{
9495	if ((res >> 26) != ALC_HP_EVENT)
9496		return;
9497	alc262_fujitsu_automute(codec, 1);
9498}
9499
9500static void alc262_fujitsu_init_hook(struct hda_codec *codec)
9501{
9502	alc262_fujitsu_automute(codec, 1);
9503}
9504
9505/* bind volumes of both NID 0x0c and 0x0d */
9506static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
9507	.ops = &snd_hda_bind_vol,
9508	.values = {
9509		HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
9510		HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
9511		0
9512	},
9513};
9514
9515/* mute/unmute internal speaker according to the hp jack and mute state */
9516static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
9517{
9518	struct alc_spec *spec = codec->spec;
9519	unsigned int mute;
9520
9521	if (force || !spec->sense_updated) {
9522		unsigned int present_int_hp;
9523		/* need to execute and sync at first */
9524		snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9525		present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
9526					AC_VERB_GET_PIN_SENSE, 0);
9527		spec->jack_present = (present_int_hp & 0x80000000) != 0;
9528		spec->sense_updated = 1;
9529	}
9530	if (spec->jack_present) {
9531		/* mute internal speaker */
9532		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9533					 HDA_AMP_MUTE, HDA_AMP_MUTE);
9534		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9535					 HDA_AMP_MUTE, HDA_AMP_MUTE);
9536	} else {
9537		/* unmute internal speaker if necessary */
9538		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9539		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9540					 HDA_AMP_MUTE, mute);
9541		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9542					 HDA_AMP_MUTE, mute);
9543	}
9544}
9545
9546/* unsolicited event for HP jack sensing */
9547static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
9548				       unsigned int res)
9549{
9550	if ((res >> 26) != ALC_HP_EVENT)
9551		return;
9552	alc262_lenovo_3000_automute(codec, 1);
9553}
9554
9555/* bind hp and internal speaker mute (with plug check) */
9556static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
9557					 struct snd_ctl_elem_value *ucontrol)
9558{
9559	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9560	long *valp = ucontrol->value.integer.value;
9561	int change;
9562
9563	change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9564						 HDA_AMP_MUTE,
9565						 valp ? 0 : HDA_AMP_MUTE);
9566	change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9567						 HDA_AMP_MUTE,
9568						 valp ? 0 : HDA_AMP_MUTE);
9569
9570	if (change)
9571		alc262_fujitsu_automute(codec, 0);
9572	return change;
9573}
9574
9575static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
9576	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9577	{
9578		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9579		.name = "Master Playback Switch",
9580		.info = snd_hda_mixer_amp_switch_info,
9581		.get = snd_hda_mixer_amp_switch_get,
9582		.put = alc262_fujitsu_master_sw_put,
9583		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9584	},
9585	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9586	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9587	HDA_CODEC_VOLUME("PC Speaker Volume", 0x0b, 0x05, HDA_INPUT),
9588	HDA_CODEC_MUTE("PC Speaker Switch", 0x0b, 0x05, HDA_INPUT),
9589	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9590	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9591	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9592	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9593	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9594	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9595	{ } /* end */
9596};
9597
9598/* bind hp and internal speaker mute (with plug check) */
9599static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
9600					 struct snd_ctl_elem_value *ucontrol)
9601{
9602	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9603	long *valp = ucontrol->value.integer.value;
9604	int change;
9605
9606	change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9607						 HDA_AMP_MUTE,
9608						 valp ? 0 : HDA_AMP_MUTE);
9609
9610	if (change)
9611		alc262_lenovo_3000_automute(codec, 0);
9612	return change;
9613}
9614
9615static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
9616	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9617	{
9618		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9619		.name = "Master Playback Switch",
9620		.info = snd_hda_mixer_amp_switch_info,
9621		.get = snd_hda_mixer_amp_switch_get,
9622		.put = alc262_lenovo_3000_master_sw_put,
9623		.private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
9624	},
9625	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9626	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9627	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9628	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9629	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9630	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9631	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9632	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9633	{ } /* end */
9634};
9635
9636static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
9637	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9638	{
9639		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9640		.name = "Master Playback Switch",
9641		.info = snd_hda_mixer_amp_switch_info,
9642		.get = snd_hda_mixer_amp_switch_get,
9643		.put = alc262_sony_master_sw_put,
9644		.private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9645	},
9646	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9647	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9648	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9649	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9650	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9651	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9652	{ } /* end */
9653};
9654
9655/* additional init verbs for Benq laptops */
9656static struct hda_verb alc262_EAPD_verbs[] = {
9657	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9658	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
9659	{}
9660};
9661
9662static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
9663	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9664	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9665
9666	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9667	{0x20, AC_VERB_SET_PROC_COEF,  0x3050},
9668	{}
9669};
9670
9671/* Samsung Q1 Ultra Vista model setup */
9672static struct snd_kcontrol_new alc262_ultra_mixer[] = {
9673	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9674	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9675	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9676	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9677	HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
9678	HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
9679	{ } /* end */
9680};
9681
9682static struct hda_verb alc262_ultra_verbs[] = {
9683	/* output mixer */
9684	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9685	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9686	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9687	/* speaker */
9688	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9689	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9690	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9691	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9692	/* HP */
9693	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9694	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9695	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9696	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9697	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9698	/* internal mic */
9699	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9700	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9701	/* ADC, choose mic */
9702	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9703	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9704	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9705	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9706	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9707	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9708	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9709	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9710	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
9711	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
9712	{}
9713};
9714
9715/* mute/unmute internal speaker according to the hp jack and mute state */
9716static void alc262_ultra_automute(struct hda_codec *codec)
9717{
9718	struct alc_spec *spec = codec->spec;
9719	unsigned int mute;
9720
9721	mute = 0;
9722	/* auto-mute only when HP is used as HP */
9723	if (!spec->cur_mux[0]) {
9724		unsigned int present;
9725		/* need to execute and sync at first */
9726		snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9727		present = snd_hda_codec_read(codec, 0x15, 0,
9728					     AC_VERB_GET_PIN_SENSE, 0);
9729		spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9730		if (spec->jack_present)
9731			mute = HDA_AMP_MUTE;
9732	}
9733	/* mute/unmute internal speaker */
9734	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9735				 HDA_AMP_MUTE, mute);
9736	/* mute/unmute HP */
9737	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9738				 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
9739}
9740
9741/* unsolicited event for HP jack sensing */
9742static void alc262_ultra_unsol_event(struct hda_codec *codec,
9743				       unsigned int res)
9744{
9745	if ((res >> 26) != ALC880_HP_EVENT)
9746		return;
9747	alc262_ultra_automute(codec);
9748}
9749
9750static struct hda_input_mux alc262_ultra_capture_source = {
9751	.num_items = 2,
9752	.items = {
9753		{ "Mic", 0x1 },
9754		{ "Headphone", 0x7 },
9755	},
9756};
9757
9758static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
9759				     struct snd_ctl_elem_value *ucontrol)
9760{
9761	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9762	struct alc_spec *spec = codec->spec;
9763	int ret;
9764
9765	ret = alc_mux_enum_put(kcontrol, ucontrol);
9766	if (!ret)
9767		return 0;
9768	/* reprogram the HP pin as mic or HP according to the input source */
9769	snd_hda_codec_write_cache(codec, 0x15, 0,
9770				  AC_VERB_SET_PIN_WIDGET_CONTROL,
9771				  spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
9772	alc262_ultra_automute(codec); /* mute/unmute HP */
9773	return ret;
9774}
9775
9776static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
9777	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
9778	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
9779	{
9780		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9781		.name = "Capture Source",
9782		.info = alc_mux_enum_info,
9783		.get = alc_mux_enum_get,
9784		.put = alc262_ultra_mux_enum_put,
9785	},
9786	{ } /* end */
9787};
9788
9789/* add playback controls from the parsed DAC table */
9790static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
9791					     const struct auto_pin_cfg *cfg)
9792{
9793	hda_nid_t nid;
9794	int err;
9795
9796	spec->multiout.num_dacs = 1;	/* only use one dac */
9797	spec->multiout.dac_nids = spec->private_dac_nids;
9798	spec->multiout.dac_nids[0] = 2;
9799
9800	nid = cfg->line_out_pins[0];
9801	if (nid) {
9802		err = add_control(spec, ALC_CTL_WIDGET_VOL,
9803				  "Front Playback Volume",
9804				  HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
9805		if (err < 0)
9806			return err;
9807		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9808				  "Front Playback Switch",
9809				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9810		if (err < 0)
9811			return err;
9812	}
9813
9814	nid = cfg->speaker_pins[0];
9815	if (nid) {
9816		if (nid == 0x16) {
9817			err = add_control(spec, ALC_CTL_WIDGET_VOL,
9818					  "Speaker Playback Volume",
9819					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9820							      HDA_OUTPUT));
9821			if (err < 0)
9822				return err;
9823			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9824					  "Speaker Playback Switch",
9825					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9826							      HDA_OUTPUT));
9827			if (err < 0)
9828				return err;
9829		} else {
9830			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9831					  "Speaker Playback Switch",
9832					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9833							      HDA_OUTPUT));
9834			if (err < 0)
9835				return err;
9836		}
9837	}
9838	nid = cfg->hp_pins[0];
9839	if (nid) {
9840		/* spec->multiout.hp_nid = 2; */
9841		if (nid == 0x16) {
9842			err = add_control(spec, ALC_CTL_WIDGET_VOL,
9843					  "Headphone Playback Volume",
9844					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9845							      HDA_OUTPUT));
9846			if (err < 0)
9847				return err;
9848			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9849					  "Headphone Playback Switch",
9850					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9851							      HDA_OUTPUT));
9852			if (err < 0)
9853				return err;
9854		} else {
9855			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9856					  "Headphone Playback Switch",
9857					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9858							      HDA_OUTPUT));
9859			if (err < 0)
9860				return err;
9861		}
9862	}
9863	return 0;
9864}
9865
9866/* identical with ALC880 */
9867#define alc262_auto_create_analog_input_ctls \
9868	alc880_auto_create_analog_input_ctls
9869
9870/*
9871 * generic initialization of ADC, input mixers and output mixers
9872 */
9873static struct hda_verb alc262_volume_init_verbs[] = {
9874	/*
9875	 * Unmute ADC0-2 and set the default input to mic-in
9876	 */
9877	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9878	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9879	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9880	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9881	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9882	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9883
9884	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9885	 * mixer widget
9886	 * Note: PASD motherboards uses the Line In 2 as the input for
9887	 * front panel mic (mic 2)
9888	 */
9889	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9890	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9891	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9892	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9893	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9894	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9895
9896	/*
9897	 * Set up output mixers (0x0c - 0x0f)
9898	 */
9899	/* set vol=0 to output mixers */
9900	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9901	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9902	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9903
9904	/* set up input amps for analog loopback */
9905	/* Amp Indices: DAC = 0, mixer = 1 */
9906	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9907	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9908	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9909	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9910	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9911	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9912
9913	/* FIXME: use matrix-type input source selection */
9914	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9915	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9916	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9917	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9918	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9919	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9920	/* Input mixer2 */
9921	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9922	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9923	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9924	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9925	/* Input mixer3 */
9926	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9927	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9928	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9929	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9930
9931	{ }
9932};
9933
9934static struct hda_verb alc262_HP_BPC_init_verbs[] = {
9935	/*
9936	 * Unmute ADC0-2 and set the default input to mic-in
9937	 */
9938	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9939	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9940	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9941	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9942	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9943	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9944
9945	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9946	 * mixer widget
9947	 * Note: PASD motherboards uses the Line In 2 as the input for
9948	 * front panel mic (mic 2)
9949	 */
9950	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9951	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9952	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9953	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9954	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9955	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9956	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9957        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9958
9959	/*
9960	 * Set up output mixers (0x0c - 0x0e)
9961	 */
9962	/* set vol=0 to output mixers */
9963	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9964	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9965	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9966
9967	/* set up input amps for analog loopback */
9968	/* Amp Indices: DAC = 0, mixer = 1 */
9969	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9970	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9971	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9972	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9973	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9974	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9975
9976	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9977	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9978	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9979
9980	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9981	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9982
9983	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9984	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9985
9986	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9987	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9988        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9989	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9990	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9991
9992	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9993	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9994        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9995	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9996	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9997	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9998
9999
10000	/* FIXME: use matrix-type input source selection */
10001	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10002	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10003	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10004	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10005	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10006	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10007	/* Input mixer2 */
10008	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10009	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10010	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10011	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10012	/* Input mixer3 */
10013	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10014	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10015	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10016	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10017
10018	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10019
10020	{ }
10021};
10022
10023static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10024	/*
10025	 * Unmute ADC0-2 and set the default input to mic-in
10026	 */
10027	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10028	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10029	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10030	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10031	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10032	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10033
10034	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10035	 * mixer widget
10036	 * Note: PASD motherboards uses the Line In 2 as the input for front
10037	 * panel mic (mic 2)
10038	 */
10039	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10040	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10041	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10042	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10043	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10044	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10045	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10046	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10047	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10048	/*
10049	 * Set up output mixers (0x0c - 0x0e)
10050	 */
10051	/* set vol=0 to output mixers */
10052	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10053	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10054	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10055
10056	/* set up input amps for analog loopback */
10057	/* Amp Indices: DAC = 0, mixer = 1 */
10058	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10059	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10060	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10061	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10062	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10063	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10064
10065
10066	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },	/* HP */
10067	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Mono */
10068	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* rear MIC */
10069	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* Line in */
10070	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* Front MIC */
10071	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Line out */
10072	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* CD in */
10073
10074	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10075	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10076
10077	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10078	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10079
10080	/* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10081	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10082	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10083	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10084	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10085	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10086
10087	/* FIXME: use matrix-type input source selection */
10088	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10089	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10090	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10091	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10092	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10093	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10094	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10095        /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
10096	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10097	/* Input mixer2 */
10098	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10099	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10100	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10101	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10102	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10103        /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10104	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10105	/* Input mixer3 */
10106	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10107	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10108	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10109	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10110	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10111        /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10112	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10113
10114	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10115
10116	{ }
10117};
10118
10119static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10120
10121	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Front Speaker */
10122	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10123	{0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10124
10125	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* MIC jack */
10126	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* Front MIC */
10127	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10128	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10129
10130	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },	/* HP  jack */
10131	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10132	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10133	{}
10134};
10135
10136
10137#ifdef CONFIG_SND_HDA_POWER_SAVE
10138#define alc262_loopbacks	alc880_loopbacks
10139#endif
10140
10141/* pcm configuration: identiacal with ALC880 */
10142#define alc262_pcm_analog_playback	alc880_pcm_analog_playback
10143#define alc262_pcm_analog_capture	alc880_pcm_analog_capture
10144#define alc262_pcm_digital_playback	alc880_pcm_digital_playback
10145#define alc262_pcm_digital_capture	alc880_pcm_digital_capture
10146
10147/*
10148 * BIOS auto configuration
10149 */
10150static int alc262_parse_auto_config(struct hda_codec *codec)
10151{
10152	struct alc_spec *spec = codec->spec;
10153	int err;
10154	static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10155
10156	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10157					   alc262_ignore);
10158	if (err < 0)
10159		return err;
10160	if (!spec->autocfg.line_outs)
10161		return 0; /* can't find valid BIOS pin config */
10162	err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10163	if (err < 0)
10164		return err;
10165	err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10166	if (err < 0)
10167		return err;
10168
10169	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10170
10171	if (spec->autocfg.dig_out_pin)
10172		spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10173	if (spec->autocfg.dig_in_pin)
10174		spec->dig_in_nid = ALC262_DIGIN_NID;
10175
10176	if (spec->kctls.list)
10177		add_mixer(spec, spec->kctls.list);
10178
10179	add_verb(spec, alc262_volume_init_verbs);
10180	spec->num_mux_defs = 1;
10181	spec->input_mux = &spec->private_imux;
10182
10183	err = alc_auto_add_mic_boost(codec);
10184	if (err < 0)
10185		return err;
10186
10187	store_pin_configs(codec);
10188	return 1;
10189}
10190
10191#define alc262_auto_init_multi_out	alc882_auto_init_multi_out
10192#define alc262_auto_init_hp_out		alc882_auto_init_hp_out
10193#define alc262_auto_init_analog_input	alc882_auto_init_analog_input
10194#define alc262_auto_init_input_src	alc882_auto_init_input_src
10195
10196
10197/* init callback for auto-configuration model -- overriding the default init */
10198static void alc262_auto_init(struct hda_codec *codec)
10199{
10200	struct alc_spec *spec = codec->spec;
10201	alc262_auto_init_multi_out(codec);
10202	alc262_auto_init_hp_out(codec);
10203	alc262_auto_init_analog_input(codec);
10204	alc262_auto_init_input_src(codec);
10205	if (spec->unsol_event)
10206		alc_inithook(codec);
10207}
10208
10209/*
10210 * configuration and preset
10211 */
10212static const char *alc262_models[ALC262_MODEL_LAST] = {
10213	[ALC262_BASIC]		= "basic",
10214	[ALC262_HIPPO]		= "hippo",
10215	[ALC262_HIPPO_1]	= "hippo_1",
10216	[ALC262_FUJITSU]	= "fujitsu",
10217	[ALC262_HP_BPC]		= "hp-bpc",
10218	[ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
10219	[ALC262_HP_TC_T5735]	= "hp-tc-t5735",
10220	[ALC262_HP_RP5700]	= "hp-rp5700",
10221	[ALC262_BENQ_ED8]	= "benq",
10222	[ALC262_BENQ_T31]	= "benq-t31",
10223	[ALC262_SONY_ASSAMD]	= "sony-assamd",
10224	[ALC262_TOSHIBA_S06]	= "toshiba-s06",
10225	[ALC262_TOSHIBA_RX1]	= "toshiba-rx1",
10226	[ALC262_ULTRA]		= "ultra",
10227	[ALC262_LENOVO_3000]	= "lenovo-3000",
10228	[ALC262_NEC]		= "nec",
10229	[ALC262_AUTO]		= "auto",
10230};
10231
10232static struct snd_pci_quirk alc262_cfg_tbl[] = {
10233	SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10234	SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
10235	SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
10236	SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
10237	SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
10238	SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
10239	SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
10240	SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
10241	SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
10242	SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
10243	SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
10244	SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
10245	SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
10246	SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
10247	SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
10248	SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
10249	SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
10250	SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
10251	SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10252	SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10253	SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
10254	SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10255		      ALC262_HP_TC_T5735),
10256	SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
10257	SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10258	SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
10259	SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10260	SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10261	SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
10262	SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10263		      ALC262_TOSHIBA_RX1),
10264	SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
10265	SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
10266	SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
10267	SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
10268	SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA),
10269	SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
10270	SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10271	SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10272	SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
10273	{}
10274};
10275
10276static struct alc_config_preset alc262_presets[] = {
10277	[ALC262_BASIC] = {
10278		.mixers = { alc262_base_mixer },
10279		.init_verbs = { alc262_init_verbs },
10280		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10281		.dac_nids = alc262_dac_nids,
10282		.hp_nid = 0x03,
10283		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10284		.channel_mode = alc262_modes,
10285		.input_mux = &alc262_capture_source,
10286	},
10287	[ALC262_HIPPO] = {
10288		.mixers = { alc262_base_mixer },
10289		.init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10290		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10291		.dac_nids = alc262_dac_nids,
10292		.hp_nid = 0x03,
10293		.dig_out_nid = ALC262_DIGOUT_NID,
10294		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10295		.channel_mode = alc262_modes,
10296		.input_mux = &alc262_capture_source,
10297		.unsol_event = alc262_hippo_unsol_event,
10298		.init_hook = alc262_hippo_automute,
10299	},
10300	[ALC262_HIPPO_1] = {
10301		.mixers = { alc262_hippo1_mixer },
10302		.init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10303		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10304		.dac_nids = alc262_dac_nids,
10305		.hp_nid = 0x02,
10306		.dig_out_nid = ALC262_DIGOUT_NID,
10307		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10308		.channel_mode = alc262_modes,
10309		.input_mux = &alc262_capture_source,
10310		.unsol_event = alc262_hippo1_unsol_event,
10311		.init_hook = alc262_hippo1_automute,
10312	},
10313	[ALC262_FUJITSU] = {
10314		.mixers = { alc262_fujitsu_mixer },
10315		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10316				alc262_fujitsu_unsol_verbs },
10317		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10318		.dac_nids = alc262_dac_nids,
10319		.hp_nid = 0x03,
10320		.dig_out_nid = ALC262_DIGOUT_NID,
10321		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10322		.channel_mode = alc262_modes,
10323		.input_mux = &alc262_fujitsu_capture_source,
10324		.unsol_event = alc262_fujitsu_unsol_event,
10325		.init_hook = alc262_fujitsu_init_hook,
10326	},
10327	[ALC262_HP_BPC] = {
10328		.mixers = { alc262_HP_BPC_mixer },
10329		.init_verbs = { alc262_HP_BPC_init_verbs },
10330		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10331		.dac_nids = alc262_dac_nids,
10332		.hp_nid = 0x03,
10333		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10334		.channel_mode = alc262_modes,
10335		.input_mux = &alc262_HP_capture_source,
10336		.unsol_event = alc262_hp_bpc_unsol_event,
10337		.init_hook = alc262_hp_bpc_automute,
10338	},
10339	[ALC262_HP_BPC_D7000_WF] = {
10340		.mixers = { alc262_HP_BPC_WildWest_mixer },
10341		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10342		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10343		.dac_nids = alc262_dac_nids,
10344		.hp_nid = 0x03,
10345		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10346		.channel_mode = alc262_modes,
10347		.input_mux = &alc262_HP_D7000_capture_source,
10348		.unsol_event = alc262_hp_wildwest_unsol_event,
10349		.init_hook = alc262_hp_wildwest_automute,
10350	},
10351	[ALC262_HP_BPC_D7000_WL] = {
10352		.mixers = { alc262_HP_BPC_WildWest_mixer,
10353			    alc262_HP_BPC_WildWest_option_mixer },
10354		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10355		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10356		.dac_nids = alc262_dac_nids,
10357		.hp_nid = 0x03,
10358		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10359		.channel_mode = alc262_modes,
10360		.input_mux = &alc262_HP_D7000_capture_source,
10361		.unsol_event = alc262_hp_wildwest_unsol_event,
10362		.init_hook = alc262_hp_wildwest_automute,
10363	},
10364	[ALC262_HP_TC_T5735] = {
10365		.mixers = { alc262_hp_t5735_mixer },
10366		.init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
10367		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10368		.dac_nids = alc262_dac_nids,
10369		.hp_nid = 0x03,
10370		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10371		.channel_mode = alc262_modes,
10372		.input_mux = &alc262_capture_source,
10373		.unsol_event = alc262_hp_t5735_unsol_event,
10374		.init_hook = alc262_hp_t5735_init_hook,
10375	},
10376	[ALC262_HP_RP5700] = {
10377		.mixers = { alc262_hp_rp5700_mixer },
10378		.init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
10379		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10380		.dac_nids = alc262_dac_nids,
10381		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10382		.channel_mode = alc262_modes,
10383		.input_mux = &alc262_hp_rp5700_capture_source,
10384        },
10385	[ALC262_BENQ_ED8] = {
10386		.mixers = { alc262_base_mixer },
10387		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
10388		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10389		.dac_nids = alc262_dac_nids,
10390		.hp_nid = 0x03,
10391		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10392		.channel_mode = alc262_modes,
10393		.input_mux = &alc262_capture_source,
10394	},
10395	[ALC262_SONY_ASSAMD] = {
10396		.mixers = { alc262_sony_mixer },
10397		.init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
10398		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10399		.dac_nids = alc262_dac_nids,
10400		.hp_nid = 0x02,
10401		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10402		.channel_mode = alc262_modes,
10403		.input_mux = &alc262_capture_source,
10404		.unsol_event = alc262_hippo_unsol_event,
10405		.init_hook = alc262_hippo_automute,
10406	},
10407	[ALC262_BENQ_T31] = {
10408		.mixers = { alc262_benq_t31_mixer },
10409		.init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
10410		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10411		.dac_nids = alc262_dac_nids,
10412		.hp_nid = 0x03,
10413		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10414		.channel_mode = alc262_modes,
10415		.input_mux = &alc262_capture_source,
10416		.unsol_event = alc262_hippo_unsol_event,
10417		.init_hook = alc262_hippo_automute,
10418	},
10419	[ALC262_ULTRA] = {
10420		.mixers = { alc262_ultra_mixer },
10421		.cap_mixer = alc262_ultra_capture_mixer,
10422		.init_verbs = { alc262_ultra_verbs },
10423		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10424		.dac_nids = alc262_dac_nids,
10425		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10426		.channel_mode = alc262_modes,
10427		.input_mux = &alc262_ultra_capture_source,
10428		.adc_nids = alc262_adc_nids, /* ADC0 */
10429		.capsrc_nids = alc262_capsrc_nids,
10430		.num_adc_nids = 1, /* single ADC */
10431		.unsol_event = alc262_ultra_unsol_event,
10432		.init_hook = alc262_ultra_automute,
10433	},
10434	[ALC262_LENOVO_3000] = {
10435		.mixers = { alc262_lenovo_3000_mixer },
10436		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10437				alc262_lenovo_3000_unsol_verbs },
10438		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10439		.dac_nids = alc262_dac_nids,
10440		.hp_nid = 0x03,
10441		.dig_out_nid = ALC262_DIGOUT_NID,
10442		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10443		.channel_mode = alc262_modes,
10444		.input_mux = &alc262_fujitsu_capture_source,
10445		.unsol_event = alc262_lenovo_3000_unsol_event,
10446	},
10447	[ALC262_NEC] = {
10448		.mixers = { alc262_nec_mixer },
10449		.init_verbs = { alc262_nec_verbs },
10450		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10451		.dac_nids = alc262_dac_nids,
10452		.hp_nid = 0x03,
10453		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10454		.channel_mode = alc262_modes,
10455		.input_mux = &alc262_capture_source,
10456	},
10457	[ALC262_TOSHIBA_S06] = {
10458		.mixers = { alc262_toshiba_s06_mixer },
10459		.init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
10460							alc262_eapd_verbs },
10461		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10462		.capsrc_nids = alc262_dmic_capsrc_nids,
10463		.dac_nids = alc262_dac_nids,
10464		.adc_nids = alc262_dmic_adc_nids, /* ADC0 */
10465		.dig_out_nid = ALC262_DIGOUT_NID,
10466		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10467		.channel_mode = alc262_modes,
10468		.input_mux = &alc262_dmic_capture_source,
10469		.unsol_event = alc262_toshiba_s06_unsol_event,
10470		.init_hook = alc262_toshiba_s06_init_hook,
10471	},
10472	[ALC262_TOSHIBA_RX1] = {
10473		.mixers = { alc262_toshiba_rx1_mixer },
10474		.init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
10475		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10476		.dac_nids = alc262_dac_nids,
10477		.hp_nid = 0x03,
10478		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10479		.channel_mode = alc262_modes,
10480		.input_mux = &alc262_capture_source,
10481		.unsol_event = alc262_hippo_unsol_event,
10482		.init_hook = alc262_hippo_automute,
10483	},
10484};
10485
10486static int patch_alc262(struct hda_codec *codec)
10487{
10488	struct alc_spec *spec;
10489	int board_config;
10490	int err;
10491
10492	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10493	if (spec == NULL)
10494		return -ENOMEM;
10495
10496	codec->spec = spec;
10497#if 0
10498	/* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
10499	 * under-run
10500	 */
10501	{
10502	int tmp;
10503	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10504	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
10505	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10506	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
10507	}
10508#endif
10509
10510	alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10511
10512	board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
10513						  alc262_models,
10514						  alc262_cfg_tbl);
10515
10516	if (board_config < 0) {
10517		printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
10518		       "trying auto-probe from BIOS...\n");
10519		board_config = ALC262_AUTO;
10520	}
10521
10522	if (board_config == ALC262_AUTO) {
10523		/* automatic parse from the BIOS config */
10524		err = alc262_parse_auto_config(codec);
10525		if (err < 0) {
10526			alc_free(codec);
10527			return err;
10528		} else if (!err) {
10529			printk(KERN_INFO
10530			       "hda_codec: Cannot set up configuration "
10531			       "from BIOS.  Using base mode...\n");
10532			board_config = ALC262_BASIC;
10533		}
10534	}
10535
10536	if (board_config != ALC262_AUTO)
10537		setup_preset(spec, &alc262_presets[board_config]);
10538
10539	spec->stream_name_analog = "ALC262 Analog";
10540	spec->stream_analog_playback = &alc262_pcm_analog_playback;
10541	spec->stream_analog_capture = &alc262_pcm_analog_capture;
10542
10543	spec->stream_name_digital = "ALC262 Digital";
10544	spec->stream_digital_playback = &alc262_pcm_digital_playback;
10545	spec->stream_digital_capture = &alc262_pcm_digital_capture;
10546
10547	spec->is_mix_capture = 1;
10548	if (!spec->adc_nids && spec->input_mux) {
10549		/* check whether NID 0x07 is valid */
10550		unsigned int wcap = get_wcaps(codec, 0x07);
10551
10552		/* get type */
10553		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
10554		if (wcap != AC_WID_AUD_IN) {
10555			spec->adc_nids = alc262_adc_nids_alt;
10556			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
10557			spec->capsrc_nids = alc262_capsrc_nids_alt;
10558		} else {
10559			spec->adc_nids = alc262_adc_nids;
10560			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
10561			spec->capsrc_nids = alc262_capsrc_nids;
10562		}
10563	}
10564	if (!spec->cap_mixer)
10565		set_capture_mixer(spec);
10566
10567	spec->vmaster_nid = 0x0c;
10568
10569	codec->patch_ops = alc_patch_ops;
10570	if (board_config == ALC262_AUTO)
10571		spec->init_hook = alc262_auto_init;
10572#ifdef CONFIG_SND_HDA_POWER_SAVE
10573	if (!spec->loopback.amplist)
10574		spec->loopback.amplist = alc262_loopbacks;
10575#endif
10576
10577	return 0;
10578}
10579
10580/*
10581 *  ALC268 channel source setting (2 channel)
10582 */
10583#define ALC268_DIGOUT_NID	ALC880_DIGOUT_NID
10584#define alc268_modes		alc260_modes
10585
10586static hda_nid_t alc268_dac_nids[2] = {
10587	/* front, hp */
10588	0x02, 0x03
10589};
10590
10591static hda_nid_t alc268_adc_nids[2] = {
10592	/* ADC0-1 */
10593	0x08, 0x07
10594};
10595
10596static hda_nid_t alc268_adc_nids_alt[1] = {
10597	/* ADC0 */
10598	0x08
10599};
10600
10601static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
10602
10603static struct snd_kcontrol_new alc268_base_mixer[] = {
10604	/* output mixer control */
10605	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10606	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10607	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10608	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10609	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10610	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10611	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10612	{ }
10613};
10614
10615/* bind Beep switches of both NID 0x0f and 0x10 */
10616static struct hda_bind_ctls alc268_bind_beep_sw = {
10617	.ops = &snd_hda_bind_sw,
10618	.values = {
10619		HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
10620		HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
10621		0
10622	},
10623};
10624
10625static struct snd_kcontrol_new alc268_beep_mixer[] = {
10626	HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
10627	HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
10628	{ }
10629};
10630
10631static struct hda_verb alc268_eapd_verbs[] = {
10632	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10633	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10634	{ }
10635};
10636
10637/* Toshiba specific */
10638#define alc268_toshiba_automute	alc262_hippo_automute
10639
10640static struct hda_verb alc268_toshiba_verbs[] = {
10641	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10642	{ } /* end */
10643};
10644
10645static struct hda_input_mux alc268_acer_lc_capture_source = {
10646	.num_items = 2,
10647	.items = {
10648		{ "i-Mic", 0x6 },
10649		{ "E-Mic", 0x0 },
10650	},
10651};
10652
10653/* Acer specific */
10654/* bind volumes of both NID 0x02 and 0x03 */
10655static struct hda_bind_ctls alc268_acer_bind_master_vol = {
10656	.ops = &snd_hda_bind_vol,
10657	.values = {
10658		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
10659		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
10660		0
10661	},
10662};
10663
10664/* mute/unmute internal speaker according to the hp jack and mute state */
10665static void alc268_acer_automute(struct hda_codec *codec, int force)
10666{
10667	struct alc_spec *spec = codec->spec;
10668	unsigned int mute;
10669
10670	if (force || !spec->sense_updated) {
10671		unsigned int present;
10672		present = snd_hda_codec_read(codec, 0x14, 0,
10673				    	 AC_VERB_GET_PIN_SENSE, 0);
10674		spec->jack_present = (present & 0x80000000) != 0;
10675		spec->sense_updated = 1;
10676	}
10677	if (spec->jack_present)
10678		mute = HDA_AMP_MUTE; /* mute internal speaker */
10679	else /* unmute internal speaker if necessary */
10680		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10681	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10682				 HDA_AMP_MUTE, mute);
10683}
10684
10685
10686/* bind hp and internal speaker mute (with plug check) */
10687static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
10688				     struct snd_ctl_elem_value *ucontrol)
10689{
10690	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10691	long *valp = ucontrol->value.integer.value;
10692	int change;
10693
10694	change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10695					  HDA_AMP_MUTE,
10696					  valp[0] ? 0 : HDA_AMP_MUTE);
10697	change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10698					   HDA_AMP_MUTE,
10699					   valp[1] ? 0 : HDA_AMP_MUTE);
10700	if (change)
10701		alc268_acer_automute(codec, 0);
10702	return change;
10703}
10704
10705static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
10706	/* output mixer control */
10707	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10708	{
10709		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10710		.name = "Master Playback Switch",
10711		.info = snd_hda_mixer_amp_switch_info,
10712		.get = snd_hda_mixer_amp_switch_get,
10713		.put = alc268_acer_master_sw_put,
10714		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10715	},
10716	HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
10717	{ }
10718};
10719
10720static struct snd_kcontrol_new alc268_acer_mixer[] = {
10721	/* output mixer control */
10722	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10723	{
10724		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10725		.name = "Master Playback Switch",
10726		.info = snd_hda_mixer_amp_switch_info,
10727		.get = snd_hda_mixer_amp_switch_get,
10728		.put = alc268_acer_master_sw_put,
10729		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10730	},
10731	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10732	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10733	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10734	{ }
10735};
10736
10737static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
10738	/* output mixer control */
10739	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10740	{
10741		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10742		.name = "Master Playback Switch",
10743		.info = snd_hda_mixer_amp_switch_info,
10744		.get = snd_hda_mixer_amp_switch_get,
10745		.put = alc268_acer_master_sw_put,
10746		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10747	},
10748	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10749	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10750	{ }
10751};
10752
10753static struct hda_verb alc268_acer_aspire_one_verbs[] = {
10754	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10755	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10756	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10757	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10758	{0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
10759	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
10760	{ }
10761};
10762
10763static struct hda_verb alc268_acer_verbs[] = {
10764	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
10765	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10766	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10767	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10768	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10769	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10770	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10771	{ }
10772};
10773
10774/* unsolicited event for HP jack sensing */
10775static void alc268_toshiba_unsol_event(struct hda_codec *codec,
10776				       unsigned int res)
10777{
10778	if ((res >> 26) != ALC880_HP_EVENT)
10779		return;
10780	alc268_toshiba_automute(codec);
10781}
10782
10783static void alc268_acer_unsol_event(struct hda_codec *codec,
10784				       unsigned int res)
10785{
10786	if ((res >> 26) != ALC880_HP_EVENT)
10787		return;
10788	alc268_acer_automute(codec, 1);
10789}
10790
10791static void alc268_acer_init_hook(struct hda_codec *codec)
10792{
10793	alc268_acer_automute(codec, 1);
10794}
10795
10796/* toggle speaker-output according to the hp-jack state */
10797static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
10798{
10799	unsigned int present;
10800	unsigned char bits;
10801
10802	present = snd_hda_codec_read(codec, 0x15, 0,
10803				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10804	bits = present ? AMP_IN_MUTE(0) : 0;
10805	snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
10806				AMP_IN_MUTE(0), bits);
10807	snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
10808				AMP_IN_MUTE(0), bits);
10809}
10810
10811
10812static void alc268_acer_mic_automute(struct hda_codec *codec)
10813{
10814	unsigned int present;
10815
10816	present = snd_hda_codec_read(codec, 0x18, 0,
10817				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10818	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
10819			    present ? 0x0 : 0x6);
10820}
10821
10822static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
10823				    unsigned int res)
10824{
10825	if ((res >> 26) == ALC880_HP_EVENT)
10826		alc268_aspire_one_speaker_automute(codec);
10827	if ((res >> 26) == ALC880_MIC_EVENT)
10828		alc268_acer_mic_automute(codec);
10829}
10830
10831static void alc268_acer_lc_init_hook(struct hda_codec *codec)
10832{
10833	alc268_aspire_one_speaker_automute(codec);
10834	alc268_acer_mic_automute(codec);
10835}
10836
10837static struct snd_kcontrol_new alc268_dell_mixer[] = {
10838	/* output mixer control */
10839	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10840	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10841	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10842	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10843	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10844	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10845	{ }
10846};
10847
10848static struct hda_verb alc268_dell_verbs[] = {
10849	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10850	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10851	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10852	{ }
10853};
10854
10855/* mute/unmute internal speaker according to the hp jack and mute state */
10856static void alc268_dell_automute(struct hda_codec *codec)
10857{
10858	unsigned int present;
10859	unsigned int mute;
10860
10861	present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
10862	if (present & 0x80000000)
10863		mute = HDA_AMP_MUTE;
10864	else
10865		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
10866	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10867				 HDA_AMP_MUTE, mute);
10868}
10869
10870static void alc268_dell_unsol_event(struct hda_codec *codec,
10871				    unsigned int res)
10872{
10873	if ((res >> 26) != ALC880_HP_EVENT)
10874		return;
10875	alc268_dell_automute(codec);
10876}
10877
10878#define alc268_dell_init_hook	alc268_dell_automute
10879
10880static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
10881	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10882	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10883	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10884	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10885	HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10886	HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
10887	HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
10888	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10889	{ }
10890};
10891
10892static struct hda_verb alc267_quanta_il1_verbs[] = {
10893	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10894	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
10895	{ }
10896};
10897
10898static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
10899{
10900	unsigned int present;
10901
10902	present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
10903		& AC_PINSENSE_PRESENCE;
10904	snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
10905			    present ? 0 : PIN_OUT);
10906}
10907
10908static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
10909{
10910	unsigned int present;
10911
10912	present = snd_hda_codec_read(codec, 0x18, 0,
10913				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10914	snd_hda_codec_write(codec, 0x23, 0,
10915			    AC_VERB_SET_CONNECT_SEL,
10916			    present ? 0x00 : 0x01);
10917}
10918
10919static void alc267_quanta_il1_automute(struct hda_codec *codec)
10920{
10921	alc267_quanta_il1_hp_automute(codec);
10922	alc267_quanta_il1_mic_automute(codec);
10923}
10924
10925static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
10926					   unsigned int res)
10927{
10928	switch (res >> 26) {
10929	case ALC880_HP_EVENT:
10930		alc267_quanta_il1_hp_automute(codec);
10931		break;
10932	case ALC880_MIC_EVENT:
10933		alc267_quanta_il1_mic_automute(codec);
10934		break;
10935	}
10936}
10937
10938/*
10939 * generic initialization of ADC, input mixers and output mixers
10940 */
10941static struct hda_verb alc268_base_init_verbs[] = {
10942	/* Unmute DAC0-1 and set vol = 0 */
10943	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10944	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10945	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10946	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10947	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10948	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10949
10950	/*
10951	 * Set up output mixers (0x0c - 0x0e)
10952	 */
10953	/* set vol=0 to output mixers */
10954	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10955	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10956	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10957        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
10958
10959	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10960	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10961
10962	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10963	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10964	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10965	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10966	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10967	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10968	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10969	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10970
10971	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10972	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10973	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10974	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10975	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10976	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10977	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10978
10979	/* set PCBEEP vol = 0, mute connections */
10980	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10981	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10982	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10983
10984	/* Unmute Selector 23h,24h and set the default input to mic-in */
10985
10986	{0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
10987	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10988	{0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
10989	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10990
10991	{ }
10992};
10993
10994/*
10995 * generic initialization of ADC, input mixers and output mixers
10996 */
10997static struct hda_verb alc268_volume_init_verbs[] = {
10998	/* set output DAC */
10999	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11000	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11001	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11002	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11003
11004	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11005	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11006	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11007	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11008	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11009
11010	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11011	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11012	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11013	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11014	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11015
11016	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11017	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11018	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11019	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11020
11021	/* set PCBEEP vol = 0, mute connections */
11022	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11023	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11024	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11025
11026	{ }
11027};
11028
11029static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11030	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11031	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11032	{
11033		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11034		/* The multiple "Capture Source" controls confuse alsamixer
11035		 * So call somewhat different..
11036		 */
11037		/* .name = "Capture Source", */
11038		.name = "Input Source",
11039		.count = 1,
11040		.info = alc_mux_enum_info,
11041		.get = alc_mux_enum_get,
11042		.put = alc_mux_enum_put,
11043	},
11044	{ } /* end */
11045};
11046
11047static struct snd_kcontrol_new alc268_capture_mixer[] = {
11048	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11049	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11050	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11051	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11052	{
11053		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11054		/* The multiple "Capture Source" controls confuse alsamixer
11055		 * So call somewhat different..
11056		 */
11057		/* .name = "Capture Source", */
11058		.name = "Input Source",
11059		.count = 2,
11060		.info = alc_mux_enum_info,
11061		.get = alc_mux_enum_get,
11062		.put = alc_mux_enum_put,
11063	},
11064	{ } /* end */
11065};
11066
11067static struct hda_input_mux alc268_capture_source = {
11068	.num_items = 4,
11069	.items = {
11070		{ "Mic", 0x0 },
11071		{ "Front Mic", 0x1 },
11072		{ "Line", 0x2 },
11073		{ "CD", 0x3 },
11074	},
11075};
11076
11077static struct hda_input_mux alc268_acer_capture_source = {
11078	.num_items = 3,
11079	.items = {
11080		{ "Mic", 0x0 },
11081		{ "Internal Mic", 0x1 },
11082		{ "Line", 0x2 },
11083	},
11084};
11085
11086static struct hda_input_mux alc268_acer_dmic_capture_source = {
11087	.num_items = 3,
11088	.items = {
11089		{ "Mic", 0x0 },
11090		{ "Internal Mic", 0x6 },
11091		{ "Line", 0x2 },
11092	},
11093};
11094
11095#ifdef CONFIG_SND_DEBUG
11096static struct snd_kcontrol_new alc268_test_mixer[] = {
11097	/* Volume widgets */
11098	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11099	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11100	HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11101	HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11102	HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11103	HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11104	HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11105	HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11106	HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11107	HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11108	HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11109	HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11110	HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11111	/* The below appears problematic on some hardwares */
11112	/*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11113	HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11114	HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11115	HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11116	HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11117
11118	/* Modes for retasking pin widgets */
11119	ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11120	ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11121	ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11122	ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11123
11124	/* Controls for GPIO pins, assuming they are configured as outputs */
11125	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11126	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11127	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11128	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11129
11130	/* Switches to allow the digital SPDIF output pin to be enabled.
11131	 * The ALC268 does not have an SPDIF input.
11132	 */
11133	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11134
11135	/* A switch allowing EAPD to be enabled.  Some laptops seem to use
11136	 * this output to turn on an external amplifier.
11137	 */
11138	ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11139	ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11140
11141	{ } /* end */
11142};
11143#endif
11144
11145/* create input playback/capture controls for the given pin */
11146static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11147				    const char *ctlname, int idx)
11148{
11149	char name[32];
11150	int err;
11151
11152	sprintf(name, "%s Playback Volume", ctlname);
11153	if (nid == 0x14) {
11154		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11155				  HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11156						      HDA_OUTPUT));
11157		if (err < 0)
11158			return err;
11159	} else if (nid == 0x15) {
11160		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11161				  HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11162						      HDA_OUTPUT));
11163		if (err < 0)
11164			return err;
11165	} else
11166		return -1;
11167	sprintf(name, "%s Playback Switch", ctlname);
11168	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11169			  HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11170	if (err < 0)
11171		return err;
11172	return 0;
11173}
11174
11175/* add playback controls from the parsed DAC table */
11176static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11177					     const struct auto_pin_cfg *cfg)
11178{
11179	hda_nid_t nid;
11180	int err;
11181
11182	spec->multiout.num_dacs = 2;	/* only use one dac */
11183	spec->multiout.dac_nids = spec->private_dac_nids;
11184	spec->multiout.dac_nids[0] = 2;
11185	spec->multiout.dac_nids[1] = 3;
11186
11187	nid = cfg->line_out_pins[0];
11188	if (nid)
11189		alc268_new_analog_output(spec, nid, "Front", 0);
11190
11191	nid = cfg->speaker_pins[0];
11192	if (nid == 0x1d) {
11193		err = add_control(spec, ALC_CTL_WIDGET_VOL,
11194				  "Speaker Playback Volume",
11195				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11196		if (err < 0)
11197			return err;
11198	}
11199	nid = cfg->hp_pins[0];
11200	if (nid)
11201		alc268_new_analog_output(spec, nid, "Headphone", 0);
11202
11203	nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11204	if (nid == 0x16) {
11205		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11206				  "Mono Playback Switch",
11207				  HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11208		if (err < 0)
11209			return err;
11210	}
11211	return 0;
11212}
11213
11214/* create playback/capture controls for input pins */
11215static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11216						const struct auto_pin_cfg *cfg)
11217{
11218	struct hda_input_mux *imux = &spec->private_imux;
11219	int i, idx1;
11220
11221	for (i = 0; i < AUTO_PIN_LAST; i++) {
11222		switch(cfg->input_pins[i]) {
11223		case 0x18:
11224			idx1 = 0;	/* Mic 1 */
11225			break;
11226		case 0x19:
11227			idx1 = 1;	/* Mic 2 */
11228			break;
11229		case 0x1a:
11230			idx1 = 2;	/* Line In */
11231			break;
11232		case 0x1c:
11233			idx1 = 3;	/* CD */
11234			break;
11235		case 0x12:
11236		case 0x13:
11237			idx1 = 6;	/* digital mics */
11238			break;
11239		default:
11240			continue;
11241		}
11242		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11243		imux->items[imux->num_items].index = idx1;
11244		imux->num_items++;
11245	}
11246	return 0;
11247}
11248
11249static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11250{
11251	struct alc_spec *spec = codec->spec;
11252	hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11253	hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11254	hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11255	unsigned int	dac_vol1, dac_vol2;
11256
11257	if (speaker_nid) {
11258		snd_hda_codec_write(codec, speaker_nid, 0,
11259				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11260		snd_hda_codec_write(codec, 0x0f, 0,
11261				    AC_VERB_SET_AMP_GAIN_MUTE,
11262				    AMP_IN_UNMUTE(1));
11263		snd_hda_codec_write(codec, 0x10, 0,
11264				    AC_VERB_SET_AMP_GAIN_MUTE,
11265				    AMP_IN_UNMUTE(1));
11266	} else {
11267		snd_hda_codec_write(codec, 0x0f, 0,
11268				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11269		snd_hda_codec_write(codec, 0x10, 0,
11270				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11271	}
11272
11273	dac_vol1 = dac_vol2 = 0xb000 | 0x40;	/* set max volume  */
11274	if (line_nid == 0x14)
11275		dac_vol2 = AMP_OUT_ZERO;
11276	else if (line_nid == 0x15)
11277		dac_vol1 = AMP_OUT_ZERO;
11278	if (hp_nid == 0x14)
11279		dac_vol2 = AMP_OUT_ZERO;
11280	else if (hp_nid == 0x15)
11281		dac_vol1 = AMP_OUT_ZERO;
11282	if (line_nid != 0x16 || hp_nid != 0x16 ||
11283	    spec->autocfg.line_out_pins[1] != 0x16 ||
11284	    spec->autocfg.line_out_pins[2] != 0x16)
11285		dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11286
11287	snd_hda_codec_write(codec, 0x02, 0,
11288			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11289	snd_hda_codec_write(codec, 0x03, 0,
11290			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11291}
11292
11293/* pcm configuration: identiacal with ALC880 */
11294#define alc268_pcm_analog_playback	alc880_pcm_analog_playback
11295#define alc268_pcm_analog_capture	alc880_pcm_analog_capture
11296#define alc268_pcm_analog_alt_capture	alc880_pcm_analog_alt_capture
11297#define alc268_pcm_digital_playback	alc880_pcm_digital_playback
11298
11299/*
11300 * BIOS auto configuration
11301 */
11302static int alc268_parse_auto_config(struct hda_codec *codec)
11303{
11304	struct alc_spec *spec = codec->spec;
11305	int err;
11306	static hda_nid_t alc268_ignore[] = { 0 };
11307
11308	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11309					   alc268_ignore);
11310	if (err < 0)
11311		return err;
11312	if (!spec->autocfg.line_outs)
11313		return 0; /* can't find valid BIOS pin config */
11314
11315	err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11316	if (err < 0)
11317		return err;
11318	err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11319	if (err < 0)
11320		return err;
11321
11322	spec->multiout.max_channels = 2;
11323
11324	/* digital only support output */
11325	if (spec->autocfg.dig_out_pin)
11326		spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
11327
11328	if (spec->kctls.list)
11329		add_mixer(spec, spec->kctls.list);
11330
11331	if (spec->autocfg.speaker_pins[0] != 0x1d)
11332		add_mixer(spec, alc268_beep_mixer);
11333
11334	add_verb(spec, alc268_volume_init_verbs);
11335	spec->num_mux_defs = 1;
11336	spec->input_mux = &spec->private_imux;
11337
11338	err = alc_auto_add_mic_boost(codec);
11339	if (err < 0)
11340		return err;
11341
11342	store_pin_configs(codec);
11343	return 1;
11344}
11345
11346#define alc268_auto_init_multi_out	alc882_auto_init_multi_out
11347#define alc268_auto_init_hp_out		alc882_auto_init_hp_out
11348#define alc268_auto_init_analog_input	alc882_auto_init_analog_input
11349
11350/* init callback for auto-configuration model -- overriding the default init */
11351static void alc268_auto_init(struct hda_codec *codec)
11352{
11353	struct alc_spec *spec = codec->spec;
11354	alc268_auto_init_multi_out(codec);
11355	alc268_auto_init_hp_out(codec);
11356	alc268_auto_init_mono_speaker_out(codec);
11357	alc268_auto_init_analog_input(codec);
11358	if (spec->unsol_event)
11359		alc_inithook(codec);
11360}
11361
11362/*
11363 * configuration and preset
11364 */
11365static const char *alc268_models[ALC268_MODEL_LAST] = {
11366	[ALC267_QUANTA_IL1]	= "quanta-il1",
11367	[ALC268_3ST]		= "3stack",
11368	[ALC268_TOSHIBA]	= "toshiba",
11369	[ALC268_ACER]		= "acer",
11370	[ALC268_ACER_DMIC]	= "acer-dmic",
11371	[ALC268_ACER_ASPIRE_ONE]	= "acer-aspire",
11372	[ALC268_DELL]		= "dell",
11373	[ALC268_ZEPTO]		= "zepto",
11374#ifdef CONFIG_SND_DEBUG
11375	[ALC268_TEST]		= "test",
11376#endif
11377	[ALC268_AUTO]		= "auto",
11378};
11379
11380static struct snd_pci_quirk alc268_cfg_tbl[] = {
11381	SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
11382	SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
11383	SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
11384	SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
11385	SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
11386	SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
11387						ALC268_ACER_ASPIRE_ONE),
11388	SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
11389	SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
11390	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
11391	SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
11392	SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
11393	SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
11394	SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
11395	SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
11396	SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
11397	SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
11398	{}
11399};
11400
11401static struct alc_config_preset alc268_presets[] = {
11402	[ALC267_QUANTA_IL1] = {
11403		.mixers = { alc267_quanta_il1_mixer },
11404		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11405				alc267_quanta_il1_verbs },
11406		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11407		.dac_nids = alc268_dac_nids,
11408		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11409		.adc_nids = alc268_adc_nids_alt,
11410		.hp_nid = 0x03,
11411		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11412		.channel_mode = alc268_modes,
11413		.input_mux = &alc268_capture_source,
11414		.unsol_event = alc267_quanta_il1_unsol_event,
11415		.init_hook = alc267_quanta_il1_automute,
11416	},
11417	[ALC268_3ST] = {
11418		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11419			    alc268_beep_mixer },
11420		.init_verbs = { alc268_base_init_verbs },
11421		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11422		.dac_nids = alc268_dac_nids,
11423                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11424                .adc_nids = alc268_adc_nids_alt,
11425		.capsrc_nids = alc268_capsrc_nids,
11426		.hp_nid = 0x03,
11427		.dig_out_nid = ALC268_DIGOUT_NID,
11428		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11429		.channel_mode = alc268_modes,
11430		.input_mux = &alc268_capture_source,
11431	},
11432	[ALC268_TOSHIBA] = {
11433		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11434			    alc268_beep_mixer },
11435		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11436				alc268_toshiba_verbs },
11437		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11438		.dac_nids = alc268_dac_nids,
11439		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11440		.adc_nids = alc268_adc_nids_alt,
11441		.capsrc_nids = alc268_capsrc_nids,
11442		.hp_nid = 0x03,
11443		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11444		.channel_mode = alc268_modes,
11445		.input_mux = &alc268_capture_source,
11446		.unsol_event = alc268_toshiba_unsol_event,
11447		.init_hook = alc268_toshiba_automute,
11448	},
11449	[ALC268_ACER] = {
11450		.mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
11451			    alc268_beep_mixer },
11452		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11453				alc268_acer_verbs },
11454		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11455		.dac_nids = alc268_dac_nids,
11456		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11457		.adc_nids = alc268_adc_nids_alt,
11458		.capsrc_nids = alc268_capsrc_nids,
11459		.hp_nid = 0x02,
11460		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11461		.channel_mode = alc268_modes,
11462		.input_mux = &alc268_acer_capture_source,
11463		.unsol_event = alc268_acer_unsol_event,
11464		.init_hook = alc268_acer_init_hook,
11465	},
11466	[ALC268_ACER_DMIC] = {
11467		.mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
11468			    alc268_beep_mixer },
11469		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11470				alc268_acer_verbs },
11471		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11472		.dac_nids = alc268_dac_nids,
11473		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11474		.adc_nids = alc268_adc_nids_alt,
11475		.capsrc_nids = alc268_capsrc_nids,
11476		.hp_nid = 0x02,
11477		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11478		.channel_mode = alc268_modes,
11479		.input_mux = &alc268_acer_dmic_capture_source,
11480		.unsol_event = alc268_acer_unsol_event,
11481		.init_hook = alc268_acer_init_hook,
11482	},
11483	[ALC268_ACER_ASPIRE_ONE] = {
11484		.mixers = { alc268_acer_aspire_one_mixer,
11485				alc268_capture_alt_mixer },
11486		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11487				alc268_acer_aspire_one_verbs },
11488		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11489		.dac_nids = alc268_dac_nids,
11490		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11491		.adc_nids = alc268_adc_nids_alt,
11492		.capsrc_nids = alc268_capsrc_nids,
11493		.hp_nid = 0x03,
11494		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11495		.channel_mode = alc268_modes,
11496		.input_mux = &alc268_acer_lc_capture_source,
11497		.unsol_event = alc268_acer_lc_unsol_event,
11498		.init_hook = alc268_acer_lc_init_hook,
11499	},
11500	[ALC268_DELL] = {
11501		.mixers = { alc268_dell_mixer, alc268_beep_mixer },
11502		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11503				alc268_dell_verbs },
11504		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11505		.dac_nids = alc268_dac_nids,
11506		.hp_nid = 0x02,
11507		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11508		.channel_mode = alc268_modes,
11509		.unsol_event = alc268_dell_unsol_event,
11510		.init_hook = alc268_dell_init_hook,
11511		.input_mux = &alc268_capture_source,
11512	},
11513	[ALC268_ZEPTO] = {
11514		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11515			    alc268_beep_mixer },
11516		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11517				alc268_toshiba_verbs },
11518		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11519		.dac_nids = alc268_dac_nids,
11520		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11521		.adc_nids = alc268_adc_nids_alt,
11522		.capsrc_nids = alc268_capsrc_nids,
11523		.hp_nid = 0x03,
11524		.dig_out_nid = ALC268_DIGOUT_NID,
11525		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11526		.channel_mode = alc268_modes,
11527		.input_mux = &alc268_capture_source,
11528		.unsol_event = alc268_toshiba_unsol_event,
11529		.init_hook = alc268_toshiba_automute
11530	},
11531#ifdef CONFIG_SND_DEBUG
11532	[ALC268_TEST] = {
11533		.mixers = { alc268_test_mixer, alc268_capture_mixer },
11534		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11535				alc268_volume_init_verbs },
11536		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11537		.dac_nids = alc268_dac_nids,
11538		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11539		.adc_nids = alc268_adc_nids_alt,
11540		.capsrc_nids = alc268_capsrc_nids,
11541		.hp_nid = 0x03,
11542		.dig_out_nid = ALC268_DIGOUT_NID,
11543		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11544		.channel_mode = alc268_modes,
11545		.input_mux = &alc268_capture_source,
11546	},
11547#endif
11548};
11549
11550static int patch_alc268(struct hda_codec *codec)
11551{
11552	struct alc_spec *spec;
11553	int board_config;
11554	int err;
11555
11556	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
11557	if (spec == NULL)
11558		return -ENOMEM;
11559
11560	codec->spec = spec;
11561
11562	board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
11563						  alc268_models,
11564						  alc268_cfg_tbl);
11565
11566	if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
11567		printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
11568		       "trying auto-probe from BIOS...\n");
11569		board_config = ALC268_AUTO;
11570	}
11571
11572	if (board_config == ALC268_AUTO) {
11573		/* automatic parse from the BIOS config */
11574		err = alc268_parse_auto_config(codec);
11575		if (err < 0) {
11576			alc_free(codec);
11577			return err;
11578		} else if (!err) {
11579			printk(KERN_INFO
11580			       "hda_codec: Cannot set up configuration "
11581			       "from BIOS.  Using base mode...\n");
11582			board_config = ALC268_3ST;
11583		}
11584	}
11585
11586	if (board_config != ALC268_AUTO)
11587		setup_preset(spec, &alc268_presets[board_config]);
11588
11589	if (codec->vendor_id == 0x10ec0267) {
11590		spec->stream_name_analog = "ALC267 Analog";
11591		spec->stream_name_digital = "ALC267 Digital";
11592	} else {
11593		spec->stream_name_analog = "ALC268 Analog";
11594		spec->stream_name_digital = "ALC268 Digital";
11595	}
11596
11597	spec->stream_analog_playback = &alc268_pcm_analog_playback;
11598	spec->stream_analog_capture = &alc268_pcm_analog_capture;
11599	spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
11600
11601	spec->stream_digital_playback = &alc268_pcm_digital_playback;
11602
11603	if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
11604		/* override the amp caps for beep generator */
11605		snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
11606					  (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
11607					  (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
11608					  (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
11609					  (0 << AC_AMPCAP_MUTE_SHIFT));
11610
11611	if (!spec->adc_nids && spec->input_mux) {
11612		/* check whether NID 0x07 is valid */
11613		unsigned int wcap = get_wcaps(codec, 0x07);
11614		int i;
11615
11616		/* get type */
11617		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11618		if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
11619			spec->adc_nids = alc268_adc_nids_alt;
11620			spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
11621			add_mixer(spec, alc268_capture_alt_mixer);
11622		} else {
11623			spec->adc_nids = alc268_adc_nids;
11624			spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
11625			add_mixer(spec, alc268_capture_mixer);
11626		}
11627		spec->capsrc_nids = alc268_capsrc_nids;
11628		/* set default input source */
11629		for (i = 0; i < spec->num_adc_nids; i++)
11630			snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
11631				0, AC_VERB_SET_CONNECT_SEL,
11632				spec->input_mux->items[0].index);
11633	}
11634
11635	spec->vmaster_nid = 0x02;
11636
11637	codec->patch_ops = alc_patch_ops;
11638	if (board_config == ALC268_AUTO)
11639		spec->init_hook = alc268_auto_init;
11640
11641	return 0;
11642}
11643
11644/*
11645 *  ALC269 channel source setting (2 channel)
11646 */
11647#define ALC269_DIGOUT_NID	ALC880_DIGOUT_NID
11648
11649#define alc269_dac_nids		alc260_dac_nids
11650
11651static hda_nid_t alc269_adc_nids[1] = {
11652	/* ADC1 */
11653	0x08,
11654};
11655
11656static hda_nid_t alc269_capsrc_nids[1] = {
11657	0x23,
11658};
11659
11660/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
11661 *       not a mux!
11662 */
11663
11664static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
11665	.num_items = 2,
11666	.items = {
11667		{ "i-Mic", 0x5 },
11668		{ "e-Mic", 0x0 },
11669	},
11670};
11671
11672static struct hda_input_mux alc269_eeepc_amic_capture_source = {
11673	.num_items = 2,
11674	.items = {
11675		{ "i-Mic", 0x1 },
11676		{ "e-Mic", 0x0 },
11677	},
11678};
11679
11680#define alc269_modes		alc260_modes
11681#define alc269_capture_source	alc880_lg_lw_capture_source
11682
11683static struct snd_kcontrol_new alc269_base_mixer[] = {
11684	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11685	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11686	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11687	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11688	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11689	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11690	HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11691	HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11692	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11693	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11694	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11695	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11696	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11697	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11698	{ } /* end */
11699};
11700
11701static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
11702	/* output mixer control */
11703	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11704	{
11705		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11706		.name = "Master Playback Switch",
11707		.info = snd_hda_mixer_amp_switch_info,
11708		.get = snd_hda_mixer_amp_switch_get,
11709		.put = alc268_acer_master_sw_put,
11710		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11711	},
11712	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11713	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11714	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11715	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11716	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11717	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11718	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
11719	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
11720	{ }
11721};
11722
11723static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
11724	/* output mixer control */
11725	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11726	{
11727		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11728		.name = "Master Playback Switch",
11729		.info = snd_hda_mixer_amp_switch_info,
11730		.get = snd_hda_mixer_amp_switch_get,
11731		.put = alc268_acer_master_sw_put,
11732		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11733	},
11734	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11735	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11736	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11737	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11738	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11739	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11740	HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
11741	HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
11742	HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
11743	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
11744	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
11745	{ }
11746};
11747
11748/* bind volumes of both NID 0x0c and 0x0d */
11749static struct hda_bind_ctls alc269_epc_bind_vol = {
11750	.ops = &snd_hda_bind_vol,
11751	.values = {
11752		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11753		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11754		0
11755	},
11756};
11757
11758static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
11759	HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11760	HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
11761	HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11762	{ } /* end */
11763};
11764
11765/* capture mixer elements */
11766static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
11767	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11768	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11769	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11770	{ } /* end */
11771};
11772
11773/* FSC amilo */
11774static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
11775	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11776	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11777	HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol),
11778	{ } /* end */
11779};
11780
11781/* beep control */
11782static struct snd_kcontrol_new alc269_beep_mixer[] = {
11783	HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11784	HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11785	{ } /* end */
11786};
11787
11788static struct hda_verb alc269_quanta_fl1_verbs[] = {
11789	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11790	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11791	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11792	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11793	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11794	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11795	{ }
11796};
11797
11798static struct hda_verb alc269_lifebook_verbs[] = {
11799	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11800	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
11801	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11802	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11803	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11804	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11805	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11806	{0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11807	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11808	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11809	{ }
11810};
11811
11812/* toggle speaker-output according to the hp-jack state */
11813static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
11814{
11815	unsigned int present;
11816	unsigned char bits;
11817
11818	present = snd_hda_codec_read(codec, 0x15, 0,
11819			AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11820	bits = present ? AMP_IN_MUTE(0) : 0;
11821	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11822			AMP_IN_MUTE(0), bits);
11823	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11824			AMP_IN_MUTE(0), bits);
11825
11826	snd_hda_codec_write(codec, 0x20, 0,
11827			AC_VERB_SET_COEF_INDEX, 0x0c);
11828	snd_hda_codec_write(codec, 0x20, 0,
11829			AC_VERB_SET_PROC_COEF, 0x680);
11830
11831	snd_hda_codec_write(codec, 0x20, 0,
11832			AC_VERB_SET_COEF_INDEX, 0x0c);
11833	snd_hda_codec_write(codec, 0x20, 0,
11834			AC_VERB_SET_PROC_COEF, 0x480);
11835}
11836
11837/* toggle speaker-output according to the hp-jacks state */
11838static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
11839{
11840	unsigned int present;
11841	unsigned char bits;
11842
11843	/* Check laptop headphone socket */
11844	present = snd_hda_codec_read(codec, 0x15, 0,
11845			AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11846
11847	/* Check port replicator headphone socket */
11848	present |= snd_hda_codec_read(codec, 0x1a, 0,
11849			AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11850
11851	bits = present ? AMP_IN_MUTE(0) : 0;
11852	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11853			AMP_IN_MUTE(0), bits);
11854	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11855			AMP_IN_MUTE(0), bits);
11856
11857	snd_hda_codec_write(codec, 0x20, 0,
11858			AC_VERB_SET_COEF_INDEX, 0x0c);
11859	snd_hda_codec_write(codec, 0x20, 0,
11860			AC_VERB_SET_PROC_COEF, 0x680);
11861
11862	snd_hda_codec_write(codec, 0x20, 0,
11863			AC_VERB_SET_COEF_INDEX, 0x0c);
11864	snd_hda_codec_write(codec, 0x20, 0,
11865			AC_VERB_SET_PROC_COEF, 0x480);
11866}
11867
11868static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
11869{
11870	unsigned int present;
11871
11872	present = snd_hda_codec_read(codec, 0x18, 0,
11873				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11874	snd_hda_codec_write(codec, 0x23, 0,
11875			    AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
11876}
11877
11878static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
11879{
11880	unsigned int present_laptop;
11881	unsigned int present_dock;
11882
11883	present_laptop = snd_hda_codec_read(codec, 0x18, 0,
11884				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11885
11886	present_dock = snd_hda_codec_read(codec, 0x1b, 0,
11887				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11888
11889	/* Laptop mic port overrides dock mic port, design decision */
11890	if (present_dock)
11891		snd_hda_codec_write(codec, 0x23, 0,
11892				AC_VERB_SET_CONNECT_SEL, 0x3);
11893	if (present_laptop)
11894		snd_hda_codec_write(codec, 0x23, 0,
11895				AC_VERB_SET_CONNECT_SEL, 0x0);
11896	if (!present_dock && !present_laptop)
11897		snd_hda_codec_write(codec, 0x23, 0,
11898				AC_VERB_SET_CONNECT_SEL, 0x1);
11899}
11900
11901static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
11902				    unsigned int res)
11903{
11904	if ((res >> 26) == ALC880_HP_EVENT)
11905		alc269_quanta_fl1_speaker_automute(codec);
11906	if ((res >> 26) == ALC880_MIC_EVENT)
11907		alc269_quanta_fl1_mic_automute(codec);
11908}
11909
11910static void alc269_lifebook_unsol_event(struct hda_codec *codec,
11911					unsigned int res)
11912{
11913	if ((res >> 26) == ALC880_HP_EVENT)
11914		alc269_lifebook_speaker_automute(codec);
11915	if ((res >> 26) == ALC880_MIC_EVENT)
11916		alc269_lifebook_mic_autoswitch(codec);
11917}
11918
11919static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
11920{
11921	alc269_quanta_fl1_speaker_automute(codec);
11922	alc269_quanta_fl1_mic_automute(codec);
11923}
11924
11925static void alc269_lifebook_init_hook(struct hda_codec *codec)
11926{
11927	alc269_lifebook_speaker_automute(codec);
11928	alc269_lifebook_mic_autoswitch(codec);
11929}
11930
11931static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
11932	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11933	{0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
11934	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11935	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
11936	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11937	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11938	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11939	{}
11940};
11941
11942static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
11943	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11944	{0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
11945	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11946	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
11947	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11948	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11949	{}
11950};
11951
11952/* toggle speaker-output according to the hp-jack state */
11953static void alc269_speaker_automute(struct hda_codec *codec)
11954{
11955	unsigned int present;
11956	unsigned char bits;
11957
11958	present = snd_hda_codec_read(codec, 0x15, 0,
11959				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11960	bits = present ? AMP_IN_MUTE(0) : 0;
11961	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11962				AMP_IN_MUTE(0), bits);
11963	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11964				AMP_IN_MUTE(0), bits);
11965}
11966
11967static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
11968{
11969	unsigned int present;
11970
11971	present = snd_hda_codec_read(codec, 0x18, 0,
11972				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11973	snd_hda_codec_write(codec, 0x23, 0,
11974				AC_VERB_SET_CONNECT_SEL,  (present ? 0 : 5));
11975}
11976
11977static void alc269_eeepc_amic_automute(struct hda_codec *codec)
11978{
11979	unsigned int present;
11980
11981	present = snd_hda_codec_read(codec, 0x18, 0,
11982				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11983	snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11984				0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
11985	snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11986				0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
11987}
11988
11989/* unsolicited event for HP jack sensing */
11990static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
11991				     unsigned int res)
11992{
11993	if ((res >> 26) == ALC880_HP_EVENT)
11994		alc269_speaker_automute(codec);
11995
11996	if ((res >> 26) == ALC880_MIC_EVENT)
11997		alc269_eeepc_dmic_automute(codec);
11998}
11999
12000static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
12001{
12002	alc269_speaker_automute(codec);
12003	alc269_eeepc_dmic_automute(codec);
12004}
12005
12006/* unsolicited event for HP jack sensing */
12007static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
12008				     unsigned int res)
12009{
12010	if ((res >> 26) == ALC880_HP_EVENT)
12011		alc269_speaker_automute(codec);
12012
12013	if ((res >> 26) == ALC880_MIC_EVENT)
12014		alc269_eeepc_amic_automute(codec);
12015}
12016
12017static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
12018{
12019	alc269_speaker_automute(codec);
12020	alc269_eeepc_amic_automute(codec);
12021}
12022
12023/*
12024 * generic initialization of ADC, input mixers and output mixers
12025 */
12026static struct hda_verb alc269_init_verbs[] = {
12027	/*
12028	 * Unmute ADC0 and set the default input to mic-in
12029	 */
12030	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12031
12032	/* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12033	 * analog-loopback mixer widget
12034	 * Note: PASD motherboards uses the Line In 2 as the input for
12035	 * front panel mic (mic 2)
12036	 */
12037	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12038	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12039	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12040	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12041	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12042	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12043
12044	/*
12045	 * Set up output mixers (0x0c - 0x0e)
12046	 */
12047	/* set vol=0 to output mixers */
12048	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12049	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12050
12051	/* set up input amps for analog loopback */
12052	/* Amp Indices: DAC = 0, mixer = 1 */
12053	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12054	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12055	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12056	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12057	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12058	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12059
12060	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12061	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12062	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12063	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12064	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12065	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12066	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12067
12068	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12069	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12070	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12071	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12072	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12073	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12074	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12075
12076	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12077	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12078
12079	/* FIXME: use matrix-type input source selection */
12080	/* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12081	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12082	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12083	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12084	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12085	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12086
12087	/* set EAPD */
12088	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12089	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12090	{ }
12091};
12092
12093/* add playback controls from the parsed DAC table */
12094static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12095					     const struct auto_pin_cfg *cfg)
12096{
12097	hda_nid_t nid;
12098	int err;
12099
12100	spec->multiout.num_dacs = 1;	/* only use one dac */
12101	spec->multiout.dac_nids = spec->private_dac_nids;
12102	spec->multiout.dac_nids[0] = 2;
12103
12104	nid = cfg->line_out_pins[0];
12105	if (nid) {
12106		err = add_control(spec, ALC_CTL_WIDGET_VOL,
12107				  "Front Playback Volume",
12108				  HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12109		if (err < 0)
12110			return err;
12111		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12112				  "Front Playback Switch",
12113				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12114		if (err < 0)
12115			return err;
12116	}
12117
12118	nid = cfg->speaker_pins[0];
12119	if (nid) {
12120		if (!cfg->line_out_pins[0]) {
12121			err = add_control(spec, ALC_CTL_WIDGET_VOL,
12122					  "Speaker Playback Volume",
12123					  HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12124							      HDA_OUTPUT));
12125			if (err < 0)
12126				return err;
12127		}
12128		if (nid == 0x16) {
12129			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12130					  "Speaker Playback Switch",
12131					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12132							      HDA_OUTPUT));
12133			if (err < 0)
12134				return err;
12135		} else {
12136			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12137					  "Speaker Playback Switch",
12138					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12139							      HDA_OUTPUT));
12140			if (err < 0)
12141				return err;
12142		}
12143	}
12144	nid = cfg->hp_pins[0];
12145	if (nid) {
12146		/* spec->multiout.hp_nid = 2; */
12147		if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12148			err = add_control(spec, ALC_CTL_WIDGET_VOL,
12149					  "Headphone Playback Volume",
12150					  HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12151							      HDA_OUTPUT));
12152			if (err < 0)
12153				return err;
12154		}
12155		if (nid == 0x16) {
12156			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12157					  "Headphone Playback Switch",
12158					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12159							      HDA_OUTPUT));
12160			if (err < 0)
12161				return err;
12162		} else {
12163			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12164					  "Headphone Playback Switch",
12165					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12166							      HDA_OUTPUT));
12167			if (err < 0)
12168				return err;
12169		}
12170	}
12171	return 0;
12172}
12173
12174static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
12175						const struct auto_pin_cfg *cfg)
12176{
12177	int err;
12178
12179	err = alc880_auto_create_analog_input_ctls(spec, cfg);
12180	if (err < 0)
12181		return err;
12182	/* digital-mic input pin is excluded in alc880_auto_create..()
12183	 * because it's under 0x18
12184	 */
12185	if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
12186	    cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
12187		struct hda_input_mux *imux = &spec->private_imux;
12188		imux->items[imux->num_items].label = "Int Mic";
12189		imux->items[imux->num_items].index = 0x05;
12190		imux->num_items++;
12191	}
12192	return 0;
12193}
12194
12195#ifdef CONFIG_SND_HDA_POWER_SAVE
12196#define alc269_loopbacks	alc880_loopbacks
12197#endif
12198
12199/* pcm configuration: identiacal with ALC880 */
12200#define alc269_pcm_analog_playback	alc880_pcm_analog_playback
12201#define alc269_pcm_analog_capture	alc880_pcm_analog_capture
12202#define alc269_pcm_digital_playback	alc880_pcm_digital_playback
12203#define alc269_pcm_digital_capture	alc880_pcm_digital_capture
12204
12205/*
12206 * BIOS auto configuration
12207 */
12208static int alc269_parse_auto_config(struct hda_codec *codec)
12209{
12210	struct alc_spec *spec = codec->spec;
12211	int i, err;
12212	static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12213
12214	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12215					   alc269_ignore);
12216	if (err < 0)
12217		return err;
12218
12219	err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12220	if (err < 0)
12221		return err;
12222	err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12223	if (err < 0)
12224		return err;
12225
12226	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12227
12228	if (spec->autocfg.dig_out_pin)
12229		spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12230
12231	if (spec->kctls.list)
12232		add_mixer(spec, spec->kctls.list);
12233
12234	/* create a beep mixer control if the pin 0x1d isn't assigned */
12235	for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++)
12236		if (spec->autocfg.input_pins[i] == 0x1d)
12237			break;
12238	if (i >= ARRAY_SIZE(spec->autocfg.input_pins))
12239		add_mixer(spec, alc269_beep_mixer);
12240
12241	add_verb(spec, alc269_init_verbs);
12242	spec->num_mux_defs = 1;
12243	spec->input_mux = &spec->private_imux;
12244	/* set default input source */
12245	snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12246				  0, AC_VERB_SET_CONNECT_SEL,
12247				  spec->input_mux->items[0].index);
12248
12249	err = alc_auto_add_mic_boost(codec);
12250	if (err < 0)
12251		return err;
12252
12253	if (!spec->cap_mixer)
12254		set_capture_mixer(spec);
12255
12256	store_pin_configs(codec);
12257	return 1;
12258}
12259
12260#define alc269_auto_init_multi_out	alc882_auto_init_multi_out
12261#define alc269_auto_init_hp_out		alc882_auto_init_hp_out
12262#define alc269_auto_init_analog_input	alc882_auto_init_analog_input
12263
12264
12265/* init callback for auto-configuration model -- overriding the default init */
12266static void alc269_auto_init(struct hda_codec *codec)
12267{
12268	struct alc_spec *spec = codec->spec;
12269	alc269_auto_init_multi_out(codec);
12270	alc269_auto_init_hp_out(codec);
12271	alc269_auto_init_analog_input(codec);
12272	if (spec->unsol_event)
12273		alc_inithook(codec);
12274}
12275
12276/*
12277 * configuration and preset
12278 */
12279static const char *alc269_models[ALC269_MODEL_LAST] = {
12280	[ALC269_BASIC]			= "basic",
12281	[ALC269_QUANTA_FL1]		= "quanta",
12282	[ALC269_ASUS_EEEPC_P703]	= "eeepc-p703",
12283	[ALC269_ASUS_EEEPC_P901]	= "eeepc-p901",
12284	[ALC269_FUJITSU]		= "fujitsu",
12285	[ALC269_LIFEBOOK]		= "lifebook"
12286};
12287
12288static struct snd_pci_quirk alc269_cfg_tbl[] = {
12289	SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
12290	SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12291		      ALC269_ASUS_EEEPC_P703),
12292	SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12293		      ALC269_ASUS_EEEPC_P901),
12294	SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12295		      ALC269_ASUS_EEEPC_P901),
12296	SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
12297	SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
12298	{}
12299};
12300
12301static struct alc_config_preset alc269_presets[] = {
12302	[ALC269_BASIC] = {
12303		.mixers = { alc269_base_mixer },
12304		.init_verbs = { alc269_init_verbs },
12305		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
12306		.dac_nids = alc269_dac_nids,
12307		.hp_nid = 0x03,
12308		.num_channel_mode = ARRAY_SIZE(alc269_modes),
12309		.channel_mode = alc269_modes,
12310		.input_mux = &alc269_capture_source,
12311	},
12312	[ALC269_QUANTA_FL1] = {
12313		.mixers = { alc269_quanta_fl1_mixer },
12314		.init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
12315		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
12316		.dac_nids = alc269_dac_nids,
12317		.hp_nid = 0x03,
12318		.num_channel_mode = ARRAY_SIZE(alc269_modes),
12319		.channel_mode = alc269_modes,
12320		.input_mux = &alc269_capture_source,
12321		.unsol_event = alc269_quanta_fl1_unsol_event,
12322		.init_hook = alc269_quanta_fl1_init_hook,
12323	},
12324	[ALC269_ASUS_EEEPC_P703] = {
12325		.mixers = { alc269_eeepc_mixer },
12326		.cap_mixer = alc269_epc_capture_mixer,
12327		.init_verbs = { alc269_init_verbs,
12328				alc269_eeepc_amic_init_verbs },
12329		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
12330		.dac_nids = alc269_dac_nids,
12331		.hp_nid = 0x03,
12332		.num_channel_mode = ARRAY_SIZE(alc269_modes),
12333		.channel_mode = alc269_modes,
12334		.input_mux = &alc269_eeepc_amic_capture_source,
12335		.unsol_event = alc269_eeepc_amic_unsol_event,
12336		.init_hook = alc269_eeepc_amic_inithook,
12337	},
12338	[ALC269_ASUS_EEEPC_P901] = {
12339		.mixers = { alc269_eeepc_mixer },
12340		.cap_mixer = alc269_epc_capture_mixer,
12341		.init_verbs = { alc269_init_verbs,
12342				alc269_eeepc_dmic_init_verbs },
12343		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
12344		.dac_nids = alc269_dac_nids,
12345		.hp_nid = 0x03,
12346		.num_channel_mode = ARRAY_SIZE(alc269_modes),
12347		.channel_mode = alc269_modes,
12348		.input_mux = &alc269_eeepc_dmic_capture_source,
12349		.unsol_event = alc269_eeepc_dmic_unsol_event,
12350		.init_hook = alc269_eeepc_dmic_inithook,
12351	},
12352	[ALC269_FUJITSU] = {
12353		.mixers = { alc269_fujitsu_mixer, alc269_beep_mixer },
12354		.cap_mixer = alc269_epc_capture_mixer,
12355		.init_verbs = { alc269_init_verbs,
12356				alc269_eeepc_dmic_init_verbs },
12357		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
12358		.dac_nids = alc269_dac_nids,
12359		.hp_nid = 0x03,
12360		.num_channel_mode = ARRAY_SIZE(alc269_modes),
12361		.channel_mode = alc269_modes,
12362		.input_mux = &alc269_eeepc_dmic_capture_source,
12363		.unsol_event = alc269_eeepc_dmic_unsol_event,
12364		.init_hook = alc269_eeepc_dmic_inithook,
12365	},
12366	[ALC269_LIFEBOOK] = {
12367		.mixers = { alc269_lifebook_mixer },
12368		.init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
12369		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
12370		.dac_nids = alc269_dac_nids,
12371		.hp_nid = 0x03,
12372		.num_channel_mode = ARRAY_SIZE(alc269_modes),
12373		.channel_mode = alc269_modes,
12374		.input_mux = &alc269_capture_source,
12375		.unsol_event = alc269_lifebook_unsol_event,
12376		.init_hook = alc269_lifebook_init_hook,
12377	},
12378};
12379
12380static int patch_alc269(struct hda_codec *codec)
12381{
12382	struct alc_spec *spec;
12383	int board_config;
12384	int err;
12385
12386	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12387	if (spec == NULL)
12388		return -ENOMEM;
12389
12390	codec->spec = spec;
12391
12392	alc_fix_pll_init(codec, 0x20, 0x04, 15);
12393
12394	board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
12395						  alc269_models,
12396						  alc269_cfg_tbl);
12397
12398	if (board_config < 0) {
12399		printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
12400		       "trying auto-probe from BIOS...\n");
12401		board_config = ALC269_AUTO;
12402	}
12403
12404	if (board_config == ALC269_AUTO) {
12405		/* automatic parse from the BIOS config */
12406		err = alc269_parse_auto_config(codec);
12407		if (err < 0) {
12408			alc_free(codec);
12409			return err;
12410		} else if (!err) {
12411			printk(KERN_INFO
12412			       "hda_codec: Cannot set up configuration "
12413			       "from BIOS.  Using base mode...\n");
12414			board_config = ALC269_BASIC;
12415		}
12416	}
12417
12418	if (board_config != ALC269_AUTO)
12419		setup_preset(spec, &alc269_presets[board_config]);
12420
12421	spec->stream_name_analog = "ALC269 Analog";
12422	spec->stream_analog_playback = &alc269_pcm_analog_playback;
12423	spec->stream_analog_capture = &alc269_pcm_analog_capture;
12424
12425	spec->stream_name_digital = "ALC269 Digital";
12426	spec->stream_digital_playback = &alc269_pcm_digital_playback;
12427	spec->stream_digital_capture = &alc269_pcm_digital_capture;
12428
12429	spec->adc_nids = alc269_adc_nids;
12430	spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
12431	spec->capsrc_nids = alc269_capsrc_nids;
12432	if (!spec->cap_mixer)
12433		set_capture_mixer(spec);
12434
12435	codec->patch_ops = alc_patch_ops;
12436	if (board_config == ALC269_AUTO)
12437		spec->init_hook = alc269_auto_init;
12438#ifdef CONFIG_SND_HDA_POWER_SAVE
12439	if (!spec->loopback.amplist)
12440		spec->loopback.amplist = alc269_loopbacks;
12441#endif
12442
12443	return 0;
12444}
12445
12446/*
12447 *  ALC861 channel source setting (2/6 channel selection for 3-stack)
12448 */
12449
12450/*
12451 * set the path ways for 2 channel output
12452 * need to set the codec line out and mic 1 pin widgets to inputs
12453 */
12454static struct hda_verb alc861_threestack_ch2_init[] = {
12455	/* set pin widget 1Ah (line in) for input */
12456	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12457	/* set pin widget 18h (mic1/2) for input, for mic also enable
12458	 * the vref
12459	 */
12460	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12461
12462	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12463#if 0
12464	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12465	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12466#endif
12467	{ } /* end */
12468};
12469/*
12470 * 6ch mode
12471 * need to set the codec line out and mic 1 pin widgets to outputs
12472 */
12473static struct hda_verb alc861_threestack_ch6_init[] = {
12474	/* set pin widget 1Ah (line in) for output (Back Surround)*/
12475	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12476	/* set pin widget 18h (mic1) for output (CLFE)*/
12477	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12478
12479	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12480	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12481
12482	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12483#if 0
12484	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12485	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12486#endif
12487	{ } /* end */
12488};
12489
12490static struct hda_channel_mode alc861_threestack_modes[2] = {
12491	{ 2, alc861_threestack_ch2_init },
12492	{ 6, alc861_threestack_ch6_init },
12493};
12494/* Set mic1 as input and unmute the mixer */
12495static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
12496	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12497	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12498	{ } /* end */
12499};
12500/* Set mic1 as output and mute mixer */
12501static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
12502	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12503	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12504	{ } /* end */
12505};
12506
12507static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
12508	{ 2, alc861_uniwill_m31_ch2_init },
12509	{ 4, alc861_uniwill_m31_ch4_init },
12510};
12511
12512/* Set mic1 and line-in as input and unmute the mixer */
12513static struct hda_verb alc861_asus_ch2_init[] = {
12514	/* set pin widget 1Ah (line in) for input */
12515	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12516	/* set pin widget 18h (mic1/2) for input, for mic also enable
12517	 * the vref
12518	 */
12519	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12520
12521	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12522#if 0
12523	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12524	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12525#endif
12526	{ } /* end */
12527};
12528/* Set mic1 nad line-in as output and mute mixer */
12529static struct hda_verb alc861_asus_ch6_init[] = {
12530	/* set pin widget 1Ah (line in) for output (Back Surround)*/
12531	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12532	/* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12533	/* set pin widget 18h (mic1) for output (CLFE)*/
12534	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12535	/* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12536	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12537	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12538
12539	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12540#if 0
12541	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12542	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12543#endif
12544	{ } /* end */
12545};
12546
12547static struct hda_channel_mode alc861_asus_modes[2] = {
12548	{ 2, alc861_asus_ch2_init },
12549	{ 6, alc861_asus_ch6_init },
12550};
12551
12552/* patch-ALC861 */
12553
12554static struct snd_kcontrol_new alc861_base_mixer[] = {
12555        /* output mixer control */
12556	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12557	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12558	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12559	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12560	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12561
12562        /*Input mixer control */
12563	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12564	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12565	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12566	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12567	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12568	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12569	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12570	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12571	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12572	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12573
12574	{ } /* end */
12575};
12576
12577static struct snd_kcontrol_new alc861_3ST_mixer[] = {
12578        /* output mixer control */
12579	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12580	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12581	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12582	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12583	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12584
12585	/* Input mixer control */
12586	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12587	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12588	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12589	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12590	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12591	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12592	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12593	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12594	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12595	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12596
12597	{
12598		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12599		.name = "Channel Mode",
12600		.info = alc_ch_mode_info,
12601		.get = alc_ch_mode_get,
12602		.put = alc_ch_mode_put,
12603                .private_value = ARRAY_SIZE(alc861_threestack_modes),
12604	},
12605	{ } /* end */
12606};
12607
12608static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
12609        /* output mixer control */
12610	HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12611	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12612	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12613
12614	{ } /* end */
12615};
12616
12617static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
12618        /* output mixer control */
12619	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12620	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12621	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12622	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12623	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12624
12625	/* Input mixer control */
12626	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12627	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12628	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12629	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12630	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12631	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12632	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12633	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12634	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12635	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12636
12637	{
12638		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12639		.name = "Channel Mode",
12640		.info = alc_ch_mode_info,
12641		.get = alc_ch_mode_get,
12642		.put = alc_ch_mode_put,
12643                .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
12644	},
12645	{ } /* end */
12646};
12647
12648static struct snd_kcontrol_new alc861_asus_mixer[] = {
12649        /* output mixer control */
12650	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12651	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12652	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12653	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12654	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12655
12656	/* Input mixer control */
12657	HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12658	HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12659	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12660	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12661	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12662	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12663	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12664	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12665	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12666	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
12667
12668	{
12669		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12670		.name = "Channel Mode",
12671		.info = alc_ch_mode_info,
12672		.get = alc_ch_mode_get,
12673		.put = alc_ch_mode_put,
12674                .private_value = ARRAY_SIZE(alc861_asus_modes),
12675	},
12676	{ }
12677};
12678
12679/* additional mixer */
12680static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
12681	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12682	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12683	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
12684	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
12685	{ }
12686};
12687
12688/*
12689 * generic initialization of ADC, input mixers and output mixers
12690 */
12691static struct hda_verb alc861_base_init_verbs[] = {
12692	/*
12693	 * Unmute ADC0 and set the default input to mic-in
12694	 */
12695	/* port-A for surround (rear panel) */
12696	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12697	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
12698	/* port-B for mic-in (rear panel) with vref */
12699	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12700	/* port-C for line-in (rear panel) */
12701	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12702	/* port-D for Front */
12703	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12704	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12705	/* port-E for HP out (front panel) */
12706	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12707	/* route front PCM to HP */
12708	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12709	/* port-F for mic-in (front panel) with vref */
12710	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12711	/* port-G for CLFE (rear panel) */
12712	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12713	{ 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12714	/* port-H for side (rear panel) */
12715	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12716	{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
12717	/* CD-in */
12718	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12719	/* route front mic to ADC1*/
12720	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12721	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12722
12723	/* Unmute DAC0~3 & spdif out*/
12724	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12725	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12726	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12727	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12728	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12729
12730	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12731	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12732        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12733	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12734        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12735
12736	/* Unmute Stereo Mixer 15 */
12737	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12738	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12739	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12740	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12741
12742	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12743	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12744	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12745	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12746	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12747	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12748	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12749	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12750	/* hp used DAC 3 (Front) */
12751	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12752        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12753
12754	{ }
12755};
12756
12757static struct hda_verb alc861_threestack_init_verbs[] = {
12758	/*
12759	 * Unmute ADC0 and set the default input to mic-in
12760	 */
12761	/* port-A for surround (rear panel) */
12762	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12763	/* port-B for mic-in (rear panel) with vref */
12764	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12765	/* port-C for line-in (rear panel) */
12766	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12767	/* port-D for Front */
12768	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12769	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12770	/* port-E for HP out (front panel) */
12771	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12772	/* route front PCM to HP */
12773	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12774	/* port-F for mic-in (front panel) with vref */
12775	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12776	/* port-G for CLFE (rear panel) */
12777	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12778	/* port-H for side (rear panel) */
12779	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12780	/* CD-in */
12781	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12782	/* route front mic to ADC1*/
12783	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12784	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12785	/* Unmute DAC0~3 & spdif out*/
12786	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12787	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12788	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12789	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12790	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12791
12792	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12793	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12794        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12795	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12796        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12797
12798	/* Unmute Stereo Mixer 15 */
12799	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12800	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12801	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12802	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12803
12804	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12805	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12806	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12807	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12808	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12809	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12810	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12811	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12812	/* hp used DAC 3 (Front) */
12813	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12814        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12815	{ }
12816};
12817
12818static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
12819	/*
12820	 * Unmute ADC0 and set the default input to mic-in
12821	 */
12822	/* port-A for surround (rear panel) */
12823	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12824	/* port-B for mic-in (rear panel) with vref */
12825	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12826	/* port-C for line-in (rear panel) */
12827	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12828	/* port-D for Front */
12829	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12830	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12831	/* port-E for HP out (front panel) */
12832	/* this has to be set to VREF80 */
12833	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12834	/* route front PCM to HP */
12835	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12836	/* port-F for mic-in (front panel) with vref */
12837	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12838	/* port-G for CLFE (rear panel) */
12839	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12840	/* port-H for side (rear panel) */
12841	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12842	/* CD-in */
12843	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12844	/* route front mic to ADC1*/
12845	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12846	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12847	/* Unmute DAC0~3 & spdif out*/
12848	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12849	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12850	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12851	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12852	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12853
12854	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12855	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12856        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12857	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12858        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12859
12860	/* Unmute Stereo Mixer 15 */
12861	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12862	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12863	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12864	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12865
12866	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12867	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12868	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12869	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12870	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12871	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12872	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12873	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12874	/* hp used DAC 3 (Front) */
12875	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12876        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12877	{ }
12878};
12879
12880static struct hda_verb alc861_asus_init_verbs[] = {
12881	/*
12882	 * Unmute ADC0 and set the default input to mic-in
12883	 */
12884	/* port-A for surround (rear panel)
12885	 * according to codec#0 this is the HP jack
12886	 */
12887	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
12888	/* route front PCM to HP */
12889	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
12890	/* port-B for mic-in (rear panel) with vref */
12891	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12892	/* port-C for line-in (rear panel) */
12893	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12894	/* port-D for Front */
12895	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12896	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12897	/* port-E for HP out (front panel) */
12898	/* this has to be set to VREF80 */
12899	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12900	/* route front PCM to HP */
12901	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12902	/* port-F for mic-in (front panel) with vref */
12903	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12904	/* port-G for CLFE (rear panel) */
12905	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12906	/* port-H for side (rear panel) */
12907	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12908	/* CD-in */
12909	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12910	/* route front mic to ADC1*/
12911	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12912	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12913	/* Unmute DAC0~3 & spdif out*/
12914	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12915	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12916	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12917	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12918	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12919	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12920	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12921        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12922	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12923        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12924
12925	/* Unmute Stereo Mixer 15 */
12926	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12927	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12928	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12929	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12930
12931	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12932	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12933	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12934	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12935	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12936	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12937	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12938	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12939	/* hp used DAC 3 (Front) */
12940	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12941	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12942	{ }
12943};
12944
12945/* additional init verbs for ASUS laptops */
12946static struct hda_verb alc861_asus_laptop_init_verbs[] = {
12947	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
12948	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
12949	{ }
12950};
12951
12952/*
12953 * generic initialization of ADC, input mixers and output mixers
12954 */
12955static struct hda_verb alc861_auto_init_verbs[] = {
12956	/*
12957	 * Unmute ADC0 and set the default input to mic-in
12958	 */
12959	/* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
12960	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12961
12962	/* Unmute DAC0~3 & spdif out*/
12963	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12964	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12965	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12966	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12967	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12968
12969	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12970	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12971	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12972	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12973	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12974
12975	/* Unmute Stereo Mixer 15 */
12976	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12977	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12978	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12979	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
12980
12981	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12982	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12983	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12984	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12985	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12986	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12987	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12988	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12989
12990	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12991	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12992	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12993	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12994	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12995	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12996	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12997	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12998
12999	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},	/* set Mic 1 */
13000
13001	{ }
13002};
13003
13004static struct hda_verb alc861_toshiba_init_verbs[] = {
13005	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13006
13007	{ }
13008};
13009
13010/* toggle speaker-output according to the hp-jack state */
13011static void alc861_toshiba_automute(struct hda_codec *codec)
13012{
13013	unsigned int present;
13014
13015	present = snd_hda_codec_read(codec, 0x0f, 0,
13016				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13017	snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
13018				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13019	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
13020				 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
13021}
13022
13023static void alc861_toshiba_unsol_event(struct hda_codec *codec,
13024				       unsigned int res)
13025{
13026	if ((res >> 26) == ALC880_HP_EVENT)
13027		alc861_toshiba_automute(codec);
13028}
13029
13030/* pcm configuration: identiacal with ALC880 */
13031#define alc861_pcm_analog_playback	alc880_pcm_analog_playback
13032#define alc861_pcm_analog_capture	alc880_pcm_analog_capture
13033#define alc861_pcm_digital_playback	alc880_pcm_digital_playback
13034#define alc861_pcm_digital_capture	alc880_pcm_digital_capture
13035
13036
13037#define ALC861_DIGOUT_NID	0x07
13038
13039static struct hda_channel_mode alc861_8ch_modes[1] = {
13040	{ 8, NULL }
13041};
13042
13043static hda_nid_t alc861_dac_nids[4] = {
13044	/* front, surround, clfe, side */
13045	0x03, 0x06, 0x05, 0x04
13046};
13047
13048static hda_nid_t alc660_dac_nids[3] = {
13049	/* front, clfe, surround */
13050	0x03, 0x05, 0x06
13051};
13052
13053static hda_nid_t alc861_adc_nids[1] = {
13054	/* ADC0-2 */
13055	0x08,
13056};
13057
13058static struct hda_input_mux alc861_capture_source = {
13059	.num_items = 5,
13060	.items = {
13061		{ "Mic", 0x0 },
13062		{ "Front Mic", 0x3 },
13063		{ "Line", 0x1 },
13064		{ "CD", 0x4 },
13065		{ "Mixer", 0x5 },
13066	},
13067};
13068
13069/* fill in the dac_nids table from the parsed pin configuration */
13070static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
13071				     const struct auto_pin_cfg *cfg)
13072{
13073	int i;
13074	hda_nid_t nid;
13075
13076	spec->multiout.dac_nids = spec->private_dac_nids;
13077	for (i = 0; i < cfg->line_outs; i++) {
13078		nid = cfg->line_out_pins[i];
13079		if (nid) {
13080			if (i >= ARRAY_SIZE(alc861_dac_nids))
13081				continue;
13082			spec->multiout.dac_nids[i] = alc861_dac_nids[i];
13083		}
13084	}
13085	spec->multiout.num_dacs = cfg->line_outs;
13086	return 0;
13087}
13088
13089/* add playback controls from the parsed DAC table */
13090static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
13091					     const struct auto_pin_cfg *cfg)
13092{
13093	char name[32];
13094	static const char *chname[4] = {
13095		"Front", "Surround", NULL /*CLFE*/, "Side"
13096	};
13097	hda_nid_t nid;
13098	int i, idx, err;
13099
13100	for (i = 0; i < cfg->line_outs; i++) {
13101		nid = spec->multiout.dac_nids[i];
13102		if (!nid)
13103			continue;
13104		if (nid == 0x05) {
13105			/* Center/LFE */
13106			err = add_control(spec, ALC_CTL_BIND_MUTE,
13107					  "Center Playback Switch",
13108					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13109							      HDA_OUTPUT));
13110			if (err < 0)
13111				return err;
13112			err = add_control(spec, ALC_CTL_BIND_MUTE,
13113					  "LFE Playback Switch",
13114					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13115							      HDA_OUTPUT));
13116			if (err < 0)
13117				return err;
13118		} else {
13119			for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13120			     idx++)
13121				if (nid == alc861_dac_nids[idx])
13122					break;
13123			sprintf(name, "%s Playback Switch", chname[idx]);
13124			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13125					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13126							      HDA_OUTPUT));
13127			if (err < 0)
13128				return err;
13129		}
13130	}
13131	return 0;
13132}
13133
13134static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13135{
13136	int err;
13137	hda_nid_t nid;
13138
13139	if (!pin)
13140		return 0;
13141
13142	if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13143		nid = 0x03;
13144		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13145				  "Headphone Playback Switch",
13146				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13147		if (err < 0)
13148			return err;
13149		spec->multiout.hp_nid = nid;
13150	}
13151	return 0;
13152}
13153
13154/* create playback/capture controls for input pins */
13155static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13156						const struct auto_pin_cfg *cfg)
13157{
13158	struct hda_input_mux *imux = &spec->private_imux;
13159	int i, err, idx, idx1;
13160
13161	for (i = 0; i < AUTO_PIN_LAST; i++) {
13162		switch (cfg->input_pins[i]) {
13163		case 0x0c:
13164			idx1 = 1;
13165			idx = 2;	/* Line In */
13166			break;
13167		case 0x0f:
13168			idx1 = 2;
13169			idx = 2;	/* Line In */
13170			break;
13171		case 0x0d:
13172			idx1 = 0;
13173			idx = 1;	/* Mic In */
13174			break;
13175		case 0x10:
13176			idx1 = 3;
13177			idx = 1;	/* Mic In */
13178			break;
13179		case 0x11:
13180			idx1 = 4;
13181			idx = 0;	/* CD */
13182			break;
13183		default:
13184			continue;
13185		}
13186
13187		err = new_analog_input(spec, cfg->input_pins[i],
13188				       auto_pin_cfg_labels[i], idx, 0x15);
13189		if (err < 0)
13190			return err;
13191
13192		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
13193		imux->items[imux->num_items].index = idx1;
13194		imux->num_items++;
13195	}
13196	return 0;
13197}
13198
13199static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13200					      hda_nid_t nid,
13201					      int pin_type, int dac_idx)
13202{
13203	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13204			    pin_type);
13205	snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13206			    AMP_OUT_UNMUTE);
13207}
13208
13209static void alc861_auto_init_multi_out(struct hda_codec *codec)
13210{
13211	struct alc_spec *spec = codec->spec;
13212	int i;
13213
13214	alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
13215	for (i = 0; i < spec->autocfg.line_outs; i++) {
13216		hda_nid_t nid = spec->autocfg.line_out_pins[i];
13217		int pin_type = get_pin_type(spec->autocfg.line_out_type);
13218		if (nid)
13219			alc861_auto_set_output_and_unmute(codec, nid, pin_type,
13220							  spec->multiout.dac_nids[i]);
13221	}
13222}
13223
13224static void alc861_auto_init_hp_out(struct hda_codec *codec)
13225{
13226	struct alc_spec *spec = codec->spec;
13227	hda_nid_t pin;
13228
13229	pin = spec->autocfg.hp_pins[0];
13230	if (pin) /* connect to front */
13231		alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13232						  spec->multiout.dac_nids[0]);
13233	pin = spec->autocfg.speaker_pins[0];
13234	if (pin)
13235		alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13236}
13237
13238static void alc861_auto_init_analog_input(struct hda_codec *codec)
13239{
13240	struct alc_spec *spec = codec->spec;
13241	int i;
13242
13243	for (i = 0; i < AUTO_PIN_LAST; i++) {
13244		hda_nid_t nid = spec->autocfg.input_pins[i];
13245		if (nid >= 0x0c && nid <= 0x11) {
13246			snd_hda_codec_write(codec, nid, 0,
13247					    AC_VERB_SET_PIN_WIDGET_CONTROL,
13248					    i <= AUTO_PIN_FRONT_MIC ?
13249					    PIN_VREF80 : PIN_IN);
13250		}
13251	}
13252}
13253
13254/* parse the BIOS configuration and set up the alc_spec */
13255/* return 1 if successful, 0 if the proper config is not found,
13256 * or a negative error code
13257 */
13258static int alc861_parse_auto_config(struct hda_codec *codec)
13259{
13260	struct alc_spec *spec = codec->spec;
13261	int err;
13262	static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13263
13264	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13265					   alc861_ignore);
13266	if (err < 0)
13267		return err;
13268	if (!spec->autocfg.line_outs)
13269		return 0; /* can't find valid BIOS pin config */
13270
13271	err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13272	if (err < 0)
13273		return err;
13274	err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13275	if (err < 0)
13276		return err;
13277	err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13278	if (err < 0)
13279		return err;
13280	err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13281	if (err < 0)
13282		return err;
13283
13284	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13285
13286	if (spec->autocfg.dig_out_pin)
13287		spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13288
13289	if (spec->kctls.list)
13290		add_mixer(spec, spec->kctls.list);
13291
13292	add_verb(spec, alc861_auto_init_verbs);
13293
13294	spec->num_mux_defs = 1;
13295	spec->input_mux = &spec->private_imux;
13296
13297	spec->adc_nids = alc861_adc_nids;
13298	spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
13299	set_capture_mixer(spec);
13300
13301	store_pin_configs(codec);
13302	return 1;
13303}
13304
13305/* additional initialization for auto-configuration model */
13306static void alc861_auto_init(struct hda_codec *codec)
13307{
13308	struct alc_spec *spec = codec->spec;
13309	alc861_auto_init_multi_out(codec);
13310	alc861_auto_init_hp_out(codec);
13311	alc861_auto_init_analog_input(codec);
13312	if (spec->unsol_event)
13313		alc_inithook(codec);
13314}
13315
13316#ifdef CONFIG_SND_HDA_POWER_SAVE
13317static struct hda_amp_list alc861_loopbacks[] = {
13318	{ 0x15, HDA_INPUT, 0 },
13319	{ 0x15, HDA_INPUT, 1 },
13320	{ 0x15, HDA_INPUT, 2 },
13321	{ 0x15, HDA_INPUT, 3 },
13322	{ } /* end */
13323};
13324#endif
13325
13326
13327/*
13328 * configuration and preset
13329 */
13330static const char *alc861_models[ALC861_MODEL_LAST] = {
13331	[ALC861_3ST]		= "3stack",
13332	[ALC660_3ST]		= "3stack-660",
13333	[ALC861_3ST_DIG]	= "3stack-dig",
13334	[ALC861_6ST_DIG]	= "6stack-dig",
13335	[ALC861_UNIWILL_M31]	= "uniwill-m31",
13336	[ALC861_TOSHIBA]	= "toshiba",
13337	[ALC861_ASUS]		= "asus",
13338	[ALC861_ASUS_LAPTOP]	= "asus-laptop",
13339	[ALC861_AUTO]		= "auto",
13340};
13341
13342static struct snd_pci_quirk alc861_cfg_tbl[] = {
13343	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
13344	SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13345	SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13346	SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
13347	SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
13348	SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
13349	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
13350	/* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
13351	 *        Any other models that need this preset?
13352	 */
13353	/* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
13354	SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
13355	SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
13356	SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
13357	SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
13358	SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
13359	/* FIXME: the below seems conflict */
13360	/* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
13361	SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
13362	SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
13363	{}
13364};
13365
13366static struct alc_config_preset alc861_presets[] = {
13367	[ALC861_3ST] = {
13368		.mixers = { alc861_3ST_mixer },
13369		.init_verbs = { alc861_threestack_init_verbs },
13370		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13371		.dac_nids = alc861_dac_nids,
13372		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13373		.channel_mode = alc861_threestack_modes,
13374		.need_dac_fix = 1,
13375		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13376		.adc_nids = alc861_adc_nids,
13377		.input_mux = &alc861_capture_source,
13378	},
13379	[ALC861_3ST_DIG] = {
13380		.mixers = { alc861_base_mixer },
13381		.init_verbs = { alc861_threestack_init_verbs },
13382		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13383		.dac_nids = alc861_dac_nids,
13384		.dig_out_nid = ALC861_DIGOUT_NID,
13385		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13386		.channel_mode = alc861_threestack_modes,
13387		.need_dac_fix = 1,
13388		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13389		.adc_nids = alc861_adc_nids,
13390		.input_mux = &alc861_capture_source,
13391	},
13392	[ALC861_6ST_DIG] = {
13393		.mixers = { alc861_base_mixer },
13394		.init_verbs = { alc861_base_init_verbs },
13395		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13396		.dac_nids = alc861_dac_nids,
13397		.dig_out_nid = ALC861_DIGOUT_NID,
13398		.num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
13399		.channel_mode = alc861_8ch_modes,
13400		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13401		.adc_nids = alc861_adc_nids,
13402		.input_mux = &alc861_capture_source,
13403	},
13404	[ALC660_3ST] = {
13405		.mixers = { alc861_3ST_mixer },
13406		.init_verbs = { alc861_threestack_init_verbs },
13407		.num_dacs = ARRAY_SIZE(alc660_dac_nids),
13408		.dac_nids = alc660_dac_nids,
13409		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13410		.channel_mode = alc861_threestack_modes,
13411		.need_dac_fix = 1,
13412		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13413		.adc_nids = alc861_adc_nids,
13414		.input_mux = &alc861_capture_source,
13415	},
13416	[ALC861_UNIWILL_M31] = {
13417		.mixers = { alc861_uniwill_m31_mixer },
13418		.init_verbs = { alc861_uniwill_m31_init_verbs },
13419		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13420		.dac_nids = alc861_dac_nids,
13421		.dig_out_nid = ALC861_DIGOUT_NID,
13422		.num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
13423		.channel_mode = alc861_uniwill_m31_modes,
13424		.need_dac_fix = 1,
13425		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13426		.adc_nids = alc861_adc_nids,
13427		.input_mux = &alc861_capture_source,
13428	},
13429	[ALC861_TOSHIBA] = {
13430		.mixers = { alc861_toshiba_mixer },
13431		.init_verbs = { alc861_base_init_verbs,
13432				alc861_toshiba_init_verbs },
13433		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13434		.dac_nids = alc861_dac_nids,
13435		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13436		.channel_mode = alc883_3ST_2ch_modes,
13437		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13438		.adc_nids = alc861_adc_nids,
13439		.input_mux = &alc861_capture_source,
13440		.unsol_event = alc861_toshiba_unsol_event,
13441		.init_hook = alc861_toshiba_automute,
13442	},
13443	[ALC861_ASUS] = {
13444		.mixers = { alc861_asus_mixer },
13445		.init_verbs = { alc861_asus_init_verbs },
13446		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13447		.dac_nids = alc861_dac_nids,
13448		.dig_out_nid = ALC861_DIGOUT_NID,
13449		.num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
13450		.channel_mode = alc861_asus_modes,
13451		.need_dac_fix = 1,
13452		.hp_nid = 0x06,
13453		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13454		.adc_nids = alc861_adc_nids,
13455		.input_mux = &alc861_capture_source,
13456	},
13457	[ALC861_ASUS_LAPTOP] = {
13458		.mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
13459		.init_verbs = { alc861_asus_init_verbs,
13460				alc861_asus_laptop_init_verbs },
13461		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13462		.dac_nids = alc861_dac_nids,
13463		.dig_out_nid = ALC861_DIGOUT_NID,
13464		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13465		.channel_mode = alc883_3ST_2ch_modes,
13466		.need_dac_fix = 1,
13467		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13468		.adc_nids = alc861_adc_nids,
13469		.input_mux = &alc861_capture_source,
13470	},
13471};
13472
13473
13474static int patch_alc861(struct hda_codec *codec)
13475{
13476	struct alc_spec *spec;
13477	int board_config;
13478	int err;
13479
13480	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13481	if (spec == NULL)
13482		return -ENOMEM;
13483
13484	codec->spec = spec;
13485
13486        board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
13487						  alc861_models,
13488						  alc861_cfg_tbl);
13489
13490	if (board_config < 0) {
13491		printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
13492		       "trying auto-probe from BIOS...\n");
13493		board_config = ALC861_AUTO;
13494	}
13495
13496	if (board_config == ALC861_AUTO) {
13497		/* automatic parse from the BIOS config */
13498		err = alc861_parse_auto_config(codec);
13499		if (err < 0) {
13500			alc_free(codec);
13501			return err;
13502		} else if (!err) {
13503			printk(KERN_INFO
13504			       "hda_codec: Cannot set up configuration "
13505			       "from BIOS.  Using base mode...\n");
13506		   board_config = ALC861_3ST_DIG;
13507		}
13508	}
13509
13510	if (board_config != ALC861_AUTO)
13511		setup_preset(spec, &alc861_presets[board_config]);
13512
13513	spec->stream_name_analog = "ALC861 Analog";
13514	spec->stream_analog_playback = &alc861_pcm_analog_playback;
13515	spec->stream_analog_capture = &alc861_pcm_analog_capture;
13516
13517	spec->stream_name_digital = "ALC861 Digital";
13518	spec->stream_digital_playback = &alc861_pcm_digital_playback;
13519	spec->stream_digital_capture = &alc861_pcm_digital_capture;
13520
13521	spec->vmaster_nid = 0x03;
13522
13523	codec->patch_ops = alc_patch_ops;
13524	if (board_config == ALC861_AUTO)
13525		spec->init_hook = alc861_auto_init;
13526#ifdef CONFIG_SND_HDA_POWER_SAVE
13527	if (!spec->loopback.amplist)
13528		spec->loopback.amplist = alc861_loopbacks;
13529#endif
13530
13531	return 0;
13532}
13533
13534/*
13535 * ALC861-VD support
13536 *
13537 * Based on ALC882
13538 *
13539 * In addition, an independent DAC
13540 */
13541#define ALC861VD_DIGOUT_NID	0x06
13542
13543static hda_nid_t alc861vd_dac_nids[4] = {
13544	/* front, surr, clfe, side surr */
13545	0x02, 0x03, 0x04, 0x05
13546};
13547
13548/* dac_nids for ALC660vd are in a different order - according to
13549 * Realtek's driver.
13550 * This should probably tesult in a different mixer for 6stack models
13551 * of ALC660vd codecs, but for now there is only 3stack mixer
13552 * - and it is the same as in 861vd.
13553 * adc_nids in ALC660vd are (is) the same as in 861vd
13554 */
13555static hda_nid_t alc660vd_dac_nids[3] = {
13556	/* front, rear, clfe, rear_surr */
13557	0x02, 0x04, 0x03
13558};
13559
13560static hda_nid_t alc861vd_adc_nids[1] = {
13561	/* ADC0 */
13562	0x09,
13563};
13564
13565static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
13566
13567/* input MUX */
13568/* FIXME: should be a matrix-type input source selection */
13569static struct hda_input_mux alc861vd_capture_source = {
13570	.num_items = 4,
13571	.items = {
13572		{ "Mic", 0x0 },
13573		{ "Front Mic", 0x1 },
13574		{ "Line", 0x2 },
13575		{ "CD", 0x4 },
13576	},
13577};
13578
13579static struct hda_input_mux alc861vd_dallas_capture_source = {
13580	.num_items = 2,
13581	.items = {
13582		{ "Ext Mic", 0x0 },
13583		{ "Int Mic", 0x1 },
13584	},
13585};
13586
13587static struct hda_input_mux alc861vd_hp_capture_source = {
13588	.num_items = 2,
13589	.items = {
13590		{ "Front Mic", 0x0 },
13591		{ "ATAPI Mic", 0x1 },
13592	},
13593};
13594
13595/*
13596 * 2ch mode
13597 */
13598static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
13599	{ 2, NULL }
13600};
13601
13602/*
13603 * 6ch mode
13604 */
13605static struct hda_verb alc861vd_6stack_ch6_init[] = {
13606	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13607	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13608	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13609	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13610	{ } /* end */
13611};
13612
13613/*
13614 * 8ch mode
13615 */
13616static struct hda_verb alc861vd_6stack_ch8_init[] = {
13617	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13618	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13619	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13620	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13621	{ } /* end */
13622};
13623
13624static struct hda_channel_mode alc861vd_6stack_modes[2] = {
13625	{ 6, alc861vd_6stack_ch6_init },
13626	{ 8, alc861vd_6stack_ch8_init },
13627};
13628
13629static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
13630	{
13631		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13632		.name = "Channel Mode",
13633		.info = alc_ch_mode_info,
13634		.get = alc_ch_mode_get,
13635		.put = alc_ch_mode_put,
13636	},
13637	{ } /* end */
13638};
13639
13640/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
13641 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
13642 */
13643static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
13644	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13645	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13646
13647	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13648	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
13649
13650	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
13651				HDA_OUTPUT),
13652	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
13653				HDA_OUTPUT),
13654	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13655	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
13656
13657	HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
13658	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
13659
13660	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13661
13662	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13663	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13664	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13665
13666	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13667	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13668	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13669
13670	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13671	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13672
13673	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13674	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13675
13676	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13677	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13678
13679	{ } /* end */
13680};
13681
13682static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
13683	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13684	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13685
13686	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13687
13688	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13689	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13690	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13691
13692	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13693	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13694	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13695
13696	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13697	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13698
13699	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13700	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13701
13702	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13703	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13704
13705	{ } /* end */
13706};
13707
13708static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
13709	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13710	/*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
13711	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13712
13713	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13714
13715	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13716	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13717	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13718
13719	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13720	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13721	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13722
13723	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13724	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13725
13726	{ } /* end */
13727};
13728
13729/* Pin assignment: Speaker=0x14, HP = 0x15,
13730 *                 Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
13731 */
13732static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
13733	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13734	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
13735	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13736	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13737	HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
13738	HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13739	HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13740	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
13741	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13742	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13743	HDA_CODEC_VOLUME("PC Beep Volume", 0x0b, 0x05, HDA_INPUT),
13744	HDA_CODEC_MUTE("PC Beep Switch", 0x0b, 0x05, HDA_INPUT),
13745	{ } /* end */
13746};
13747
13748/* Pin assignment: Speaker=0x14, Line-out = 0x15,
13749 *                 Front Mic=0x18, ATAPI Mic = 0x19,
13750 */
13751static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
13752	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13753	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13754	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13755	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13756	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13757	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13758	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13759	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13760
13761	{ } /* end */
13762};
13763
13764/*
13765 * generic initialization of ADC, input mixers and output mixers
13766 */
13767static struct hda_verb alc861vd_volume_init_verbs[] = {
13768	/*
13769	 * Unmute ADC0 and set the default input to mic-in
13770	 */
13771	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13772	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13773
13774	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
13775	 * the analog-loopback mixer widget
13776	 */
13777	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13778	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13779	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13780	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13781	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13782	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13783
13784	/* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
13785	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13786	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13787	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13788	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
13789
13790	/*
13791	 * Set up output mixers (0x02 - 0x05)
13792	 */
13793	/* set vol=0 to output mixers */
13794	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13795	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13796	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13797	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13798
13799	/* set up input amps for analog loopback */
13800	/* Amp Indices: DAC = 0, mixer = 1 */
13801	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13802	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13803	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13804	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13805	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13806	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13807	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13808	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13809
13810	{ }
13811};
13812
13813/*
13814 * 3-stack pin configuration:
13815 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
13816 */
13817static struct hda_verb alc861vd_3stack_init_verbs[] = {
13818	/*
13819	 * Set pin mode and muting
13820	 */
13821	/* set front pin widgets 0x14 for output */
13822	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13823	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13824	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13825
13826	/* Mic (rear) pin: input vref at 80% */
13827	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13828	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13829	/* Front Mic pin: input vref at 80% */
13830	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13831	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13832	/* Line In pin: input */
13833	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13834	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13835	/* Line-2 In: Headphone output (output 0 - 0x0c) */
13836	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13837	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13838	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13839	/* CD pin widget for input */
13840	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13841
13842	{ }
13843};
13844
13845/*
13846 * 6-stack pin configuration:
13847 */
13848static struct hda_verb alc861vd_6stack_init_verbs[] = {
13849	/*
13850	 * Set pin mode and muting
13851	 */
13852	/* set front pin widgets 0x14 for output */
13853	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13854	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13855	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13856
13857	/* Rear Pin: output 1 (0x0d) */
13858	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13859	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13860	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13861	/* CLFE Pin: output 2 (0x0e) */
13862	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13863	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13864	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
13865	/* Side Pin: output 3 (0x0f) */
13866	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13867	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13868	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
13869
13870	/* Mic (rear) pin: input vref at 80% */
13871	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13872	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13873	/* Front Mic pin: input vref at 80% */
13874	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13875	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13876	/* Line In pin: input */
13877	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13878	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13879	/* Line-2 In: Headphone output (output 0 - 0x0c) */
13880	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13881	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13882	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13883	/* CD pin widget for input */
13884	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13885
13886	{ }
13887};
13888
13889static struct hda_verb alc861vd_eapd_verbs[] = {
13890	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13891	{ }
13892};
13893
13894static struct hda_verb alc660vd_eapd_verbs[] = {
13895	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13896	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13897	{ }
13898};
13899
13900static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
13901	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13902	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13903	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
13904	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13905	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13906	{}
13907};
13908
13909/* toggle speaker-output according to the hp-jack state */
13910static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
13911{
13912	unsigned int present;
13913	unsigned char bits;
13914
13915	present = snd_hda_codec_read(codec, 0x1b, 0,
13916				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13917	bits = present ? HDA_AMP_MUTE : 0;
13918	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13919				 HDA_AMP_MUTE, bits);
13920}
13921
13922static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
13923{
13924	unsigned int present;
13925	unsigned char bits;
13926
13927	present = snd_hda_codec_read(codec, 0x18, 0,
13928				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13929	bits = present ? HDA_AMP_MUTE : 0;
13930	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
13931				 HDA_AMP_MUTE, bits);
13932}
13933
13934static void alc861vd_lenovo_automute(struct hda_codec *codec)
13935{
13936	alc861vd_lenovo_hp_automute(codec);
13937	alc861vd_lenovo_mic_automute(codec);
13938}
13939
13940static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
13941					unsigned int res)
13942{
13943	switch (res >> 26) {
13944	case ALC880_HP_EVENT:
13945		alc861vd_lenovo_hp_automute(codec);
13946		break;
13947	case ALC880_MIC_EVENT:
13948		alc861vd_lenovo_mic_automute(codec);
13949		break;
13950	}
13951}
13952
13953static struct hda_verb alc861vd_dallas_verbs[] = {
13954	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13955	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13956	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13957	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13958
13959	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13960	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13961	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13962	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13963	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13964	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13965	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13966	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13967
13968	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13969	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13970	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13971	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13972	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13973	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13974	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13975	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13976
13977	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
13978	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13979	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
13980	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13981	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13982	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13983	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13984	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13985
13986	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13987	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13988	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13989	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13990
13991	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13992	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13993	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13994
13995	{ } /* end */
13996};
13997
13998/* toggle speaker-output according to the hp-jack state */
13999static void alc861vd_dallas_automute(struct hda_codec *codec)
14000{
14001	unsigned int present;
14002
14003	present = snd_hda_codec_read(codec, 0x15, 0,
14004				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14005	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14006				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
14007}
14008
14009static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
14010{
14011	if ((res >> 26) == ALC880_HP_EVENT)
14012		alc861vd_dallas_automute(codec);
14013}
14014
14015#ifdef CONFIG_SND_HDA_POWER_SAVE
14016#define alc861vd_loopbacks	alc880_loopbacks
14017#endif
14018
14019/* pcm configuration: identiacal with ALC880 */
14020#define alc861vd_pcm_analog_playback	alc880_pcm_analog_playback
14021#define alc861vd_pcm_analog_capture	alc880_pcm_analog_capture
14022#define alc861vd_pcm_digital_playback	alc880_pcm_digital_playback
14023#define alc861vd_pcm_digital_capture	alc880_pcm_digital_capture
14024
14025/*
14026 * configuration and preset
14027 */
14028static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14029	[ALC660VD_3ST]		= "3stack-660",
14030	[ALC660VD_3ST_DIG]	= "3stack-660-digout",
14031	[ALC660VD_ASUS_V1S]	= "asus-v1s",
14032	[ALC861VD_3ST]		= "3stack",
14033	[ALC861VD_3ST_DIG]	= "3stack-digout",
14034	[ALC861VD_6ST_DIG]	= "6stack-digout",
14035	[ALC861VD_LENOVO]	= "lenovo",
14036	[ALC861VD_DALLAS]	= "dallas",
14037	[ALC861VD_HP]		= "hp",
14038	[ALC861VD_AUTO]		= "auto",
14039};
14040
14041static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
14042	SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14043	SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
14044	SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
14045	SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
14046	SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
14047	SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
14048	SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
14049	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
14050	/*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
14051	SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
14052	SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
14053	SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
14054	SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
14055	SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
14056	SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
14057	SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO),
14058	SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
14059	{}
14060};
14061
14062static struct alc_config_preset alc861vd_presets[] = {
14063	[ALC660VD_3ST] = {
14064		.mixers = { alc861vd_3st_mixer },
14065		.init_verbs = { alc861vd_volume_init_verbs,
14066				 alc861vd_3stack_init_verbs },
14067		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14068		.dac_nids = alc660vd_dac_nids,
14069		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14070		.channel_mode = alc861vd_3stack_2ch_modes,
14071		.input_mux = &alc861vd_capture_source,
14072	},
14073	[ALC660VD_3ST_DIG] = {
14074		.mixers = { alc861vd_3st_mixer },
14075		.init_verbs = { alc861vd_volume_init_verbs,
14076				 alc861vd_3stack_init_verbs },
14077		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14078		.dac_nids = alc660vd_dac_nids,
14079		.dig_out_nid = ALC861VD_DIGOUT_NID,
14080		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14081		.channel_mode = alc861vd_3stack_2ch_modes,
14082		.input_mux = &alc861vd_capture_source,
14083	},
14084	[ALC861VD_3ST] = {
14085		.mixers = { alc861vd_3st_mixer },
14086		.init_verbs = { alc861vd_volume_init_verbs,
14087				 alc861vd_3stack_init_verbs },
14088		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14089		.dac_nids = alc861vd_dac_nids,
14090		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14091		.channel_mode = alc861vd_3stack_2ch_modes,
14092		.input_mux = &alc861vd_capture_source,
14093	},
14094	[ALC861VD_3ST_DIG] = {
14095		.mixers = { alc861vd_3st_mixer },
14096		.init_verbs = { alc861vd_volume_init_verbs,
14097		 		 alc861vd_3stack_init_verbs },
14098		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14099		.dac_nids = alc861vd_dac_nids,
14100		.dig_out_nid = ALC861VD_DIGOUT_NID,
14101		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14102		.channel_mode = alc861vd_3stack_2ch_modes,
14103		.input_mux = &alc861vd_capture_source,
14104	},
14105	[ALC861VD_6ST_DIG] = {
14106		.mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14107		.init_verbs = { alc861vd_volume_init_verbs,
14108				alc861vd_6stack_init_verbs },
14109		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14110		.dac_nids = alc861vd_dac_nids,
14111		.dig_out_nid = ALC861VD_DIGOUT_NID,
14112		.num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14113		.channel_mode = alc861vd_6stack_modes,
14114		.input_mux = &alc861vd_capture_source,
14115	},
14116	[ALC861VD_LENOVO] = {
14117		.mixers = { alc861vd_lenovo_mixer },
14118		.init_verbs = { alc861vd_volume_init_verbs,
14119				alc861vd_3stack_init_verbs,
14120				alc861vd_eapd_verbs,
14121				alc861vd_lenovo_unsol_verbs },
14122		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14123		.dac_nids = alc660vd_dac_nids,
14124		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14125		.channel_mode = alc861vd_3stack_2ch_modes,
14126		.input_mux = &alc861vd_capture_source,
14127		.unsol_event = alc861vd_lenovo_unsol_event,
14128		.init_hook = alc861vd_lenovo_automute,
14129	},
14130	[ALC861VD_DALLAS] = {
14131		.mixers = { alc861vd_dallas_mixer },
14132		.init_verbs = { alc861vd_dallas_verbs },
14133		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14134		.dac_nids = alc861vd_dac_nids,
14135		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14136		.channel_mode = alc861vd_3stack_2ch_modes,
14137		.input_mux = &alc861vd_dallas_capture_source,
14138		.unsol_event = alc861vd_dallas_unsol_event,
14139		.init_hook = alc861vd_dallas_automute,
14140	},
14141	[ALC861VD_HP] = {
14142		.mixers = { alc861vd_hp_mixer },
14143		.init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14144		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14145		.dac_nids = alc861vd_dac_nids,
14146		.dig_out_nid = ALC861VD_DIGOUT_NID,
14147		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14148		.channel_mode = alc861vd_3stack_2ch_modes,
14149		.input_mux = &alc861vd_hp_capture_source,
14150		.unsol_event = alc861vd_dallas_unsol_event,
14151		.init_hook = alc861vd_dallas_automute,
14152	},
14153	[ALC660VD_ASUS_V1S] = {
14154		.mixers = { alc861vd_lenovo_mixer },
14155		.init_verbs = { alc861vd_volume_init_verbs,
14156				alc861vd_3stack_init_verbs,
14157				alc861vd_eapd_verbs,
14158				alc861vd_lenovo_unsol_verbs },
14159		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14160		.dac_nids = alc660vd_dac_nids,
14161		.dig_out_nid = ALC861VD_DIGOUT_NID,
14162		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14163		.channel_mode = alc861vd_3stack_2ch_modes,
14164		.input_mux = &alc861vd_capture_source,
14165		.unsol_event = alc861vd_lenovo_unsol_event,
14166		.init_hook = alc861vd_lenovo_automute,
14167	},
14168};
14169
14170/*
14171 * BIOS auto configuration
14172 */
14173static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14174				hda_nid_t nid, int pin_type, int dac_idx)
14175{
14176	alc_set_pin_output(codec, nid, pin_type);
14177}
14178
14179static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14180{
14181	struct alc_spec *spec = codec->spec;
14182	int i;
14183
14184	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
14185	for (i = 0; i <= HDA_SIDE; i++) {
14186		hda_nid_t nid = spec->autocfg.line_out_pins[i];
14187		int pin_type = get_pin_type(spec->autocfg.line_out_type);
14188		if (nid)
14189			alc861vd_auto_set_output_and_unmute(codec, nid,
14190							    pin_type, i);
14191	}
14192}
14193
14194
14195static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14196{
14197	struct alc_spec *spec = codec->spec;
14198	hda_nid_t pin;
14199
14200	pin = spec->autocfg.hp_pins[0];
14201	if (pin) /* connect to front and  use dac 0 */
14202		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
14203	pin = spec->autocfg.speaker_pins[0];
14204	if (pin)
14205		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14206}
14207
14208#define alc861vd_is_input_pin(nid)	alc880_is_input_pin(nid)
14209#define ALC861VD_PIN_CD_NID		ALC880_PIN_CD_NID
14210
14211static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14212{
14213	struct alc_spec *spec = codec->spec;
14214	int i;
14215
14216	for (i = 0; i < AUTO_PIN_LAST; i++) {
14217		hda_nid_t nid = spec->autocfg.input_pins[i];
14218		if (alc861vd_is_input_pin(nid)) {
14219			snd_hda_codec_write(codec, nid, 0,
14220					AC_VERB_SET_PIN_WIDGET_CONTROL,
14221					i <= AUTO_PIN_FRONT_MIC ?
14222							PIN_VREF80 : PIN_IN);
14223			if (nid != ALC861VD_PIN_CD_NID)
14224				snd_hda_codec_write(codec, nid, 0,
14225						AC_VERB_SET_AMP_GAIN_MUTE,
14226						AMP_OUT_MUTE);
14227		}
14228	}
14229}
14230
14231#define alc861vd_auto_init_input_src	alc882_auto_init_input_src
14232
14233#define alc861vd_idx_to_mixer_vol(nid)		((nid) + 0x02)
14234#define alc861vd_idx_to_mixer_switch(nid)	((nid) + 0x0c)
14235
14236/* add playback controls from the parsed DAC table */
14237/* Based on ALC880 version. But ALC861VD has separate,
14238 * different NIDs for mute/unmute switch and volume control */
14239static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14240					     const struct auto_pin_cfg *cfg)
14241{
14242	char name[32];
14243	static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14244	hda_nid_t nid_v, nid_s;
14245	int i, err;
14246
14247	for (i = 0; i < cfg->line_outs; i++) {
14248		if (!spec->multiout.dac_nids[i])
14249			continue;
14250		nid_v = alc861vd_idx_to_mixer_vol(
14251				alc880_dac_to_idx(
14252					spec->multiout.dac_nids[i]));
14253		nid_s = alc861vd_idx_to_mixer_switch(
14254				alc880_dac_to_idx(
14255					spec->multiout.dac_nids[i]));
14256
14257		if (i == 2) {
14258			/* Center/LFE */
14259			err = add_control(spec, ALC_CTL_WIDGET_VOL,
14260					  "Center Playback Volume",
14261					  HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14262							      HDA_OUTPUT));
14263			if (err < 0)
14264				return err;
14265			err = add_control(spec, ALC_CTL_WIDGET_VOL,
14266					  "LFE Playback Volume",
14267					  HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14268							      HDA_OUTPUT));
14269			if (err < 0)
14270				return err;
14271			err = add_control(spec, ALC_CTL_BIND_MUTE,
14272					  "Center Playback Switch",
14273					  HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14274							      HDA_INPUT));
14275			if (err < 0)
14276				return err;
14277			err = add_control(spec, ALC_CTL_BIND_MUTE,
14278					  "LFE Playback Switch",
14279					  HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14280							      HDA_INPUT));
14281			if (err < 0)
14282				return err;
14283		} else {
14284			sprintf(name, "%s Playback Volume", chname[i]);
14285			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14286					  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14287							      HDA_OUTPUT));
14288			if (err < 0)
14289				return err;
14290			sprintf(name, "%s Playback Switch", chname[i]);
14291			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14292					  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
14293							      HDA_INPUT));
14294			if (err < 0)
14295				return err;
14296		}
14297	}
14298	return 0;
14299}
14300
14301/* add playback controls for speaker and HP outputs */
14302/* Based on ALC880 version. But ALC861VD has separate,
14303 * different NIDs for mute/unmute switch and volume control */
14304static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
14305					hda_nid_t pin, const char *pfx)
14306{
14307	hda_nid_t nid_v, nid_s;
14308	int err;
14309	char name[32];
14310
14311	if (!pin)
14312		return 0;
14313
14314	if (alc880_is_fixed_pin(pin)) {
14315		nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14316		/* specify the DAC as the extra output */
14317		if (!spec->multiout.hp_nid)
14318			spec->multiout.hp_nid = nid_v;
14319		else
14320			spec->multiout.extra_out_nid[0] = nid_v;
14321		/* control HP volume/switch on the output mixer amp */
14322		nid_v = alc861vd_idx_to_mixer_vol(
14323				alc880_fixed_pin_idx(pin));
14324		nid_s = alc861vd_idx_to_mixer_switch(
14325				alc880_fixed_pin_idx(pin));
14326
14327		sprintf(name, "%s Playback Volume", pfx);
14328		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14329				  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
14330		if (err < 0)
14331			return err;
14332		sprintf(name, "%s Playback Switch", pfx);
14333		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14334				  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
14335		if (err < 0)
14336			return err;
14337	} else if (alc880_is_multi_pin(pin)) {
14338		/* set manual connection */
14339		/* we have only a switch on HP-out PIN */
14340		sprintf(name, "%s Playback Switch", pfx);
14341		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14342				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
14343		if (err < 0)
14344			return err;
14345	}
14346	return 0;
14347}
14348
14349/* parse the BIOS configuration and set up the alc_spec
14350 * return 1 if successful, 0 if the proper config is not found,
14351 * or a negative error code
14352 * Based on ALC880 version - had to change it to override
14353 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
14354static int alc861vd_parse_auto_config(struct hda_codec *codec)
14355{
14356	struct alc_spec *spec = codec->spec;
14357	int err;
14358	static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
14359
14360	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14361					   alc861vd_ignore);
14362	if (err < 0)
14363		return err;
14364	if (!spec->autocfg.line_outs)
14365		return 0; /* can't find valid BIOS pin config */
14366
14367	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
14368	if (err < 0)
14369		return err;
14370	err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
14371	if (err < 0)
14372		return err;
14373	err = alc861vd_auto_create_extra_out(spec,
14374					     spec->autocfg.speaker_pins[0],
14375					     "Speaker");
14376	if (err < 0)
14377		return err;
14378	err = alc861vd_auto_create_extra_out(spec,
14379					     spec->autocfg.hp_pins[0],
14380					     "Headphone");
14381	if (err < 0)
14382		return err;
14383	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
14384	if (err < 0)
14385		return err;
14386
14387	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14388
14389	if (spec->autocfg.dig_out_pin)
14390		spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
14391
14392	if (spec->kctls.list)
14393		add_mixer(spec, spec->kctls.list);
14394
14395	add_verb(spec, alc861vd_volume_init_verbs);
14396
14397	spec->num_mux_defs = 1;
14398	spec->input_mux = &spec->private_imux;
14399
14400	err = alc_auto_add_mic_boost(codec);
14401	if (err < 0)
14402		return err;
14403
14404	store_pin_configs(codec);
14405	return 1;
14406}
14407
14408/* additional initialization for auto-configuration model */
14409static void alc861vd_auto_init(struct hda_codec *codec)
14410{
14411	struct alc_spec *spec = codec->spec;
14412	alc861vd_auto_init_multi_out(codec);
14413	alc861vd_auto_init_hp_out(codec);
14414	alc861vd_auto_init_analog_input(codec);
14415	alc861vd_auto_init_input_src(codec);
14416	if (spec->unsol_event)
14417		alc_inithook(codec);
14418}
14419
14420static int patch_alc861vd(struct hda_codec *codec)
14421{
14422	struct alc_spec *spec;
14423	int err, board_config;
14424
14425	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14426	if (spec == NULL)
14427		return -ENOMEM;
14428
14429	codec->spec = spec;
14430
14431	board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
14432						  alc861vd_models,
14433						  alc861vd_cfg_tbl);
14434
14435	if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
14436		printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
14437			"ALC861VD, trying auto-probe from BIOS...\n");
14438		board_config = ALC861VD_AUTO;
14439	}
14440
14441	if (board_config == ALC861VD_AUTO) {
14442		/* automatic parse from the BIOS config */
14443		err = alc861vd_parse_auto_config(codec);
14444		if (err < 0) {
14445			alc_free(codec);
14446			return err;
14447		} else if (!err) {
14448			printk(KERN_INFO
14449			       "hda_codec: Cannot set up configuration "
14450			       "from BIOS.  Using base mode...\n");
14451			board_config = ALC861VD_3ST;
14452		}
14453	}
14454
14455	if (board_config != ALC861VD_AUTO)
14456		setup_preset(spec, &alc861vd_presets[board_config]);
14457
14458	if (codec->vendor_id == 0x10ec0660) {
14459		spec->stream_name_analog = "ALC660-VD Analog";
14460		spec->stream_name_digital = "ALC660-VD Digital";
14461		/* always turn on EAPD */
14462		add_verb(spec, alc660vd_eapd_verbs);
14463	} else {
14464		spec->stream_name_analog = "ALC861VD Analog";
14465		spec->stream_name_digital = "ALC861VD Digital";
14466	}
14467
14468	spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
14469	spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
14470
14471	spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
14472	spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
14473
14474	spec->adc_nids = alc861vd_adc_nids;
14475	spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
14476	spec->capsrc_nids = alc861vd_capsrc_nids;
14477	spec->is_mix_capture = 1;
14478
14479	set_capture_mixer(spec);
14480
14481	spec->vmaster_nid = 0x02;
14482
14483	codec->patch_ops = alc_patch_ops;
14484
14485	if (board_config == ALC861VD_AUTO)
14486		spec->init_hook = alc861vd_auto_init;
14487#ifdef CONFIG_SND_HDA_POWER_SAVE
14488	if (!spec->loopback.amplist)
14489		spec->loopback.amplist = alc861vd_loopbacks;
14490#endif
14491
14492	return 0;
14493}
14494
14495/*
14496 * ALC662 support
14497 *
14498 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
14499 * configuration.  Each pin widget can choose any input DACs and a mixer.
14500 * Each ADC is connected from a mixer of all inputs.  This makes possible
14501 * 6-channel independent captures.
14502 *
14503 * In addition, an independent DAC for the multi-playback (not used in this
14504 * driver yet).
14505 */
14506#define ALC662_DIGOUT_NID	0x06
14507#define ALC662_DIGIN_NID	0x0a
14508
14509static hda_nid_t alc662_dac_nids[4] = {
14510	/* front, rear, clfe, rear_surr */
14511	0x02, 0x03, 0x04
14512};
14513
14514static hda_nid_t alc662_adc_nids[1] = {
14515	/* ADC1-2 */
14516	0x09,
14517};
14518
14519static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
14520
14521/* input MUX */
14522/* FIXME: should be a matrix-type input source selection */
14523static struct hda_input_mux alc662_capture_source = {
14524	.num_items = 4,
14525	.items = {
14526		{ "Mic", 0x0 },
14527		{ "Front Mic", 0x1 },
14528		{ "Line", 0x2 },
14529		{ "CD", 0x4 },
14530	},
14531};
14532
14533static struct hda_input_mux alc662_lenovo_101e_capture_source = {
14534	.num_items = 2,
14535	.items = {
14536		{ "Mic", 0x1 },
14537		{ "Line", 0x2 },
14538	},
14539};
14540
14541static struct hda_input_mux alc662_eeepc_capture_source = {
14542	.num_items = 2,
14543	.items = {
14544		{ "i-Mic", 0x1 },
14545		{ "e-Mic", 0x0 },
14546	},
14547};
14548
14549static struct hda_input_mux alc663_capture_source = {
14550	.num_items = 3,
14551	.items = {
14552		{ "Mic", 0x0 },
14553		{ "Front Mic", 0x1 },
14554		{ "Line", 0x2 },
14555	},
14556};
14557
14558static struct hda_input_mux alc663_m51va_capture_source = {
14559	.num_items = 2,
14560	.items = {
14561		{ "Ext-Mic", 0x0 },
14562		{ "D-Mic", 0x9 },
14563	},
14564};
14565
14566/*
14567 * 2ch mode
14568 */
14569static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
14570	{ 2, NULL }
14571};
14572
14573/*
14574 * 2ch mode
14575 */
14576static struct hda_verb alc662_3ST_ch2_init[] = {
14577	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
14578	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14579	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
14580	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14581	{ } /* end */
14582};
14583
14584/*
14585 * 6ch mode
14586 */
14587static struct hda_verb alc662_3ST_ch6_init[] = {
14588	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14589	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14590	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
14591	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14592	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14593	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
14594	{ } /* end */
14595};
14596
14597static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
14598	{ 2, alc662_3ST_ch2_init },
14599	{ 6, alc662_3ST_ch6_init },
14600};
14601
14602/*
14603 * 2ch mode
14604 */
14605static struct hda_verb alc662_sixstack_ch6_init[] = {
14606	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14607	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14608	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14609	{ } /* end */
14610};
14611
14612/*
14613 * 6ch mode
14614 */
14615static struct hda_verb alc662_sixstack_ch8_init[] = {
14616	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14617	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14618	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14619	{ } /* end */
14620};
14621
14622static struct hda_channel_mode alc662_5stack_modes[2] = {
14623	{ 2, alc662_sixstack_ch6_init },
14624	{ 6, alc662_sixstack_ch8_init },
14625};
14626
14627/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14628 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14629 */
14630
14631static struct snd_kcontrol_new alc662_base_mixer[] = {
14632	/* output mixer control */
14633	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
14634	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14635	HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
14636	HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14637	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14638	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14639	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14640	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14641	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14642
14643	/*Input mixer control */
14644	HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
14645	HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
14646	HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
14647	HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
14648	HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
14649	HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
14650	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
14651	HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
14652	{ } /* end */
14653};
14654
14655static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
14656	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14657	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14658	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14659	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14660	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14661	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14662	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14663	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14664	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14665	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14666	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14667	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14668	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14669	{ } /* end */
14670};
14671
14672static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
14673	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14674	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14675	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14676	HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14677	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14678	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14679	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14680	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14681	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14682	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14683	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14684	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14685	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14686	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14687	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14688	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14689	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14690	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14691	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14692	{ } /* end */
14693};
14694
14695static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
14696	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14697	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
14698	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14699	HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
14700	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14701	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14702	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14703	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14704	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14705	{ } /* end */
14706};
14707
14708static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
14709	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14710
14711	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14712	HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14713
14714	HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
14715	HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14716	HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14717
14718	HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
14719	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14720	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14721	{ } /* end */
14722};
14723
14724static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
14725	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14726	HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14727	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14728	HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
14729	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14730	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14731	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
14732	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
14733	HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14734	HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
14735	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14736	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14737	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14738	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14739	{ } /* end */
14740};
14741
14742static struct hda_bind_ctls alc663_asus_bind_master_vol = {
14743	.ops = &snd_hda_bind_vol,
14744	.values = {
14745		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14746		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
14747		0
14748	},
14749};
14750
14751static struct hda_bind_ctls alc663_asus_one_bind_switch = {
14752	.ops = &snd_hda_bind_sw,
14753	.values = {
14754		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14755		HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14756		0
14757	},
14758};
14759
14760static struct snd_kcontrol_new alc663_m51va_mixer[] = {
14761	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14762	HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
14763	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14764	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14765	{ } /* end */
14766};
14767
14768static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
14769	.ops = &snd_hda_bind_sw,
14770	.values = {
14771		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14772		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14773		HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14774		0
14775	},
14776};
14777
14778static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
14779	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14780	HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
14781	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14782	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14783	HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14784	HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14785
14786	{ } /* end */
14787};
14788
14789static struct hda_bind_ctls alc663_asus_four_bind_switch = {
14790	.ops = &snd_hda_bind_sw,
14791	.values = {
14792		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14793		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14794		HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
14795		0
14796	},
14797};
14798
14799static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
14800	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14801	HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
14802	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14803	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14804	HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14805	HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14806	{ } /* end */
14807};
14808
14809static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
14810	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14811	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14812	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14813	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14814	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14815	HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14816	HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14817	{ } /* end */
14818};
14819
14820static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
14821	.ops = &snd_hda_bind_vol,
14822	.values = {
14823		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14824		HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
14825		0
14826	},
14827};
14828
14829static struct hda_bind_ctls alc663_asus_two_bind_switch = {
14830	.ops = &snd_hda_bind_sw,
14831	.values = {
14832		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14833		HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
14834		0
14835	},
14836};
14837
14838static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
14839	HDA_BIND_VOL("Master Playback Volume",
14840				&alc663_asus_two_bind_master_vol),
14841	HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14842	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14843	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14844	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14845	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14846	{ } /* end */
14847};
14848
14849static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
14850	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14851	HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14852	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14853	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14854	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14855	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14856	{ } /* end */
14857};
14858
14859static struct snd_kcontrol_new alc663_g71v_mixer[] = {
14860	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14861	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14862	HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14863	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14864	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14865
14866	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14867	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14868	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14869	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14870	{ } /* end */
14871};
14872
14873static struct snd_kcontrol_new alc663_g50v_mixer[] = {
14874	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14875	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14876	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14877
14878	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14879	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14880	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14881	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14882	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14883	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14884	{ } /* end */
14885};
14886
14887static struct snd_kcontrol_new alc662_chmode_mixer[] = {
14888	{
14889		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14890		.name = "Channel Mode",
14891		.info = alc_ch_mode_info,
14892		.get = alc_ch_mode_get,
14893		.put = alc_ch_mode_put,
14894	},
14895	{ } /* end */
14896};
14897
14898static struct hda_verb alc662_init_verbs[] = {
14899	/* ADC: mute amp left and right */
14900	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14901	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14902	/* Front mixer: unmute input/output amp left and right (volume = 0) */
14903
14904	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14905	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14906	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14907	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14908	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14909
14910	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14911	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14912	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14913	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14914	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14915	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14916
14917	/* Front Pin: output 0 (0x0c) */
14918	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14919	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14920
14921	/* Rear Pin: output 1 (0x0d) */
14922	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14923	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14924
14925	/* CLFE Pin: output 2 (0x0e) */
14926	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14927	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14928
14929	/* Mic (rear) pin: input vref at 80% */
14930	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14931	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14932	/* Front Mic pin: input vref at 80% */
14933	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14934	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14935	/* Line In pin: input */
14936	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14937	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14938	/* Line-2 In: Headphone output (output 0 - 0x0c) */
14939	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14940	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14941	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14942	/* CD pin widget for input */
14943	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14944
14945	/* FIXME: use matrix-type input source selection */
14946	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
14947	/* Input mixer */
14948	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14949	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14950	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14951	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14952
14953	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14954	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14955	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14956	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14957
14958	/* always trun on EAPD */
14959	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14960	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14961
14962	{ }
14963};
14964
14965static struct hda_verb alc662_sue_init_verbs[] = {
14966	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
14967	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
14968	{}
14969};
14970
14971static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
14972	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14973	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14974	{}
14975};
14976
14977/* Set Unsolicited Event*/
14978static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
14979	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14980	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14981	{}
14982};
14983
14984/*
14985 * generic initialization of ADC, input mixers and output mixers
14986 */
14987static struct hda_verb alc662_auto_init_verbs[] = {
14988	/*
14989	 * Unmute ADC and set the default input to mic-in
14990	 */
14991	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14992	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14993
14994	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
14995	 * mixer widget
14996	 * Note: PASD motherboards uses the Line In 2 as the input for front
14997	 * panel mic (mic 2)
14998	 */
14999	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
15000	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15001	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15002	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15003	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15004	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15005
15006	/*
15007	 * Set up output mixers (0x0c - 0x0f)
15008	 */
15009	/* set vol=0 to output mixers */
15010	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15011	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15012	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15013
15014	/* set up input amps for analog loopback */
15015	/* Amp Indices: DAC = 0, mixer = 1 */
15016	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15017	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15018	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15019	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15020	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15021	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15022
15023
15024	/* FIXME: use matrix-type input source selection */
15025	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15026	/* Input mixer */
15027	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15028	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15029	{ }
15030};
15031
15032/* additional verbs for ALC663 */
15033static struct hda_verb alc663_auto_init_verbs[] = {
15034	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15035	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15036	{ }
15037};
15038
15039static struct hda_verb alc663_m51va_init_verbs[] = {
15040	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15041	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15042	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15043	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15044	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
15045	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15046	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15047	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15048	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15049	{}
15050};
15051
15052static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15053	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15054	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15055	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
15056	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15057	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15058	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15059	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15060	{}
15061};
15062
15063static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15064	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15065	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15066	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15067	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
15068	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15069	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15070	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15071	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15072	{}
15073};
15074
15075static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15076	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15077	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15078	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
15079	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15080	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15081	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15082	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15083	{}
15084};
15085
15086static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15087	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15088	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15089	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15090	{0x21, AC_VERB_SET_CONNECT_SEL, 0x0},	/* Headphone */
15091	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15092	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15093	{0x15, AC_VERB_SET_CONNECT_SEL, 0x0},	/* Headphone */
15094	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15095	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15096	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15097	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15098	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15099	{}
15100};
15101
15102static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15103	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15104	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15105	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15106	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
15107	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15108	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15109	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
15110	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15111	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15112	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15113	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15114	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15115	{}
15116};
15117
15118static struct hda_verb alc663_g71v_init_verbs[] = {
15119	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15120	/* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15121	/* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15122
15123	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15124	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15125	{0x21, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
15126
15127	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15128	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15129	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15130	{}
15131};
15132
15133static struct hda_verb alc663_g50v_init_verbs[] = {
15134	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15135	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15136	{0x21, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
15137
15138	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15139	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15140	{}
15141};
15142
15143static struct hda_verb alc662_ecs_init_verbs[] = {
15144	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15145	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15146	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15147	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15148	{}
15149};
15150
15151static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15152	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15153	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15154	{ } /* end */
15155};
15156
15157static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15158{
15159	unsigned int present;
15160	unsigned char bits;
15161
15162	present = snd_hda_codec_read(codec, 0x14, 0,
15163				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15164	bits = present ? HDA_AMP_MUTE : 0;
15165	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15166				 HDA_AMP_MUTE, bits);
15167}
15168
15169static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15170{
15171	unsigned int present;
15172	unsigned char bits;
15173
15174 	present = snd_hda_codec_read(codec, 0x1b, 0,
15175				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15176	bits = present ? HDA_AMP_MUTE : 0;
15177	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15178				 HDA_AMP_MUTE, bits);
15179	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15180				 HDA_AMP_MUTE, bits);
15181}
15182
15183static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15184					   unsigned int res)
15185{
15186	if ((res >> 26) == ALC880_HP_EVENT)
15187		alc662_lenovo_101e_all_automute(codec);
15188	if ((res >> 26) == ALC880_FRONT_EVENT)
15189		alc662_lenovo_101e_ispeaker_automute(codec);
15190}
15191
15192static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15193{
15194	unsigned int present;
15195
15196	present = snd_hda_codec_read(codec, 0x18, 0,
15197				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15198	snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15199			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15200	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15201			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15202	snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15203			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15204	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15205			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15206}
15207
15208/* unsolicited event for HP jack sensing */
15209static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15210				     unsigned int res)
15211{
15212	if ((res >> 26) == ALC880_HP_EVENT)
15213		alc262_hippo1_automute( codec );
15214
15215	if ((res >> 26) == ALC880_MIC_EVENT)
15216		alc662_eeepc_mic_automute(codec);
15217}
15218
15219static void alc662_eeepc_inithook(struct hda_codec *codec)
15220{
15221	alc262_hippo1_automute( codec );
15222	alc662_eeepc_mic_automute(codec);
15223}
15224
15225static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
15226{
15227	unsigned int mute;
15228	unsigned int present;
15229
15230	snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
15231	present = snd_hda_codec_read(codec, 0x14, 0,
15232				     AC_VERB_GET_PIN_SENSE, 0);
15233	present = (present & 0x80000000) != 0;
15234	if (present) {
15235		/* mute internal speaker */
15236		snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15237					HDA_AMP_MUTE, HDA_AMP_MUTE);
15238	} else {
15239		/* unmute internal speaker if necessary */
15240		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
15241		snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15242					HDA_AMP_MUTE, mute);
15243	}
15244}
15245
15246/* unsolicited event for HP jack sensing */
15247static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
15248					  unsigned int res)
15249{
15250	if ((res >> 26) == ALC880_HP_EVENT)
15251		alc662_eeepc_ep20_automute(codec);
15252}
15253
15254static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
15255{
15256	alc662_eeepc_ep20_automute(codec);
15257}
15258
15259static void alc663_m51va_speaker_automute(struct hda_codec *codec)
15260{
15261	unsigned int present;
15262	unsigned char bits;
15263
15264	present = snd_hda_codec_read(codec, 0x21, 0,
15265			AC_VERB_GET_PIN_SENSE, 0)
15266			& AC_PINSENSE_PRESENCE;
15267	bits = present ? HDA_AMP_MUTE : 0;
15268	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15269				AMP_IN_MUTE(0), bits);
15270	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15271				AMP_IN_MUTE(0), bits);
15272}
15273
15274static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
15275{
15276	unsigned int present;
15277	unsigned char bits;
15278
15279	present = snd_hda_codec_read(codec, 0x21, 0,
15280			AC_VERB_GET_PIN_SENSE, 0)
15281			& AC_PINSENSE_PRESENCE;
15282	bits = present ? HDA_AMP_MUTE : 0;
15283	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15284				AMP_IN_MUTE(0), bits);
15285	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15286				AMP_IN_MUTE(0), bits);
15287	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15288				AMP_IN_MUTE(0), bits);
15289	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15290				AMP_IN_MUTE(0), bits);
15291}
15292
15293static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
15294{
15295	unsigned int present;
15296	unsigned char bits;
15297
15298	present = snd_hda_codec_read(codec, 0x15, 0,
15299			AC_VERB_GET_PIN_SENSE, 0)
15300			& AC_PINSENSE_PRESENCE;
15301	bits = present ? HDA_AMP_MUTE : 0;
15302	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15303				AMP_IN_MUTE(0), bits);
15304	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15305				AMP_IN_MUTE(0), bits);
15306	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15307				AMP_IN_MUTE(0), bits);
15308	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15309				AMP_IN_MUTE(0), bits);
15310}
15311
15312static void alc662_f5z_speaker_automute(struct hda_codec *codec)
15313{
15314	unsigned int present;
15315	unsigned char bits;
15316
15317	present = snd_hda_codec_read(codec, 0x1b, 0,
15318			AC_VERB_GET_PIN_SENSE, 0)
15319			& AC_PINSENSE_PRESENCE;
15320	bits = present ? 0 : PIN_OUT;
15321	snd_hda_codec_write(codec, 0x14, 0,
15322			 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
15323}
15324
15325static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
15326{
15327	unsigned int present1, present2;
15328
15329	present1 = snd_hda_codec_read(codec, 0x21, 0,
15330			AC_VERB_GET_PIN_SENSE, 0)
15331			& AC_PINSENSE_PRESENCE;
15332	present2 = snd_hda_codec_read(codec, 0x15, 0,
15333			AC_VERB_GET_PIN_SENSE, 0)
15334			& AC_PINSENSE_PRESENCE;
15335
15336	if (present1 || present2) {
15337		snd_hda_codec_write_cache(codec, 0x14, 0,
15338			AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
15339	} else {
15340		snd_hda_codec_write_cache(codec, 0x14, 0,
15341			AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
15342	}
15343}
15344
15345static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
15346{
15347	unsigned int present1, present2;
15348
15349	present1 = snd_hda_codec_read(codec, 0x1b, 0,
15350				AC_VERB_GET_PIN_SENSE, 0)
15351				& AC_PINSENSE_PRESENCE;
15352	present2 = snd_hda_codec_read(codec, 0x15, 0,
15353				AC_VERB_GET_PIN_SENSE, 0)
15354				& AC_PINSENSE_PRESENCE;
15355
15356	if (present1 || present2) {
15357		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15358				AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15359		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15360				AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15361	} else {
15362		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15363				AMP_IN_MUTE(0), 0);
15364		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15365				AMP_IN_MUTE(0), 0);
15366	}
15367}
15368
15369static void alc663_m51va_mic_automute(struct hda_codec *codec)
15370{
15371	unsigned int present;
15372
15373	present = snd_hda_codec_read(codec, 0x18, 0,
15374			AC_VERB_GET_PIN_SENSE, 0)
15375			& AC_PINSENSE_PRESENCE;
15376	snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15377			0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15378	snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15379			0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15380	snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15381			0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15382	snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15383			0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15384}
15385
15386static void alc663_m51va_unsol_event(struct hda_codec *codec,
15387					   unsigned int res)
15388{
15389	switch (res >> 26) {
15390	case ALC880_HP_EVENT:
15391		alc663_m51va_speaker_automute(codec);
15392		break;
15393	case ALC880_MIC_EVENT:
15394		alc663_m51va_mic_automute(codec);
15395		break;
15396	}
15397}
15398
15399static void alc663_m51va_inithook(struct hda_codec *codec)
15400{
15401	alc663_m51va_speaker_automute(codec);
15402	alc663_m51va_mic_automute(codec);
15403}
15404
15405/* ***************** Mode1 ******************************/
15406static void alc663_mode1_unsol_event(struct hda_codec *codec,
15407					   unsigned int res)
15408{
15409	switch (res >> 26) {
15410	case ALC880_HP_EVENT:
15411		alc663_m51va_speaker_automute(codec);
15412		break;
15413	case ALC880_MIC_EVENT:
15414		alc662_eeepc_mic_automute(codec);
15415		break;
15416	}
15417}
15418
15419static void alc663_mode1_inithook(struct hda_codec *codec)
15420{
15421	alc663_m51va_speaker_automute(codec);
15422	alc662_eeepc_mic_automute(codec);
15423}
15424/* ***************** Mode2 ******************************/
15425static void alc662_mode2_unsol_event(struct hda_codec *codec,
15426					   unsigned int res)
15427{
15428	switch (res >> 26) {
15429	case ALC880_HP_EVENT:
15430		alc662_f5z_speaker_automute(codec);
15431		break;
15432	case ALC880_MIC_EVENT:
15433		alc662_eeepc_mic_automute(codec);
15434		break;
15435	}
15436}
15437
15438static void alc662_mode2_inithook(struct hda_codec *codec)
15439{
15440	alc662_f5z_speaker_automute(codec);
15441	alc662_eeepc_mic_automute(codec);
15442}
15443/* ***************** Mode3 ******************************/
15444static void alc663_mode3_unsol_event(struct hda_codec *codec,
15445					   unsigned int res)
15446{
15447	switch (res >> 26) {
15448	case ALC880_HP_EVENT:
15449		alc663_two_hp_m1_speaker_automute(codec);
15450		break;
15451	case ALC880_MIC_EVENT:
15452		alc662_eeepc_mic_automute(codec);
15453		break;
15454	}
15455}
15456
15457static void alc663_mode3_inithook(struct hda_codec *codec)
15458{
15459	alc663_two_hp_m1_speaker_automute(codec);
15460	alc662_eeepc_mic_automute(codec);
15461}
15462/* ***************** Mode4 ******************************/
15463static void alc663_mode4_unsol_event(struct hda_codec *codec,
15464					   unsigned int res)
15465{
15466	switch (res >> 26) {
15467	case ALC880_HP_EVENT:
15468		alc663_21jd_two_speaker_automute(codec);
15469		break;
15470	case ALC880_MIC_EVENT:
15471		alc662_eeepc_mic_automute(codec);
15472		break;
15473	}
15474}
15475
15476static void alc663_mode4_inithook(struct hda_codec *codec)
15477{
15478	alc663_21jd_two_speaker_automute(codec);
15479	alc662_eeepc_mic_automute(codec);
15480}
15481/* ***************** Mode5 ******************************/
15482static void alc663_mode5_unsol_event(struct hda_codec *codec,
15483					   unsigned int res)
15484{
15485	switch (res >> 26) {
15486	case ALC880_HP_EVENT:
15487		alc663_15jd_two_speaker_automute(codec);
15488		break;
15489	case ALC880_MIC_EVENT:
15490		alc662_eeepc_mic_automute(codec);
15491		break;
15492	}
15493}
15494
15495static void alc663_mode5_inithook(struct hda_codec *codec)
15496{
15497	alc663_15jd_two_speaker_automute(codec);
15498	alc662_eeepc_mic_automute(codec);
15499}
15500/* ***************** Mode6 ******************************/
15501static void alc663_mode6_unsol_event(struct hda_codec *codec,
15502					   unsigned int res)
15503{
15504	switch (res >> 26) {
15505	case ALC880_HP_EVENT:
15506		alc663_two_hp_m2_speaker_automute(codec);
15507		break;
15508	case ALC880_MIC_EVENT:
15509		alc662_eeepc_mic_automute(codec);
15510		break;
15511	}
15512}
15513
15514static void alc663_mode6_inithook(struct hda_codec *codec)
15515{
15516	alc663_two_hp_m2_speaker_automute(codec);
15517	alc662_eeepc_mic_automute(codec);
15518}
15519
15520static void alc663_g71v_hp_automute(struct hda_codec *codec)
15521{
15522	unsigned int present;
15523	unsigned char bits;
15524
15525	present = snd_hda_codec_read(codec, 0x21, 0,
15526				     AC_VERB_GET_PIN_SENSE, 0)
15527		& AC_PINSENSE_PRESENCE;
15528	bits = present ? HDA_AMP_MUTE : 0;
15529	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15530				 HDA_AMP_MUTE, bits);
15531	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15532				 HDA_AMP_MUTE, bits);
15533}
15534
15535static void alc663_g71v_front_automute(struct hda_codec *codec)
15536{
15537	unsigned int present;
15538	unsigned char bits;
15539
15540	present = snd_hda_codec_read(codec, 0x15, 0,
15541				     AC_VERB_GET_PIN_SENSE, 0)
15542		& AC_PINSENSE_PRESENCE;
15543	bits = present ? HDA_AMP_MUTE : 0;
15544	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15545				 HDA_AMP_MUTE, bits);
15546}
15547
15548static void alc663_g71v_unsol_event(struct hda_codec *codec,
15549					   unsigned int res)
15550{
15551	switch (res >> 26) {
15552	case ALC880_HP_EVENT:
15553		alc663_g71v_hp_automute(codec);
15554		break;
15555	case ALC880_FRONT_EVENT:
15556		alc663_g71v_front_automute(codec);
15557		break;
15558	case ALC880_MIC_EVENT:
15559		alc662_eeepc_mic_automute(codec);
15560		break;
15561	}
15562}
15563
15564static void alc663_g71v_inithook(struct hda_codec *codec)
15565{
15566	alc663_g71v_front_automute(codec);
15567	alc663_g71v_hp_automute(codec);
15568	alc662_eeepc_mic_automute(codec);
15569}
15570
15571static void alc663_g50v_unsol_event(struct hda_codec *codec,
15572					   unsigned int res)
15573{
15574	switch (res >> 26) {
15575	case ALC880_HP_EVENT:
15576		alc663_m51va_speaker_automute(codec);
15577		break;
15578	case ALC880_MIC_EVENT:
15579		alc662_eeepc_mic_automute(codec);
15580		break;
15581	}
15582}
15583
15584static void alc663_g50v_inithook(struct hda_codec *codec)
15585{
15586	alc663_m51va_speaker_automute(codec);
15587	alc662_eeepc_mic_automute(codec);
15588}
15589
15590/* bind hp and internal speaker mute (with plug check) */
15591static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol,
15592				     struct snd_ctl_elem_value *ucontrol)
15593{
15594	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
15595	long *valp = ucontrol->value.integer.value;
15596	int change;
15597
15598	change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
15599					  HDA_AMP_MUTE,
15600					  valp[0] ? 0 : HDA_AMP_MUTE);
15601	change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
15602					   HDA_AMP_MUTE,
15603					   valp[1] ? 0 : HDA_AMP_MUTE);
15604	if (change)
15605		alc262_hippo1_automute(codec);
15606	return change;
15607}
15608
15609static struct snd_kcontrol_new alc662_ecs_mixer[] = {
15610	HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15611	{
15612		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15613		.name = "Master Playback Switch",
15614		.info = snd_hda_mixer_amp_switch_info,
15615		.get = snd_hda_mixer_amp_switch_get,
15616		.put = alc662_ecs_master_sw_put,
15617		.private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15618	},
15619
15620	HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
15621	HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
15622	HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
15623
15624	HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15625	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15626	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15627	{ } /* end */
15628};
15629
15630#ifdef CONFIG_SND_HDA_POWER_SAVE
15631#define alc662_loopbacks	alc880_loopbacks
15632#endif
15633
15634
15635/* pcm configuration: identiacal with ALC880 */
15636#define alc662_pcm_analog_playback	alc880_pcm_analog_playback
15637#define alc662_pcm_analog_capture	alc880_pcm_analog_capture
15638#define alc662_pcm_digital_playback	alc880_pcm_digital_playback
15639#define alc662_pcm_digital_capture	alc880_pcm_digital_capture
15640
15641/*
15642 * configuration and preset
15643 */
15644static const char *alc662_models[ALC662_MODEL_LAST] = {
15645	[ALC662_3ST_2ch_DIG]	= "3stack-dig",
15646	[ALC662_3ST_6ch_DIG]	= "3stack-6ch-dig",
15647	[ALC662_3ST_6ch]	= "3stack-6ch",
15648	[ALC662_5ST_DIG]	= "6stack-dig",
15649	[ALC662_LENOVO_101E]	= "lenovo-101e",
15650	[ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
15651	[ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
15652	[ALC662_ECS] = "ecs",
15653	[ALC663_ASUS_M51VA] = "m51va",
15654	[ALC663_ASUS_G71V] = "g71v",
15655	[ALC663_ASUS_H13] = "h13",
15656	[ALC663_ASUS_G50V] = "g50v",
15657	[ALC663_ASUS_MODE1] = "asus-mode1",
15658	[ALC662_ASUS_MODE2] = "asus-mode2",
15659	[ALC663_ASUS_MODE3] = "asus-mode3",
15660	[ALC663_ASUS_MODE4] = "asus-mode4",
15661	[ALC663_ASUS_MODE5] = "asus-mode5",
15662	[ALC663_ASUS_MODE6] = "asus-mode6",
15663	[ALC662_AUTO]		= "auto",
15664};
15665
15666static struct snd_pci_quirk alc662_cfg_tbl[] = {
15667	SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
15668	SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
15669	SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
15670	SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
15671	SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
15672	SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
15673	SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),
15674	SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
15675	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
15676	SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
15677	SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),
15678	SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
15679	SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
15680	SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
15681	SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
15682	SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
15683	SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
15684	SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
15685	SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
15686	SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
15687	SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
15688	SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
15689	SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
15690	SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
15691	SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
15692	SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
15693	SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
15694	SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
15695	SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
15696	SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
15697	SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
15698	SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
15699	SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
15700	SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
15701	SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
15702	SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
15703	SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
15704	SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
15705		      ALC662_3ST_6ch_DIG),
15706	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
15707	SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
15708	SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
15709	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
15710		      ALC662_3ST_6ch_DIG),
15711	SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
15712	SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
15713					ALC662_3ST_6ch_DIG),
15714	SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13),
15715	SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13),
15716	SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13),
15717	{}
15718};
15719
15720static struct alc_config_preset alc662_presets[] = {
15721	[ALC662_3ST_2ch_DIG] = {
15722		.mixers = { alc662_3ST_2ch_mixer },
15723		.init_verbs = { alc662_init_verbs },
15724		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15725		.dac_nids = alc662_dac_nids,
15726		.dig_out_nid = ALC662_DIGOUT_NID,
15727		.dig_in_nid = ALC662_DIGIN_NID,
15728		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15729		.channel_mode = alc662_3ST_2ch_modes,
15730		.input_mux = &alc662_capture_source,
15731	},
15732	[ALC662_3ST_6ch_DIG] = {
15733		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
15734		.init_verbs = { alc662_init_verbs },
15735		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15736		.dac_nids = alc662_dac_nids,
15737		.dig_out_nid = ALC662_DIGOUT_NID,
15738		.dig_in_nid = ALC662_DIGIN_NID,
15739		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15740		.channel_mode = alc662_3ST_6ch_modes,
15741		.need_dac_fix = 1,
15742		.input_mux = &alc662_capture_source,
15743	},
15744	[ALC662_3ST_6ch] = {
15745		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
15746		.init_verbs = { alc662_init_verbs },
15747		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15748		.dac_nids = alc662_dac_nids,
15749		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15750		.channel_mode = alc662_3ST_6ch_modes,
15751		.need_dac_fix = 1,
15752		.input_mux = &alc662_capture_source,
15753	},
15754	[ALC662_5ST_DIG] = {
15755		.mixers = { alc662_base_mixer, alc662_chmode_mixer },
15756		.init_verbs = { alc662_init_verbs },
15757		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15758		.dac_nids = alc662_dac_nids,
15759		.dig_out_nid = ALC662_DIGOUT_NID,
15760		.dig_in_nid = ALC662_DIGIN_NID,
15761		.num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
15762		.channel_mode = alc662_5stack_modes,
15763		.input_mux = &alc662_capture_source,
15764	},
15765	[ALC662_LENOVO_101E] = {
15766		.mixers = { alc662_lenovo_101e_mixer },
15767		.init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
15768		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15769		.dac_nids = alc662_dac_nids,
15770		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15771		.channel_mode = alc662_3ST_2ch_modes,
15772		.input_mux = &alc662_lenovo_101e_capture_source,
15773		.unsol_event = alc662_lenovo_101e_unsol_event,
15774		.init_hook = alc662_lenovo_101e_all_automute,
15775	},
15776	[ALC662_ASUS_EEEPC_P701] = {
15777		.mixers = { alc662_eeepc_p701_mixer },
15778		.init_verbs = { alc662_init_verbs,
15779				alc662_eeepc_sue_init_verbs },
15780		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15781		.dac_nids = alc662_dac_nids,
15782		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15783		.channel_mode = alc662_3ST_2ch_modes,
15784		.input_mux = &alc662_eeepc_capture_source,
15785		.unsol_event = alc662_eeepc_unsol_event,
15786		.init_hook = alc662_eeepc_inithook,
15787	},
15788	[ALC662_ASUS_EEEPC_EP20] = {
15789		.mixers = { alc662_eeepc_ep20_mixer,
15790			    alc662_chmode_mixer },
15791		.init_verbs = { alc662_init_verbs,
15792				alc662_eeepc_ep20_sue_init_verbs },
15793		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15794		.dac_nids = alc662_dac_nids,
15795		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15796		.channel_mode = alc662_3ST_6ch_modes,
15797		.input_mux = &alc662_lenovo_101e_capture_source,
15798		.unsol_event = alc662_eeepc_ep20_unsol_event,
15799		.init_hook = alc662_eeepc_ep20_inithook,
15800	},
15801	[ALC662_ECS] = {
15802		.mixers = { alc662_ecs_mixer },
15803		.init_verbs = { alc662_init_verbs,
15804				alc662_ecs_init_verbs },
15805		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15806		.dac_nids = alc662_dac_nids,
15807		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15808		.channel_mode = alc662_3ST_2ch_modes,
15809		.input_mux = &alc662_eeepc_capture_source,
15810		.unsol_event = alc662_eeepc_unsol_event,
15811		.init_hook = alc662_eeepc_inithook,
15812	},
15813	[ALC663_ASUS_M51VA] = {
15814		.mixers = { alc663_m51va_mixer },
15815		.init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15816		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15817		.dac_nids = alc662_dac_nids,
15818		.dig_out_nid = ALC662_DIGOUT_NID,
15819		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15820		.channel_mode = alc662_3ST_2ch_modes,
15821		.input_mux = &alc663_m51va_capture_source,
15822		.unsol_event = alc663_m51va_unsol_event,
15823		.init_hook = alc663_m51va_inithook,
15824	},
15825	[ALC663_ASUS_G71V] = {
15826		.mixers = { alc663_g71v_mixer },
15827		.init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
15828		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15829		.dac_nids = alc662_dac_nids,
15830		.dig_out_nid = ALC662_DIGOUT_NID,
15831		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15832		.channel_mode = alc662_3ST_2ch_modes,
15833		.input_mux = &alc662_eeepc_capture_source,
15834		.unsol_event = alc663_g71v_unsol_event,
15835		.init_hook = alc663_g71v_inithook,
15836	},
15837	[ALC663_ASUS_H13] = {
15838		.mixers = { alc663_m51va_mixer },
15839		.init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15840		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15841		.dac_nids = alc662_dac_nids,
15842		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15843		.channel_mode = alc662_3ST_2ch_modes,
15844		.input_mux = &alc663_m51va_capture_source,
15845		.unsol_event = alc663_m51va_unsol_event,
15846		.init_hook = alc663_m51va_inithook,
15847	},
15848	[ALC663_ASUS_G50V] = {
15849		.mixers = { alc663_g50v_mixer },
15850		.init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
15851		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15852		.dac_nids = alc662_dac_nids,
15853		.dig_out_nid = ALC662_DIGOUT_NID,
15854		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15855		.channel_mode = alc662_3ST_6ch_modes,
15856		.input_mux = &alc663_capture_source,
15857		.unsol_event = alc663_g50v_unsol_event,
15858		.init_hook = alc663_g50v_inithook,
15859	},
15860	[ALC663_ASUS_MODE1] = {
15861		.mixers = { alc663_m51va_mixer },
15862		.cap_mixer = alc662_auto_capture_mixer,
15863		.init_verbs = { alc662_init_verbs,
15864				alc663_21jd_amic_init_verbs },
15865		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15866		.hp_nid = 0x03,
15867		.dac_nids = alc662_dac_nids,
15868		.dig_out_nid = ALC662_DIGOUT_NID,
15869		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15870		.channel_mode = alc662_3ST_2ch_modes,
15871		.input_mux = &alc662_eeepc_capture_source,
15872		.unsol_event = alc663_mode1_unsol_event,
15873		.init_hook = alc663_mode1_inithook,
15874	},
15875	[ALC662_ASUS_MODE2] = {
15876		.mixers = { alc662_1bjd_mixer },
15877		.cap_mixer = alc662_auto_capture_mixer,
15878		.init_verbs = { alc662_init_verbs,
15879				alc662_1bjd_amic_init_verbs },
15880		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15881		.dac_nids = alc662_dac_nids,
15882		.dig_out_nid = ALC662_DIGOUT_NID,
15883		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15884		.channel_mode = alc662_3ST_2ch_modes,
15885		.input_mux = &alc662_eeepc_capture_source,
15886		.unsol_event = alc662_mode2_unsol_event,
15887		.init_hook = alc662_mode2_inithook,
15888	},
15889	[ALC663_ASUS_MODE3] = {
15890		.mixers = { alc663_two_hp_m1_mixer },
15891		.cap_mixer = alc662_auto_capture_mixer,
15892		.init_verbs = { alc662_init_verbs,
15893				alc663_two_hp_amic_m1_init_verbs },
15894		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15895		.hp_nid = 0x03,
15896		.dac_nids = alc662_dac_nids,
15897		.dig_out_nid = ALC662_DIGOUT_NID,
15898		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15899		.channel_mode = alc662_3ST_2ch_modes,
15900		.input_mux = &alc662_eeepc_capture_source,
15901		.unsol_event = alc663_mode3_unsol_event,
15902		.init_hook = alc663_mode3_inithook,
15903	},
15904	[ALC663_ASUS_MODE4] = {
15905		.mixers = { alc663_asus_21jd_clfe_mixer },
15906		.cap_mixer = alc662_auto_capture_mixer,
15907		.init_verbs = { alc662_init_verbs,
15908				alc663_21jd_amic_init_verbs},
15909		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15910		.hp_nid = 0x03,
15911		.dac_nids = alc662_dac_nids,
15912		.dig_out_nid = ALC662_DIGOUT_NID,
15913		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15914		.channel_mode = alc662_3ST_2ch_modes,
15915		.input_mux = &alc662_eeepc_capture_source,
15916		.unsol_event = alc663_mode4_unsol_event,
15917		.init_hook = alc663_mode4_inithook,
15918	},
15919	[ALC663_ASUS_MODE5] = {
15920		.mixers = { alc663_asus_15jd_clfe_mixer },
15921		.cap_mixer = alc662_auto_capture_mixer,
15922		.init_verbs = { alc662_init_verbs,
15923				alc663_15jd_amic_init_verbs },
15924		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15925		.hp_nid = 0x03,
15926		.dac_nids = alc662_dac_nids,
15927		.dig_out_nid = ALC662_DIGOUT_NID,
15928		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15929		.channel_mode = alc662_3ST_2ch_modes,
15930		.input_mux = &alc662_eeepc_capture_source,
15931		.unsol_event = alc663_mode5_unsol_event,
15932		.init_hook = alc663_mode5_inithook,
15933	},
15934	[ALC663_ASUS_MODE6] = {
15935		.mixers = { alc663_two_hp_m2_mixer },
15936		.cap_mixer = alc662_auto_capture_mixer,
15937		.init_verbs = { alc662_init_verbs,
15938				alc663_two_hp_amic_m2_init_verbs },
15939		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15940		.hp_nid = 0x03,
15941		.dac_nids = alc662_dac_nids,
15942		.dig_out_nid = ALC662_DIGOUT_NID,
15943		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15944		.channel_mode = alc662_3ST_2ch_modes,
15945		.input_mux = &alc662_eeepc_capture_source,
15946		.unsol_event = alc663_mode6_unsol_event,
15947		.init_hook = alc663_mode6_inithook,
15948	},
15949};
15950
15951
15952/*
15953 * BIOS auto configuration
15954 */
15955
15956/* add playback controls from the parsed DAC table */
15957static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
15958					     const struct auto_pin_cfg *cfg)
15959{
15960	char name[32];
15961	static const char *chname[4] = {
15962		"Front", "Surround", NULL /*CLFE*/, "Side"
15963	};
15964	hda_nid_t nid;
15965	int i, err;
15966
15967	for (i = 0; i < cfg->line_outs; i++) {
15968		if (!spec->multiout.dac_nids[i])
15969			continue;
15970		nid = alc880_idx_to_dac(i);
15971		if (i == 2) {
15972			/* Center/LFE */
15973			err = add_control(spec, ALC_CTL_WIDGET_VOL,
15974					  "Center Playback Volume",
15975					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
15976							      HDA_OUTPUT));
15977			if (err < 0)
15978				return err;
15979			err = add_control(spec, ALC_CTL_WIDGET_VOL,
15980					  "LFE Playback Volume",
15981					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
15982							      HDA_OUTPUT));
15983			if (err < 0)
15984				return err;
15985			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
15986					  "Center Playback Switch",
15987					  HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
15988							      HDA_INPUT));
15989			if (err < 0)
15990				return err;
15991			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
15992					  "LFE Playback Switch",
15993					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
15994							      HDA_INPUT));
15995			if (err < 0)
15996				return err;
15997		} else {
15998			sprintf(name, "%s Playback Volume", chname[i]);
15999			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16000					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
16001							      HDA_OUTPUT));
16002			if (err < 0)
16003				return err;
16004			sprintf(name, "%s Playback Switch", chname[i]);
16005			err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16006				HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16007						    3, 0, HDA_INPUT));
16008			if (err < 0)
16009				return err;
16010		}
16011	}
16012	return 0;
16013}
16014
16015/* add playback controls for speaker and HP outputs */
16016static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16017					const char *pfx)
16018{
16019	hda_nid_t nid;
16020	int err;
16021	char name[32];
16022
16023	if (!pin)
16024		return 0;
16025
16026	if (pin == 0x17) {
16027		/* ALC663 has a mono output pin on 0x17 */
16028		sprintf(name, "%s Playback Switch", pfx);
16029		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16030				  HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16031		return err;
16032	}
16033
16034	if (alc880_is_fixed_pin(pin)) {
16035		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16036                /* printk("DAC nid=%x\n",nid); */
16037		/* specify the DAC as the extra output */
16038		if (!spec->multiout.hp_nid)
16039			spec->multiout.hp_nid = nid;
16040		else
16041			spec->multiout.extra_out_nid[0] = nid;
16042		/* control HP volume/switch on the output mixer amp */
16043		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16044		sprintf(name, "%s Playback Volume", pfx);
16045		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16046				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16047		if (err < 0)
16048			return err;
16049		sprintf(name, "%s Playback Switch", pfx);
16050		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
16051				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
16052		if (err < 0)
16053			return err;
16054	} else if (alc880_is_multi_pin(pin)) {
16055		/* set manual connection */
16056		/* we have only a switch on HP-out PIN */
16057		sprintf(name, "%s Playback Switch", pfx);
16058		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16059				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16060		if (err < 0)
16061			return err;
16062	}
16063	return 0;
16064}
16065
16066/* create playback/capture controls for input pins */
16067static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
16068						const struct auto_pin_cfg *cfg)
16069{
16070	struct hda_input_mux *imux = &spec->private_imux;
16071	int i, err, idx;
16072
16073	for (i = 0; i < AUTO_PIN_LAST; i++) {
16074		if (alc880_is_input_pin(cfg->input_pins[i])) {
16075			idx = alc880_input_pin_idx(cfg->input_pins[i]);
16076			err = new_analog_input(spec, cfg->input_pins[i],
16077					       auto_pin_cfg_labels[i],
16078					       idx, 0x0b);
16079			if (err < 0)
16080				return err;
16081			imux->items[imux->num_items].label =
16082				auto_pin_cfg_labels[i];
16083			imux->items[imux->num_items].index =
16084				alc880_input_pin_idx(cfg->input_pins[i]);
16085			imux->num_items++;
16086		}
16087	}
16088	return 0;
16089}
16090
16091static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16092					      hda_nid_t nid, int pin_type,
16093					      int dac_idx)
16094{
16095	alc_set_pin_output(codec, nid, pin_type);
16096	/* need the manual connection? */
16097	if (alc880_is_multi_pin(nid)) {
16098		struct alc_spec *spec = codec->spec;
16099		int idx = alc880_multi_pin_idx(nid);
16100		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16101				    AC_VERB_SET_CONNECT_SEL,
16102				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16103	}
16104}
16105
16106static void alc662_auto_init_multi_out(struct hda_codec *codec)
16107{
16108	struct alc_spec *spec = codec->spec;
16109	int i;
16110
16111	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
16112	for (i = 0; i <= HDA_SIDE; i++) {
16113		hda_nid_t nid = spec->autocfg.line_out_pins[i];
16114		int pin_type = get_pin_type(spec->autocfg.line_out_type);
16115		if (nid)
16116			alc662_auto_set_output_and_unmute(codec, nid, pin_type,
16117							  i);
16118	}
16119}
16120
16121static void alc662_auto_init_hp_out(struct hda_codec *codec)
16122{
16123	struct alc_spec *spec = codec->spec;
16124	hda_nid_t pin;
16125
16126	pin = spec->autocfg.hp_pins[0];
16127	if (pin) /* connect to front */
16128		/* use dac 0 */
16129		alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
16130	pin = spec->autocfg.speaker_pins[0];
16131	if (pin)
16132		alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
16133}
16134
16135#define alc662_is_input_pin(nid)	alc880_is_input_pin(nid)
16136#define ALC662_PIN_CD_NID		ALC880_PIN_CD_NID
16137
16138static void alc662_auto_init_analog_input(struct hda_codec *codec)
16139{
16140	struct alc_spec *spec = codec->spec;
16141	int i;
16142
16143	for (i = 0; i < AUTO_PIN_LAST; i++) {
16144		hda_nid_t nid = spec->autocfg.input_pins[i];
16145		if (alc662_is_input_pin(nid)) {
16146			snd_hda_codec_write(codec, nid, 0,
16147					    AC_VERB_SET_PIN_WIDGET_CONTROL,
16148					    (i <= AUTO_PIN_FRONT_MIC ?
16149					     PIN_VREF80 : PIN_IN));
16150			if (nid != ALC662_PIN_CD_NID)
16151				snd_hda_codec_write(codec, nid, 0,
16152						    AC_VERB_SET_AMP_GAIN_MUTE,
16153						    AMP_OUT_MUTE);
16154		}
16155	}
16156}
16157
16158#define alc662_auto_init_input_src	alc882_auto_init_input_src
16159
16160static int alc662_parse_auto_config(struct hda_codec *codec)
16161{
16162	struct alc_spec *spec = codec->spec;
16163	int err;
16164	static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
16165
16166	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16167					   alc662_ignore);
16168	if (err < 0)
16169		return err;
16170	if (!spec->autocfg.line_outs)
16171		return 0; /* can't find valid BIOS pin config */
16172
16173	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16174	if (err < 0)
16175		return err;
16176	err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
16177	if (err < 0)
16178		return err;
16179	err = alc662_auto_create_extra_out(spec,
16180					   spec->autocfg.speaker_pins[0],
16181					   "Speaker");
16182	if (err < 0)
16183		return err;
16184	err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
16185					   "Headphone");
16186	if (err < 0)
16187		return err;
16188	err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
16189	if (err < 0)
16190		return err;
16191
16192	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16193
16194	if (spec->autocfg.dig_out_pin)
16195		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
16196
16197	if (spec->kctls.list)
16198		add_mixer(spec, spec->kctls.list);
16199
16200	spec->num_mux_defs = 1;
16201	spec->input_mux = &spec->private_imux;
16202
16203	add_verb(spec, alc662_auto_init_verbs);
16204	if (codec->vendor_id == 0x10ec0663)
16205		add_verb(spec, alc663_auto_init_verbs);
16206
16207	err = alc_auto_add_mic_boost(codec);
16208	if (err < 0)
16209		return err;
16210
16211	store_pin_configs(codec);
16212	return 1;
16213}
16214
16215/* additional initialization for auto-configuration model */
16216static void alc662_auto_init(struct hda_codec *codec)
16217{
16218	struct alc_spec *spec = codec->spec;
16219	alc662_auto_init_multi_out(codec);
16220	alc662_auto_init_hp_out(codec);
16221	alc662_auto_init_analog_input(codec);
16222	alc662_auto_init_input_src(codec);
16223	if (spec->unsol_event)
16224		alc_inithook(codec);
16225}
16226
16227static int patch_alc662(struct hda_codec *codec)
16228{
16229	struct alc_spec *spec;
16230	int err, board_config;
16231
16232	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16233	if (!spec)
16234		return -ENOMEM;
16235
16236	codec->spec = spec;
16237
16238	alc_fix_pll_init(codec, 0x20, 0x04, 15);
16239
16240	board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
16241						  alc662_models,
16242			  	                  alc662_cfg_tbl);
16243	if (board_config < 0) {
16244		printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
16245		       "trying auto-probe from BIOS...\n");
16246		board_config = ALC662_AUTO;
16247	}
16248
16249	if (board_config == ALC662_AUTO) {
16250		/* automatic parse from the BIOS config */
16251		err = alc662_parse_auto_config(codec);
16252		if (err < 0) {
16253			alc_free(codec);
16254			return err;
16255		} else if (!err) {
16256			printk(KERN_INFO
16257			       "hda_codec: Cannot set up configuration "
16258			       "from BIOS.  Using base mode...\n");
16259			board_config = ALC662_3ST_2ch_DIG;
16260		}
16261	}
16262
16263	if (board_config != ALC662_AUTO)
16264		setup_preset(spec, &alc662_presets[board_config]);
16265
16266	if (codec->vendor_id == 0x10ec0663) {
16267		spec->stream_name_analog = "ALC663 Analog";
16268		spec->stream_name_digital = "ALC663 Digital";
16269	} else if (codec->vendor_id == 0x10ec0272) {
16270		spec->stream_name_analog = "ALC272 Analog";
16271		spec->stream_name_digital = "ALC272 Digital";
16272	} else {
16273		spec->stream_name_analog = "ALC662 Analog";
16274		spec->stream_name_digital = "ALC662 Digital";
16275	}
16276
16277	spec->stream_analog_playback = &alc662_pcm_analog_playback;
16278	spec->stream_analog_capture = &alc662_pcm_analog_capture;
16279
16280	spec->stream_digital_playback = &alc662_pcm_digital_playback;
16281	spec->stream_digital_capture = &alc662_pcm_digital_capture;
16282
16283	spec->adc_nids = alc662_adc_nids;
16284	spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
16285	spec->capsrc_nids = alc662_capsrc_nids;
16286	spec->is_mix_capture = 1;
16287
16288	if (!spec->cap_mixer)
16289		set_capture_mixer(spec);
16290
16291	spec->vmaster_nid = 0x02;
16292
16293	codec->patch_ops = alc_patch_ops;
16294	if (board_config == ALC662_AUTO)
16295		spec->init_hook = alc662_auto_init;
16296#ifdef CONFIG_SND_HDA_POWER_SAVE
16297	if (!spec->loopback.amplist)
16298		spec->loopback.amplist = alc662_loopbacks;
16299#endif
16300
16301	return 0;
16302}
16303
16304/*
16305 * patch entries
16306 */
16307struct hda_codec_preset snd_hda_preset_realtek[] = {
16308	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
16309	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
16310	{ .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
16311	{ .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
16312	{ .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
16313	{ .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
16314	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
16315	  .patch = patch_alc861 },
16316	{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
16317	{ .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
16318	{ .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
16319	{ .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
16320	  .patch = patch_alc883 },
16321	{ .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
16322	  .patch = patch_alc662 },
16323	{ .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
16324	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
16325	{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
16326	{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
16327	{ .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
16328	  .patch = patch_alc882 }, /* should be patch_alc883() in future */
16329	{ .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
16330	  .patch = patch_alc882 }, /* should be patch_alc883() in future */
16331	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
16332	{ .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
16333	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
16334	{ .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
16335	  .patch = patch_alc883 },
16336	{ .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
16337	{} /* terminator */
16338};
16339