patch_realtek.c revision c238b4f4038e0e49bb241640610584a088b268b1
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_AUTO,
136	ALC269_MODEL_LAST /* last tag */
137};
138
139/* ALC861 models */
140enum {
141	ALC861_3ST,
142	ALC660_3ST,
143	ALC861_3ST_DIG,
144	ALC861_6ST_DIG,
145	ALC861_UNIWILL_M31,
146	ALC861_TOSHIBA,
147	ALC861_ASUS,
148	ALC861_ASUS_LAPTOP,
149	ALC861_AUTO,
150	ALC861_MODEL_LAST,
151};
152
153/* ALC861-VD models */
154enum {
155	ALC660VD_3ST,
156	ALC660VD_3ST_DIG,
157	ALC660VD_ASUS_V1S,
158	ALC861VD_3ST,
159	ALC861VD_3ST_DIG,
160	ALC861VD_6ST_DIG,
161	ALC861VD_LENOVO,
162	ALC861VD_DALLAS,
163	ALC861VD_HP,
164	ALC861VD_AUTO,
165	ALC861VD_MODEL_LAST,
166};
167
168/* ALC662 models */
169enum {
170	ALC662_3ST_2ch_DIG,
171	ALC662_3ST_6ch_DIG,
172	ALC662_3ST_6ch,
173	ALC662_5ST_DIG,
174	ALC662_LENOVO_101E,
175	ALC662_ASUS_EEEPC_P701,
176	ALC662_ASUS_EEEPC_EP20,
177	ALC663_ASUS_M51VA,
178	ALC663_ASUS_G71V,
179	ALC663_ASUS_H13,
180	ALC663_ASUS_G50V,
181	ALC662_ECS,
182	ALC663_ASUS_MODE1,
183	ALC662_ASUS_MODE2,
184	ALC663_ASUS_MODE3,
185	ALC663_ASUS_MODE4,
186	ALC663_ASUS_MODE5,
187	ALC663_ASUS_MODE6,
188	ALC662_AUTO,
189	ALC662_MODEL_LAST,
190};
191
192/* ALC882 models */
193enum {
194	ALC882_3ST_DIG,
195	ALC882_6ST_DIG,
196	ALC882_ARIMA,
197	ALC882_W2JC,
198	ALC882_TARGA,
199	ALC882_ASUS_A7J,
200	ALC882_ASUS_A7M,
201	ALC885_MACPRO,
202	ALC885_MBP3,
203	ALC885_IMAC24,
204	ALC882_AUTO,
205	ALC882_MODEL_LAST,
206};
207
208/* ALC883 models */
209enum {
210	ALC883_3ST_2ch_DIG,
211	ALC883_3ST_6ch_DIG,
212	ALC883_3ST_6ch,
213	ALC883_6ST_DIG,
214	ALC883_TARGA_DIG,
215	ALC883_TARGA_2ch_DIG,
216	ALC883_ACER,
217	ALC883_ACER_ASPIRE,
218	ALC883_MEDION,
219	ALC883_MEDION_MD2,
220	ALC883_LAPTOP_EAPD,
221	ALC883_LENOVO_101E_2ch,
222	ALC883_LENOVO_NB0763,
223	ALC888_LENOVO_MS7195_DIG,
224	ALC888_LENOVO_SKY,
225	ALC883_HAIER_W66,
226	ALC888_3ST_HP,
227	ALC888_6ST_DELL,
228	ALC883_MITAC,
229	ALC883_CLEVO_M720,
230	ALC883_FUJITSU_PI2515,
231	ALC883_3ST_6ch_INTEL,
232	ALC888_ASUS_M90V,
233	ALC888_ASUS_EEE1601,
234	ALC883_AUTO,
235	ALC883_MODEL_LAST,
236};
237
238/* for GPIO Poll */
239#define GPIO_MASK	0x03
240
241struct alc_spec {
242	/* codec parameterization */
243	struct snd_kcontrol_new *mixers[5];	/* mixer arrays */
244	unsigned int num_mixers;
245	struct snd_kcontrol_new *cap_mixer;	/* capture mixer */
246
247	const struct hda_verb *init_verbs[5];	/* initialization verbs
248						 * don't forget NULL
249						 * termination!
250						 */
251	unsigned int num_init_verbs;
252
253	char *stream_name_analog;	/* analog PCM stream */
254	struct hda_pcm_stream *stream_analog_playback;
255	struct hda_pcm_stream *stream_analog_capture;
256	struct hda_pcm_stream *stream_analog_alt_playback;
257	struct hda_pcm_stream *stream_analog_alt_capture;
258
259	char *stream_name_digital;	/* digital PCM stream */
260	struct hda_pcm_stream *stream_digital_playback;
261	struct hda_pcm_stream *stream_digital_capture;
262
263	/* playback */
264	struct hda_multi_out multiout;	/* playback set-up
265					 * max_channels, dacs must be set
266					 * dig_out_nid and hp_nid are optional
267					 */
268	hda_nid_t alt_dac_nid;
269
270	/* capture */
271	unsigned int num_adc_nids;
272	hda_nid_t *adc_nids;
273	hda_nid_t *capsrc_nids;
274	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
275	unsigned char is_mix_capture;	/* matrix-style capture (non-mux) */
276
277	/* capture source */
278	unsigned int num_mux_defs;
279	const struct hda_input_mux *input_mux;
280	unsigned int cur_mux[3];
281
282	/* channel model */
283	const struct hda_channel_mode *channel_mode;
284	int num_channel_mode;
285	int need_dac_fix;
286
287	/* PCM information */
288	struct hda_pcm pcm_rec[3];	/* used in alc_build_pcms() */
289
290	/* dynamic controls, init_verbs and input_mux */
291	struct auto_pin_cfg autocfg;
292	struct snd_array kctls;
293	struct hda_input_mux private_imux;
294	hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
295
296	/* hooks */
297	void (*init_hook)(struct hda_codec *codec);
298	void (*unsol_event)(struct hda_codec *codec, unsigned int res);
299
300	/* for pin sensing */
301	unsigned int sense_updated: 1;
302	unsigned int jack_present: 1;
303	unsigned int master_sw: 1;
304
305	/* for virtual master */
306	hda_nid_t vmaster_nid;
307#ifdef CONFIG_SND_HDA_POWER_SAVE
308	struct hda_loopback_check loopback;
309#endif
310
311	/* for PLL fix */
312	hda_nid_t pll_nid;
313	unsigned int pll_coef_idx, pll_coef_bit;
314
315#ifdef SND_HDA_NEEDS_RESUME
316#define ALC_MAX_PINS	16
317	unsigned int num_pins;
318	hda_nid_t pin_nids[ALC_MAX_PINS];
319	unsigned int pin_cfgs[ALC_MAX_PINS];
320#endif
321};
322
323/*
324 * configuration template - to be copied to the spec instance
325 */
326struct alc_config_preset {
327	struct snd_kcontrol_new *mixers[5]; /* should be identical size
328					     * with spec
329					     */
330	struct snd_kcontrol_new *cap_mixer; /* capture mixer */
331	const struct hda_verb *init_verbs[5];
332	unsigned int num_dacs;
333	hda_nid_t *dac_nids;
334	hda_nid_t dig_out_nid;		/* optional */
335	hda_nid_t hp_nid;		/* optional */
336	unsigned int num_adc_nids;
337	hda_nid_t *adc_nids;
338	hda_nid_t *capsrc_nids;
339	hda_nid_t dig_in_nid;
340	unsigned int num_channel_mode;
341	const struct hda_channel_mode *channel_mode;
342	int need_dac_fix;
343	unsigned int num_mux_defs;
344	const struct hda_input_mux *input_mux;
345	void (*unsol_event)(struct hda_codec *, unsigned int);
346	void (*init_hook)(struct hda_codec *);
347#ifdef CONFIG_SND_HDA_POWER_SAVE
348	struct hda_amp_list *loopbacks;
349#endif
350};
351
352
353/*
354 * input MUX handling
355 */
356static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
357			     struct snd_ctl_elem_info *uinfo)
358{
359	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
360	struct alc_spec *spec = codec->spec;
361	unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
362	if (mux_idx >= spec->num_mux_defs)
363		mux_idx = 0;
364	return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
365}
366
367static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
368			    struct snd_ctl_elem_value *ucontrol)
369{
370	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
371	struct alc_spec *spec = codec->spec;
372	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
373
374	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
375	return 0;
376}
377
378static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
379			    struct snd_ctl_elem_value *ucontrol)
380{
381	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
382	struct alc_spec *spec = codec->spec;
383	const struct hda_input_mux *imux = spec->input_mux;
384	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
385	hda_nid_t nid = spec->capsrc_nids ?
386		spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
387
388	if (spec->is_mix_capture) {
389		/* Matrix-mixer style (e.g. ALC882) */
390		unsigned int *cur_val = &spec->cur_mux[adc_idx];
391		unsigned int i, idx;
392
393		idx = ucontrol->value.enumerated.item[0];
394		if (idx >= imux->num_items)
395			idx = imux->num_items - 1;
396		if (*cur_val == idx)
397			return 0;
398		for (i = 0; i < imux->num_items; i++) {
399			unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
400			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
401						 imux->items[i].index,
402						 HDA_AMP_MUTE, v);
403		}
404		*cur_val = idx;
405		return 1;
406	} else {
407		/* MUX style (e.g. ALC880) */
408		unsigned int mux_idx;
409		mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
410		return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx],
411					     ucontrol, nid,
412					     &spec->cur_mux[adc_idx]);
413	}
414}
415
416/*
417 * channel mode setting
418 */
419static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
420			    struct snd_ctl_elem_info *uinfo)
421{
422	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
423	struct alc_spec *spec = codec->spec;
424	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
425				    spec->num_channel_mode);
426}
427
428static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
429			   struct snd_ctl_elem_value *ucontrol)
430{
431	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
432	struct alc_spec *spec = codec->spec;
433	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
434				   spec->num_channel_mode,
435				   spec->multiout.max_channels);
436}
437
438static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
439			   struct snd_ctl_elem_value *ucontrol)
440{
441	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
442	struct alc_spec *spec = codec->spec;
443	int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
444				      spec->num_channel_mode,
445				      &spec->multiout.max_channels);
446	if (err >= 0 && spec->need_dac_fix)
447		spec->multiout.num_dacs = spec->multiout.max_channels / 2;
448	return err;
449}
450
451/*
452 * Control the mode of pin widget settings via the mixer.  "pc" is used
453 * instead of "%" to avoid consequences of accidently treating the % as
454 * being part of a format specifier.  Maximum allowed length of a value is
455 * 63 characters plus NULL terminator.
456 *
457 * Note: some retasking pin complexes seem to ignore requests for input
458 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
459 * are requested.  Therefore order this list so that this behaviour will not
460 * cause problems when mixer clients move through the enum sequentially.
461 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
462 * March 2006.
463 */
464static char *alc_pin_mode_names[] = {
465	"Mic 50pc bias", "Mic 80pc bias",
466	"Line in", "Line out", "Headphone out",
467};
468static unsigned char alc_pin_mode_values[] = {
469	PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
470};
471/* The control can present all 5 options, or it can limit the options based
472 * in the pin being assumed to be exclusively an input or an output pin.  In
473 * addition, "input" pins may or may not process the mic bias option
474 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
475 * accept requests for bias as of chip versions up to March 2006) and/or
476 * wiring in the computer.
477 */
478#define ALC_PIN_DIR_IN              0x00
479#define ALC_PIN_DIR_OUT             0x01
480#define ALC_PIN_DIR_INOUT           0x02
481#define ALC_PIN_DIR_IN_NOMICBIAS    0x03
482#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
483
484/* Info about the pin modes supported by the different pin direction modes.
485 * For each direction the minimum and maximum values are given.
486 */
487static signed char alc_pin_mode_dir_info[5][2] = {
488	{ 0, 2 },    /* ALC_PIN_DIR_IN */
489	{ 3, 4 },    /* ALC_PIN_DIR_OUT */
490	{ 0, 4 },    /* ALC_PIN_DIR_INOUT */
491	{ 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
492	{ 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
493};
494#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
495#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
496#define alc_pin_mode_n_items(_dir) \
497	(alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
498
499static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
500			     struct snd_ctl_elem_info *uinfo)
501{
502	unsigned int item_num = uinfo->value.enumerated.item;
503	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
504
505	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
506	uinfo->count = 1;
507	uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
508
509	if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
510		item_num = alc_pin_mode_min(dir);
511	strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
512	return 0;
513}
514
515static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
516			    struct snd_ctl_elem_value *ucontrol)
517{
518	unsigned int i;
519	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
520	hda_nid_t nid = kcontrol->private_value & 0xffff;
521	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
522	long *valp = ucontrol->value.integer.value;
523	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
524						 AC_VERB_GET_PIN_WIDGET_CONTROL,
525						 0x00);
526
527	/* Find enumerated value for current pinctl setting */
528	i = alc_pin_mode_min(dir);
529	while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
530		i++;
531	*valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
532	return 0;
533}
534
535static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
536			    struct snd_ctl_elem_value *ucontrol)
537{
538	signed int change;
539	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
540	hda_nid_t nid = kcontrol->private_value & 0xffff;
541	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
542	long val = *ucontrol->value.integer.value;
543	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
544						 AC_VERB_GET_PIN_WIDGET_CONTROL,
545						 0x00);
546
547	if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
548		val = alc_pin_mode_min(dir);
549
550	change = pinctl != alc_pin_mode_values[val];
551	if (change) {
552		/* Set pin mode to that requested */
553		snd_hda_codec_write_cache(codec, nid, 0,
554					  AC_VERB_SET_PIN_WIDGET_CONTROL,
555					  alc_pin_mode_values[val]);
556
557		/* Also enable the retasking pin's input/output as required
558		 * for the requested pin mode.  Enum values of 2 or less are
559		 * input modes.
560		 *
561		 * Dynamically switching the input/output buffers probably
562		 * reduces noise slightly (particularly on input) so we'll
563		 * do it.  However, having both input and output buffers
564		 * enabled simultaneously doesn't seem to be problematic if
565		 * this turns out to be necessary in the future.
566		 */
567		if (val <= 2) {
568			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
569						 HDA_AMP_MUTE, HDA_AMP_MUTE);
570			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
571						 HDA_AMP_MUTE, 0);
572		} else {
573			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
574						 HDA_AMP_MUTE, HDA_AMP_MUTE);
575			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
576						 HDA_AMP_MUTE, 0);
577		}
578	}
579	return change;
580}
581
582#define ALC_PIN_MODE(xname, nid, dir) \
583	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
584	  .info = alc_pin_mode_info, \
585	  .get = alc_pin_mode_get, \
586	  .put = alc_pin_mode_put, \
587	  .private_value = nid | (dir<<16) }
588
589/* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
590 * together using a mask with more than one bit set.  This control is
591 * currently used only by the ALC260 test model.  At this stage they are not
592 * needed for any "production" models.
593 */
594#ifdef CONFIG_SND_DEBUG
595#define alc_gpio_data_info	snd_ctl_boolean_mono_info
596
597static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
598			     struct snd_ctl_elem_value *ucontrol)
599{
600	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
601	hda_nid_t nid = kcontrol->private_value & 0xffff;
602	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
603	long *valp = ucontrol->value.integer.value;
604	unsigned int val = snd_hda_codec_read(codec, nid, 0,
605					      AC_VERB_GET_GPIO_DATA, 0x00);
606
607	*valp = (val & mask) != 0;
608	return 0;
609}
610static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
611			     struct snd_ctl_elem_value *ucontrol)
612{
613	signed int change;
614	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
615	hda_nid_t nid = kcontrol->private_value & 0xffff;
616	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
617	long val = *ucontrol->value.integer.value;
618	unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
619						    AC_VERB_GET_GPIO_DATA,
620						    0x00);
621
622	/* Set/unset the masked GPIO bit(s) as needed */
623	change = (val == 0 ? 0 : mask) != (gpio_data & mask);
624	if (val == 0)
625		gpio_data &= ~mask;
626	else
627		gpio_data |= mask;
628	snd_hda_codec_write_cache(codec, nid, 0,
629				  AC_VERB_SET_GPIO_DATA, gpio_data);
630
631	return change;
632}
633#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
634	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
635	  .info = alc_gpio_data_info, \
636	  .get = alc_gpio_data_get, \
637	  .put = alc_gpio_data_put, \
638	  .private_value = nid | (mask<<16) }
639#endif   /* CONFIG_SND_DEBUG */
640
641/* A switch control to allow the enabling of the digital IO pins on the
642 * ALC260.  This is incredibly simplistic; the intention of this control is
643 * to provide something in the test model allowing digital outputs to be
644 * identified if present.  If models are found which can utilise these
645 * outputs a more complete mixer control can be devised for those models if
646 * necessary.
647 */
648#ifdef CONFIG_SND_DEBUG
649#define alc_spdif_ctrl_info	snd_ctl_boolean_mono_info
650
651static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
652			      struct snd_ctl_elem_value *ucontrol)
653{
654	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
655	hda_nid_t nid = kcontrol->private_value & 0xffff;
656	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
657	long *valp = ucontrol->value.integer.value;
658	unsigned int val = snd_hda_codec_read(codec, nid, 0,
659					      AC_VERB_GET_DIGI_CONVERT_1, 0x00);
660
661	*valp = (val & mask) != 0;
662	return 0;
663}
664static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
665			      struct snd_ctl_elem_value *ucontrol)
666{
667	signed int change;
668	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
669	hda_nid_t nid = kcontrol->private_value & 0xffff;
670	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
671	long val = *ucontrol->value.integer.value;
672	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
673						    AC_VERB_GET_DIGI_CONVERT_1,
674						    0x00);
675
676	/* Set/unset the masked control bit(s) as needed */
677	change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
678	if (val==0)
679		ctrl_data &= ~mask;
680	else
681		ctrl_data |= mask;
682	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
683				  ctrl_data);
684
685	return change;
686}
687#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
688	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
689	  .info = alc_spdif_ctrl_info, \
690	  .get = alc_spdif_ctrl_get, \
691	  .put = alc_spdif_ctrl_put, \
692	  .private_value = nid | (mask<<16) }
693#endif   /* CONFIG_SND_DEBUG */
694
695/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
696 * Again, this is only used in the ALC26x test models to help identify when
697 * the EAPD line must be asserted for features to work.
698 */
699#ifdef CONFIG_SND_DEBUG
700#define alc_eapd_ctrl_info	snd_ctl_boolean_mono_info
701
702static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
703			      struct snd_ctl_elem_value *ucontrol)
704{
705	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
706	hda_nid_t nid = kcontrol->private_value & 0xffff;
707	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
708	long *valp = ucontrol->value.integer.value;
709	unsigned int val = snd_hda_codec_read(codec, nid, 0,
710					      AC_VERB_GET_EAPD_BTLENABLE, 0x00);
711
712	*valp = (val & mask) != 0;
713	return 0;
714}
715
716static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
717			      struct snd_ctl_elem_value *ucontrol)
718{
719	int change;
720	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
721	hda_nid_t nid = kcontrol->private_value & 0xffff;
722	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
723	long val = *ucontrol->value.integer.value;
724	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
725						    AC_VERB_GET_EAPD_BTLENABLE,
726						    0x00);
727
728	/* Set/unset the masked control bit(s) as needed */
729	change = (!val ? 0 : mask) != (ctrl_data & mask);
730	if (!val)
731		ctrl_data &= ~mask;
732	else
733		ctrl_data |= mask;
734	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
735				  ctrl_data);
736
737	return change;
738}
739
740#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
741	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
742	  .info = alc_eapd_ctrl_info, \
743	  .get = alc_eapd_ctrl_get, \
744	  .put = alc_eapd_ctrl_put, \
745	  .private_value = nid | (mask<<16) }
746#endif   /* CONFIG_SND_DEBUG */
747
748/*
749 */
750static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
751{
752	if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
753		return;
754	spec->mixers[spec->num_mixers++] = mix;
755}
756
757static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
758{
759	if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
760		return;
761	spec->init_verbs[spec->num_init_verbs++] = verb;
762}
763
764/*
765 * set up from the preset table
766 */
767static void setup_preset(struct alc_spec *spec,
768			 const struct alc_config_preset *preset)
769{
770	int i;
771
772	for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
773		add_mixer(spec, preset->mixers[i]);
774	spec->cap_mixer = preset->cap_mixer;
775	for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
776	     i++)
777		add_verb(spec, preset->init_verbs[i]);
778
779	spec->channel_mode = preset->channel_mode;
780	spec->num_channel_mode = preset->num_channel_mode;
781	spec->need_dac_fix = preset->need_dac_fix;
782
783	spec->multiout.max_channels = spec->channel_mode[0].channels;
784
785	spec->multiout.num_dacs = preset->num_dacs;
786	spec->multiout.dac_nids = preset->dac_nids;
787	spec->multiout.dig_out_nid = preset->dig_out_nid;
788	spec->multiout.hp_nid = preset->hp_nid;
789
790	spec->num_mux_defs = preset->num_mux_defs;
791	if (!spec->num_mux_defs)
792		spec->num_mux_defs = 1;
793	spec->input_mux = preset->input_mux;
794
795	spec->num_adc_nids = preset->num_adc_nids;
796	spec->adc_nids = preset->adc_nids;
797	spec->capsrc_nids = preset->capsrc_nids;
798	spec->dig_in_nid = preset->dig_in_nid;
799
800	spec->unsol_event = preset->unsol_event;
801	spec->init_hook = preset->init_hook;
802#ifdef CONFIG_SND_HDA_POWER_SAVE
803	spec->loopback.amplist = preset->loopbacks;
804#endif
805}
806
807/* Enable GPIO mask and set output */
808static struct hda_verb alc_gpio1_init_verbs[] = {
809	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
810	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
811	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
812	{ }
813};
814
815static struct hda_verb alc_gpio2_init_verbs[] = {
816	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
817	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
818	{0x01, AC_VERB_SET_GPIO_DATA, 0x02},
819	{ }
820};
821
822static struct hda_verb alc_gpio3_init_verbs[] = {
823	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
824	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
825	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
826	{ }
827};
828
829/*
830 * Fix hardware PLL issue
831 * On some codecs, the analog PLL gating control must be off while
832 * the default value is 1.
833 */
834static void alc_fix_pll(struct hda_codec *codec)
835{
836	struct alc_spec *spec = codec->spec;
837	unsigned int val;
838
839	if (!spec->pll_nid)
840		return;
841	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
842			    spec->pll_coef_idx);
843	val = snd_hda_codec_read(codec, spec->pll_nid, 0,
844				 AC_VERB_GET_PROC_COEF, 0);
845	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
846			    spec->pll_coef_idx);
847	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
848			    val & ~(1 << spec->pll_coef_bit));
849}
850
851static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
852			     unsigned int coef_idx, unsigned int coef_bit)
853{
854	struct alc_spec *spec = codec->spec;
855	spec->pll_nid = nid;
856	spec->pll_coef_idx = coef_idx;
857	spec->pll_coef_bit = coef_bit;
858	alc_fix_pll(codec);
859}
860
861static void alc_sku_automute(struct hda_codec *codec)
862{
863	struct alc_spec *spec = codec->spec;
864	unsigned int present;
865	unsigned int hp_nid = spec->autocfg.hp_pins[0];
866	unsigned int sp_nid = spec->autocfg.speaker_pins[0];
867
868	/* need to execute and sync at first */
869	snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
870	present = snd_hda_codec_read(codec, hp_nid, 0,
871				     AC_VERB_GET_PIN_SENSE, 0);
872	spec->jack_present = (present & 0x80000000) != 0;
873	snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
874			    spec->jack_present ? 0 : PIN_OUT);
875}
876
877#if 0 /* it's broken in some acses -- temporarily disabled */
878static void alc_mic_automute(struct hda_codec *codec)
879{
880	struct alc_spec *spec = codec->spec;
881	unsigned int present;
882	unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
883	unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
884	unsigned int mix_nid = spec->capsrc_nids[0];
885	unsigned int capsrc_idx_mic, capsrc_idx_fmic;
886
887	capsrc_idx_mic = mic_nid - 0x18;
888	capsrc_idx_fmic = fmic_nid - 0x18;
889	present = snd_hda_codec_read(codec, mic_nid, 0,
890				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
891	snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
892		    0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
893	snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
894		    0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
895	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
896			 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
897}
898#else
899#define alc_mic_automute(codec) /* NOP */
900#endif /* disabled */
901
902/* unsolicited event for HP jack sensing */
903static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
904{
905	if (codec->vendor_id == 0x10ec0880)
906		res >>= 28;
907	else
908		res >>= 26;
909	if (res == ALC880_HP_EVENT)
910		alc_sku_automute(codec);
911
912	if (res == ALC880_MIC_EVENT)
913		alc_mic_automute(codec);
914}
915
916static void alc_inithook(struct hda_codec *codec)
917{
918	alc_sku_automute(codec);
919	alc_mic_automute(codec);
920}
921
922/* additional initialization for ALC888 variants */
923static void alc888_coef_init(struct hda_codec *codec)
924{
925	unsigned int tmp;
926
927	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
928	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
929	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
930	if ((tmp & 0xf0) == 2)
931		/* alc888S-VC */
932		snd_hda_codec_read(codec, 0x20, 0,
933				   AC_VERB_SET_PROC_COEF, 0x830);
934	 else
935		 /* alc888-VB */
936		 snd_hda_codec_read(codec, 0x20, 0,
937				    AC_VERB_SET_PROC_COEF, 0x3030);
938}
939
940/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
941 *	31 ~ 16 :	Manufacture ID
942 *	15 ~ 8	:	SKU ID
943 *	7  ~ 0	:	Assembly ID
944 *	port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
945 */
946static void alc_subsystem_id(struct hda_codec *codec,
947			     unsigned int porta, unsigned int porte,
948			     unsigned int portd)
949{
950	unsigned int ass, tmp, i;
951	unsigned nid;
952	struct alc_spec *spec = codec->spec;
953
954	ass = codec->subsystem_id & 0xffff;
955	if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
956		goto do_sku;
957
958	/*
959	 * 31~30	: port conetcivity
960	 * 29~21	: reserve
961	 * 20		: PCBEEP input
962	 * 19~16	: Check sum (15:1)
963	 * 15~1		: Custom
964	 * 0		: override
965	*/
966	nid = 0x1d;
967	if (codec->vendor_id == 0x10ec0260)
968		nid = 0x17;
969	ass = snd_hda_codec_read(codec, nid, 0,
970				 AC_VERB_GET_CONFIG_DEFAULT, 0);
971	if (!(ass & 1) && !(ass & 0x100000))
972		return;
973	if ((ass >> 30) != 1)	/* no physical connection */
974		return;
975
976	/* check sum */
977	tmp = 0;
978	for (i = 1; i < 16; i++) {
979		if ((ass >> i) & 1)
980			tmp++;
981	}
982	if (((ass >> 16) & 0xf) != tmp)
983		return;
984do_sku:
985	/*
986	 * 0 : override
987	 * 1 :	Swap Jack
988	 * 2 : 0 --> Desktop, 1 --> Laptop
989	 * 3~5 : External Amplifier control
990	 * 7~6 : Reserved
991	*/
992	tmp = (ass & 0x38) >> 3;	/* external Amp control */
993	switch (tmp) {
994	case 1:
995		snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
996		break;
997	case 3:
998		snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
999		break;
1000	case 7:
1001		snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1002		break;
1003	case 5:	/* set EAPD output high */
1004		switch (codec->vendor_id) {
1005		case 0x10ec0260:
1006			snd_hda_codec_write(codec, 0x0f, 0,
1007					    AC_VERB_SET_EAPD_BTLENABLE, 2);
1008			snd_hda_codec_write(codec, 0x10, 0,
1009					    AC_VERB_SET_EAPD_BTLENABLE, 2);
1010			break;
1011		case 0x10ec0262:
1012		case 0x10ec0267:
1013		case 0x10ec0268:
1014		case 0x10ec0269:
1015		case 0x10ec0660:
1016		case 0x10ec0662:
1017		case 0x10ec0663:
1018		case 0x10ec0862:
1019		case 0x10ec0889:
1020			snd_hda_codec_write(codec, 0x14, 0,
1021					    AC_VERB_SET_EAPD_BTLENABLE, 2);
1022			snd_hda_codec_write(codec, 0x15, 0,
1023					    AC_VERB_SET_EAPD_BTLENABLE, 2);
1024			break;
1025		}
1026		switch (codec->vendor_id) {
1027		case 0x10ec0260:
1028			snd_hda_codec_write(codec, 0x1a, 0,
1029					    AC_VERB_SET_COEF_INDEX, 7);
1030			tmp = snd_hda_codec_read(codec, 0x1a, 0,
1031						 AC_VERB_GET_PROC_COEF, 0);
1032			snd_hda_codec_write(codec, 0x1a, 0,
1033					    AC_VERB_SET_COEF_INDEX, 7);
1034			snd_hda_codec_write(codec, 0x1a, 0,
1035					    AC_VERB_SET_PROC_COEF,
1036					    tmp | 0x2010);
1037			break;
1038		case 0x10ec0262:
1039		case 0x10ec0880:
1040		case 0x10ec0882:
1041		case 0x10ec0883:
1042		case 0x10ec0885:
1043		case 0x10ec0889:
1044			snd_hda_codec_write(codec, 0x20, 0,
1045					    AC_VERB_SET_COEF_INDEX, 7);
1046			tmp = snd_hda_codec_read(codec, 0x20, 0,
1047						 AC_VERB_GET_PROC_COEF, 0);
1048			snd_hda_codec_write(codec, 0x20, 0,
1049					    AC_VERB_SET_COEF_INDEX, 7);
1050			snd_hda_codec_write(codec, 0x20, 0,
1051					    AC_VERB_SET_PROC_COEF,
1052					    tmp | 0x2010);
1053			break;
1054		case 0x10ec0888:
1055			/*alc888_coef_init(codec);*/ /* called in alc_init() */
1056			break;
1057		case 0x10ec0267:
1058		case 0x10ec0268:
1059			snd_hda_codec_write(codec, 0x20, 0,
1060					    AC_VERB_SET_COEF_INDEX, 7);
1061			tmp = snd_hda_codec_read(codec, 0x20, 0,
1062						 AC_VERB_GET_PROC_COEF, 0);
1063			snd_hda_codec_write(codec, 0x20, 0,
1064					    AC_VERB_SET_COEF_INDEX, 7);
1065			snd_hda_codec_write(codec, 0x20, 0,
1066					    AC_VERB_SET_PROC_COEF,
1067					    tmp | 0x3000);
1068			break;
1069		}
1070	default:
1071		break;
1072	}
1073
1074	/* is laptop or Desktop and enable the function "Mute internal speaker
1075	 * when the external headphone out jack is plugged"
1076	 */
1077	if (!(ass & 0x8000))
1078		return;
1079	/*
1080	 * 10~8 : Jack location
1081	 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1082	 * 14~13: Resvered
1083	 * 15   : 1 --> enable the function "Mute internal speaker
1084	 *	        when the external headphone out jack is plugged"
1085	 */
1086	if (!spec->autocfg.speaker_pins[0]) {
1087		if (spec->autocfg.line_out_pins[0])
1088			spec->autocfg.speaker_pins[0] =
1089				spec->autocfg.line_out_pins[0];
1090		else
1091			return;
1092	}
1093
1094	if (!spec->autocfg.hp_pins[0]) {
1095		tmp = (ass >> 11) & 0x3;	/* HP to chassis */
1096		if (tmp == 0)
1097			spec->autocfg.hp_pins[0] = porta;
1098		else if (tmp == 1)
1099			spec->autocfg.hp_pins[0] = porte;
1100		else if (tmp == 2)
1101			spec->autocfg.hp_pins[0] = portd;
1102		else
1103			return;
1104	}
1105	if (spec->autocfg.hp_pins[0])
1106		snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
1107			AC_VERB_SET_UNSOLICITED_ENABLE,
1108			AC_USRSP_EN | ALC880_HP_EVENT);
1109
1110#if 0 /* it's broken in some acses -- temporarily disabled */
1111	if (spec->autocfg.input_pins[AUTO_PIN_MIC] &&
1112		spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC])
1113		snd_hda_codec_write(codec,
1114			spec->autocfg.input_pins[AUTO_PIN_MIC], 0,
1115			AC_VERB_SET_UNSOLICITED_ENABLE,
1116			AC_USRSP_EN | ALC880_MIC_EVENT);
1117#endif /* disabled */
1118
1119	spec->unsol_event = alc_sku_unsol_event;
1120}
1121
1122/*
1123 * Fix-up pin default configurations
1124 */
1125
1126struct alc_pincfg {
1127	hda_nid_t nid;
1128	u32 val;
1129};
1130
1131static void alc_fix_pincfg(struct hda_codec *codec,
1132			   const struct snd_pci_quirk *quirk,
1133			   const struct alc_pincfg **pinfix)
1134{
1135	const struct alc_pincfg *cfg;
1136
1137	quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1138	if (!quirk)
1139		return;
1140
1141	cfg = pinfix[quirk->value];
1142	for (; cfg->nid; cfg++) {
1143		int i;
1144		u32 val = cfg->val;
1145		for (i = 0; i < 4; i++) {
1146			snd_hda_codec_write(codec, cfg->nid, 0,
1147				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
1148				    val & 0xff);
1149			val >>= 8;
1150		}
1151	}
1152}
1153
1154/*
1155 * ALC880 3-stack model
1156 *
1157 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1158 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1159 *                 F-Mic = 0x1b, HP = 0x19
1160 */
1161
1162static hda_nid_t alc880_dac_nids[4] = {
1163	/* front, rear, clfe, rear_surr */
1164	0x02, 0x05, 0x04, 0x03
1165};
1166
1167static hda_nid_t alc880_adc_nids[3] = {
1168	/* ADC0-2 */
1169	0x07, 0x08, 0x09,
1170};
1171
1172/* The datasheet says the node 0x07 is connected from inputs,
1173 * but it shows zero connection in the real implementation on some devices.
1174 * Note: this is a 915GAV bug, fixed on 915GLV
1175 */
1176static hda_nid_t alc880_adc_nids_alt[2] = {
1177	/* ADC1-2 */
1178	0x08, 0x09,
1179};
1180
1181#define ALC880_DIGOUT_NID	0x06
1182#define ALC880_DIGIN_NID	0x0a
1183
1184static struct hda_input_mux alc880_capture_source = {
1185	.num_items = 4,
1186	.items = {
1187		{ "Mic", 0x0 },
1188		{ "Front Mic", 0x3 },
1189		{ "Line", 0x2 },
1190		{ "CD", 0x4 },
1191	},
1192};
1193
1194/* channel source setting (2/6 channel selection for 3-stack) */
1195/* 2ch mode */
1196static struct hda_verb alc880_threestack_ch2_init[] = {
1197	/* set line-in to input, mute it */
1198	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1199	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1200	/* set mic-in to input vref 80%, mute it */
1201	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1202	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1203	{ } /* end */
1204};
1205
1206/* 6ch mode */
1207static struct hda_verb alc880_threestack_ch6_init[] = {
1208	/* set line-in to output, unmute it */
1209	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1210	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1211	/* set mic-in to output, unmute it */
1212	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1213	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1214	{ } /* end */
1215};
1216
1217static struct hda_channel_mode alc880_threestack_modes[2] = {
1218	{ 2, alc880_threestack_ch2_init },
1219	{ 6, alc880_threestack_ch6_init },
1220};
1221
1222static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1223	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1224	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1225	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1226	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1227	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1228	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1229	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1230	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1231	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1232	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1233	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1234	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1235	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1236	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1237	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1238	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1239	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1240	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1241	HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1242	{
1243		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1244		.name = "Channel Mode",
1245		.info = alc_ch_mode_info,
1246		.get = alc_ch_mode_get,
1247		.put = alc_ch_mode_put,
1248	},
1249	{ } /* end */
1250};
1251
1252/* capture mixer elements */
1253static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1254			    struct snd_ctl_elem_info *uinfo)
1255{
1256	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1257	struct alc_spec *spec = codec->spec;
1258	int err;
1259
1260	mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
1261	kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1262						      HDA_INPUT);
1263	err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1264	mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */
1265	return err;
1266}
1267
1268static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1269			   unsigned int size, unsigned int __user *tlv)
1270{
1271	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1272	struct alc_spec *spec = codec->spec;
1273	int err;
1274
1275	mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
1276	kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1277						      HDA_INPUT);
1278	err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1279	mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */
1280	return err;
1281}
1282
1283typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1284			     struct snd_ctl_elem_value *ucontrol);
1285
1286static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1287				 struct snd_ctl_elem_value *ucontrol,
1288				 getput_call_t func)
1289{
1290	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1291	struct alc_spec *spec = codec->spec;
1292	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1293	int err;
1294
1295	mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
1296	kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1297						      3, 0, HDA_INPUT);
1298	err = func(kcontrol, ucontrol);
1299	mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */
1300	return err;
1301}
1302
1303static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1304			   struct snd_ctl_elem_value *ucontrol)
1305{
1306	return alc_cap_getput_caller(kcontrol, ucontrol,
1307				     snd_hda_mixer_amp_volume_get);
1308}
1309
1310static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1311			   struct snd_ctl_elem_value *ucontrol)
1312{
1313	return alc_cap_getput_caller(kcontrol, ucontrol,
1314				     snd_hda_mixer_amp_volume_put);
1315}
1316
1317/* capture mixer elements */
1318#define alc_cap_sw_info		snd_ctl_boolean_stereo_info
1319
1320static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1321			  struct snd_ctl_elem_value *ucontrol)
1322{
1323	return alc_cap_getput_caller(kcontrol, ucontrol,
1324				     snd_hda_mixer_amp_switch_get);
1325}
1326
1327static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1328			  struct snd_ctl_elem_value *ucontrol)
1329{
1330	return alc_cap_getput_caller(kcontrol, ucontrol,
1331				     snd_hda_mixer_amp_switch_put);
1332}
1333
1334#define DEFINE_CAPMIX(num) \
1335static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
1336	{ \
1337		.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1338		.name = "Capture Switch", \
1339		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1340		.count = num, \
1341		.info = alc_cap_sw_info, \
1342		.get = alc_cap_sw_get, \
1343		.put = alc_cap_sw_put, \
1344	}, \
1345	{ \
1346		.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1347		.name = "Capture Volume", \
1348		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1349			   SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1350			   SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1351		.count = num, \
1352		.info = alc_cap_vol_info, \
1353		.get = alc_cap_vol_get, \
1354		.put = alc_cap_vol_put, \
1355		.tlv = { .c = alc_cap_vol_tlv }, \
1356	}, \
1357	{ \
1358		.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1359		/* .name = "Capture Source", */ \
1360		.name = "Input Source", \
1361		.count = num, \
1362		.info = alc_mux_enum_info, \
1363		.get = alc_mux_enum_get, \
1364		.put = alc_mux_enum_put, \
1365	}, \
1366	{ } /* end */ \
1367}
1368
1369/* up to three ADCs */
1370DEFINE_CAPMIX(1);
1371DEFINE_CAPMIX(2);
1372DEFINE_CAPMIX(3);
1373
1374
1375/*
1376 * ALC880 5-stack model
1377 *
1378 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1379 *      Side = 0x02 (0xd)
1380 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1381 *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1382 */
1383
1384/* additional mixers to alc880_three_stack_mixer */
1385static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1386	HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1387	HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1388	{ } /* end */
1389};
1390
1391/* channel source setting (6/8 channel selection for 5-stack) */
1392/* 6ch mode */
1393static struct hda_verb alc880_fivestack_ch6_init[] = {
1394	/* set line-in to input, mute it */
1395	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1396	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1397	{ } /* end */
1398};
1399
1400/* 8ch mode */
1401static struct hda_verb alc880_fivestack_ch8_init[] = {
1402	/* set line-in to output, unmute it */
1403	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1404	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1405	{ } /* end */
1406};
1407
1408static struct hda_channel_mode alc880_fivestack_modes[2] = {
1409	{ 6, alc880_fivestack_ch6_init },
1410	{ 8, alc880_fivestack_ch8_init },
1411};
1412
1413
1414/*
1415 * ALC880 6-stack model
1416 *
1417 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1418 *      Side = 0x05 (0x0f)
1419 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1420 *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1421 */
1422
1423static hda_nid_t alc880_6st_dac_nids[4] = {
1424	/* front, rear, clfe, rear_surr */
1425	0x02, 0x03, 0x04, 0x05
1426};
1427
1428static struct hda_input_mux alc880_6stack_capture_source = {
1429	.num_items = 4,
1430	.items = {
1431		{ "Mic", 0x0 },
1432		{ "Front Mic", 0x1 },
1433		{ "Line", 0x2 },
1434		{ "CD", 0x4 },
1435	},
1436};
1437
1438/* fixed 8-channels */
1439static struct hda_channel_mode alc880_sixstack_modes[1] = {
1440	{ 8, NULL },
1441};
1442
1443static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1444	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1445	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1446	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1447	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1448	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1449	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1450	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1451	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1452	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1453	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1454	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1455	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1456	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1457	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1458	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1459	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1460	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1461	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1462	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1463	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1464	{
1465		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1466		.name = "Channel Mode",
1467		.info = alc_ch_mode_info,
1468		.get = alc_ch_mode_get,
1469		.put = alc_ch_mode_put,
1470	},
1471	{ } /* end */
1472};
1473
1474
1475/*
1476 * ALC880 W810 model
1477 *
1478 * W810 has rear IO for:
1479 * Front (DAC 02)
1480 * Surround (DAC 03)
1481 * Center/LFE (DAC 04)
1482 * Digital out (06)
1483 *
1484 * The system also has a pair of internal speakers, and a headphone jack.
1485 * These are both connected to Line2 on the codec, hence to DAC 02.
1486 *
1487 * There is a variable resistor to control the speaker or headphone
1488 * volume. This is a hardware-only device without a software API.
1489 *
1490 * Plugging headphones in will disable the internal speakers. This is
1491 * implemented in hardware, not via the driver using jack sense. In
1492 * a similar fashion, plugging into the rear socket marked "front" will
1493 * disable both the speakers and headphones.
1494 *
1495 * For input, there's a microphone jack, and an "audio in" jack.
1496 * These may not do anything useful with this driver yet, because I
1497 * haven't setup any initialization verbs for these yet...
1498 */
1499
1500static hda_nid_t alc880_w810_dac_nids[3] = {
1501	/* front, rear/surround, clfe */
1502	0x02, 0x03, 0x04
1503};
1504
1505/* fixed 6 channels */
1506static struct hda_channel_mode alc880_w810_modes[1] = {
1507	{ 6, NULL }
1508};
1509
1510/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1511static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1512	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1513	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1514	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1515	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1516	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1517	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1518	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1519	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1520	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1521	{ } /* end */
1522};
1523
1524
1525/*
1526 * Z710V model
1527 *
1528 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1529 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1530 *                 Line = 0x1a
1531 */
1532
1533static hda_nid_t alc880_z71v_dac_nids[1] = {
1534	0x02
1535};
1536#define ALC880_Z71V_HP_DAC	0x03
1537
1538/* fixed 2 channels */
1539static struct hda_channel_mode alc880_2_jack_modes[1] = {
1540	{ 2, NULL }
1541};
1542
1543static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1544	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1545	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1546	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1547	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1548	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1549	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1550	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1551	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1552	{ } /* end */
1553};
1554
1555
1556/*
1557 * ALC880 F1734 model
1558 *
1559 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1560 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1561 */
1562
1563static hda_nid_t alc880_f1734_dac_nids[1] = {
1564	0x03
1565};
1566#define ALC880_F1734_HP_DAC	0x02
1567
1568static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1569	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1570	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1571	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1572	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1573	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1574	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1575	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1576	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1577	{ } /* end */
1578};
1579
1580static struct hda_input_mux alc880_f1734_capture_source = {
1581	.num_items = 2,
1582	.items = {
1583		{ "Mic", 0x1 },
1584		{ "CD", 0x4 },
1585	},
1586};
1587
1588
1589/*
1590 * ALC880 ASUS model
1591 *
1592 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1593 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1594 *  Mic = 0x18, Line = 0x1a
1595 */
1596
1597#define alc880_asus_dac_nids	alc880_w810_dac_nids	/* identical with w810 */
1598#define alc880_asus_modes	alc880_threestack_modes	/* 2/6 channel mode */
1599
1600static struct snd_kcontrol_new alc880_asus_mixer[] = {
1601	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1602	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1603	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1604	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1605	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1606	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1607	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1608	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1609	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1610	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1611	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1612	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1613	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1614	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1615	{
1616		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1617		.name = "Channel Mode",
1618		.info = alc_ch_mode_info,
1619		.get = alc_ch_mode_get,
1620		.put = alc_ch_mode_put,
1621	},
1622	{ } /* end */
1623};
1624
1625/*
1626 * ALC880 ASUS W1V model
1627 *
1628 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1629 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1630 *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1631 */
1632
1633/* additional mixers to alc880_asus_mixer */
1634static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1635	HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1636	HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1637	{ } /* end */
1638};
1639
1640/* additional mixers to alc880_asus_mixer */
1641static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1642	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1643	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1644	{ } /* end */
1645};
1646
1647/* TCL S700 */
1648static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1649	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1650	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1651	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1652	HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1653	HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1654	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1655	HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1656	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1657	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1658	{ } /* end */
1659};
1660
1661/* Uniwill */
1662static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1663	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1664	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1665	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1666	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1667	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1668	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1669	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1670	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1671	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1672	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1673	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1674	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1675	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1676	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1677	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1678	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1679	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1680	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1681	{
1682		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1683		.name = "Channel Mode",
1684		.info = alc_ch_mode_info,
1685		.get = alc_ch_mode_get,
1686		.put = alc_ch_mode_put,
1687	},
1688	{ } /* end */
1689};
1690
1691static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1692	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1693	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1694	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1695	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1696	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1697	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1698	HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1699	HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1700	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1701	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1702	{ } /* end */
1703};
1704
1705static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1706	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1707	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1708	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1709	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1710	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1711	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1712	{ } /* end */
1713};
1714
1715/*
1716 * virtual master controls
1717 */
1718
1719/*
1720 * slave controls for virtual master
1721 */
1722static const char *alc_slave_vols[] = {
1723	"Front Playback Volume",
1724	"Surround Playback Volume",
1725	"Center Playback Volume",
1726	"LFE Playback Volume",
1727	"Side Playback Volume",
1728	"Headphone Playback Volume",
1729	"Speaker Playback Volume",
1730	"Mono Playback Volume",
1731	"Line-Out Playback Volume",
1732	"PCM Playback Volume",
1733	NULL,
1734};
1735
1736static const char *alc_slave_sws[] = {
1737	"Front Playback Switch",
1738	"Surround Playback Switch",
1739	"Center Playback Switch",
1740	"LFE Playback Switch",
1741	"Side Playback Switch",
1742	"Headphone Playback Switch",
1743	"Speaker Playback Switch",
1744	"Mono Playback Switch",
1745	"IEC958 Playback Switch",
1746	NULL,
1747};
1748
1749/*
1750 * build control elements
1751 */
1752
1753static void alc_free_kctls(struct hda_codec *codec);
1754
1755static int alc_build_controls(struct hda_codec *codec)
1756{
1757	struct alc_spec *spec = codec->spec;
1758	int err;
1759	int i;
1760
1761	for (i = 0; i < spec->num_mixers; i++) {
1762		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1763		if (err < 0)
1764			return err;
1765	}
1766	if (spec->cap_mixer) {
1767		err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
1768		if (err < 0)
1769			return err;
1770	}
1771	if (spec->multiout.dig_out_nid) {
1772		err = snd_hda_create_spdif_out_ctls(codec,
1773						    spec->multiout.dig_out_nid);
1774		if (err < 0)
1775			return err;
1776		err = snd_hda_create_spdif_share_sw(codec,
1777						    &spec->multiout);
1778		if (err < 0)
1779			return err;
1780		spec->multiout.share_spdif = 1;
1781	}
1782	if (spec->dig_in_nid) {
1783		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1784		if (err < 0)
1785			return err;
1786	}
1787
1788	/* if we have no master control, let's create it */
1789	if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1790		unsigned int vmaster_tlv[4];
1791		snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1792					HDA_OUTPUT, vmaster_tlv);
1793		err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1794					  vmaster_tlv, alc_slave_vols);
1795		if (err < 0)
1796			return err;
1797	}
1798	if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1799		err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1800					  NULL, alc_slave_sws);
1801		if (err < 0)
1802			return err;
1803	}
1804
1805	alc_free_kctls(codec); /* no longer needed */
1806	return 0;
1807}
1808
1809
1810/*
1811 * initialize the codec volumes, etc
1812 */
1813
1814/*
1815 * generic initialization of ADC, input mixers and output mixers
1816 */
1817static struct hda_verb alc880_volume_init_verbs[] = {
1818	/*
1819	 * Unmute ADC0-2 and set the default input to mic-in
1820	 */
1821	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1822	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1823	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1824	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1825	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1826	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1827
1828	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1829	 * mixer widget
1830	 * Note: PASD motherboards uses the Line In 2 as the input for front
1831	 * panel mic (mic 2)
1832	 */
1833	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1834	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1835	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1836	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1837	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1838	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1839	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1840	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1841
1842	/*
1843	 * Set up output mixers (0x0c - 0x0f)
1844	 */
1845	/* set vol=0 to output mixers */
1846	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1847	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1848	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1849	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1850	/* set up input amps for analog loopback */
1851	/* Amp Indices: DAC = 0, mixer = 1 */
1852	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1853	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1854	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1855	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1856	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1857	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1858	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1859	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1860
1861	{ }
1862};
1863
1864/*
1865 * 3-stack pin configuration:
1866 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1867 */
1868static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1869	/*
1870	 * preset connection lists of input pins
1871	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1872	 */
1873	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1874	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1875	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1876
1877	/*
1878	 * Set pin mode and muting
1879	 */
1880	/* set front pin widgets 0x14 for output */
1881	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1882	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1883	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1884	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1885	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1886	/* Mic2 (as headphone out) for HP output */
1887	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1888	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1889	/* Line In pin widget for input */
1890	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1891	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1892	/* Line2 (as front mic) pin widget for input and vref at 80% */
1893	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1894	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1895	/* CD pin widget for input */
1896	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1897
1898	{ }
1899};
1900
1901/*
1902 * 5-stack pin configuration:
1903 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1904 * line-in/side = 0x1a, f-mic = 0x1b
1905 */
1906static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1907	/*
1908	 * preset connection lists of input pins
1909	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1910	 */
1911	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1912	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1913
1914	/*
1915	 * Set pin mode and muting
1916	 */
1917	/* set pin widgets 0x14-0x17 for output */
1918	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1919	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1920	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1921	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1922	/* unmute pins for output (no gain on this amp) */
1923	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1924	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1925	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1926	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1927
1928	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1929	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1930	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1931	/* Mic2 (as headphone out) for HP output */
1932	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1933	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1934	/* Line In pin widget for input */
1935	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1936	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1937	/* Line2 (as front mic) pin widget for input and vref at 80% */
1938	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1939	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1940	/* CD pin widget for input */
1941	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1942
1943	{ }
1944};
1945
1946/*
1947 * W810 pin configuration:
1948 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1949 */
1950static struct hda_verb alc880_pin_w810_init_verbs[] = {
1951	/* hphone/speaker input selector: front DAC */
1952	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1953
1954	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1955	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1956	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1957	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1958	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1959	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1960
1961	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1962	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1963
1964	{ }
1965};
1966
1967/*
1968 * Z71V pin configuration:
1969 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1970 */
1971static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1972	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1973	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1974	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1975	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1976
1977	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1978	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1979	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1980	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1981
1982	{ }
1983};
1984
1985/*
1986 * 6-stack pin configuration:
1987 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1988 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1989 */
1990static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1991	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1992
1993	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1994	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1995	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1996	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1997	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1998	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1999	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2000	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2001
2002	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2003	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2004	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2005	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2006	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2007	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2008	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2009	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2010	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2011
2012	{ }
2013};
2014
2015/*
2016 * Uniwill pin configuration:
2017 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2018 * line = 0x1a
2019 */
2020static struct hda_verb alc880_uniwill_init_verbs[] = {
2021	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2022
2023	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2024	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2025	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2026	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2027	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2028	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2029	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2030	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2031	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2032	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2033	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2034	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2035	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2036	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2037
2038	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2039	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2040	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2041	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2042	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2043	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2044	/* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2045	/* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2046	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2047
2048	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2049	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2050
2051	{ }
2052};
2053
2054/*
2055* Uniwill P53
2056* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
2057 */
2058static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2059	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2060
2061	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2062	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2063	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2064	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2065	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2066	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2067	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2068	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2069	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2070	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2071	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2072	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2073
2074	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2075	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2076	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2077	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2078	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2079	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2080
2081	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2082	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2083
2084	{ }
2085};
2086
2087static struct hda_verb alc880_beep_init_verbs[] = {
2088	{ 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2089	{ }
2090};
2091
2092/* toggle speaker-output according to the hp-jack state */
2093static void alc880_uniwill_hp_automute(struct hda_codec *codec)
2094{
2095 	unsigned int present;
2096	unsigned char bits;
2097
2098 	present = snd_hda_codec_read(codec, 0x14, 0,
2099				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2100	bits = present ? HDA_AMP_MUTE : 0;
2101	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
2102				 HDA_AMP_MUTE, bits);
2103	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
2104				 HDA_AMP_MUTE, bits);
2105}
2106
2107/* auto-toggle front mic */
2108static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2109{
2110 	unsigned int present;
2111	unsigned char bits;
2112
2113	present = snd_hda_codec_read(codec, 0x18, 0,
2114				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2115	bits = present ? HDA_AMP_MUTE : 0;
2116	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2117}
2118
2119static void alc880_uniwill_automute(struct hda_codec *codec)
2120{
2121	alc880_uniwill_hp_automute(codec);
2122	alc880_uniwill_mic_automute(codec);
2123}
2124
2125static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2126				       unsigned int res)
2127{
2128	/* Looks like the unsol event is incompatible with the standard
2129	 * definition.  4bit tag is placed at 28 bit!
2130	 */
2131	switch (res >> 28) {
2132	case ALC880_HP_EVENT:
2133		alc880_uniwill_hp_automute(codec);
2134		break;
2135	case ALC880_MIC_EVENT:
2136		alc880_uniwill_mic_automute(codec);
2137		break;
2138	}
2139}
2140
2141static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
2142{
2143 	unsigned int present;
2144	unsigned char bits;
2145
2146 	present = snd_hda_codec_read(codec, 0x14, 0,
2147				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2148	bits = present ? HDA_AMP_MUTE : 0;
2149	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
2150}
2151
2152static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2153{
2154	unsigned int present;
2155
2156	present = snd_hda_codec_read(codec, 0x21, 0,
2157				     AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2158	present &= HDA_AMP_VOLMASK;
2159	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2160				 HDA_AMP_VOLMASK, present);
2161	snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2162				 HDA_AMP_VOLMASK, present);
2163}
2164
2165static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2166					   unsigned int res)
2167{
2168	/* Looks like the unsol event is incompatible with the standard
2169	 * definition.  4bit tag is placed at 28 bit!
2170	 */
2171	if ((res >> 28) == ALC880_HP_EVENT)
2172		alc880_uniwill_p53_hp_automute(codec);
2173	if ((res >> 28) == ALC880_DCVOL_EVENT)
2174		alc880_uniwill_p53_dcvol_automute(codec);
2175}
2176
2177/*
2178 * F1734 pin configuration:
2179 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2180 */
2181static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2182	{0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2183	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2184	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2185	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2186	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2187
2188	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2189	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2190	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2191	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2192
2193	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2194	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2195	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2196	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2197	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2198	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2199	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2200	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2201	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2202
2203	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2204	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2205
2206	{ }
2207};
2208
2209/*
2210 * ASUS pin configuration:
2211 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2212 */
2213static struct hda_verb alc880_pin_asus_init_verbs[] = {
2214	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2215	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2216	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2217	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2218
2219	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2220	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2221	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2222	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2223	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2224	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2225	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2226	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2227
2228	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2229	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2230	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2231	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2232	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2233	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2234	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2235	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2236	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2237
2238	{ }
2239};
2240
2241/* Enable GPIO mask and set output */
2242#define alc880_gpio1_init_verbs	alc_gpio1_init_verbs
2243#define alc880_gpio2_init_verbs	alc_gpio2_init_verbs
2244
2245/* Clevo m520g init */
2246static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2247	/* headphone output */
2248	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2249	/* line-out */
2250	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2251	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2252	/* Line-in */
2253	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2254	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2255	/* CD */
2256	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2257	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2258	/* Mic1 (rear panel) */
2259	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2260	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2261	/* Mic2 (front panel) */
2262	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2263	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2264	/* headphone */
2265	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2266	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2267        /* change to EAPD mode */
2268	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2269	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2270
2271	{ }
2272};
2273
2274static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2275	/* change to EAPD mode */
2276	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2277	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2278
2279	/* Headphone output */
2280	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2281	/* Front output*/
2282	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2283	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2284
2285	/* Line In pin widget for input */
2286	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2287	/* CD pin widget for input */
2288	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2289	/* Mic1 (rear panel) pin widget for input and vref at 80% */
2290	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2291
2292	/* change to EAPD mode */
2293	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2294	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
2295
2296	{ }
2297};
2298
2299/*
2300 * LG m1 express dual
2301 *
2302 * Pin assignment:
2303 *   Rear Line-In/Out (blue): 0x14
2304 *   Build-in Mic-In: 0x15
2305 *   Speaker-out: 0x17
2306 *   HP-Out (green): 0x1b
2307 *   Mic-In/Out (red): 0x19
2308 *   SPDIF-Out: 0x1e
2309 */
2310
2311/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2312static hda_nid_t alc880_lg_dac_nids[3] = {
2313	0x05, 0x02, 0x03
2314};
2315
2316/* seems analog CD is not working */
2317static struct hda_input_mux alc880_lg_capture_source = {
2318	.num_items = 3,
2319	.items = {
2320		{ "Mic", 0x1 },
2321		{ "Line", 0x5 },
2322		{ "Internal Mic", 0x6 },
2323	},
2324};
2325
2326/* 2,4,6 channel modes */
2327static struct hda_verb alc880_lg_ch2_init[] = {
2328	/* set line-in and mic-in to input */
2329	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2330	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2331	{ }
2332};
2333
2334static struct hda_verb alc880_lg_ch4_init[] = {
2335	/* set line-in to out and mic-in to input */
2336	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2337	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2338	{ }
2339};
2340
2341static struct hda_verb alc880_lg_ch6_init[] = {
2342	/* set line-in and mic-in to output */
2343	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2344	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2345	{ }
2346};
2347
2348static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2349	{ 2, alc880_lg_ch2_init },
2350	{ 4, alc880_lg_ch4_init },
2351	{ 6, alc880_lg_ch6_init },
2352};
2353
2354static struct snd_kcontrol_new alc880_lg_mixer[] = {
2355	HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2356	HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2357	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2358	HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2359	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2360	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2361	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2362	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2363	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2364	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2365	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2366	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2367	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2368	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2369	{
2370		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2371		.name = "Channel Mode",
2372		.info = alc_ch_mode_info,
2373		.get = alc_ch_mode_get,
2374		.put = alc_ch_mode_put,
2375	},
2376	{ } /* end */
2377};
2378
2379static struct hda_verb alc880_lg_init_verbs[] = {
2380	/* set capture source to mic-in */
2381	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2382	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2383	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2384	/* mute all amp mixer inputs */
2385	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2386	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2387	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2388	/* line-in to input */
2389	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2390	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2391	/* built-in mic */
2392	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2393	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2394	/* speaker-out */
2395	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2396	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2397	/* mic-in to input */
2398	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2399	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2400	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2401	/* HP-out */
2402	{0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2403	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2404	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2405	/* jack sense */
2406	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2407	{ }
2408};
2409
2410/* toggle speaker-output according to the hp-jack state */
2411static void alc880_lg_automute(struct hda_codec *codec)
2412{
2413	unsigned int present;
2414	unsigned char bits;
2415
2416	present = snd_hda_codec_read(codec, 0x1b, 0,
2417				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2418	bits = present ? HDA_AMP_MUTE : 0;
2419	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2420				 HDA_AMP_MUTE, bits);
2421}
2422
2423static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2424{
2425	/* Looks like the unsol event is incompatible with the standard
2426	 * definition.  4bit tag is placed at 28 bit!
2427	 */
2428	if ((res >> 28) == 0x01)
2429		alc880_lg_automute(codec);
2430}
2431
2432/*
2433 * LG LW20
2434 *
2435 * Pin assignment:
2436 *   Speaker-out: 0x14
2437 *   Mic-In: 0x18
2438 *   Built-in Mic-In: 0x19
2439 *   Line-In: 0x1b
2440 *   HP-Out: 0x1a
2441 *   SPDIF-Out: 0x1e
2442 */
2443
2444static struct hda_input_mux alc880_lg_lw_capture_source = {
2445	.num_items = 3,
2446	.items = {
2447		{ "Mic", 0x0 },
2448		{ "Internal Mic", 0x1 },
2449		{ "Line In", 0x2 },
2450	},
2451};
2452
2453#define alc880_lg_lw_modes alc880_threestack_modes
2454
2455static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2456	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2457	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2458	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2459	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2460	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2461	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2462	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2463	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2464	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2465	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2466	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2467	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2468	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2469	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2470	{
2471		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2472		.name = "Channel Mode",
2473		.info = alc_ch_mode_info,
2474		.get = alc_ch_mode_get,
2475		.put = alc_ch_mode_put,
2476	},
2477	{ } /* end */
2478};
2479
2480static struct hda_verb alc880_lg_lw_init_verbs[] = {
2481	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2482	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2483	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2484
2485	/* set capture source to mic-in */
2486	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2487	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2488	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2489	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2490	/* speaker-out */
2491	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2492	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2493	/* HP-out */
2494	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2495	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2496	/* mic-in to input */
2497	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2498	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2499	/* built-in mic */
2500	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2501	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2502	/* jack sense */
2503	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2504	{ }
2505};
2506
2507/* toggle speaker-output according to the hp-jack state */
2508static void alc880_lg_lw_automute(struct hda_codec *codec)
2509{
2510	unsigned int present;
2511	unsigned char bits;
2512
2513	present = snd_hda_codec_read(codec, 0x1b, 0,
2514				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2515	bits = present ? HDA_AMP_MUTE : 0;
2516	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2517				 HDA_AMP_MUTE, bits);
2518}
2519
2520static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2521{
2522	/* Looks like the unsol event is incompatible with the standard
2523	 * definition.  4bit tag is placed at 28 bit!
2524	 */
2525	if ((res >> 28) == 0x01)
2526		alc880_lg_lw_automute(codec);
2527}
2528
2529static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2530	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2531	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2532	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2533	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2534	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2535	HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2536	{ } /* end */
2537};
2538
2539static struct hda_input_mux alc880_medion_rim_capture_source = {
2540	.num_items = 2,
2541	.items = {
2542		{ "Mic", 0x0 },
2543		{ "Internal Mic", 0x1 },
2544	},
2545};
2546
2547static struct hda_verb alc880_medion_rim_init_verbs[] = {
2548	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2549
2550	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2551	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2552
2553	/* Mic1 (rear panel) pin widget for input and vref at 80% */
2554	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2555	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2556	/* Mic2 (as headphone out) for HP output */
2557	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2558	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2559	/* Internal Speaker */
2560	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2561	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2562
2563	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2564	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2565
2566	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2567	{ }
2568};
2569
2570/* toggle speaker-output according to the hp-jack state */
2571static void alc880_medion_rim_automute(struct hda_codec *codec)
2572{
2573	unsigned int present;
2574	unsigned char bits;
2575
2576	present = snd_hda_codec_read(codec, 0x14, 0,
2577				     AC_VERB_GET_PIN_SENSE, 0)
2578		& AC_PINSENSE_PRESENCE;
2579	bits = present ? HDA_AMP_MUTE : 0;
2580	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
2581				 HDA_AMP_MUTE, bits);
2582	if (present)
2583		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2584	else
2585		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2586}
2587
2588static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2589					  unsigned int res)
2590{
2591	/* Looks like the unsol event is incompatible with the standard
2592	 * definition.  4bit tag is placed at 28 bit!
2593	 */
2594	if ((res >> 28) == ALC880_HP_EVENT)
2595		alc880_medion_rim_automute(codec);
2596}
2597
2598#ifdef CONFIG_SND_HDA_POWER_SAVE
2599static struct hda_amp_list alc880_loopbacks[] = {
2600	{ 0x0b, HDA_INPUT, 0 },
2601	{ 0x0b, HDA_INPUT, 1 },
2602	{ 0x0b, HDA_INPUT, 2 },
2603	{ 0x0b, HDA_INPUT, 3 },
2604	{ 0x0b, HDA_INPUT, 4 },
2605	{ } /* end */
2606};
2607
2608static struct hda_amp_list alc880_lg_loopbacks[] = {
2609	{ 0x0b, HDA_INPUT, 1 },
2610	{ 0x0b, HDA_INPUT, 6 },
2611	{ 0x0b, HDA_INPUT, 7 },
2612	{ } /* end */
2613};
2614#endif
2615
2616/*
2617 * Common callbacks
2618 */
2619
2620static int alc_init(struct hda_codec *codec)
2621{
2622	struct alc_spec *spec = codec->spec;
2623	unsigned int i;
2624
2625	alc_fix_pll(codec);
2626	if (codec->vendor_id == 0x10ec0888)
2627		alc888_coef_init(codec);
2628
2629	for (i = 0; i < spec->num_init_verbs; i++)
2630		snd_hda_sequence_write(codec, spec->init_verbs[i]);
2631
2632	if (spec->init_hook)
2633		spec->init_hook(codec);
2634
2635	return 0;
2636}
2637
2638static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2639{
2640	struct alc_spec *spec = codec->spec;
2641
2642	if (spec->unsol_event)
2643		spec->unsol_event(codec, res);
2644}
2645
2646#ifdef CONFIG_SND_HDA_POWER_SAVE
2647static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2648{
2649	struct alc_spec *spec = codec->spec;
2650	return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2651}
2652#endif
2653
2654/*
2655 * Analog playback callbacks
2656 */
2657static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2658				    struct hda_codec *codec,
2659				    struct snd_pcm_substream *substream)
2660{
2661	struct alc_spec *spec = codec->spec;
2662	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2663					     hinfo);
2664}
2665
2666static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2667				       struct hda_codec *codec,
2668				       unsigned int stream_tag,
2669				       unsigned int format,
2670				       struct snd_pcm_substream *substream)
2671{
2672	struct alc_spec *spec = codec->spec;
2673	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2674						stream_tag, format, substream);
2675}
2676
2677static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2678				       struct hda_codec *codec,
2679				       struct snd_pcm_substream *substream)
2680{
2681	struct alc_spec *spec = codec->spec;
2682	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2683}
2684
2685/*
2686 * Digital out
2687 */
2688static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2689					struct hda_codec *codec,
2690					struct snd_pcm_substream *substream)
2691{
2692	struct alc_spec *spec = codec->spec;
2693	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2694}
2695
2696static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2697					   struct hda_codec *codec,
2698					   unsigned int stream_tag,
2699					   unsigned int format,
2700					   struct snd_pcm_substream *substream)
2701{
2702	struct alc_spec *spec = codec->spec;
2703	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2704					     stream_tag, format, substream);
2705}
2706
2707static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2708					 struct hda_codec *codec,
2709					 struct snd_pcm_substream *substream)
2710{
2711	struct alc_spec *spec = codec->spec;
2712	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2713}
2714
2715/*
2716 * Analog capture
2717 */
2718static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2719				      struct hda_codec *codec,
2720				      unsigned int stream_tag,
2721				      unsigned int format,
2722				      struct snd_pcm_substream *substream)
2723{
2724	struct alc_spec *spec = codec->spec;
2725
2726	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
2727				   stream_tag, 0, format);
2728	return 0;
2729}
2730
2731static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2732				      struct hda_codec *codec,
2733				      struct snd_pcm_substream *substream)
2734{
2735	struct alc_spec *spec = codec->spec;
2736
2737	snd_hda_codec_cleanup_stream(codec,
2738				     spec->adc_nids[substream->number + 1]);
2739	return 0;
2740}
2741
2742
2743/*
2744 */
2745static struct hda_pcm_stream alc880_pcm_analog_playback = {
2746	.substreams = 1,
2747	.channels_min = 2,
2748	.channels_max = 8,
2749	/* NID is set in alc_build_pcms */
2750	.ops = {
2751		.open = alc880_playback_pcm_open,
2752		.prepare = alc880_playback_pcm_prepare,
2753		.cleanup = alc880_playback_pcm_cleanup
2754	},
2755};
2756
2757static struct hda_pcm_stream alc880_pcm_analog_capture = {
2758	.substreams = 1,
2759	.channels_min = 2,
2760	.channels_max = 2,
2761	/* NID is set in alc_build_pcms */
2762};
2763
2764static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
2765	.substreams = 1,
2766	.channels_min = 2,
2767	.channels_max = 2,
2768	/* NID is set in alc_build_pcms */
2769};
2770
2771static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
2772	.substreams = 2, /* can be overridden */
2773	.channels_min = 2,
2774	.channels_max = 2,
2775	/* NID is set in alc_build_pcms */
2776	.ops = {
2777		.prepare = alc880_alt_capture_pcm_prepare,
2778		.cleanup = alc880_alt_capture_pcm_cleanup
2779	},
2780};
2781
2782static struct hda_pcm_stream alc880_pcm_digital_playback = {
2783	.substreams = 1,
2784	.channels_min = 2,
2785	.channels_max = 2,
2786	/* NID is set in alc_build_pcms */
2787	.ops = {
2788		.open = alc880_dig_playback_pcm_open,
2789		.close = alc880_dig_playback_pcm_close,
2790		.prepare = alc880_dig_playback_pcm_prepare
2791	},
2792};
2793
2794static struct hda_pcm_stream alc880_pcm_digital_capture = {
2795	.substreams = 1,
2796	.channels_min = 2,
2797	.channels_max = 2,
2798	/* NID is set in alc_build_pcms */
2799};
2800
2801/* Used by alc_build_pcms to flag that a PCM has no playback stream */
2802static struct hda_pcm_stream alc_pcm_null_stream = {
2803	.substreams = 0,
2804	.channels_min = 0,
2805	.channels_max = 0,
2806};
2807
2808static int alc_build_pcms(struct hda_codec *codec)
2809{
2810	struct alc_spec *spec = codec->spec;
2811	struct hda_pcm *info = spec->pcm_rec;
2812	int i;
2813
2814	codec->num_pcms = 1;
2815	codec->pcm_info = info;
2816
2817	info->name = spec->stream_name_analog;
2818	if (spec->stream_analog_playback) {
2819		if (snd_BUG_ON(!spec->multiout.dac_nids))
2820			return -EINVAL;
2821		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2822		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2823	}
2824	if (spec->stream_analog_capture) {
2825		if (snd_BUG_ON(!spec->adc_nids))
2826			return -EINVAL;
2827		info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2828		info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2829	}
2830
2831	if (spec->channel_mode) {
2832		info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2833		for (i = 0; i < spec->num_channel_mode; i++) {
2834			if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2835				info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2836			}
2837		}
2838	}
2839
2840	/* SPDIF for stream index #1 */
2841	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2842		codec->num_pcms = 2;
2843		info = spec->pcm_rec + 1;
2844		info->name = spec->stream_name_digital;
2845		info->pcm_type = HDA_PCM_TYPE_SPDIF;
2846		if (spec->multiout.dig_out_nid &&
2847		    spec->stream_digital_playback) {
2848			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2849			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2850		}
2851		if (spec->dig_in_nid &&
2852		    spec->stream_digital_capture) {
2853			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2854			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2855		}
2856		/* FIXME: do we need this for all Realtek codec models? */
2857		codec->spdif_status_reset = 1;
2858	}
2859
2860	/* If the use of more than one ADC is requested for the current
2861	 * model, configure a second analog capture-only PCM.
2862	 */
2863	/* Additional Analaog capture for index #2 */
2864	if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
2865	    (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
2866		codec->num_pcms = 3;
2867		info = spec->pcm_rec + 2;
2868		info->name = spec->stream_name_analog;
2869		if (spec->alt_dac_nid) {
2870			info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2871				*spec->stream_analog_alt_playback;
2872			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2873				spec->alt_dac_nid;
2874		} else {
2875			info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2876				alc_pcm_null_stream;
2877			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2878		}
2879		if (spec->num_adc_nids > 1) {
2880			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2881				*spec->stream_analog_alt_capture;
2882			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
2883				spec->adc_nids[1];
2884			info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
2885				spec->num_adc_nids - 1;
2886		} else {
2887			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2888				alc_pcm_null_stream;
2889			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
2890		}
2891	}
2892
2893	return 0;
2894}
2895
2896static void alc_free_kctls(struct hda_codec *codec)
2897{
2898	struct alc_spec *spec = codec->spec;
2899
2900	if (spec->kctls.list) {
2901		struct snd_kcontrol_new *kctl = spec->kctls.list;
2902		int i;
2903		for (i = 0; i < spec->kctls.used; i++)
2904			kfree(kctl[i].name);
2905	}
2906	snd_array_free(&spec->kctls);
2907}
2908
2909static void alc_free(struct hda_codec *codec)
2910{
2911	struct alc_spec *spec = codec->spec;
2912
2913	if (!spec)
2914		return;
2915
2916	alc_free_kctls(codec);
2917	kfree(spec);
2918	codec->spec = NULL; /* to be sure */
2919}
2920
2921#ifdef SND_HDA_NEEDS_RESUME
2922static void store_pin_configs(struct hda_codec *codec)
2923{
2924	struct alc_spec *spec = codec->spec;
2925	hda_nid_t nid, end_nid;
2926
2927	end_nid = codec->start_nid + codec->num_nodes;
2928	for (nid = codec->start_nid; nid < end_nid; nid++) {
2929		unsigned int wid_caps = get_wcaps(codec, nid);
2930		unsigned int wid_type =
2931			(wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
2932		if (wid_type != AC_WID_PIN)
2933			continue;
2934		if (spec->num_pins >= ARRAY_SIZE(spec->pin_nids))
2935			break;
2936		spec->pin_nids[spec->num_pins] = nid;
2937		spec->pin_cfgs[spec->num_pins] =
2938			snd_hda_codec_read(codec, nid, 0,
2939					   AC_VERB_GET_CONFIG_DEFAULT, 0);
2940		spec->num_pins++;
2941	}
2942}
2943
2944static void resume_pin_configs(struct hda_codec *codec)
2945{
2946	struct alc_spec *spec = codec->spec;
2947	int i;
2948
2949	for (i = 0; i < spec->num_pins; i++) {
2950		hda_nid_t pin_nid = spec->pin_nids[i];
2951		unsigned int pin_config = spec->pin_cfgs[i];
2952		snd_hda_codec_write(codec, pin_nid, 0,
2953				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
2954				    pin_config & 0x000000ff);
2955		snd_hda_codec_write(codec, pin_nid, 0,
2956				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
2957				    (pin_config & 0x0000ff00) >> 8);
2958		snd_hda_codec_write(codec, pin_nid, 0,
2959				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
2960				    (pin_config & 0x00ff0000) >> 16);
2961		snd_hda_codec_write(codec, pin_nid, 0,
2962				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
2963				    pin_config >> 24);
2964	}
2965}
2966
2967static int alc_resume(struct hda_codec *codec)
2968{
2969	resume_pin_configs(codec);
2970	codec->patch_ops.init(codec);
2971	snd_hda_codec_resume_amp(codec);
2972	snd_hda_codec_resume_cache(codec);
2973	return 0;
2974}
2975#else
2976#define store_pin_configs(codec)
2977#endif
2978
2979/*
2980 */
2981static struct hda_codec_ops alc_patch_ops = {
2982	.build_controls = alc_build_controls,
2983	.build_pcms = alc_build_pcms,
2984	.init = alc_init,
2985	.free = alc_free,
2986	.unsol_event = alc_unsol_event,
2987#ifdef SND_HDA_NEEDS_RESUME
2988	.resume = alc_resume,
2989#endif
2990#ifdef CONFIG_SND_HDA_POWER_SAVE
2991	.check_power_status = alc_check_power_status,
2992#endif
2993};
2994
2995
2996/*
2997 * Test configuration for debugging
2998 *
2999 * Almost all inputs/outputs are enabled.  I/O pins can be configured via
3000 * enum controls.
3001 */
3002#ifdef CONFIG_SND_DEBUG
3003static hda_nid_t alc880_test_dac_nids[4] = {
3004	0x02, 0x03, 0x04, 0x05
3005};
3006
3007static struct hda_input_mux alc880_test_capture_source = {
3008	.num_items = 7,
3009	.items = {
3010		{ "In-1", 0x0 },
3011		{ "In-2", 0x1 },
3012		{ "In-3", 0x2 },
3013		{ "In-4", 0x3 },
3014		{ "CD", 0x4 },
3015		{ "Front", 0x5 },
3016		{ "Surround", 0x6 },
3017	},
3018};
3019
3020static struct hda_channel_mode alc880_test_modes[4] = {
3021	{ 2, NULL },
3022	{ 4, NULL },
3023	{ 6, NULL },
3024	{ 8, NULL },
3025};
3026
3027static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3028				 struct snd_ctl_elem_info *uinfo)
3029{
3030	static char *texts[] = {
3031		"N/A", "Line Out", "HP Out",
3032		"In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3033	};
3034	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3035	uinfo->count = 1;
3036	uinfo->value.enumerated.items = 8;
3037	if (uinfo->value.enumerated.item >= 8)
3038		uinfo->value.enumerated.item = 7;
3039	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3040	return 0;
3041}
3042
3043static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3044				struct snd_ctl_elem_value *ucontrol)
3045{
3046	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3047	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3048	unsigned int pin_ctl, item = 0;
3049
3050	pin_ctl = snd_hda_codec_read(codec, nid, 0,
3051				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3052	if (pin_ctl & AC_PINCTL_OUT_EN) {
3053		if (pin_ctl & AC_PINCTL_HP_EN)
3054			item = 2;
3055		else
3056			item = 1;
3057	} else if (pin_ctl & AC_PINCTL_IN_EN) {
3058		switch (pin_ctl & AC_PINCTL_VREFEN) {
3059		case AC_PINCTL_VREF_HIZ: item = 3; break;
3060		case AC_PINCTL_VREF_50:  item = 4; break;
3061		case AC_PINCTL_VREF_GRD: item = 5; break;
3062		case AC_PINCTL_VREF_80:  item = 6; break;
3063		case AC_PINCTL_VREF_100: item = 7; break;
3064		}
3065	}
3066	ucontrol->value.enumerated.item[0] = item;
3067	return 0;
3068}
3069
3070static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3071				struct snd_ctl_elem_value *ucontrol)
3072{
3073	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3074	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3075	static unsigned int ctls[] = {
3076		0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3077		AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3078		AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3079		AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3080		AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3081		AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3082	};
3083	unsigned int old_ctl, new_ctl;
3084
3085	old_ctl = snd_hda_codec_read(codec, nid, 0,
3086				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3087	new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3088	if (old_ctl != new_ctl) {
3089		int val;
3090		snd_hda_codec_write_cache(codec, nid, 0,
3091					  AC_VERB_SET_PIN_WIDGET_CONTROL,
3092					  new_ctl);
3093		val = ucontrol->value.enumerated.item[0] >= 3 ?
3094			HDA_AMP_MUTE : 0;
3095		snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3096					 HDA_AMP_MUTE, val);
3097		return 1;
3098	}
3099	return 0;
3100}
3101
3102static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3103				 struct snd_ctl_elem_info *uinfo)
3104{
3105	static char *texts[] = {
3106		"Front", "Surround", "CLFE", "Side"
3107	};
3108	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3109	uinfo->count = 1;
3110	uinfo->value.enumerated.items = 4;
3111	if (uinfo->value.enumerated.item >= 4)
3112		uinfo->value.enumerated.item = 3;
3113	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3114	return 0;
3115}
3116
3117static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3118				struct snd_ctl_elem_value *ucontrol)
3119{
3120	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3121	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3122	unsigned int sel;
3123
3124	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3125	ucontrol->value.enumerated.item[0] = sel & 3;
3126	return 0;
3127}
3128
3129static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3130				struct snd_ctl_elem_value *ucontrol)
3131{
3132	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3133	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3134	unsigned int sel;
3135
3136	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3137	if (ucontrol->value.enumerated.item[0] != sel) {
3138		sel = ucontrol->value.enumerated.item[0] & 3;
3139		snd_hda_codec_write_cache(codec, nid, 0,
3140					  AC_VERB_SET_CONNECT_SEL, sel);
3141		return 1;
3142	}
3143	return 0;
3144}
3145
3146#define PIN_CTL_TEST(xname,nid) {			\
3147		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
3148			.name = xname,		       \
3149			.info = alc_test_pin_ctl_info, \
3150			.get = alc_test_pin_ctl_get,   \
3151			.put = alc_test_pin_ctl_put,   \
3152			.private_value = nid	       \
3153			}
3154
3155#define PIN_SRC_TEST(xname,nid) {			\
3156		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
3157			.name = xname,		       \
3158			.info = alc_test_pin_src_info, \
3159			.get = alc_test_pin_src_get,   \
3160			.put = alc_test_pin_src_put,   \
3161			.private_value = nid	       \
3162			}
3163
3164static struct snd_kcontrol_new alc880_test_mixer[] = {
3165	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3166	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3167	HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3168	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3169	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3170	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3171	HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3172	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
3173	PIN_CTL_TEST("Front Pin Mode", 0x14),
3174	PIN_CTL_TEST("Surround Pin Mode", 0x15),
3175	PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3176	PIN_CTL_TEST("Side Pin Mode", 0x17),
3177	PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3178	PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3179	PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3180	PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3181	PIN_SRC_TEST("In-1 Pin Source", 0x18),
3182	PIN_SRC_TEST("In-2 Pin Source", 0x19),
3183	PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3184	PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3185	HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3186	HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3187	HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3188	HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3189	HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3190	HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3191	HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3192	HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3193	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3194	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
3195	{
3196		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3197		.name = "Channel Mode",
3198		.info = alc_ch_mode_info,
3199		.get = alc_ch_mode_get,
3200		.put = alc_ch_mode_put,
3201	},
3202	{ } /* end */
3203};
3204
3205static struct hda_verb alc880_test_init_verbs[] = {
3206	/* Unmute inputs of 0x0c - 0x0f */
3207	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3208	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3209	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3210	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3211	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3212	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3213	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3214	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3215	/* Vol output for 0x0c-0x0f */
3216	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3217	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3218	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3219	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3220	/* Set output pins 0x14-0x17 */
3221	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3222	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3223	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3224	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3225	/* Unmute output pins 0x14-0x17 */
3226	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3227	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3228	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3229	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3230	/* Set input pins 0x18-0x1c */
3231	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3232	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3233	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3234	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3235	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3236	/* Mute input pins 0x18-0x1b */
3237	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3238	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3239	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3240	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3241	/* ADC set up */
3242	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3243	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3244	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3245	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3246	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3247	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3248	/* Analog input/passthru */
3249	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3250	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3251	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3252	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3253	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3254	{ }
3255};
3256#endif
3257
3258/*
3259 */
3260
3261static const char *alc880_models[ALC880_MODEL_LAST] = {
3262	[ALC880_3ST]		= "3stack",
3263	[ALC880_TCL_S700]	= "tcl",
3264	[ALC880_3ST_DIG]	= "3stack-digout",
3265	[ALC880_CLEVO]		= "clevo",
3266	[ALC880_5ST]		= "5stack",
3267	[ALC880_5ST_DIG]	= "5stack-digout",
3268	[ALC880_W810]		= "w810",
3269	[ALC880_Z71V]		= "z71v",
3270	[ALC880_6ST]		= "6stack",
3271	[ALC880_6ST_DIG]	= "6stack-digout",
3272	[ALC880_ASUS]		= "asus",
3273	[ALC880_ASUS_W1V]	= "asus-w1v",
3274	[ALC880_ASUS_DIG]	= "asus-dig",
3275	[ALC880_ASUS_DIG2]	= "asus-dig2",
3276	[ALC880_UNIWILL_DIG]	= "uniwill",
3277	[ALC880_UNIWILL_P53]	= "uniwill-p53",
3278	[ALC880_FUJITSU]	= "fujitsu",
3279	[ALC880_F1734]		= "F1734",
3280	[ALC880_LG]		= "lg",
3281	[ALC880_LG_LW]		= "lg-lw",
3282	[ALC880_MEDION_RIM]	= "medion",
3283#ifdef CONFIG_SND_DEBUG
3284	[ALC880_TEST]		= "test",
3285#endif
3286	[ALC880_AUTO]		= "auto",
3287};
3288
3289static struct snd_pci_quirk alc880_cfg_tbl[] = {
3290	SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3291	SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3292	SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3293	SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3294	SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3295	SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3296	SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3297	SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3298	SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3299	SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3300	SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3301	SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3302	SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3303	SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3304	SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3305	SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3306	SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3307	SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3308	/* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3309	SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3310	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3311	SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3312	SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3313	SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3314	SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3315	SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
3316	SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3317	SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3318	SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3319	SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3320	SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3321	SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3322	SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3323	SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3324	SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3325	SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3326	SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3327	SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3328	SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3329	SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3330	SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3331	SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3332	SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3333	SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3334	SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3335	SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3336	SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3337	SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3338	SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3339	SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3340	SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3341	SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3342	SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3343	SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3344	SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3345	SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3346	SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3347	SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3348	SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3349	SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3350	SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3351	SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3352	SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3353	SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3354	SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3355	SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3356	SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3357	SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3358	SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
3359	SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3360	SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3361	{}
3362};
3363
3364/*
3365 * ALC880 codec presets
3366 */
3367static struct alc_config_preset alc880_presets[] = {
3368	[ALC880_3ST] = {
3369		.mixers = { alc880_three_stack_mixer },
3370		.init_verbs = { alc880_volume_init_verbs,
3371				alc880_pin_3stack_init_verbs },
3372		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3373		.dac_nids = alc880_dac_nids,
3374		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3375		.channel_mode = alc880_threestack_modes,
3376		.need_dac_fix = 1,
3377		.input_mux = &alc880_capture_source,
3378	},
3379	[ALC880_3ST_DIG] = {
3380		.mixers = { alc880_three_stack_mixer },
3381		.init_verbs = { alc880_volume_init_verbs,
3382				alc880_pin_3stack_init_verbs },
3383		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3384		.dac_nids = alc880_dac_nids,
3385		.dig_out_nid = ALC880_DIGOUT_NID,
3386		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3387		.channel_mode = alc880_threestack_modes,
3388		.need_dac_fix = 1,
3389		.input_mux = &alc880_capture_source,
3390	},
3391	[ALC880_TCL_S700] = {
3392		.mixers = { alc880_tcl_s700_mixer },
3393		.init_verbs = { alc880_volume_init_verbs,
3394				alc880_pin_tcl_S700_init_verbs,
3395				alc880_gpio2_init_verbs },
3396		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3397		.dac_nids = alc880_dac_nids,
3398		.adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
3399		.num_adc_nids = 1, /* single ADC */
3400		.hp_nid = 0x03,
3401		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3402		.channel_mode = alc880_2_jack_modes,
3403		.input_mux = &alc880_capture_source,
3404	},
3405	[ALC880_5ST] = {
3406		.mixers = { alc880_three_stack_mixer,
3407			    alc880_five_stack_mixer},
3408		.init_verbs = { alc880_volume_init_verbs,
3409				alc880_pin_5stack_init_verbs },
3410		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3411		.dac_nids = alc880_dac_nids,
3412		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3413		.channel_mode = alc880_fivestack_modes,
3414		.input_mux = &alc880_capture_source,
3415	},
3416	[ALC880_5ST_DIG] = {
3417		.mixers = { alc880_three_stack_mixer,
3418			    alc880_five_stack_mixer },
3419		.init_verbs = { alc880_volume_init_verbs,
3420				alc880_pin_5stack_init_verbs },
3421		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3422		.dac_nids = alc880_dac_nids,
3423		.dig_out_nid = ALC880_DIGOUT_NID,
3424		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3425		.channel_mode = alc880_fivestack_modes,
3426		.input_mux = &alc880_capture_source,
3427	},
3428	[ALC880_6ST] = {
3429		.mixers = { alc880_six_stack_mixer },
3430		.init_verbs = { alc880_volume_init_verbs,
3431				alc880_pin_6stack_init_verbs },
3432		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3433		.dac_nids = alc880_6st_dac_nids,
3434		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3435		.channel_mode = alc880_sixstack_modes,
3436		.input_mux = &alc880_6stack_capture_source,
3437	},
3438	[ALC880_6ST_DIG] = {
3439		.mixers = { alc880_six_stack_mixer },
3440		.init_verbs = { alc880_volume_init_verbs,
3441				alc880_pin_6stack_init_verbs },
3442		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3443		.dac_nids = alc880_6st_dac_nids,
3444		.dig_out_nid = ALC880_DIGOUT_NID,
3445		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3446		.channel_mode = alc880_sixstack_modes,
3447		.input_mux = &alc880_6stack_capture_source,
3448	},
3449	[ALC880_W810] = {
3450		.mixers = { alc880_w810_base_mixer },
3451		.init_verbs = { alc880_volume_init_verbs,
3452				alc880_pin_w810_init_verbs,
3453				alc880_gpio2_init_verbs },
3454		.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3455		.dac_nids = alc880_w810_dac_nids,
3456		.dig_out_nid = ALC880_DIGOUT_NID,
3457		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3458		.channel_mode = alc880_w810_modes,
3459		.input_mux = &alc880_capture_source,
3460	},
3461	[ALC880_Z71V] = {
3462		.mixers = { alc880_z71v_mixer },
3463		.init_verbs = { alc880_volume_init_verbs,
3464				alc880_pin_z71v_init_verbs },
3465		.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3466		.dac_nids = alc880_z71v_dac_nids,
3467		.dig_out_nid = ALC880_DIGOUT_NID,
3468		.hp_nid = 0x03,
3469		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3470		.channel_mode = alc880_2_jack_modes,
3471		.input_mux = &alc880_capture_source,
3472	},
3473	[ALC880_F1734] = {
3474		.mixers = { alc880_f1734_mixer },
3475		.init_verbs = { alc880_volume_init_verbs,
3476				alc880_pin_f1734_init_verbs },
3477		.num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3478		.dac_nids = alc880_f1734_dac_nids,
3479		.hp_nid = 0x02,
3480		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3481		.channel_mode = alc880_2_jack_modes,
3482		.input_mux = &alc880_f1734_capture_source,
3483		.unsol_event = alc880_uniwill_p53_unsol_event,
3484		.init_hook = alc880_uniwill_p53_hp_automute,
3485	},
3486	[ALC880_ASUS] = {
3487		.mixers = { alc880_asus_mixer },
3488		.init_verbs = { alc880_volume_init_verbs,
3489				alc880_pin_asus_init_verbs,
3490				alc880_gpio1_init_verbs },
3491		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3492		.dac_nids = alc880_asus_dac_nids,
3493		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3494		.channel_mode = alc880_asus_modes,
3495		.need_dac_fix = 1,
3496		.input_mux = &alc880_capture_source,
3497	},
3498	[ALC880_ASUS_DIG] = {
3499		.mixers = { alc880_asus_mixer },
3500		.init_verbs = { alc880_volume_init_verbs,
3501				alc880_pin_asus_init_verbs,
3502				alc880_gpio1_init_verbs },
3503		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3504		.dac_nids = alc880_asus_dac_nids,
3505		.dig_out_nid = ALC880_DIGOUT_NID,
3506		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3507		.channel_mode = alc880_asus_modes,
3508		.need_dac_fix = 1,
3509		.input_mux = &alc880_capture_source,
3510	},
3511	[ALC880_ASUS_DIG2] = {
3512		.mixers = { alc880_asus_mixer },
3513		.init_verbs = { alc880_volume_init_verbs,
3514				alc880_pin_asus_init_verbs,
3515				alc880_gpio2_init_verbs }, /* use GPIO2 */
3516		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3517		.dac_nids = alc880_asus_dac_nids,
3518		.dig_out_nid = ALC880_DIGOUT_NID,
3519		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3520		.channel_mode = alc880_asus_modes,
3521		.need_dac_fix = 1,
3522		.input_mux = &alc880_capture_source,
3523	},
3524	[ALC880_ASUS_W1V] = {
3525		.mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3526		.init_verbs = { alc880_volume_init_verbs,
3527				alc880_pin_asus_init_verbs,
3528				alc880_gpio1_init_verbs },
3529		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3530		.dac_nids = alc880_asus_dac_nids,
3531		.dig_out_nid = ALC880_DIGOUT_NID,
3532		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3533		.channel_mode = alc880_asus_modes,
3534		.need_dac_fix = 1,
3535		.input_mux = &alc880_capture_source,
3536	},
3537	[ALC880_UNIWILL_DIG] = {
3538		.mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
3539		.init_verbs = { alc880_volume_init_verbs,
3540				alc880_pin_asus_init_verbs },
3541		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3542		.dac_nids = alc880_asus_dac_nids,
3543		.dig_out_nid = ALC880_DIGOUT_NID,
3544		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3545		.channel_mode = alc880_asus_modes,
3546		.need_dac_fix = 1,
3547		.input_mux = &alc880_capture_source,
3548	},
3549	[ALC880_UNIWILL] = {
3550		.mixers = { alc880_uniwill_mixer },
3551		.init_verbs = { alc880_volume_init_verbs,
3552				alc880_uniwill_init_verbs },
3553		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3554		.dac_nids = alc880_asus_dac_nids,
3555		.dig_out_nid = ALC880_DIGOUT_NID,
3556		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3557		.channel_mode = alc880_threestack_modes,
3558		.need_dac_fix = 1,
3559		.input_mux = &alc880_capture_source,
3560		.unsol_event = alc880_uniwill_unsol_event,
3561		.init_hook = alc880_uniwill_automute,
3562	},
3563	[ALC880_UNIWILL_P53] = {
3564		.mixers = { alc880_uniwill_p53_mixer },
3565		.init_verbs = { alc880_volume_init_verbs,
3566				alc880_uniwill_p53_init_verbs },
3567		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3568		.dac_nids = alc880_asus_dac_nids,
3569		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3570		.channel_mode = alc880_threestack_modes,
3571		.input_mux = &alc880_capture_source,
3572		.unsol_event = alc880_uniwill_p53_unsol_event,
3573		.init_hook = alc880_uniwill_p53_hp_automute,
3574	},
3575	[ALC880_FUJITSU] = {
3576		.mixers = { alc880_fujitsu_mixer,
3577			    alc880_pcbeep_mixer, },
3578		.init_verbs = { alc880_volume_init_verbs,
3579				alc880_uniwill_p53_init_verbs,
3580	       			alc880_beep_init_verbs },
3581		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3582		.dac_nids = alc880_dac_nids,
3583		.dig_out_nid = ALC880_DIGOUT_NID,
3584		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3585		.channel_mode = alc880_2_jack_modes,
3586		.input_mux = &alc880_capture_source,
3587		.unsol_event = alc880_uniwill_p53_unsol_event,
3588		.init_hook = alc880_uniwill_p53_hp_automute,
3589	},
3590	[ALC880_CLEVO] = {
3591		.mixers = { alc880_three_stack_mixer },
3592		.init_verbs = { alc880_volume_init_verbs,
3593				alc880_pin_clevo_init_verbs },
3594		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3595		.dac_nids = alc880_dac_nids,
3596		.hp_nid = 0x03,
3597		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3598		.channel_mode = alc880_threestack_modes,
3599		.need_dac_fix = 1,
3600		.input_mux = &alc880_capture_source,
3601	},
3602	[ALC880_LG] = {
3603		.mixers = { alc880_lg_mixer },
3604		.init_verbs = { alc880_volume_init_verbs,
3605				alc880_lg_init_verbs },
3606		.num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3607		.dac_nids = alc880_lg_dac_nids,
3608		.dig_out_nid = ALC880_DIGOUT_NID,
3609		.num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3610		.channel_mode = alc880_lg_ch_modes,
3611		.need_dac_fix = 1,
3612		.input_mux = &alc880_lg_capture_source,
3613		.unsol_event = alc880_lg_unsol_event,
3614		.init_hook = alc880_lg_automute,
3615#ifdef CONFIG_SND_HDA_POWER_SAVE
3616		.loopbacks = alc880_lg_loopbacks,
3617#endif
3618	},
3619	[ALC880_LG_LW] = {
3620		.mixers = { alc880_lg_lw_mixer },
3621		.init_verbs = { alc880_volume_init_verbs,
3622				alc880_lg_lw_init_verbs },
3623		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3624		.dac_nids = alc880_dac_nids,
3625		.dig_out_nid = ALC880_DIGOUT_NID,
3626		.num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3627		.channel_mode = alc880_lg_lw_modes,
3628		.input_mux = &alc880_lg_lw_capture_source,
3629		.unsol_event = alc880_lg_lw_unsol_event,
3630		.init_hook = alc880_lg_lw_automute,
3631	},
3632	[ALC880_MEDION_RIM] = {
3633		.mixers = { alc880_medion_rim_mixer },
3634		.init_verbs = { alc880_volume_init_verbs,
3635				alc880_medion_rim_init_verbs,
3636				alc_gpio2_init_verbs },
3637		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3638		.dac_nids = alc880_dac_nids,
3639		.dig_out_nid = ALC880_DIGOUT_NID,
3640		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3641		.channel_mode = alc880_2_jack_modes,
3642		.input_mux = &alc880_medion_rim_capture_source,
3643		.unsol_event = alc880_medion_rim_unsol_event,
3644		.init_hook = alc880_medion_rim_automute,
3645	},
3646#ifdef CONFIG_SND_DEBUG
3647	[ALC880_TEST] = {
3648		.mixers = { alc880_test_mixer },
3649		.init_verbs = { alc880_test_init_verbs },
3650		.num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3651		.dac_nids = alc880_test_dac_nids,
3652		.dig_out_nid = ALC880_DIGOUT_NID,
3653		.num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3654		.channel_mode = alc880_test_modes,
3655		.input_mux = &alc880_test_capture_source,
3656	},
3657#endif
3658};
3659
3660/*
3661 * Automatic parse of I/O pins from the BIOS configuration
3662 */
3663
3664enum {
3665	ALC_CTL_WIDGET_VOL,
3666	ALC_CTL_WIDGET_MUTE,
3667	ALC_CTL_BIND_MUTE,
3668};
3669static struct snd_kcontrol_new alc880_control_templates[] = {
3670	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3671	HDA_CODEC_MUTE(NULL, 0, 0, 0),
3672	HDA_BIND_MUTE(NULL, 0, 0, 0),
3673};
3674
3675/* add dynamic controls */
3676static int add_control(struct alc_spec *spec, int type, const char *name,
3677		       unsigned long val)
3678{
3679	struct snd_kcontrol_new *knew;
3680
3681	snd_array_init(&spec->kctls, sizeof(*knew), 32);
3682	knew = snd_array_new(&spec->kctls);
3683	if (!knew)
3684		return -ENOMEM;
3685	*knew = alc880_control_templates[type];
3686	knew->name = kstrdup(name, GFP_KERNEL);
3687	if (!knew->name)
3688		return -ENOMEM;
3689	knew->private_value = val;
3690	return 0;
3691}
3692
3693#define alc880_is_fixed_pin(nid)	((nid) >= 0x14 && (nid) <= 0x17)
3694#define alc880_fixed_pin_idx(nid)	((nid) - 0x14)
3695#define alc880_is_multi_pin(nid)	((nid) >= 0x18)
3696#define alc880_multi_pin_idx(nid)	((nid) - 0x18)
3697#define alc880_is_input_pin(nid)	((nid) >= 0x18)
3698#define alc880_input_pin_idx(nid)	((nid) - 0x18)
3699#define alc880_idx_to_dac(nid)		((nid) + 0x02)
3700#define alc880_dac_to_idx(nid)		((nid) - 0x02)
3701#define alc880_idx_to_mixer(nid)	((nid) + 0x0c)
3702#define alc880_idx_to_selector(nid)	((nid) + 0x10)
3703#define ALC880_PIN_CD_NID		0x1c
3704
3705/* fill in the dac_nids table from the parsed pin configuration */
3706static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3707				     const struct auto_pin_cfg *cfg)
3708{
3709	hda_nid_t nid;
3710	int assigned[4];
3711	int i, j;
3712
3713	memset(assigned, 0, sizeof(assigned));
3714	spec->multiout.dac_nids = spec->private_dac_nids;
3715
3716	/* check the pins hardwired to audio widget */
3717	for (i = 0; i < cfg->line_outs; i++) {
3718		nid = cfg->line_out_pins[i];
3719		if (alc880_is_fixed_pin(nid)) {
3720			int idx = alc880_fixed_pin_idx(nid);
3721			spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3722			assigned[idx] = 1;
3723		}
3724	}
3725	/* left pins can be connect to any audio widget */
3726	for (i = 0; i < cfg->line_outs; i++) {
3727		nid = cfg->line_out_pins[i];
3728		if (alc880_is_fixed_pin(nid))
3729			continue;
3730		/* search for an empty channel */
3731		for (j = 0; j < cfg->line_outs; j++) {
3732			if (!assigned[j]) {
3733				spec->multiout.dac_nids[i] =
3734					alc880_idx_to_dac(j);
3735				assigned[j] = 1;
3736				break;
3737			}
3738		}
3739	}
3740	spec->multiout.num_dacs = cfg->line_outs;
3741	return 0;
3742}
3743
3744/* add playback controls from the parsed DAC table */
3745static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3746					     const struct auto_pin_cfg *cfg)
3747{
3748	char name[32];
3749	static const char *chname[4] = {
3750		"Front", "Surround", NULL /*CLFE*/, "Side"
3751	};
3752	hda_nid_t nid;
3753	int i, err;
3754
3755	for (i = 0; i < cfg->line_outs; i++) {
3756		if (!spec->multiout.dac_nids[i])
3757			continue;
3758		nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3759		if (i == 2) {
3760			/* Center/LFE */
3761			err = add_control(spec, ALC_CTL_WIDGET_VOL,
3762					  "Center Playback Volume",
3763					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3764							      HDA_OUTPUT));
3765			if (err < 0)
3766				return err;
3767			err = add_control(spec, ALC_CTL_WIDGET_VOL,
3768					  "LFE Playback Volume",
3769					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3770							      HDA_OUTPUT));
3771			if (err < 0)
3772				return err;
3773			err = add_control(spec, ALC_CTL_BIND_MUTE,
3774					  "Center Playback Switch",
3775					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3776							      HDA_INPUT));
3777			if (err < 0)
3778				return err;
3779			err = add_control(spec, ALC_CTL_BIND_MUTE,
3780					  "LFE Playback Switch",
3781					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3782							      HDA_INPUT));
3783			if (err < 0)
3784				return err;
3785		} else {
3786			sprintf(name, "%s Playback Volume", chname[i]);
3787			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3788					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3789							      HDA_OUTPUT));
3790			if (err < 0)
3791				return err;
3792			sprintf(name, "%s Playback Switch", chname[i]);
3793			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3794					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3795							      HDA_INPUT));
3796			if (err < 0)
3797				return err;
3798		}
3799	}
3800	return 0;
3801}
3802
3803/* add playback controls for speaker and HP outputs */
3804static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3805					const char *pfx)
3806{
3807	hda_nid_t nid;
3808	int err;
3809	char name[32];
3810
3811	if (!pin)
3812		return 0;
3813
3814	if (alc880_is_fixed_pin(pin)) {
3815		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3816		/* specify the DAC as the extra output */
3817		if (!spec->multiout.hp_nid)
3818			spec->multiout.hp_nid = nid;
3819		else
3820			spec->multiout.extra_out_nid[0] = nid;
3821		/* control HP volume/switch on the output mixer amp */
3822		nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3823		sprintf(name, "%s Playback Volume", pfx);
3824		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3825				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3826		if (err < 0)
3827			return err;
3828		sprintf(name, "%s Playback Switch", pfx);
3829		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3830				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3831		if (err < 0)
3832			return err;
3833	} else if (alc880_is_multi_pin(pin)) {
3834		/* set manual connection */
3835		/* we have only a switch on HP-out PIN */
3836		sprintf(name, "%s Playback Switch", pfx);
3837		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3838				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3839		if (err < 0)
3840			return err;
3841	}
3842	return 0;
3843}
3844
3845/* create input playback/capture controls for the given pin */
3846static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3847			    const char *ctlname,
3848			    int idx, hda_nid_t mix_nid)
3849{
3850	char name[32];
3851	int err;
3852
3853	sprintf(name, "%s Playback Volume", ctlname);
3854	err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3855			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3856	if (err < 0)
3857		return err;
3858	sprintf(name, "%s Playback Switch", ctlname);
3859	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3860			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3861	if (err < 0)
3862		return err;
3863	return 0;
3864}
3865
3866/* create playback/capture controls for input pins */
3867static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3868						const struct auto_pin_cfg *cfg)
3869{
3870	struct hda_input_mux *imux = &spec->private_imux;
3871	int i, err, idx;
3872
3873	for (i = 0; i < AUTO_PIN_LAST; i++) {
3874		if (alc880_is_input_pin(cfg->input_pins[i])) {
3875			idx = alc880_input_pin_idx(cfg->input_pins[i]);
3876			err = new_analog_input(spec, cfg->input_pins[i],
3877					       auto_pin_cfg_labels[i],
3878					       idx, 0x0b);
3879			if (err < 0)
3880				return err;
3881			imux->items[imux->num_items].label =
3882				auto_pin_cfg_labels[i];
3883			imux->items[imux->num_items].index =
3884				alc880_input_pin_idx(cfg->input_pins[i]);
3885			imux->num_items++;
3886		}
3887	}
3888	return 0;
3889}
3890
3891static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
3892			       unsigned int pin_type)
3893{
3894	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3895			    pin_type);
3896	/* unmute pin */
3897	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3898			    AMP_OUT_UNMUTE);
3899}
3900
3901static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3902					      hda_nid_t nid, int pin_type,
3903					      int dac_idx)
3904{
3905	alc_set_pin_output(codec, nid, pin_type);
3906	/* need the manual connection? */
3907	if (alc880_is_multi_pin(nid)) {
3908		struct alc_spec *spec = codec->spec;
3909		int idx = alc880_multi_pin_idx(nid);
3910		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3911				    AC_VERB_SET_CONNECT_SEL,
3912				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3913	}
3914}
3915
3916static int get_pin_type(int line_out_type)
3917{
3918	if (line_out_type == AUTO_PIN_HP_OUT)
3919		return PIN_HP;
3920	else
3921		return PIN_OUT;
3922}
3923
3924static void alc880_auto_init_multi_out(struct hda_codec *codec)
3925{
3926	struct alc_spec *spec = codec->spec;
3927	int i;
3928
3929	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3930	for (i = 0; i < spec->autocfg.line_outs; i++) {
3931		hda_nid_t nid = spec->autocfg.line_out_pins[i];
3932		int pin_type = get_pin_type(spec->autocfg.line_out_type);
3933		alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3934	}
3935}
3936
3937static void alc880_auto_init_extra_out(struct hda_codec *codec)
3938{
3939	struct alc_spec *spec = codec->spec;
3940	hda_nid_t pin;
3941
3942	pin = spec->autocfg.speaker_pins[0];
3943	if (pin) /* connect to front */
3944		alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3945	pin = spec->autocfg.hp_pins[0];
3946	if (pin) /* connect to front */
3947		alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3948}
3949
3950static void alc880_auto_init_analog_input(struct hda_codec *codec)
3951{
3952	struct alc_spec *spec = codec->spec;
3953	int i;
3954
3955	for (i = 0; i < AUTO_PIN_LAST; i++) {
3956		hda_nid_t nid = spec->autocfg.input_pins[i];
3957		if (alc880_is_input_pin(nid)) {
3958			snd_hda_codec_write(codec, nid, 0,
3959					    AC_VERB_SET_PIN_WIDGET_CONTROL,
3960					    i <= AUTO_PIN_FRONT_MIC ?
3961					    PIN_VREF80 : PIN_IN);
3962			if (nid != ALC880_PIN_CD_NID)
3963				snd_hda_codec_write(codec, nid, 0,
3964						    AC_VERB_SET_AMP_GAIN_MUTE,
3965						    AMP_OUT_MUTE);
3966		}
3967	}
3968}
3969
3970/* parse the BIOS configuration and set up the alc_spec */
3971/* return 1 if successful, 0 if the proper config is not found,
3972 * or a negative error code
3973 */
3974static int alc880_parse_auto_config(struct hda_codec *codec)
3975{
3976	struct alc_spec *spec = codec->spec;
3977	int err;
3978	static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3979
3980	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3981					   alc880_ignore);
3982	if (err < 0)
3983		return err;
3984	if (!spec->autocfg.line_outs)
3985		return 0; /* can't find valid BIOS pin config */
3986
3987	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3988	if (err < 0)
3989		return err;
3990	err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3991	if (err < 0)
3992		return err;
3993	err = alc880_auto_create_extra_out(spec,
3994					   spec->autocfg.speaker_pins[0],
3995					   "Speaker");
3996	if (err < 0)
3997		return err;
3998	err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3999					   "Headphone");
4000	if (err < 0)
4001		return err;
4002	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
4003	if (err < 0)
4004		return err;
4005
4006	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4007
4008	if (spec->autocfg.dig_out_pin)
4009		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
4010	if (spec->autocfg.dig_in_pin)
4011		spec->dig_in_nid = ALC880_DIGIN_NID;
4012
4013	if (spec->kctls.list)
4014		add_mixer(spec, spec->kctls.list);
4015
4016	add_verb(spec, alc880_volume_init_verbs);
4017
4018	spec->num_mux_defs = 1;
4019	spec->input_mux = &spec->private_imux;
4020
4021	store_pin_configs(codec);
4022	return 1;
4023}
4024
4025/* additional initialization for auto-configuration model */
4026static void alc880_auto_init(struct hda_codec *codec)
4027{
4028	struct alc_spec *spec = codec->spec;
4029	alc880_auto_init_multi_out(codec);
4030	alc880_auto_init_extra_out(codec);
4031	alc880_auto_init_analog_input(codec);
4032	if (spec->unsol_event)
4033		alc_inithook(codec);
4034}
4035
4036/*
4037 * OK, here we have finally the patch for ALC880
4038 */
4039
4040static void set_capture_mixer(struct alc_spec *spec)
4041{
4042	static struct snd_kcontrol_new *caps[3] = {
4043		alc_capture_mixer1,
4044		alc_capture_mixer2,
4045		alc_capture_mixer3,
4046	};
4047	if (spec->num_adc_nids > 0 && spec->num_adc_nids < 3)
4048		spec->cap_mixer = caps[spec->num_adc_nids - 1];
4049}
4050
4051static int patch_alc880(struct hda_codec *codec)
4052{
4053	struct alc_spec *spec;
4054	int board_config;
4055	int err;
4056
4057	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4058	if (spec == NULL)
4059		return -ENOMEM;
4060
4061	codec->spec = spec;
4062
4063	board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4064						  alc880_models,
4065						  alc880_cfg_tbl);
4066	if (board_config < 0) {
4067		printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
4068		       "trying auto-probe from BIOS...\n");
4069		board_config = ALC880_AUTO;
4070	}
4071
4072	if (board_config == ALC880_AUTO) {
4073		/* automatic parse from the BIOS config */
4074		err = alc880_parse_auto_config(codec);
4075		if (err < 0) {
4076			alc_free(codec);
4077			return err;
4078		} else if (!err) {
4079			printk(KERN_INFO
4080			       "hda_codec: Cannot set up configuration "
4081			       "from BIOS.  Using 3-stack mode...\n");
4082			board_config = ALC880_3ST;
4083		}
4084	}
4085
4086	if (board_config != ALC880_AUTO)
4087		setup_preset(spec, &alc880_presets[board_config]);
4088
4089	spec->stream_name_analog = "ALC880 Analog";
4090	spec->stream_analog_playback = &alc880_pcm_analog_playback;
4091	spec->stream_analog_capture = &alc880_pcm_analog_capture;
4092	spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
4093
4094	spec->stream_name_digital = "ALC880 Digital";
4095	spec->stream_digital_playback = &alc880_pcm_digital_playback;
4096	spec->stream_digital_capture = &alc880_pcm_digital_capture;
4097
4098	if (!spec->adc_nids && spec->input_mux) {
4099		/* check whether NID 0x07 is valid */
4100		unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
4101		/* get type */
4102		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
4103		if (wcap != AC_WID_AUD_IN) {
4104			spec->adc_nids = alc880_adc_nids_alt;
4105			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
4106		} else {
4107			spec->adc_nids = alc880_adc_nids;
4108			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
4109		}
4110	}
4111	set_capture_mixer(spec);
4112
4113	spec->vmaster_nid = 0x0c;
4114
4115	codec->patch_ops = alc_patch_ops;
4116	if (board_config == ALC880_AUTO)
4117		spec->init_hook = alc880_auto_init;
4118#ifdef CONFIG_SND_HDA_POWER_SAVE
4119	if (!spec->loopback.amplist)
4120		spec->loopback.amplist = alc880_loopbacks;
4121#endif
4122
4123	return 0;
4124}
4125
4126
4127/*
4128 * ALC260 support
4129 */
4130
4131static hda_nid_t alc260_dac_nids[1] = {
4132	/* front */
4133	0x02,
4134};
4135
4136static hda_nid_t alc260_adc_nids[1] = {
4137	/* ADC0 */
4138	0x04,
4139};
4140
4141static hda_nid_t alc260_adc_nids_alt[1] = {
4142	/* ADC1 */
4143	0x05,
4144};
4145
4146/* NIDs used when simultaneous access to both ADCs makes sense.  Note that
4147 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4148 */
4149static hda_nid_t alc260_dual_adc_nids[2] = {
4150	/* ADC0, ADC1 */
4151	0x04, 0x05
4152};
4153
4154#define ALC260_DIGOUT_NID	0x03
4155#define ALC260_DIGIN_NID	0x06
4156
4157static struct hda_input_mux alc260_capture_source = {
4158	.num_items = 4,
4159	.items = {
4160		{ "Mic", 0x0 },
4161		{ "Front Mic", 0x1 },
4162		{ "Line", 0x2 },
4163		{ "CD", 0x4 },
4164	},
4165};
4166
4167/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
4168 * headphone jack and the internal CD lines since these are the only pins at
4169 * which audio can appear.  For flexibility, also allow the option of
4170 * recording the mixer output on the second ADC (ADC0 doesn't have a
4171 * connection to the mixer output).
4172 */
4173static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4174	{
4175		.num_items = 3,
4176		.items = {
4177			{ "Mic/Line", 0x0 },
4178			{ "CD", 0x4 },
4179			{ "Headphone", 0x2 },
4180		},
4181	},
4182	{
4183		.num_items = 4,
4184		.items = {
4185			{ "Mic/Line", 0x0 },
4186			{ "CD", 0x4 },
4187			{ "Headphone", 0x2 },
4188			{ "Mixer", 0x5 },
4189		},
4190	},
4191
4192};
4193
4194/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4195 * the Fujitsu S702x, but jacks are marked differently.
4196 */
4197static struct hda_input_mux alc260_acer_capture_sources[2] = {
4198	{
4199		.num_items = 4,
4200		.items = {
4201			{ "Mic", 0x0 },
4202			{ "Line", 0x2 },
4203			{ "CD", 0x4 },
4204			{ "Headphone", 0x5 },
4205		},
4206	},
4207	{
4208		.num_items = 5,
4209		.items = {
4210			{ "Mic", 0x0 },
4211			{ "Line", 0x2 },
4212			{ "CD", 0x4 },
4213			{ "Headphone", 0x6 },
4214			{ "Mixer", 0x5 },
4215		},
4216	},
4217};
4218/*
4219 * This is just place-holder, so there's something for alc_build_pcms to look
4220 * at when it calculates the maximum number of channels. ALC260 has no mixer
4221 * element which allows changing the channel mode, so the verb list is
4222 * never used.
4223 */
4224static struct hda_channel_mode alc260_modes[1] = {
4225	{ 2, NULL },
4226};
4227
4228
4229/* Mixer combinations
4230 *
4231 * basic: base_output + input + pc_beep + capture
4232 * HP: base_output + input + capture_alt
4233 * HP_3013: hp_3013 + input + capture
4234 * fujitsu: fujitsu + capture
4235 * acer: acer + capture
4236 */
4237
4238static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4239	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4240	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4241	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4242	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4243	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4244	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4245	{ } /* end */
4246};
4247
4248static struct snd_kcontrol_new alc260_input_mixer[] = {
4249	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4250	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4251	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4252	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4253	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4254	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4255	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4256	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4257	{ } /* end */
4258};
4259
4260static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
4261	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
4262	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
4263	{ } /* end */
4264};
4265
4266/* update HP, line and mono out pins according to the master switch */
4267static void alc260_hp_master_update(struct hda_codec *codec,
4268				    hda_nid_t hp, hda_nid_t line,
4269				    hda_nid_t mono)
4270{
4271	struct alc_spec *spec = codec->spec;
4272	unsigned int val = spec->master_sw ? PIN_HP : 0;
4273	/* change HP and line-out pins */
4274	snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4275			    val);
4276	snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4277			    val);
4278	/* mono (speaker) depending on the HP jack sense */
4279	val = (val && !spec->jack_present) ? PIN_OUT : 0;
4280	snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4281			    val);
4282}
4283
4284static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4285				   struct snd_ctl_elem_value *ucontrol)
4286{
4287	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4288	struct alc_spec *spec = codec->spec;
4289	*ucontrol->value.integer.value = spec->master_sw;
4290	return 0;
4291}
4292
4293static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4294				   struct snd_ctl_elem_value *ucontrol)
4295{
4296	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4297	struct alc_spec *spec = codec->spec;
4298	int val = !!*ucontrol->value.integer.value;
4299	hda_nid_t hp, line, mono;
4300
4301	if (val == spec->master_sw)
4302		return 0;
4303	spec->master_sw = val;
4304	hp = (kcontrol->private_value >> 16) & 0xff;
4305	line = (kcontrol->private_value >> 8) & 0xff;
4306	mono = kcontrol->private_value & 0xff;
4307	alc260_hp_master_update(codec, hp, line, mono);
4308	return 1;
4309}
4310
4311static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4312	{
4313		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4314		.name = "Master Playback Switch",
4315		.info = snd_ctl_boolean_mono_info,
4316		.get = alc260_hp_master_sw_get,
4317		.put = alc260_hp_master_sw_put,
4318		.private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4319	},
4320	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4321	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4322	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4323	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4324	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4325			      HDA_OUTPUT),
4326	HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4327	{ } /* end */
4328};
4329
4330static struct hda_verb alc260_hp_unsol_verbs[] = {
4331	{0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4332	{},
4333};
4334
4335static void alc260_hp_automute(struct hda_codec *codec)
4336{
4337	struct alc_spec *spec = codec->spec;
4338	unsigned int present;
4339
4340	present = snd_hda_codec_read(codec, 0x10, 0,
4341				     AC_VERB_GET_PIN_SENSE, 0);
4342	spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4343	alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4344}
4345
4346static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4347{
4348	if ((res >> 26) == ALC880_HP_EVENT)
4349		alc260_hp_automute(codec);
4350}
4351
4352static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4353	{
4354		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4355		.name = "Master Playback Switch",
4356		.info = snd_ctl_boolean_mono_info,
4357		.get = alc260_hp_master_sw_get,
4358		.put = alc260_hp_master_sw_put,
4359		.private_value = (0x10 << 16) | (0x15 << 8) | 0x11
4360	},
4361	HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4362	HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4363	HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4364	HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4365	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4366	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4367	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4368	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4369	{ } /* end */
4370};
4371
4372static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4373	.ops = &snd_hda_bind_vol,
4374	.values = {
4375		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4376		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4377		HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4378		0
4379	},
4380};
4381
4382static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4383	.ops = &snd_hda_bind_sw,
4384	.values = {
4385		HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4386		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4387		0
4388	},
4389};
4390
4391static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4392	HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4393	HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4394	HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4395	HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4396	{ } /* end */
4397};
4398
4399static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4400	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4401	{},
4402};
4403
4404static void alc260_hp_3013_automute(struct hda_codec *codec)
4405{
4406	struct alc_spec *spec = codec->spec;
4407	unsigned int present;
4408
4409	present = snd_hda_codec_read(codec, 0x15, 0,
4410				     AC_VERB_GET_PIN_SENSE, 0);
4411	spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4412	alc260_hp_master_update(codec, 0x10, 0x15, 0x11);
4413}
4414
4415static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4416				       unsigned int res)
4417{
4418	if ((res >> 26) == ALC880_HP_EVENT)
4419		alc260_hp_3013_automute(codec);
4420}
4421
4422static void alc260_hp_3012_automute(struct hda_codec *codec)
4423{
4424	unsigned int present, bits;
4425
4426	present = snd_hda_codec_read(codec, 0x10, 0,
4427			AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4428
4429	bits = present ? 0 : PIN_OUT;
4430	snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4431			    bits);
4432	snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4433			    bits);
4434	snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4435			    bits);
4436}
4437
4438static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4439				       unsigned int res)
4440{
4441	if ((res >> 26) == ALC880_HP_EVENT)
4442		alc260_hp_3012_automute(codec);
4443}
4444
4445/* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12,
4446 * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
4447 */
4448static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4449	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4450	HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4451	ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4452	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4453	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4454	HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4455	HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4456	ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4457	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4458	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4459	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4460	HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4461	{ } /* end */
4462};
4463
4464/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
4465 * versions of the ALC260 don't act on requests to enable mic bias from NID
4466 * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
4467 * datasheet doesn't mention this restriction.  At this stage it's not clear
4468 * whether this behaviour is intentional or is a hardware bug in chip
4469 * revisions available in early 2006.  Therefore for now allow the
4470 * "Headphone Jack Mode" control to span all choices, but if it turns out
4471 * that the lack of mic bias for this NID is intentional we could change the
4472 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4473 *
4474 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4475 * don't appear to make the mic bias available from the "line" jack, even
4476 * though the NID used for this jack (0x14) can supply it.  The theory is
4477 * that perhaps Acer have included blocking capacitors between the ALC260
4478 * and the output jack.  If this turns out to be the case for all such
4479 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4480 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4481 *
4482 * The C20x Tablet series have a mono internal speaker which is controlled
4483 * via the chip's Mono sum widget and pin complex, so include the necessary
4484 * controls for such models.  On models without a "mono speaker" the control
4485 * won't do anything.
4486 */
4487static struct snd_kcontrol_new alc260_acer_mixer[] = {
4488	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4489	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4490	ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4491	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4492			      HDA_OUTPUT),
4493	HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4494			   HDA_INPUT),
4495	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4496	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4497	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4498	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4499	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4500	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4501	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4502	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4503	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4504	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4505	{ } /* end */
4506};
4507
4508/* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4509 * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
4510 */
4511static struct snd_kcontrol_new alc260_will_mixer[] = {
4512	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4513	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4514	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4515	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4516	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4517	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4518	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4519	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4520	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4521	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4522	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4523	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4524	{ } /* end */
4525};
4526
4527/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4528 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4529 */
4530static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4531	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4532	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4533	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4534	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4535	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4536	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4537	HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4538	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4539	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4540	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4541	{ } /* end */
4542};
4543
4544/*
4545 * initialization verbs
4546 */
4547static struct hda_verb alc260_init_verbs[] = {
4548	/* Line In pin widget for input */
4549	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4550	/* CD pin widget for input */
4551	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4552	/* Mic1 (rear panel) pin widget for input and vref at 80% */
4553	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4554	/* Mic2 (front panel) pin widget for input and vref at 80% */
4555	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4556	/* LINE-2 is used for line-out in rear */
4557	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4558	/* select line-out */
4559	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4560	/* LINE-OUT pin */
4561	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4562	/* enable HP */
4563	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4564	/* enable Mono */
4565	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4566	/* mute capture amp left and right */
4567	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4568	/* set connection select to line in (default select for this ADC) */
4569	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4570	/* mute capture amp left and right */
4571	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4572	/* set connection select to line in (default select for this ADC) */
4573	{0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4574	/* set vol=0 Line-Out mixer amp left and right */
4575	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4576	/* unmute pin widget amp left and right (no gain on this amp) */
4577	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4578	/* set vol=0 HP mixer amp left and right */
4579	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4580	/* unmute pin widget amp left and right (no gain on this amp) */
4581	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4582	/* set vol=0 Mono mixer amp left and right */
4583	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4584	/* unmute pin widget amp left and right (no gain on this amp) */
4585	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4586	/* unmute LINE-2 out pin */
4587	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4588	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4589	 * Line In 2 = 0x03
4590	 */
4591	/* mute analog inputs */
4592	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4593	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4594	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4595	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4596	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4597	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4598	/* mute Front out path */
4599	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4600	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4601	/* mute Headphone out path */
4602	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4603	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4604	/* mute Mono out path */
4605	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4606	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4607	{ }
4608};
4609
4610#if 0 /* should be identical with alc260_init_verbs? */
4611static struct hda_verb alc260_hp_init_verbs[] = {
4612	/* Headphone and output */
4613	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4614	/* mono output */
4615	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4616	/* Mic1 (rear panel) pin widget for input and vref at 80% */
4617	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4618	/* Mic2 (front panel) pin widget for input and vref at 80% */
4619	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4620	/* Line In pin widget for input */
4621	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4622	/* Line-2 pin widget for output */
4623	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4624	/* CD pin widget for input */
4625	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4626	/* unmute amp left and right */
4627	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4628	/* set connection select to line in (default select for this ADC) */
4629	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4630	/* unmute Line-Out mixer amp left and right (volume = 0) */
4631	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4632	/* mute pin widget amp left and right (no gain on this amp) */
4633	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4634	/* unmute HP mixer amp left and right (volume = 0) */
4635	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4636	/* mute pin widget amp left and right (no gain on this amp) */
4637	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4638	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4639	 * Line In 2 = 0x03
4640	 */
4641	/* mute analog inputs */
4642	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4643	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4644	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4645	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4646	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4647	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4648	/* Unmute Front out path */
4649	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4650	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4651	/* Unmute Headphone out path */
4652	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4653	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4654	/* Unmute Mono out path */
4655	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4656	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4657	{ }
4658};
4659#endif
4660
4661static struct hda_verb alc260_hp_3013_init_verbs[] = {
4662	/* Line out and output */
4663	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4664	/* mono output */
4665	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4666	/* Mic1 (rear panel) pin widget for input and vref at 80% */
4667	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4668	/* Mic2 (front panel) pin widget for input and vref at 80% */
4669	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4670	/* Line In pin widget for input */
4671	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4672	/* Headphone pin widget for output */
4673	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4674	/* CD pin widget for input */
4675	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4676	/* unmute amp left and right */
4677	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4678	/* set connection select to line in (default select for this ADC) */
4679	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4680	/* unmute Line-Out mixer amp left and right (volume = 0) */
4681	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4682	/* mute pin widget amp left and right (no gain on this amp) */
4683	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4684	/* unmute HP mixer amp left and right (volume = 0) */
4685	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4686	/* mute pin widget amp left and right (no gain on this amp) */
4687	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4688	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4689	 * Line In 2 = 0x03
4690	 */
4691	/* mute analog inputs */
4692	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4693	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4694	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4695	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4696	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4697	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4698	/* Unmute Front out path */
4699	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4700	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4701	/* Unmute Headphone out path */
4702	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4703	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4704	/* Unmute Mono out path */
4705	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4706	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4707	{ }
4708};
4709
4710/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4711 * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4712 * audio = 0x16, internal speaker = 0x10.
4713 */
4714static struct hda_verb alc260_fujitsu_init_verbs[] = {
4715	/* Disable all GPIOs */
4716	{0x01, AC_VERB_SET_GPIO_MASK, 0},
4717	/* Internal speaker is connected to headphone pin */
4718	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4719	/* Headphone/Line-out jack connects to Line1 pin; make it an output */
4720	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4721	/* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4722	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4723	/* Ensure all other unused pins are disabled and muted. */
4724	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4725	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4726	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4727	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4728	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4729	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4730	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4731	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4732
4733	/* Disable digital (SPDIF) pins */
4734	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4735	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4736
4737	/* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4738	 * when acting as an output.
4739	 */
4740	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4741
4742	/* Start with output sum widgets muted and their output gains at min */
4743	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4744	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4745	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4746	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4747	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4748	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4749	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4750	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4751	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4752
4753	/* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4754	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4755	/* Unmute Line1 pin widget output buffer since it starts as an output.
4756	 * If the pin mode is changed by the user the pin mode control will
4757	 * take care of enabling the pin's input/output buffers as needed.
4758	 * Therefore there's no need to enable the input buffer at this
4759	 * stage.
4760	 */
4761	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4762	/* Unmute input buffer of pin widget used for Line-in (no equiv
4763	 * mixer ctrl)
4764	 */
4765	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4766
4767	/* Mute capture amp left and right */
4768	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4769	/* Set ADC connection select to match default mixer setting - line
4770	 * in (on mic1 pin)
4771	 */
4772	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4773
4774	/* Do the same for the second ADC: mute capture input amp and
4775	 * set ADC connection to line in (on mic1 pin)
4776	 */
4777	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4778	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4779
4780	/* Mute all inputs to mixer widget (even unconnected ones) */
4781	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4782	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4783	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4784	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4785	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4786	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4787	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4788	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4789
4790	{ }
4791};
4792
4793/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4794 * similar laptops (adapted from Fujitsu init verbs).
4795 */
4796static struct hda_verb alc260_acer_init_verbs[] = {
4797	/* On TravelMate laptops, GPIO 0 enables the internal speaker and
4798	 * the headphone jack.  Turn this on and rely on the standard mute
4799	 * methods whenever the user wants to turn these outputs off.
4800	 */
4801	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4802	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4803	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4804	/* Internal speaker/Headphone jack is connected to Line-out pin */
4805	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4806	/* Internal microphone/Mic jack is connected to Mic1 pin */
4807	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4808	/* Line In jack is connected to Line1 pin */
4809	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4810	/* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4811	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4812	/* Ensure all other unused pins are disabled and muted. */
4813	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4814	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4815	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4816	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4817	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4818	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4819	/* Disable digital (SPDIF) pins */
4820	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4821	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4822
4823	/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4824	 * bus when acting as outputs.
4825	 */
4826	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4827	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4828
4829	/* Start with output sum widgets muted and their output gains at min */
4830	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4831	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4832	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4833	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4834	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4835	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4836	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4837	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4838	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4839
4840	/* Unmute Line-out pin widget amp left and right
4841	 * (no equiv mixer ctrl)
4842	 */
4843	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4844	/* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4845	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4846	/* Unmute Mic1 and Line1 pin widget input buffers since they start as
4847	 * inputs. If the pin mode is changed by the user the pin mode control
4848	 * will take care of enabling the pin's input/output buffers as needed.
4849	 * Therefore there's no need to enable the input buffer at this
4850	 * stage.
4851	 */
4852	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4853	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4854
4855	/* Mute capture amp left and right */
4856	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4857	/* Set ADC connection select to match default mixer setting - mic
4858	 * (on mic1 pin)
4859	 */
4860	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4861
4862	/* Do similar with the second ADC: mute capture input amp and
4863	 * set ADC connection to mic to match ALSA's default state.
4864	 */
4865	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4866	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4867
4868	/* Mute all inputs to mixer widget (even unconnected ones) */
4869	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4870	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4871	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4872	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4873	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4874	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4875	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4876	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4877
4878	{ }
4879};
4880
4881static struct hda_verb alc260_will_verbs[] = {
4882	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4883	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4884	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4885	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4886	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4887	{0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4888	{}
4889};
4890
4891static struct hda_verb alc260_replacer_672v_verbs[] = {
4892	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4893	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4894	{0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4895
4896	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4897	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4898	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4899
4900	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4901	{}
4902};
4903
4904/* toggle speaker-output according to the hp-jack state */
4905static void alc260_replacer_672v_automute(struct hda_codec *codec)
4906{
4907        unsigned int present;
4908
4909	/* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4910        present = snd_hda_codec_read(codec, 0x0f, 0,
4911                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4912	if (present) {
4913		snd_hda_codec_write_cache(codec, 0x01, 0,
4914					  AC_VERB_SET_GPIO_DATA, 1);
4915		snd_hda_codec_write_cache(codec, 0x0f, 0,
4916					  AC_VERB_SET_PIN_WIDGET_CONTROL,
4917					  PIN_HP);
4918	} else {
4919		snd_hda_codec_write_cache(codec, 0x01, 0,
4920					  AC_VERB_SET_GPIO_DATA, 0);
4921		snd_hda_codec_write_cache(codec, 0x0f, 0,
4922					  AC_VERB_SET_PIN_WIDGET_CONTROL,
4923					  PIN_OUT);
4924	}
4925}
4926
4927static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4928                                       unsigned int res)
4929{
4930        if ((res >> 26) == ALC880_HP_EVENT)
4931                alc260_replacer_672v_automute(codec);
4932}
4933
4934static struct hda_verb alc260_hp_dc7600_verbs[] = {
4935	{0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
4936	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
4937	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4938	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4939	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4940	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4941	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4942	{0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4943	{0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4944	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4945	{}
4946};
4947
4948/* Test configuration for debugging, modelled after the ALC880 test
4949 * configuration.
4950 */
4951#ifdef CONFIG_SND_DEBUG
4952static hda_nid_t alc260_test_dac_nids[1] = {
4953	0x02,
4954};
4955static hda_nid_t alc260_test_adc_nids[2] = {
4956	0x04, 0x05,
4957};
4958/* For testing the ALC260, each input MUX needs its own definition since
4959 * the signal assignments are different.  This assumes that the first ADC
4960 * is NID 0x04.
4961 */
4962static struct hda_input_mux alc260_test_capture_sources[2] = {
4963	{
4964		.num_items = 7,
4965		.items = {
4966			{ "MIC1 pin", 0x0 },
4967			{ "MIC2 pin", 0x1 },
4968			{ "LINE1 pin", 0x2 },
4969			{ "LINE2 pin", 0x3 },
4970			{ "CD pin", 0x4 },
4971			{ "LINE-OUT pin", 0x5 },
4972			{ "HP-OUT pin", 0x6 },
4973		},
4974        },
4975	{
4976		.num_items = 8,
4977		.items = {
4978			{ "MIC1 pin", 0x0 },
4979			{ "MIC2 pin", 0x1 },
4980			{ "LINE1 pin", 0x2 },
4981			{ "LINE2 pin", 0x3 },
4982			{ "CD pin", 0x4 },
4983			{ "Mixer", 0x5 },
4984			{ "LINE-OUT pin", 0x6 },
4985			{ "HP-OUT pin", 0x7 },
4986		},
4987        },
4988};
4989static struct snd_kcontrol_new alc260_test_mixer[] = {
4990	/* Output driver widgets */
4991	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4992	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4993	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4994	HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4995	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4996	HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4997
4998	/* Modes for retasking pin widgets
4999	 * Note: the ALC260 doesn't seem to act on requests to enable mic
5000         * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
5001         * mention this restriction.  At this stage it's not clear whether
5002         * this behaviour is intentional or is a hardware bug in chip
5003         * revisions available at least up until early 2006.  Therefore for
5004         * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5005         * choices, but if it turns out that the lack of mic bias for these
5006         * NIDs is intentional we could change their modes from
5007         * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5008	 */
5009	ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5010	ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5011	ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5012	ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5013	ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5014	ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5015
5016	/* Loopback mixer controls */
5017	HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5018	HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5019	HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5020	HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5021	HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5022	HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5023	HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5024	HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5025	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5026	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5027	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
5028	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
5029	HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5030	HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5031	HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5032	HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5033
5034	/* Controls for GPIO pins, assuming they are configured as outputs */
5035	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5036	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5037	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5038	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5039
5040	/* Switches to allow the digital IO pins to be enabled.  The datasheet
5041	 * is ambigious as to which NID is which; testing on laptops which
5042	 * make this output available should provide clarification.
5043	 */
5044	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5045	ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5046
5047	/* A switch allowing EAPD to be enabled.  Some laptops seem to use
5048	 * this output to turn on an external amplifier.
5049	 */
5050	ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5051	ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5052
5053	{ } /* end */
5054};
5055static struct hda_verb alc260_test_init_verbs[] = {
5056	/* Enable all GPIOs as outputs with an initial value of 0 */
5057	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5058	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5059	{0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5060
5061	/* Enable retasking pins as output, initially without power amp */
5062	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5063	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5064	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5065	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5066	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5067	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5068
5069	/* Disable digital (SPDIF) pins initially, but users can enable
5070	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
5071	 * payload also sets the generation to 0, output to be in "consumer"
5072	 * PCM format, copyright asserted, no pre-emphasis and no validity
5073	 * control.
5074	 */
5075	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5076	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5077
5078	/* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
5079	 * OUT1 sum bus when acting as an output.
5080	 */
5081	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5082	{0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5083	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5084	{0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5085
5086	/* Start with output sum widgets muted and their output gains at min */
5087	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5088	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5089	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5090	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5091	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5092	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5093	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5094	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5095	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5096
5097	/* Unmute retasking pin widget output buffers since the default
5098	 * state appears to be output.  As the pin mode is changed by the
5099	 * user the pin mode control will take care of enabling the pin's
5100	 * input/output buffers as needed.
5101	 */
5102	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5103	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5104	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5105	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5106	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5107	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5108	/* Also unmute the mono-out pin widget */
5109	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5110
5111	/* Mute capture amp left and right */
5112	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5113	/* Set ADC connection select to match default mixer setting (mic1
5114	 * pin)
5115	 */
5116	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5117
5118	/* Do the same for the second ADC: mute capture input amp and
5119	 * set ADC connection to mic1 pin
5120	 */
5121	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5122	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5123
5124	/* Mute all inputs to mixer widget (even unconnected ones) */
5125	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5126	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5127	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5128	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5129	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5130	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5131	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5132	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5133
5134	{ }
5135};
5136#endif
5137
5138#define alc260_pcm_analog_playback	alc880_pcm_analog_alt_playback
5139#define alc260_pcm_analog_capture	alc880_pcm_analog_capture
5140
5141#define alc260_pcm_digital_playback	alc880_pcm_digital_playback
5142#define alc260_pcm_digital_capture	alc880_pcm_digital_capture
5143
5144/*
5145 * for BIOS auto-configuration
5146 */
5147
5148static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
5149					const char *pfx, int *vol_bits)
5150{
5151	hda_nid_t nid_vol;
5152	unsigned long vol_val, sw_val;
5153	char name[32];
5154	int err;
5155
5156	if (nid >= 0x0f && nid < 0x11) {
5157		nid_vol = nid - 0x7;
5158		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5159		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5160	} else if (nid == 0x11) {
5161		nid_vol = nid - 0x7;
5162		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5163		sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5164	} else if (nid >= 0x12 && nid <= 0x15) {
5165		nid_vol = 0x08;
5166		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5167		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5168	} else
5169		return 0; /* N/A */
5170
5171	if (!(*vol_bits & (1 << nid_vol))) {
5172		/* first control for the volume widget */
5173		snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5174		err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5175		if (err < 0)
5176			return err;
5177		*vol_bits |= (1 << nid_vol);
5178	}
5179	snprintf(name, sizeof(name), "%s Playback Switch", pfx);
5180	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5181	if (err < 0)
5182		return err;
5183	return 1;
5184}
5185
5186/* add playback controls from the parsed DAC table */
5187static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5188					     const struct auto_pin_cfg *cfg)
5189{
5190	hda_nid_t nid;
5191	int err;
5192	int vols = 0;
5193
5194	spec->multiout.num_dacs = 1;
5195	spec->multiout.dac_nids = spec->private_dac_nids;
5196	spec->multiout.dac_nids[0] = 0x02;
5197
5198	nid = cfg->line_out_pins[0];
5199	if (nid) {
5200		err = alc260_add_playback_controls(spec, nid, "Front", &vols);
5201		if (err < 0)
5202			return err;
5203	}
5204
5205	nid = cfg->speaker_pins[0];
5206	if (nid) {
5207		err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
5208		if (err < 0)
5209			return err;
5210	}
5211
5212	nid = cfg->hp_pins[0];
5213	if (nid) {
5214		err = alc260_add_playback_controls(spec, nid, "Headphone",
5215						   &vols);
5216		if (err < 0)
5217			return err;
5218	}
5219	return 0;
5220}
5221
5222/* create playback/capture controls for input pins */
5223static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5224						const struct auto_pin_cfg *cfg)
5225{
5226	struct hda_input_mux *imux = &spec->private_imux;
5227	int i, err, idx;
5228
5229	for (i = 0; i < AUTO_PIN_LAST; i++) {
5230		if (cfg->input_pins[i] >= 0x12) {
5231			idx = cfg->input_pins[i] - 0x12;
5232			err = new_analog_input(spec, cfg->input_pins[i],
5233					       auto_pin_cfg_labels[i], idx,
5234					       0x07);
5235			if (err < 0)
5236				return err;
5237			imux->items[imux->num_items].label =
5238				auto_pin_cfg_labels[i];
5239			imux->items[imux->num_items].index = idx;
5240			imux->num_items++;
5241		}
5242		if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
5243			idx = cfg->input_pins[i] - 0x09;
5244			err = new_analog_input(spec, cfg->input_pins[i],
5245					       auto_pin_cfg_labels[i], idx,
5246					       0x07);
5247			if (err < 0)
5248				return err;
5249			imux->items[imux->num_items].label =
5250				auto_pin_cfg_labels[i];
5251			imux->items[imux->num_items].index = idx;
5252			imux->num_items++;
5253		}
5254	}
5255	return 0;
5256}
5257
5258static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5259					      hda_nid_t nid, int pin_type,
5260					      int sel_idx)
5261{
5262	alc_set_pin_output(codec, nid, pin_type);
5263	/* need the manual connection? */
5264	if (nid >= 0x12) {
5265		int idx = nid - 0x12;
5266		snd_hda_codec_write(codec, idx + 0x0b, 0,
5267				    AC_VERB_SET_CONNECT_SEL, sel_idx);
5268	}
5269}
5270
5271static void alc260_auto_init_multi_out(struct hda_codec *codec)
5272{
5273	struct alc_spec *spec = codec->spec;
5274	hda_nid_t nid;
5275
5276	alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
5277	nid = spec->autocfg.line_out_pins[0];
5278	if (nid) {
5279		int pin_type = get_pin_type(spec->autocfg.line_out_type);
5280		alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5281	}
5282
5283	nid = spec->autocfg.speaker_pins[0];
5284	if (nid)
5285		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5286
5287	nid = spec->autocfg.hp_pins[0];
5288	if (nid)
5289		alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5290}
5291
5292#define ALC260_PIN_CD_NID		0x16
5293static void alc260_auto_init_analog_input(struct hda_codec *codec)
5294{
5295	struct alc_spec *spec = codec->spec;
5296	int i;
5297
5298	for (i = 0; i < AUTO_PIN_LAST; i++) {
5299		hda_nid_t nid = spec->autocfg.input_pins[i];
5300		if (nid >= 0x12) {
5301			snd_hda_codec_write(codec, nid, 0,
5302					    AC_VERB_SET_PIN_WIDGET_CONTROL,
5303					    i <= AUTO_PIN_FRONT_MIC ?
5304					    PIN_VREF80 : PIN_IN);
5305			if (nid != ALC260_PIN_CD_NID)
5306				snd_hda_codec_write(codec, nid, 0,
5307						    AC_VERB_SET_AMP_GAIN_MUTE,
5308						    AMP_OUT_MUTE);
5309		}
5310	}
5311}
5312
5313/*
5314 * generic initialization of ADC, input mixers and output mixers
5315 */
5316static struct hda_verb alc260_volume_init_verbs[] = {
5317	/*
5318	 * Unmute ADC0-1 and set the default input to mic-in
5319	 */
5320	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5321	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5322	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5323	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5324
5325	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5326	 * mixer widget
5327	 * Note: PASD motherboards uses the Line In 2 as the input for
5328	 * front panel mic (mic 2)
5329	 */
5330	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5331	/* mute analog inputs */
5332	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5333	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5334	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5335	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5336	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5337
5338	/*
5339	 * Set up output mixers (0x08 - 0x0a)
5340	 */
5341	/* set vol=0 to output mixers */
5342	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5343	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5344	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5345	/* set up input amps for analog loopback */
5346	/* Amp Indices: DAC = 0, mixer = 1 */
5347	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5348	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5349	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5350	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5351	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5352	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5353
5354	{ }
5355};
5356
5357static int alc260_parse_auto_config(struct hda_codec *codec)
5358{
5359	struct alc_spec *spec = codec->spec;
5360	int err;
5361	static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5362
5363	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5364					   alc260_ignore);
5365	if (err < 0)
5366		return err;
5367	err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5368	if (err < 0)
5369		return err;
5370	if (!spec->kctls.list)
5371		return 0; /* can't find valid BIOS pin config */
5372	err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5373	if (err < 0)
5374		return err;
5375
5376	spec->multiout.max_channels = 2;
5377
5378	if (spec->autocfg.dig_out_pin)
5379		spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5380	if (spec->kctls.list)
5381		add_mixer(spec, spec->kctls.list);
5382
5383	add_verb(spec, alc260_volume_init_verbs);
5384
5385	spec->num_mux_defs = 1;
5386	spec->input_mux = &spec->private_imux;
5387
5388	store_pin_configs(codec);
5389	return 1;
5390}
5391
5392/* additional initialization for auto-configuration model */
5393static void alc260_auto_init(struct hda_codec *codec)
5394{
5395	struct alc_spec *spec = codec->spec;
5396	alc260_auto_init_multi_out(codec);
5397	alc260_auto_init_analog_input(codec);
5398	if (spec->unsol_event)
5399		alc_inithook(codec);
5400}
5401
5402#ifdef CONFIG_SND_HDA_POWER_SAVE
5403static struct hda_amp_list alc260_loopbacks[] = {
5404	{ 0x07, HDA_INPUT, 0 },
5405	{ 0x07, HDA_INPUT, 1 },
5406	{ 0x07, HDA_INPUT, 2 },
5407	{ 0x07, HDA_INPUT, 3 },
5408	{ 0x07, HDA_INPUT, 4 },
5409	{ } /* end */
5410};
5411#endif
5412
5413/*
5414 * ALC260 configurations
5415 */
5416static const char *alc260_models[ALC260_MODEL_LAST] = {
5417	[ALC260_BASIC]		= "basic",
5418	[ALC260_HP]		= "hp",
5419	[ALC260_HP_3013]	= "hp-3013",
5420	[ALC260_HP_DC7600]	= "hp-dc7600",
5421	[ALC260_FUJITSU_S702X]	= "fujitsu",
5422	[ALC260_ACER]		= "acer",
5423	[ALC260_WILL]		= "will",
5424	[ALC260_REPLACER_672V]	= "replacer",
5425#ifdef CONFIG_SND_DEBUG
5426	[ALC260_TEST]		= "test",
5427#endif
5428	[ALC260_AUTO]		= "auto",
5429};
5430
5431static struct snd_pci_quirk alc260_cfg_tbl[] = {
5432	SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5433	SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5434	SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5435	SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5436	SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5437	SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5438	SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
5439	SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5440	SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5441	SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5442	SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5443	SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5444	SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5445	SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5446	SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5447	SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5448	SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5449	SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5450	{}
5451};
5452
5453static struct alc_config_preset alc260_presets[] = {
5454	[ALC260_BASIC] = {
5455		.mixers = { alc260_base_output_mixer,
5456			    alc260_input_mixer,
5457			    alc260_pc_beep_mixer },
5458		.init_verbs = { alc260_init_verbs },
5459		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5460		.dac_nids = alc260_dac_nids,
5461		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5462		.adc_nids = alc260_adc_nids,
5463		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5464		.channel_mode = alc260_modes,
5465		.input_mux = &alc260_capture_source,
5466	},
5467	[ALC260_HP] = {
5468		.mixers = { alc260_hp_output_mixer,
5469			    alc260_input_mixer },
5470		.init_verbs = { alc260_init_verbs,
5471				alc260_hp_unsol_verbs },
5472		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5473		.dac_nids = alc260_dac_nids,
5474		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5475		.adc_nids = alc260_adc_nids_alt,
5476		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5477		.channel_mode = alc260_modes,
5478		.input_mux = &alc260_capture_source,
5479		.unsol_event = alc260_hp_unsol_event,
5480		.init_hook = alc260_hp_automute,
5481	},
5482	[ALC260_HP_DC7600] = {
5483		.mixers = { alc260_hp_dc7600_mixer,
5484			    alc260_input_mixer },
5485		.init_verbs = { alc260_init_verbs,
5486				alc260_hp_dc7600_verbs },
5487		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5488		.dac_nids = alc260_dac_nids,
5489		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5490		.adc_nids = alc260_adc_nids_alt,
5491		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5492		.channel_mode = alc260_modes,
5493		.input_mux = &alc260_capture_source,
5494		.unsol_event = alc260_hp_3012_unsol_event,
5495		.init_hook = alc260_hp_3012_automute,
5496	},
5497	[ALC260_HP_3013] = {
5498		.mixers = { alc260_hp_3013_mixer,
5499			    alc260_input_mixer },
5500		.init_verbs = { alc260_hp_3013_init_verbs,
5501				alc260_hp_3013_unsol_verbs },
5502		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5503		.dac_nids = alc260_dac_nids,
5504		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5505		.adc_nids = alc260_adc_nids_alt,
5506		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5507		.channel_mode = alc260_modes,
5508		.input_mux = &alc260_capture_source,
5509		.unsol_event = alc260_hp_3013_unsol_event,
5510		.init_hook = alc260_hp_3013_automute,
5511	},
5512	[ALC260_FUJITSU_S702X] = {
5513		.mixers = { alc260_fujitsu_mixer },
5514		.init_verbs = { alc260_fujitsu_init_verbs },
5515		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5516		.dac_nids = alc260_dac_nids,
5517		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5518		.adc_nids = alc260_dual_adc_nids,
5519		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5520		.channel_mode = alc260_modes,
5521		.num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5522		.input_mux = alc260_fujitsu_capture_sources,
5523	},
5524	[ALC260_ACER] = {
5525		.mixers = { alc260_acer_mixer },
5526		.init_verbs = { alc260_acer_init_verbs },
5527		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5528		.dac_nids = alc260_dac_nids,
5529		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5530		.adc_nids = alc260_dual_adc_nids,
5531		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5532		.channel_mode = alc260_modes,
5533		.num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5534		.input_mux = alc260_acer_capture_sources,
5535	},
5536	[ALC260_WILL] = {
5537		.mixers = { alc260_will_mixer },
5538		.init_verbs = { alc260_init_verbs, alc260_will_verbs },
5539		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5540		.dac_nids = alc260_dac_nids,
5541		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5542		.adc_nids = alc260_adc_nids,
5543		.dig_out_nid = ALC260_DIGOUT_NID,
5544		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5545		.channel_mode = alc260_modes,
5546		.input_mux = &alc260_capture_source,
5547	},
5548	[ALC260_REPLACER_672V] = {
5549		.mixers = { alc260_replacer_672v_mixer },
5550		.init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5551		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5552		.dac_nids = alc260_dac_nids,
5553		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5554		.adc_nids = alc260_adc_nids,
5555		.dig_out_nid = ALC260_DIGOUT_NID,
5556		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5557		.channel_mode = alc260_modes,
5558		.input_mux = &alc260_capture_source,
5559		.unsol_event = alc260_replacer_672v_unsol_event,
5560		.init_hook = alc260_replacer_672v_automute,
5561	},
5562#ifdef CONFIG_SND_DEBUG
5563	[ALC260_TEST] = {
5564		.mixers = { alc260_test_mixer },
5565		.init_verbs = { alc260_test_init_verbs },
5566		.num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5567		.dac_nids = alc260_test_dac_nids,
5568		.num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5569		.adc_nids = alc260_test_adc_nids,
5570		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5571		.channel_mode = alc260_modes,
5572		.num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5573		.input_mux = alc260_test_capture_sources,
5574	},
5575#endif
5576};
5577
5578static int patch_alc260(struct hda_codec *codec)
5579{
5580	struct alc_spec *spec;
5581	int err, board_config;
5582
5583	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5584	if (spec == NULL)
5585		return -ENOMEM;
5586
5587	codec->spec = spec;
5588
5589	board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5590						  alc260_models,
5591						  alc260_cfg_tbl);
5592	if (board_config < 0) {
5593		snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5594			   "trying auto-probe from BIOS...\n");
5595		board_config = ALC260_AUTO;
5596	}
5597
5598	if (board_config == ALC260_AUTO) {
5599		/* automatic parse from the BIOS config */
5600		err = alc260_parse_auto_config(codec);
5601		if (err < 0) {
5602			alc_free(codec);
5603			return err;
5604		} else if (!err) {
5605			printk(KERN_INFO
5606			       "hda_codec: Cannot set up configuration "
5607			       "from BIOS.  Using base mode...\n");
5608			board_config = ALC260_BASIC;
5609		}
5610	}
5611
5612	if (board_config != ALC260_AUTO)
5613		setup_preset(spec, &alc260_presets[board_config]);
5614
5615	spec->stream_name_analog = "ALC260 Analog";
5616	spec->stream_analog_playback = &alc260_pcm_analog_playback;
5617	spec->stream_analog_capture = &alc260_pcm_analog_capture;
5618
5619	spec->stream_name_digital = "ALC260 Digital";
5620	spec->stream_digital_playback = &alc260_pcm_digital_playback;
5621	spec->stream_digital_capture = &alc260_pcm_digital_capture;
5622
5623	if (!spec->adc_nids && spec->input_mux) {
5624		/* check whether NID 0x04 is valid */
5625		unsigned int wcap = get_wcaps(codec, 0x04);
5626		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
5627		/* get type */
5628		if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
5629			spec->adc_nids = alc260_adc_nids_alt;
5630			spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
5631		} else {
5632			spec->adc_nids = alc260_adc_nids;
5633			spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
5634		}
5635	}
5636	set_capture_mixer(spec);
5637
5638	spec->vmaster_nid = 0x08;
5639
5640	codec->patch_ops = alc_patch_ops;
5641	if (board_config == ALC260_AUTO)
5642		spec->init_hook = alc260_auto_init;
5643#ifdef CONFIG_SND_HDA_POWER_SAVE
5644	if (!spec->loopback.amplist)
5645		spec->loopback.amplist = alc260_loopbacks;
5646#endif
5647
5648	return 0;
5649}
5650
5651
5652/*
5653 * ALC882 support
5654 *
5655 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5656 * configuration.  Each pin widget can choose any input DACs and a mixer.
5657 * Each ADC is connected from a mixer of all inputs.  This makes possible
5658 * 6-channel independent captures.
5659 *
5660 * In addition, an independent DAC for the multi-playback (not used in this
5661 * driver yet).
5662 */
5663#define ALC882_DIGOUT_NID	0x06
5664#define ALC882_DIGIN_NID	0x0a
5665
5666static struct hda_channel_mode alc882_ch_modes[1] = {
5667	{ 8, NULL }
5668};
5669
5670static hda_nid_t alc882_dac_nids[4] = {
5671	/* front, rear, clfe, rear_surr */
5672	0x02, 0x03, 0x04, 0x05
5673};
5674
5675/* identical with ALC880 */
5676#define alc882_adc_nids		alc880_adc_nids
5677#define alc882_adc_nids_alt	alc880_adc_nids_alt
5678
5679static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
5680static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
5681
5682/* input MUX */
5683/* FIXME: should be a matrix-type input source selection */
5684
5685static struct hda_input_mux alc882_capture_source = {
5686	.num_items = 4,
5687	.items = {
5688		{ "Mic", 0x0 },
5689		{ "Front Mic", 0x1 },
5690		{ "Line", 0x2 },
5691		{ "CD", 0x4 },
5692	},
5693};
5694/*
5695 * 2ch mode
5696 */
5697static struct hda_verb alc882_3ST_ch2_init[] = {
5698	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5699	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5700	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5701	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5702	{ } /* end */
5703};
5704
5705/*
5706 * 6ch mode
5707 */
5708static struct hda_verb alc882_3ST_ch6_init[] = {
5709	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5710	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5711	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5712	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5713	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5714	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5715	{ } /* end */
5716};
5717
5718static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5719	{ 2, alc882_3ST_ch2_init },
5720	{ 6, alc882_3ST_ch6_init },
5721};
5722
5723/*
5724 * 6ch mode
5725 */
5726static struct hda_verb alc882_sixstack_ch6_init[] = {
5727	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5728	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5729	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5730	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5731	{ } /* end */
5732};
5733
5734/*
5735 * 8ch mode
5736 */
5737static struct hda_verb alc882_sixstack_ch8_init[] = {
5738	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5739	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5740	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5741	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5742	{ } /* end */
5743};
5744
5745static struct hda_channel_mode alc882_sixstack_modes[2] = {
5746	{ 6, alc882_sixstack_ch6_init },
5747	{ 8, alc882_sixstack_ch8_init },
5748};
5749
5750/*
5751 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5752 */
5753
5754/*
5755 * 2ch mode
5756 */
5757static struct hda_verb alc885_mbp_ch2_init[] = {
5758	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5759	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5760	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5761	{ } /* end */
5762};
5763
5764/*
5765 * 6ch mode
5766 */
5767static struct hda_verb alc885_mbp_ch6_init[] = {
5768	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5769	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5770	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5771	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5772	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5773	{ } /* end */
5774};
5775
5776static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5777	{ 2, alc885_mbp_ch2_init },
5778	{ 6, alc885_mbp_ch6_init },
5779};
5780
5781
5782/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5783 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5784 */
5785static struct snd_kcontrol_new alc882_base_mixer[] = {
5786	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5787	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5788	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5789	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5790	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5791	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5792	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5793	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5794	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5795	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5796	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5797	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5798	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5799	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5800	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5801	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5802	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5803	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5804	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5805	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5806	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5807	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5808	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5809	{ } /* end */
5810};
5811
5812static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5813	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5814	HDA_BIND_MUTE   ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
5815	HDA_CODEC_MUTE  ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
5816	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
5817	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5818	HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5819	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5820	HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5821	HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
5822	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5823	{ } /* end */
5824};
5825static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5826	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5827	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5828	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5829	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5830	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5831	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5832	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5833	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5834	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5835	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5836	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5837	{ } /* end */
5838};
5839
5840static struct snd_kcontrol_new alc882_targa_mixer[] = {
5841	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5842	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5843	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5844	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5845	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5846	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5847	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5848	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5849	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5850	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5851	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5852	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5853	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5854	{ } /* end */
5855};
5856
5857/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5858 *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5859 */
5860static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5861	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5862	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5863	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5864	HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5865	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5866	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5867	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5868	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5869	HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5870	HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5871	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5872	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5873	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5874	{ } /* end */
5875};
5876
5877static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5878	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5879	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5880	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5881	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5882	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5883	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5884	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5885	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5886	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5887	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5888	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5889	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5890	{ } /* end */
5891};
5892
5893static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5894	{
5895		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5896		.name = "Channel Mode",
5897		.info = alc_ch_mode_info,
5898		.get = alc_ch_mode_get,
5899		.put = alc_ch_mode_put,
5900	},
5901	{ } /* end */
5902};
5903
5904static struct hda_verb alc882_init_verbs[] = {
5905	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5906	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5907	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5908	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5909	/* Rear mixer */
5910	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5911	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5912	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5913	/* CLFE mixer */
5914	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5915	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5916	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5917	/* Side mixer */
5918	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5919	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5920	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5921
5922	/* Front Pin: output 0 (0x0c) */
5923	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5924	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5925	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5926	/* Rear Pin: output 1 (0x0d) */
5927	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5928	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5929	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5930	/* CLFE Pin: output 2 (0x0e) */
5931	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5932	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5933	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5934	/* Side Pin: output 3 (0x0f) */
5935	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5936	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5937	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5938	/* Mic (rear) pin: input vref at 80% */
5939	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5940	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5941	/* Front Mic pin: input vref at 80% */
5942	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5943	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5944	/* Line In pin: input */
5945	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5946	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5947	/* Line-2 In: Headphone output (output 0 - 0x0c) */
5948	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5949	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5950	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5951	/* CD pin widget for input */
5952	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5953
5954	/* FIXME: use matrix-type input source selection */
5955	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5956	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5957	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5958	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5959	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5960	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5961	/* Input mixer2 */
5962	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5963	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5964	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5965	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5966	/* Input mixer3 */
5967	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5968	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5969	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5970	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5971	/* ADC1: mute amp left and right */
5972	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5973	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5974	/* ADC2: mute amp left and right */
5975	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5976	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5977	/* ADC3: mute amp left and right */
5978	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5979	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5980
5981	{ }
5982};
5983
5984static struct hda_verb alc882_eapd_verbs[] = {
5985	/* change to EAPD mode */
5986	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5987	{0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5988	{ }
5989};
5990
5991/* Mac Pro test */
5992static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5993	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5994	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5995	HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5996	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5997	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5998	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5999	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
6000	{ } /* end */
6001};
6002
6003static struct hda_verb alc882_macpro_init_verbs[] = {
6004	/* Front mixer: unmute input/output amp left and right (volume = 0) */
6005	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6006	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6007	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6008	/* Front Pin: output 0 (0x0c) */
6009	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6010	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6011	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6012	/* Front Mic pin: input vref at 80% */
6013	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6014	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6015	/* Speaker:  output */
6016	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6017	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6018	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
6019	/* Headphone output (output 0 - 0x0c) */
6020	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6021	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6022	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6023
6024	/* FIXME: use matrix-type input source selection */
6025	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6026	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6027	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6028	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6029	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6030	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6031	/* Input mixer2 */
6032	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6033	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6034	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6035	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6036	/* Input mixer3 */
6037	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6038	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6039	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6040	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6041	/* ADC1: mute amp left and right */
6042	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6043	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6044	/* ADC2: mute amp left and right */
6045	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6046	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6047	/* ADC3: mute amp left and right */
6048	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6049	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6050
6051	{ }
6052};
6053
6054/* Macbook Pro rev3 */
6055static struct hda_verb alc885_mbp3_init_verbs[] = {
6056	/* Front mixer: unmute input/output amp left and right (volume = 0) */
6057	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6058	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6059	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6060	/* Rear mixer */
6061	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6062	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6063	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6064	/* Front Pin: output 0 (0x0c) */
6065	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6066	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6067	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6068	/* HP Pin: output 0 (0x0d) */
6069	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
6070	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6071	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6072	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6073	/* Mic (rear) pin: input vref at 80% */
6074	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6075	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6076	/* Front Mic pin: input vref at 80% */
6077	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6078	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6079	/* Line In pin: use output 1 when in LineOut mode */
6080	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6081	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6082	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
6083
6084	/* FIXME: use matrix-type input source selection */
6085	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6086	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6087	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6088	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6089	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6090	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6091	/* Input mixer2 */
6092	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6093	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6094	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6095	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6096	/* Input mixer3 */
6097	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6098	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6099	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6100	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6101	/* ADC1: mute amp left and right */
6102	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6103	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6104	/* ADC2: mute amp left and right */
6105	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6106	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6107	/* ADC3: mute amp left and right */
6108	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6109	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6110
6111	{ }
6112};
6113
6114/* iMac 24 mixer. */
6115static struct snd_kcontrol_new alc885_imac24_mixer[] = {
6116	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6117	HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
6118	{ } /* end */
6119};
6120
6121/* iMac 24 init verbs. */
6122static struct hda_verb alc885_imac24_init_verbs[] = {
6123	/* Internal speakers: output 0 (0x0c) */
6124	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6125	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6126	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6127	/* Internal speakers: output 0 (0x0c) */
6128	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6129	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6130	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
6131	/* Headphone: output 0 (0x0c) */
6132	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6133	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6134	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6135	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6136	/* Front Mic: input vref at 80% */
6137	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6138	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6139	{ }
6140};
6141
6142/* Toggle speaker-output according to the hp-jack state */
6143static void alc885_imac24_automute(struct hda_codec *codec)
6144{
6145 	unsigned int present;
6146
6147 	present = snd_hda_codec_read(codec, 0x14, 0,
6148				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6149	snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
6150				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6151	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
6152				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6153}
6154
6155/* Processes unsolicited events. */
6156static void alc885_imac24_unsol_event(struct hda_codec *codec,
6157				      unsigned int res)
6158{
6159	/* Headphone insertion or removal. */
6160	if ((res >> 26) == ALC880_HP_EVENT)
6161		alc885_imac24_automute(codec);
6162}
6163
6164static void alc885_mbp3_automute(struct hda_codec *codec)
6165{
6166 	unsigned int present;
6167
6168 	present = snd_hda_codec_read(codec, 0x15, 0,
6169				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6170	snd_hda_codec_amp_stereo(codec, 0x14,  HDA_OUTPUT, 0,
6171				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6172	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6173				 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
6174
6175}
6176static void alc885_mbp3_unsol_event(struct hda_codec *codec,
6177				    unsigned int res)
6178{
6179	/* Headphone insertion or removal. */
6180	if ((res >> 26) == ALC880_HP_EVENT)
6181		alc885_mbp3_automute(codec);
6182}
6183
6184
6185static struct hda_verb alc882_targa_verbs[] = {
6186	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6187	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6188
6189	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6190	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6191
6192	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6193	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6194	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6195
6196	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6197	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6198	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6199	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6200	{ } /* end */
6201};
6202
6203/* toggle speaker-output according to the hp-jack state */
6204static void alc882_targa_automute(struct hda_codec *codec)
6205{
6206 	unsigned int present;
6207
6208 	present = snd_hda_codec_read(codec, 0x14, 0,
6209				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6210	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6211				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6212	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6213				  present ? 1 : 3);
6214}
6215
6216static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6217{
6218	/* Looks like the unsol event is incompatible with the standard
6219	 * definition.  4bit tag is placed at 26 bit!
6220	 */
6221	if (((res >> 26) == ALC880_HP_EVENT)) {
6222		alc882_targa_automute(codec);
6223	}
6224}
6225
6226static struct hda_verb alc882_asus_a7j_verbs[] = {
6227	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6228	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6229
6230	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6231	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6232	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6233
6234	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6235	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6236	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6237
6238	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6239	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6240	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6241	{ } /* end */
6242};
6243
6244static struct hda_verb alc882_asus_a7m_verbs[] = {
6245	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6246	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6247
6248	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6249	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6250	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6251
6252	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6253	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6254	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6255
6256	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6257	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6258	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6259 	{ } /* end */
6260};
6261
6262static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6263{
6264	unsigned int gpiostate, gpiomask, gpiodir;
6265
6266	gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6267				       AC_VERB_GET_GPIO_DATA, 0);
6268
6269	if (!muted)
6270		gpiostate |= (1 << pin);
6271	else
6272		gpiostate &= ~(1 << pin);
6273
6274	gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6275				      AC_VERB_GET_GPIO_MASK, 0);
6276	gpiomask |= (1 << pin);
6277
6278	gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6279				     AC_VERB_GET_GPIO_DIRECTION, 0);
6280	gpiodir |= (1 << pin);
6281
6282
6283	snd_hda_codec_write(codec, codec->afg, 0,
6284			    AC_VERB_SET_GPIO_MASK, gpiomask);
6285	snd_hda_codec_write(codec, codec->afg, 0,
6286			    AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6287
6288	msleep(1);
6289
6290	snd_hda_codec_write(codec, codec->afg, 0,
6291			    AC_VERB_SET_GPIO_DATA, gpiostate);
6292}
6293
6294/* set up GPIO at initialization */
6295static void alc885_macpro_init_hook(struct hda_codec *codec)
6296{
6297	alc882_gpio_mute(codec, 0, 0);
6298	alc882_gpio_mute(codec, 1, 0);
6299}
6300
6301/* set up GPIO and update auto-muting at initialization */
6302static void alc885_imac24_init_hook(struct hda_codec *codec)
6303{
6304	alc885_macpro_init_hook(codec);
6305	alc885_imac24_automute(codec);
6306}
6307
6308/*
6309 * generic initialization of ADC, input mixers and output mixers
6310 */
6311static struct hda_verb alc882_auto_init_verbs[] = {
6312	/*
6313	 * Unmute ADC0-2 and set the default input to mic-in
6314	 */
6315	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6316	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6317	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6318	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6319	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6320	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6321
6322	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6323	 * mixer widget
6324	 * Note: PASD motherboards uses the Line In 2 as the input for
6325	 * front panel mic (mic 2)
6326	 */
6327	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6328	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6329	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6330	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6331	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6332	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6333
6334	/*
6335	 * Set up output mixers (0x0c - 0x0f)
6336	 */
6337	/* set vol=0 to output mixers */
6338	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6339	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6340	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6341	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6342	/* set up input amps for analog loopback */
6343	/* Amp Indices: DAC = 0, mixer = 1 */
6344	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6345	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6346	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6347	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6348	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6349	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6350	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6351	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6352	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6353	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6354
6355	/* FIXME: use matrix-type input source selection */
6356	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6357	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6358	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6359	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6360	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6361	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6362	/* Input mixer2 */
6363	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6364	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6365	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6366	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6367	/* Input mixer3 */
6368	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6369	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6370	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6371	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6372
6373	{ }
6374};
6375
6376#ifdef CONFIG_SND_HDA_POWER_SAVE
6377#define alc882_loopbacks	alc880_loopbacks
6378#endif
6379
6380/* pcm configuration: identiacal with ALC880 */
6381#define alc882_pcm_analog_playback	alc880_pcm_analog_playback
6382#define alc882_pcm_analog_capture	alc880_pcm_analog_capture
6383#define alc882_pcm_digital_playback	alc880_pcm_digital_playback
6384#define alc882_pcm_digital_capture	alc880_pcm_digital_capture
6385
6386/*
6387 * configuration and preset
6388 */
6389static const char *alc882_models[ALC882_MODEL_LAST] = {
6390	[ALC882_3ST_DIG]	= "3stack-dig",
6391	[ALC882_6ST_DIG]	= "6stack-dig",
6392	[ALC882_ARIMA]		= "arima",
6393	[ALC882_W2JC]		= "w2jc",
6394	[ALC882_TARGA]		= "targa",
6395	[ALC882_ASUS_A7J]	= "asus-a7j",
6396	[ALC882_ASUS_A7M]	= "asus-a7m",
6397	[ALC885_MACPRO]		= "macpro",
6398	[ALC885_MBP3]		= "mbp3",
6399	[ALC885_IMAC24]		= "imac24",
6400	[ALC882_AUTO]		= "auto",
6401};
6402
6403static struct snd_pci_quirk alc882_cfg_tbl[] = {
6404	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6405	SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6406	SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6407	SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6408	SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6409	SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6410	SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6411	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6412	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6413	SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
6414	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6415	SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6416	{}
6417};
6418
6419static struct alc_config_preset alc882_presets[] = {
6420	[ALC882_3ST_DIG] = {
6421		.mixers = { alc882_base_mixer },
6422		.init_verbs = { alc882_init_verbs },
6423		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6424		.dac_nids = alc882_dac_nids,
6425		.dig_out_nid = ALC882_DIGOUT_NID,
6426		.dig_in_nid = ALC882_DIGIN_NID,
6427		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6428		.channel_mode = alc882_ch_modes,
6429		.need_dac_fix = 1,
6430		.input_mux = &alc882_capture_source,
6431	},
6432	[ALC882_6ST_DIG] = {
6433		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
6434		.init_verbs = { alc882_init_verbs },
6435		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6436		.dac_nids = alc882_dac_nids,
6437		.dig_out_nid = ALC882_DIGOUT_NID,
6438		.dig_in_nid = ALC882_DIGIN_NID,
6439		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6440		.channel_mode = alc882_sixstack_modes,
6441		.input_mux = &alc882_capture_source,
6442	},
6443	[ALC882_ARIMA] = {
6444		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
6445		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6446		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6447		.dac_nids = alc882_dac_nids,
6448		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6449		.channel_mode = alc882_sixstack_modes,
6450		.input_mux = &alc882_capture_source,
6451	},
6452	[ALC882_W2JC] = {
6453		.mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6454		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6455				alc880_gpio1_init_verbs },
6456		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6457		.dac_nids = alc882_dac_nids,
6458		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6459		.channel_mode = alc880_threestack_modes,
6460		.need_dac_fix = 1,
6461		.input_mux = &alc882_capture_source,
6462		.dig_out_nid = ALC882_DIGOUT_NID,
6463	},
6464	[ALC885_MBP3] = {
6465		.mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6466		.init_verbs = { alc885_mbp3_init_verbs,
6467				alc880_gpio1_init_verbs },
6468		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6469		.dac_nids = alc882_dac_nids,
6470		.channel_mode = alc885_mbp_6ch_modes,
6471		.num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6472		.input_mux = &alc882_capture_source,
6473		.dig_out_nid = ALC882_DIGOUT_NID,
6474		.dig_in_nid = ALC882_DIGIN_NID,
6475		.unsol_event = alc885_mbp3_unsol_event,
6476		.init_hook = alc885_mbp3_automute,
6477	},
6478	[ALC885_MACPRO] = {
6479		.mixers = { alc882_macpro_mixer },
6480		.init_verbs = { alc882_macpro_init_verbs },
6481		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6482		.dac_nids = alc882_dac_nids,
6483		.dig_out_nid = ALC882_DIGOUT_NID,
6484		.dig_in_nid = ALC882_DIGIN_NID,
6485		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6486		.channel_mode = alc882_ch_modes,
6487		.input_mux = &alc882_capture_source,
6488		.init_hook = alc885_macpro_init_hook,
6489	},
6490	[ALC885_IMAC24] = {
6491		.mixers = { alc885_imac24_mixer },
6492		.init_verbs = { alc885_imac24_init_verbs },
6493		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6494		.dac_nids = alc882_dac_nids,
6495		.dig_out_nid = ALC882_DIGOUT_NID,
6496		.dig_in_nid = ALC882_DIGIN_NID,
6497		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6498		.channel_mode = alc882_ch_modes,
6499		.input_mux = &alc882_capture_source,
6500		.unsol_event = alc885_imac24_unsol_event,
6501		.init_hook = alc885_imac24_init_hook,
6502	},
6503	[ALC882_TARGA] = {
6504		.mixers = { alc882_targa_mixer, alc882_chmode_mixer },
6505		.init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6506		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6507		.dac_nids = alc882_dac_nids,
6508		.dig_out_nid = ALC882_DIGOUT_NID,
6509		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6510		.adc_nids = alc882_adc_nids,
6511		.capsrc_nids = alc882_capsrc_nids,
6512		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6513		.channel_mode = alc882_3ST_6ch_modes,
6514		.need_dac_fix = 1,
6515		.input_mux = &alc882_capture_source,
6516		.unsol_event = alc882_targa_unsol_event,
6517		.init_hook = alc882_targa_automute,
6518	},
6519	[ALC882_ASUS_A7J] = {
6520		.mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
6521		.init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6522		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6523		.dac_nids = alc882_dac_nids,
6524		.dig_out_nid = ALC882_DIGOUT_NID,
6525		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6526		.adc_nids = alc882_adc_nids,
6527		.capsrc_nids = alc882_capsrc_nids,
6528		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6529		.channel_mode = alc882_3ST_6ch_modes,
6530		.need_dac_fix = 1,
6531		.input_mux = &alc882_capture_source,
6532	},
6533	[ALC882_ASUS_A7M] = {
6534		.mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6535		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6536				alc880_gpio1_init_verbs,
6537				alc882_asus_a7m_verbs },
6538		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6539		.dac_nids = alc882_dac_nids,
6540		.dig_out_nid = ALC882_DIGOUT_NID,
6541		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6542		.channel_mode = alc880_threestack_modes,
6543		.need_dac_fix = 1,
6544		.input_mux = &alc882_capture_source,
6545	},
6546};
6547
6548
6549/*
6550 * Pin config fixes
6551 */
6552enum {
6553	PINFIX_ABIT_AW9D_MAX
6554};
6555
6556static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6557	{ 0x15, 0x01080104 }, /* side */
6558	{ 0x16, 0x01011012 }, /* rear */
6559	{ 0x17, 0x01016011 }, /* clfe */
6560	{ }
6561};
6562
6563static const struct alc_pincfg *alc882_pin_fixes[] = {
6564	[PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6565};
6566
6567static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6568	SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6569	{}
6570};
6571
6572/*
6573 * BIOS auto configuration
6574 */
6575static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6576					      hda_nid_t nid, int pin_type,
6577					      int dac_idx)
6578{
6579	/* set as output */
6580	struct alc_spec *spec = codec->spec;
6581	int idx;
6582
6583	alc_set_pin_output(codec, nid, pin_type);
6584	if (spec->multiout.dac_nids[dac_idx] == 0x25)
6585		idx = 4;
6586	else
6587		idx = spec->multiout.dac_nids[dac_idx] - 2;
6588	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6589
6590}
6591
6592static void alc882_auto_init_multi_out(struct hda_codec *codec)
6593{
6594	struct alc_spec *spec = codec->spec;
6595	int i;
6596
6597	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6598	for (i = 0; i <= HDA_SIDE; i++) {
6599		hda_nid_t nid = spec->autocfg.line_out_pins[i];
6600		int pin_type = get_pin_type(spec->autocfg.line_out_type);
6601		if (nid)
6602			alc882_auto_set_output_and_unmute(codec, nid, pin_type,
6603							  i);
6604	}
6605}
6606
6607static void alc882_auto_init_hp_out(struct hda_codec *codec)
6608{
6609	struct alc_spec *spec = codec->spec;
6610	hda_nid_t pin;
6611
6612	pin = spec->autocfg.hp_pins[0];
6613	if (pin) /* connect to front */
6614		/* use dac 0 */
6615		alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6616	pin = spec->autocfg.speaker_pins[0];
6617	if (pin)
6618		alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
6619}
6620
6621#define alc882_is_input_pin(nid)	alc880_is_input_pin(nid)
6622#define ALC882_PIN_CD_NID		ALC880_PIN_CD_NID
6623
6624static void alc882_auto_init_analog_input(struct hda_codec *codec)
6625{
6626	struct alc_spec *spec = codec->spec;
6627	int i;
6628
6629	for (i = 0; i < AUTO_PIN_LAST; i++) {
6630		hda_nid_t nid = spec->autocfg.input_pins[i];
6631		unsigned int vref;
6632		if (!nid)
6633			continue;
6634		vref = PIN_IN;
6635		if (1 /*i <= AUTO_PIN_FRONT_MIC*/) {
6636			unsigned int pincap;
6637			pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
6638			if ((pincap >> AC_PINCAP_VREF_SHIFT) &
6639			    AC_PINCAP_VREF_80)
6640				vref = PIN_VREF80;
6641		}
6642		snd_hda_codec_write(codec, nid, 0,
6643				    AC_VERB_SET_PIN_WIDGET_CONTROL, vref);
6644		if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
6645			snd_hda_codec_write(codec, nid, 0,
6646					    AC_VERB_SET_AMP_GAIN_MUTE,
6647					    AMP_OUT_MUTE);
6648	}
6649}
6650
6651static void alc882_auto_init_input_src(struct hda_codec *codec)
6652{
6653	struct alc_spec *spec = codec->spec;
6654	const struct hda_input_mux *imux = spec->input_mux;
6655	int c;
6656
6657	for (c = 0; c < spec->num_adc_nids; c++) {
6658		hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
6659		hda_nid_t nid = spec->capsrc_nids[c];
6660		int conns, mute, idx, item;
6661
6662		conns = snd_hda_get_connections(codec, nid, conn_list,
6663						ARRAY_SIZE(conn_list));
6664		if (conns < 0)
6665			continue;
6666		for (idx = 0; idx < conns; idx++) {
6667			/* if the current connection is the selected one,
6668			 * unmute it as default - otherwise mute it
6669			 */
6670			mute = AMP_IN_MUTE(idx);
6671			for (item = 0; item < imux->num_items; item++) {
6672				if (imux->items[item].index == idx) {
6673					if (spec->cur_mux[c] == item)
6674						mute = AMP_IN_UNMUTE(idx);
6675					break;
6676				}
6677			}
6678			snd_hda_codec_write(codec, nid, 0,
6679					    AC_VERB_SET_AMP_GAIN_MUTE, mute);
6680		}
6681	}
6682}
6683
6684/* add mic boosts if needed */
6685static int alc_auto_add_mic_boost(struct hda_codec *codec)
6686{
6687	struct alc_spec *spec = codec->spec;
6688	int err;
6689	hda_nid_t nid;
6690
6691	nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
6692	if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6693		err = add_control(spec, ALC_CTL_WIDGET_VOL,
6694				  "Mic Boost",
6695				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6696		if (err < 0)
6697			return err;
6698	}
6699	nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6700	if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6701		err = add_control(spec, ALC_CTL_WIDGET_VOL,
6702				  "Front Mic Boost",
6703				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6704		if (err < 0)
6705			return err;
6706	}
6707	return 0;
6708}
6709
6710/* almost identical with ALC880 parser... */
6711static int alc882_parse_auto_config(struct hda_codec *codec)
6712{
6713	struct alc_spec *spec = codec->spec;
6714	int err = alc880_parse_auto_config(codec);
6715
6716	if (err < 0)
6717		return err;
6718	else if (!err)
6719		return 0; /* no config found */
6720
6721	err = alc_auto_add_mic_boost(codec);
6722	if (err < 0)
6723		return err;
6724
6725	/* hack - override the init verbs */
6726	spec->init_verbs[0] = alc882_auto_init_verbs;
6727
6728	return 1; /* config found */
6729}
6730
6731/* additional initialization for auto-configuration model */
6732static void alc882_auto_init(struct hda_codec *codec)
6733{
6734	struct alc_spec *spec = codec->spec;
6735	alc882_auto_init_multi_out(codec);
6736	alc882_auto_init_hp_out(codec);
6737	alc882_auto_init_analog_input(codec);
6738	alc882_auto_init_input_src(codec);
6739	if (spec->unsol_event)
6740		alc_inithook(codec);
6741}
6742
6743static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
6744
6745static int patch_alc882(struct hda_codec *codec)
6746{
6747	struct alc_spec *spec;
6748	int err, board_config;
6749
6750	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6751	if (spec == NULL)
6752		return -ENOMEM;
6753
6754	codec->spec = spec;
6755
6756	board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6757						  alc882_models,
6758						  alc882_cfg_tbl);
6759
6760	if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
6761		/* Pick up systems that don't supply PCI SSID */
6762		switch (codec->subsystem_id) {
6763		case 0x106b0c00: /* Mac Pro */
6764			board_config = ALC885_MACPRO;
6765			break;
6766		case 0x106b1000: /* iMac 24 */
6767		case 0x106b2800: /* AppleTV */
6768			board_config = ALC885_IMAC24;
6769			break;
6770		case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
6771		case 0x106b00a4: /* MacbookPro4,1 */
6772		case 0x106b2c00: /* Macbook Pro rev3 */
6773		case 0x106b3600: /* Macbook 3.1 */
6774			board_config = ALC885_MBP3;
6775			break;
6776		default:
6777			/* ALC889A is handled better as ALC888-compatible */
6778			if (codec->revision_id == 0x100101 ||
6779			    codec->revision_id == 0x100103) {
6780				alc_free(codec);
6781				return patch_alc883(codec);
6782			}
6783			printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6784		       			 "trying auto-probe from BIOS...\n");
6785			board_config = ALC882_AUTO;
6786		}
6787	}
6788
6789	alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6790
6791	if (board_config == ALC882_AUTO) {
6792		/* automatic parse from the BIOS config */
6793		err = alc882_parse_auto_config(codec);
6794		if (err < 0) {
6795			alc_free(codec);
6796			return err;
6797		} else if (!err) {
6798			printk(KERN_INFO
6799			       "hda_codec: Cannot set up configuration "
6800			       "from BIOS.  Using base mode...\n");
6801			board_config = ALC882_3ST_DIG;
6802		}
6803	}
6804
6805	if (board_config != ALC882_AUTO)
6806		setup_preset(spec, &alc882_presets[board_config]);
6807
6808	if (codec->vendor_id == 0x10ec0885) {
6809		spec->stream_name_analog = "ALC885 Analog";
6810		spec->stream_name_digital = "ALC885 Digital";
6811	} else {
6812		spec->stream_name_analog = "ALC882 Analog";
6813		spec->stream_name_digital = "ALC882 Digital";
6814	}
6815
6816	spec->stream_analog_playback = &alc882_pcm_analog_playback;
6817	spec->stream_analog_capture = &alc882_pcm_analog_capture;
6818	/* FIXME: setup DAC5 */
6819	/*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
6820	spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
6821
6822	spec->stream_digital_playback = &alc882_pcm_digital_playback;
6823	spec->stream_digital_capture = &alc882_pcm_digital_capture;
6824
6825	spec->is_mix_capture = 1; /* matrix-style capture */
6826	if (!spec->adc_nids && spec->input_mux) {
6827		/* check whether NID 0x07 is valid */
6828		unsigned int wcap = get_wcaps(codec, 0x07);
6829		/* get type */
6830		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6831		if (wcap != AC_WID_AUD_IN) {
6832			spec->adc_nids = alc882_adc_nids_alt;
6833			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6834			spec->capsrc_nids = alc882_capsrc_nids_alt;
6835		} else {
6836			spec->adc_nids = alc882_adc_nids;
6837			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6838			spec->capsrc_nids = alc882_capsrc_nids;
6839		}
6840	}
6841	set_capture_mixer(spec);
6842
6843	spec->vmaster_nid = 0x0c;
6844
6845	codec->patch_ops = alc_patch_ops;
6846	if (board_config == ALC882_AUTO)
6847		spec->init_hook = alc882_auto_init;
6848#ifdef CONFIG_SND_HDA_POWER_SAVE
6849	if (!spec->loopback.amplist)
6850		spec->loopback.amplist = alc882_loopbacks;
6851#endif
6852
6853	return 0;
6854}
6855
6856/*
6857 * ALC883 support
6858 *
6859 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6860 * configuration.  Each pin widget can choose any input DACs and a mixer.
6861 * Each ADC is connected from a mixer of all inputs.  This makes possible
6862 * 6-channel independent captures.
6863 *
6864 * In addition, an independent DAC for the multi-playback (not used in this
6865 * driver yet).
6866 */
6867#define ALC883_DIGOUT_NID	0x06
6868#define ALC883_DIGIN_NID	0x0a
6869
6870static hda_nid_t alc883_dac_nids[4] = {
6871	/* front, rear, clfe, rear_surr */
6872	0x02, 0x03, 0x04, 0x05
6873};
6874
6875static hda_nid_t alc883_adc_nids[2] = {
6876	/* ADC1-2 */
6877	0x08, 0x09,
6878};
6879
6880static hda_nid_t alc883_adc_nids_alt[1] = {
6881	/* ADC1 */
6882	0x08,
6883};
6884
6885static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
6886
6887/* input MUX */
6888/* FIXME: should be a matrix-type input source selection */
6889
6890static struct hda_input_mux alc883_capture_source = {
6891	.num_items = 4,
6892	.items = {
6893		{ "Mic", 0x0 },
6894		{ "Front Mic", 0x1 },
6895		{ "Line", 0x2 },
6896		{ "CD", 0x4 },
6897	},
6898};
6899
6900static struct hda_input_mux alc883_3stack_6ch_intel = {
6901	.num_items = 4,
6902	.items = {
6903		{ "Mic", 0x1 },
6904		{ "Front Mic", 0x0 },
6905		{ "Line", 0x2 },
6906		{ "CD", 0x4 },
6907	},
6908};
6909
6910static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6911	.num_items = 2,
6912	.items = {
6913		{ "Mic", 0x1 },
6914		{ "Line", 0x2 },
6915	},
6916};
6917
6918static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6919	.num_items = 4,
6920	.items = {
6921		{ "Mic", 0x0 },
6922		{ "iMic", 0x1 },
6923		{ "Line", 0x2 },
6924		{ "CD", 0x4 },
6925	},
6926};
6927
6928static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6929	.num_items = 2,
6930	.items = {
6931		{ "Mic", 0x0 },
6932		{ "Int Mic", 0x1 },
6933	},
6934};
6935
6936static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6937	.num_items = 3,
6938	.items = {
6939		{ "Mic", 0x0 },
6940		{ "Front Mic", 0x1 },
6941		{ "Line", 0x4 },
6942	},
6943};
6944
6945static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6946	.num_items = 2,
6947	.items = {
6948		{ "Mic", 0x0 },
6949		{ "Line", 0x2 },
6950	},
6951};
6952
6953/*
6954 * 2ch mode
6955 */
6956static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6957	{ 2, NULL }
6958};
6959
6960/*
6961 * 2ch mode
6962 */
6963static struct hda_verb alc883_3ST_ch2_init[] = {
6964	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6965	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6966	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6967	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6968	{ } /* end */
6969};
6970
6971/*
6972 * 4ch mode
6973 */
6974static struct hda_verb alc883_3ST_ch4_init[] = {
6975	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6976	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6977	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6978	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6979	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6980	{ } /* end */
6981};
6982
6983/*
6984 * 6ch mode
6985 */
6986static struct hda_verb alc883_3ST_ch6_init[] = {
6987	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6988	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6989	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6990	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6991	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6992	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6993	{ } /* end */
6994};
6995
6996static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
6997	{ 2, alc883_3ST_ch2_init },
6998	{ 4, alc883_3ST_ch4_init },
6999	{ 6, alc883_3ST_ch6_init },
7000};
7001
7002/*
7003 * 2ch mode
7004 */
7005static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7006	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7007	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7008	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7009	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7010	{ } /* end */
7011};
7012
7013/*
7014 * 4ch mode
7015 */
7016static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7017	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7018	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7019	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7020	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7021	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7022	{ } /* end */
7023};
7024
7025/*
7026 * 6ch mode
7027 */
7028static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7029	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7030	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7031	{ 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7032	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7033	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7034	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7035	{ } /* end */
7036};
7037
7038static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7039	{ 2, alc883_3ST_ch2_intel_init },
7040	{ 4, alc883_3ST_ch4_intel_init },
7041	{ 6, alc883_3ST_ch6_intel_init },
7042};
7043
7044/*
7045 * 6ch mode
7046 */
7047static struct hda_verb alc883_sixstack_ch6_init[] = {
7048	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7049	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7050	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7051	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7052	{ } /* end */
7053};
7054
7055/*
7056 * 8ch mode
7057 */
7058static struct hda_verb alc883_sixstack_ch8_init[] = {
7059	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7060	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7061	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7062	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7063	{ } /* end */
7064};
7065
7066static struct hda_channel_mode alc883_sixstack_modes[2] = {
7067	{ 6, alc883_sixstack_ch6_init },
7068	{ 8, alc883_sixstack_ch8_init },
7069};
7070
7071static struct hda_verb alc883_medion_eapd_verbs[] = {
7072        /* eanable EAPD on medion laptop */
7073	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7074	{0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7075	{ }
7076};
7077
7078/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7079 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7080 */
7081
7082static struct snd_kcontrol_new alc883_base_mixer[] = {
7083	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7084	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7085	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7086	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7087	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7088	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7089	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7090	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7091	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7092	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7093	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7094	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7095	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7096	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7097	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7098	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7099	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7100	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7101	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7102	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7103	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7104	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7105	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7106	{ } /* end */
7107};
7108
7109static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7110	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7111	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7112	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7113	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7114	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7115	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7116	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7117	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7118	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7119	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7120	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7121	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7122	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7123	{ } /* end */
7124};
7125
7126static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7127	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7128	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7129	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7130	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7131	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7132	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7133	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7134	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7135	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7136	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7137	{ } /* end */
7138};
7139
7140static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7141	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7142	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7143	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7144	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7145	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7146	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7147	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7148	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7149	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7150	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7151	{ } /* end */
7152};
7153
7154static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7155	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7156	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7157	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7158	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7159	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7160	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7161	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7162	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7163	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7164	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7165	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7166	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7167	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7168	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7169	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7170	{ } /* end */
7171};
7172
7173static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7174	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7175	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7176	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7177	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7178	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7179	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7180	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7181	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7182	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7183	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7184	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7185	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7186	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7187	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7188	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7189	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7190	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7191	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7192	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7193	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7194	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7195	{ } /* end */
7196};
7197
7198static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7199	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7200	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7201	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7202	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7203	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7204			      HDA_OUTPUT),
7205	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7206	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7207	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7208	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7209	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7210	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7211	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7212	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7213	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7214	HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7215	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7216	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7217	HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7218	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7219	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7220	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7221	{ } /* end */
7222};
7223
7224static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7225	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7226	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7227	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7228	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7229	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7230	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7231	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7232	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7233	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7234	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7235	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7236	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7237	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7238	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7239	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7240	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7241	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7242	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7243	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7244	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7245	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7246	{ } /* end */
7247};
7248
7249static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7250	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7251	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7252	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7253	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7254	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7255	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7256	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7257	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7258	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7259	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7260	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7261	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7262	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7263	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7264	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7265	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7266	{ } /* end */
7267};
7268
7269static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7270	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7271	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7272	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7273	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7274	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7275	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7276	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7277	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7278	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7279	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7280	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7281	{ } /* end */
7282};
7283
7284static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7285	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7286	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7287	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7288	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7289	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7290	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7291	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7292	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7293	{ } /* end */
7294};
7295
7296static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7297	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7298	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7299	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7300	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7301	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7302	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7303	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7304	HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7305	HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7306	{ } /* end */
7307};
7308
7309static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7310	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7311	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7312	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7313	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7314	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7315	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7316	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7317	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7318	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7319	{ } /* end */
7320};
7321
7322static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7323	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7324	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7325	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7326	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7327	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7328	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7329	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7330	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7331	{ } /* end */
7332};
7333
7334static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7335	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7336	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7337	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7338	HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7339	HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7340						0x0d, 1, 0x0, HDA_OUTPUT),
7341	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7342	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7343	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7344	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7345	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7346	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7347	HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
7348	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7349	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7350	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7351	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7352	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7353	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7354	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7355	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7356	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7357	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7358	{ } /* end */
7359};
7360
7361static struct hda_bind_ctls alc883_bind_cap_vol = {
7362	.ops = &snd_hda_bind_vol,
7363	.values = {
7364		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7365		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7366		0
7367	},
7368};
7369
7370static struct hda_bind_ctls alc883_bind_cap_switch = {
7371	.ops = &snd_hda_bind_sw,
7372	.values = {
7373		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7374		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7375		0
7376	},
7377};
7378
7379static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7380	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7381	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7382	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7383	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7384	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7385	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7386	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7387	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7388	{ } /* end */
7389};
7390
7391static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
7392	HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7393	HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7394	{
7395		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7396		/* .name = "Capture Source", */
7397		.name = "Input Source",
7398		.count = 1,
7399		.info = alc_mux_enum_info,
7400		.get = alc_mux_enum_get,
7401		.put = alc_mux_enum_put,
7402	},
7403	{ } /* end */
7404};
7405
7406static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7407	{
7408		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7409		.name = "Channel Mode",
7410		.info = alc_ch_mode_info,
7411		.get = alc_ch_mode_get,
7412		.put = alc_ch_mode_put,
7413	},
7414	{ } /* end */
7415};
7416
7417static struct hda_verb alc883_init_verbs[] = {
7418	/* ADC1: mute amp left and right */
7419	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7420	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7421	/* ADC2: mute amp left and right */
7422	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7423	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7424	/* Front mixer: unmute input/output amp left and right (volume = 0) */
7425	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7426	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7427	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7428	/* Rear mixer */
7429	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7430	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7431	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7432	/* CLFE mixer */
7433	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7434	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7435	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7436	/* Side mixer */
7437	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7438	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7439	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7440
7441	/* mute analog input loopbacks */
7442	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7443	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7444	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7445	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7446	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7447
7448	/* Front Pin: output 0 (0x0c) */
7449	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7450	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7451	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7452	/* Rear Pin: output 1 (0x0d) */
7453	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7454	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7455	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7456	/* CLFE Pin: output 2 (0x0e) */
7457	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7458	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7459	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7460	/* Side Pin: output 3 (0x0f) */
7461	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7462	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7463	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7464	/* Mic (rear) pin: input vref at 80% */
7465	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7466	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7467	/* Front Mic pin: input vref at 80% */
7468	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7469	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7470	/* Line In pin: input */
7471	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7472	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7473	/* Line-2 In: Headphone output (output 0 - 0x0c) */
7474	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7475	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7476	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7477	/* CD pin widget for input */
7478	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7479
7480	/* FIXME: use matrix-type input source selection */
7481	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7482	/* Input mixer2 */
7483	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7484	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7485	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7486	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7487	/* Input mixer3 */
7488	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7489	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7490	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7491	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7492	{ }
7493};
7494
7495/* toggle speaker-output according to the hp-jack state */
7496static void alc883_mitac_hp_automute(struct hda_codec *codec)
7497{
7498	unsigned int present;
7499
7500	present = snd_hda_codec_read(codec, 0x15, 0,
7501				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7502	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7503				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7504	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7505				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7506}
7507
7508/* auto-toggle front mic */
7509/*
7510static void alc883_mitac_mic_automute(struct hda_codec *codec)
7511{
7512	unsigned int present;
7513	unsigned char bits;
7514
7515	present = snd_hda_codec_read(codec, 0x18, 0,
7516				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7517	bits = present ? HDA_AMP_MUTE : 0;
7518	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7519}
7520*/
7521
7522static void alc883_mitac_automute(struct hda_codec *codec)
7523{
7524	alc883_mitac_hp_automute(codec);
7525	/* alc883_mitac_mic_automute(codec); */
7526}
7527
7528static void alc883_mitac_unsol_event(struct hda_codec *codec,
7529					   unsigned int res)
7530{
7531	switch (res >> 26) {
7532	case ALC880_HP_EVENT:
7533		alc883_mitac_hp_automute(codec);
7534		break;
7535	case ALC880_MIC_EVENT:
7536		/* alc883_mitac_mic_automute(codec); */
7537		break;
7538	}
7539}
7540
7541static struct hda_verb alc883_mitac_verbs[] = {
7542	/* HP */
7543	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7544	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7545	/* Subwoofer */
7546	{0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7547	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7548
7549	/* enable unsolicited event */
7550	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7551	/* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7552
7553	{ } /* end */
7554};
7555
7556static struct hda_verb alc883_clevo_m720_verbs[] = {
7557	/* HP */
7558	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7559	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7560	/* Int speaker */
7561	{0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
7562	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7563
7564	/* enable unsolicited event */
7565	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7566	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
7567
7568	{ } /* end */
7569};
7570
7571static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
7572	/* HP */
7573	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7574	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7575	/* Subwoofer */
7576	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7577	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7578
7579	/* enable unsolicited event */
7580	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7581
7582	{ } /* end */
7583};
7584
7585static struct hda_verb alc883_tagra_verbs[] = {
7586	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7587	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7588
7589	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7590	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7591
7592	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7593	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7594	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7595
7596	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7597	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7598	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7599	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
7600
7601	{ } /* end */
7602};
7603
7604static struct hda_verb alc883_lenovo_101e_verbs[] = {
7605	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7606	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7607        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7608	{ } /* end */
7609};
7610
7611static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7612        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7613	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7614        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7615        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7616	{ } /* end */
7617};
7618
7619static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7620	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7621	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7622	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7623	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7624	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
7625	{ } /* end */
7626};
7627
7628static struct hda_verb alc883_haier_w66_verbs[] = {
7629	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7630	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7631
7632	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7633
7634	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7635	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7636	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7637	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7638	{ } /* end */
7639};
7640
7641static struct hda_verb alc888_lenovo_sky_verbs[] = {
7642	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7643	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7644	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7645	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7646	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7647	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7648	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7649	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7650	{ } /* end */
7651};
7652
7653static struct hda_verb alc888_3st_hp_verbs[] = {
7654	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Front: output 0 (0x0c) */
7655	{0x16, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Rear : output 1 (0x0d) */
7656	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02},	/* CLFE : output 2 (0x0e) */
7657	{ }
7658};
7659
7660static struct hda_verb alc888_6st_dell_verbs[] = {
7661	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7662	{ }
7663};
7664
7665static struct hda_verb alc888_3st_hp_2ch_init[] = {
7666	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7667	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7668	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7669	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7670	{ }
7671};
7672
7673static struct hda_verb alc888_3st_hp_6ch_init[] = {
7674	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7675	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7676	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7677	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7678	{ }
7679};
7680
7681static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7682	{ 2, alc888_3st_hp_2ch_init },
7683	{ 6, alc888_3st_hp_6ch_init },
7684};
7685
7686/* toggle front-jack and RCA according to the hp-jack state */
7687static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7688{
7689 	unsigned int present;
7690
7691 	present = snd_hda_codec_read(codec, 0x1b, 0,
7692				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7693	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7694				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7695	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7696				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7697}
7698
7699/* toggle RCA according to the front-jack state */
7700static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7701{
7702 	unsigned int present;
7703
7704 	present = snd_hda_codec_read(codec, 0x14, 0,
7705				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7706	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7707				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7708}
7709
7710static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7711					     unsigned int res)
7712{
7713	if ((res >> 26) == ALC880_HP_EVENT)
7714		alc888_lenovo_ms7195_front_automute(codec);
7715	if ((res >> 26) == ALC880_FRONT_EVENT)
7716		alc888_lenovo_ms7195_rca_automute(codec);
7717}
7718
7719static struct hda_verb alc883_medion_md2_verbs[] = {
7720	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7721	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7722
7723	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7724
7725	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7726	{ } /* end */
7727};
7728
7729/* toggle speaker-output according to the hp-jack state */
7730static void alc883_medion_md2_automute(struct hda_codec *codec)
7731{
7732 	unsigned int present;
7733
7734 	present = snd_hda_codec_read(codec, 0x14, 0,
7735				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7736	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7737				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7738}
7739
7740static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7741					  unsigned int res)
7742{
7743	if ((res >> 26) == ALC880_HP_EVENT)
7744		alc883_medion_md2_automute(codec);
7745}
7746
7747/* toggle speaker-output according to the hp-jack state */
7748static void alc883_tagra_automute(struct hda_codec *codec)
7749{
7750 	unsigned int present;
7751	unsigned char bits;
7752
7753 	present = snd_hda_codec_read(codec, 0x14, 0,
7754				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7755	bits = present ? HDA_AMP_MUTE : 0;
7756	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7757				 HDA_AMP_MUTE, bits);
7758	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7759				  present ? 1 : 3);
7760}
7761
7762static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7763{
7764	if ((res >> 26) == ALC880_HP_EVENT)
7765		alc883_tagra_automute(codec);
7766}
7767
7768/* toggle speaker-output according to the hp-jack state */
7769static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
7770{
7771	unsigned int present;
7772	unsigned char bits;
7773
7774	present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
7775		& AC_PINSENSE_PRESENCE;
7776	bits = present ? HDA_AMP_MUTE : 0;
7777	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7778				 HDA_AMP_MUTE, bits);
7779}
7780
7781static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
7782{
7783	unsigned int present;
7784
7785	present = snd_hda_codec_read(codec, 0x18, 0,
7786				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7787	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
7788				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7789}
7790
7791static void alc883_clevo_m720_automute(struct hda_codec *codec)
7792{
7793	alc883_clevo_m720_hp_automute(codec);
7794	alc883_clevo_m720_mic_automute(codec);
7795}
7796
7797static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
7798					   unsigned int res)
7799{
7800	switch (res >> 26) {
7801	case ALC880_HP_EVENT:
7802		alc883_clevo_m720_hp_automute(codec);
7803		break;
7804	case ALC880_MIC_EVENT:
7805		alc883_clevo_m720_mic_automute(codec);
7806		break;
7807	}
7808}
7809
7810/* toggle speaker-output according to the hp-jack state */
7811static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
7812{
7813 	unsigned int present;
7814	unsigned char bits;
7815
7816 	present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
7817		& AC_PINSENSE_PRESENCE;
7818	bits = present ? HDA_AMP_MUTE : 0;
7819	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7820				 HDA_AMP_MUTE, bits);
7821}
7822
7823static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
7824						  unsigned int res)
7825{
7826	if ((res >> 26) == ALC880_HP_EVENT)
7827		alc883_2ch_fujitsu_pi2515_automute(codec);
7828}
7829
7830static void alc883_haier_w66_automute(struct hda_codec *codec)
7831{
7832	unsigned int present;
7833	unsigned char bits;
7834
7835	present = snd_hda_codec_read(codec, 0x1b, 0,
7836				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7837	bits = present ? 0x80 : 0;
7838	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7839				 0x80, bits);
7840}
7841
7842static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7843					 unsigned int res)
7844{
7845	if ((res >> 26) == ALC880_HP_EVENT)
7846		alc883_haier_w66_automute(codec);
7847}
7848
7849static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7850{
7851 	unsigned int present;
7852	unsigned char bits;
7853
7854 	present = snd_hda_codec_read(codec, 0x14, 0,
7855				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7856	bits = present ? HDA_AMP_MUTE : 0;
7857	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7858				 HDA_AMP_MUTE, bits);
7859}
7860
7861static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7862{
7863 	unsigned int present;
7864	unsigned char bits;
7865
7866 	present = snd_hda_codec_read(codec, 0x1b, 0,
7867				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7868	bits = present ? HDA_AMP_MUTE : 0;
7869	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7870				 HDA_AMP_MUTE, bits);
7871	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7872				 HDA_AMP_MUTE, bits);
7873}
7874
7875static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7876					   unsigned int res)
7877{
7878	if ((res >> 26) == ALC880_HP_EVENT)
7879		alc883_lenovo_101e_all_automute(codec);
7880	if ((res >> 26) == ALC880_FRONT_EVENT)
7881		alc883_lenovo_101e_ispeaker_automute(codec);
7882}
7883
7884/* toggle speaker-output according to the hp-jack state */
7885static void alc883_acer_aspire_automute(struct hda_codec *codec)
7886{
7887 	unsigned int present;
7888
7889 	present = snd_hda_codec_read(codec, 0x14, 0,
7890				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7891	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7892				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7893	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7894				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7895}
7896
7897static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7898					   unsigned int res)
7899{
7900	if ((res >> 26) == ALC880_HP_EVENT)
7901		alc883_acer_aspire_automute(codec);
7902}
7903
7904static struct hda_verb alc883_acer_eapd_verbs[] = {
7905	/* HP Pin: output 0 (0x0c) */
7906	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7907	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7908	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7909	/* Front Pin: output 0 (0x0c) */
7910	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7911	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7912	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7913	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7914        /* eanable EAPD on medion laptop */
7915	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7916	{0x20, AC_VERB_SET_PROC_COEF, 0x3050},
7917	/* enable unsolicited event */
7918	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7919	{ }
7920};
7921
7922static void alc888_6st_dell_front_automute(struct hda_codec *codec)
7923{
7924 	unsigned int present;
7925
7926 	present = snd_hda_codec_read(codec, 0x1b, 0,
7927				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7928	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7929				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7930	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7931				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7932	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7933				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7934	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7935				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7936}
7937
7938static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
7939					     unsigned int res)
7940{
7941	switch (res >> 26) {
7942	case ALC880_HP_EVENT:
7943		printk("hp_event\n");
7944		alc888_6st_dell_front_automute(codec);
7945		break;
7946	}
7947}
7948
7949static void alc888_lenovo_sky_front_automute(struct hda_codec *codec)
7950{
7951	unsigned int mute;
7952	unsigned int present;
7953
7954	snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
7955	present = snd_hda_codec_read(codec, 0x1b, 0,
7956				     AC_VERB_GET_PIN_SENSE, 0);
7957	present = (present & 0x80000000) != 0;
7958	if (present) {
7959		/* mute internal speaker */
7960		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7961					 HDA_AMP_MUTE, HDA_AMP_MUTE);
7962		snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7963					 HDA_AMP_MUTE, HDA_AMP_MUTE);
7964		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7965					 HDA_AMP_MUTE, HDA_AMP_MUTE);
7966		snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7967					 HDA_AMP_MUTE, HDA_AMP_MUTE);
7968		snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
7969					 HDA_AMP_MUTE, HDA_AMP_MUTE);
7970	} else {
7971		/* unmute internal speaker if necessary */
7972		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
7973		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7974					 HDA_AMP_MUTE, mute);
7975		snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7976					 HDA_AMP_MUTE, mute);
7977		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7978					 HDA_AMP_MUTE, mute);
7979		snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7980					 HDA_AMP_MUTE, mute);
7981		snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
7982					 HDA_AMP_MUTE, mute);
7983	}
7984}
7985
7986static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec,
7987					     unsigned int res)
7988{
7989	if ((res >> 26) == ALC880_HP_EVENT)
7990		alc888_lenovo_sky_front_automute(codec);
7991}
7992
7993/*
7994 * generic initialization of ADC, input mixers and output mixers
7995 */
7996static struct hda_verb alc883_auto_init_verbs[] = {
7997	/*
7998	 * Unmute ADC0-2 and set the default input to mic-in
7999	 */
8000	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8001	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8002	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8003	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8004
8005	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8006	 * mixer widget
8007	 * Note: PASD motherboards uses the Line In 2 as the input for
8008	 * front panel mic (mic 2)
8009	 */
8010	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8011	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8012	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8013	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8014	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8015	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8016
8017	/*
8018	 * Set up output mixers (0x0c - 0x0f)
8019	 */
8020	/* set vol=0 to output mixers */
8021	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8022	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8023	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8024	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8025	/* set up input amps for analog loopback */
8026	/* Amp Indices: DAC = 0, mixer = 1 */
8027	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8028	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8029	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8030	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8031	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8032	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8033	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8034	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8035	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8036	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8037
8038	/* FIXME: use matrix-type input source selection */
8039	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8040	/* Input mixer1 */
8041	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8042	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8043	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8044	/* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8045	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8046	/* Input mixer2 */
8047	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8048	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8049	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8050	/* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8051	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8052
8053	{ }
8054};
8055
8056static struct hda_verb alc888_asus_m90v_verbs[] = {
8057	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8058	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8059	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8060	/* enable unsolicited event */
8061	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8062	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8063	{ } /* end */
8064};
8065
8066static void alc883_nb_mic_automute(struct hda_codec *codec)
8067{
8068	unsigned int present;
8069
8070	present = snd_hda_codec_read(codec, 0x18, 0,
8071				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8072	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8073			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8074	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8075			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8076}
8077
8078static void alc883_M90V_speaker_automute(struct hda_codec *codec)
8079{
8080	unsigned int present;
8081	unsigned char bits;
8082
8083	present = snd_hda_codec_read(codec, 0x1b, 0,
8084				     AC_VERB_GET_PIN_SENSE, 0)
8085		& AC_PINSENSE_PRESENCE;
8086	bits = present ? 0 : PIN_OUT;
8087	snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8088			    bits);
8089	snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8090			    bits);
8091	snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8092			    bits);
8093}
8094
8095static void alc883_mode2_unsol_event(struct hda_codec *codec,
8096					   unsigned int res)
8097{
8098	switch (res >> 26) {
8099	case ALC880_HP_EVENT:
8100		alc883_M90V_speaker_automute(codec);
8101		break;
8102	case ALC880_MIC_EVENT:
8103		alc883_nb_mic_automute(codec);
8104		break;
8105	}
8106}
8107
8108static void alc883_mode2_inithook(struct hda_codec *codec)
8109{
8110	alc883_M90V_speaker_automute(codec);
8111	alc883_nb_mic_automute(codec);
8112}
8113
8114static struct hda_verb alc888_asus_eee1601_verbs[] = {
8115	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8116	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8117	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8118	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8119	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8120	{0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8121	{0x20, AC_VERB_SET_PROC_COEF,  0x0838},
8122	/* enable unsolicited event */
8123	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8124	{ } /* end */
8125};
8126
8127static void alc883_eee1601_speaker_automute(struct hda_codec *codec)
8128{
8129	unsigned int present;
8130	unsigned char bits;
8131
8132	present = snd_hda_codec_read(codec, 0x14, 0,
8133				     AC_VERB_GET_PIN_SENSE, 0)
8134		& AC_PINSENSE_PRESENCE;
8135	bits = present ? 0 : PIN_OUT;
8136	snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8137			    bits);
8138}
8139
8140static void alc883_eee1601_unsol_event(struct hda_codec *codec,
8141					   unsigned int res)
8142{
8143	switch (res >> 26) {
8144	case ALC880_HP_EVENT:
8145		alc883_eee1601_speaker_automute(codec);
8146		break;
8147	}
8148}
8149
8150static void alc883_eee1601_inithook(struct hda_codec *codec)
8151{
8152	alc883_eee1601_speaker_automute(codec);
8153}
8154
8155#ifdef CONFIG_SND_HDA_POWER_SAVE
8156#define alc883_loopbacks	alc880_loopbacks
8157#endif
8158
8159/* pcm configuration: identiacal with ALC880 */
8160#define alc883_pcm_analog_playback	alc880_pcm_analog_playback
8161#define alc883_pcm_analog_capture	alc880_pcm_analog_capture
8162#define alc883_pcm_analog_alt_capture	alc880_pcm_analog_alt_capture
8163#define alc883_pcm_digital_playback	alc880_pcm_digital_playback
8164#define alc883_pcm_digital_capture	alc880_pcm_digital_capture
8165
8166/*
8167 * configuration and preset
8168 */
8169static const char *alc883_models[ALC883_MODEL_LAST] = {
8170	[ALC883_3ST_2ch_DIG]	= "3stack-dig",
8171	[ALC883_3ST_6ch_DIG]	= "3stack-6ch-dig",
8172	[ALC883_3ST_6ch]	= "3stack-6ch",
8173	[ALC883_6ST_DIG]	= "6stack-dig",
8174	[ALC883_TARGA_DIG]	= "targa-dig",
8175	[ALC883_TARGA_2ch_DIG]	= "targa-2ch-dig",
8176	[ALC883_ACER]		= "acer",
8177	[ALC883_ACER_ASPIRE]	= "acer-aspire",
8178	[ALC883_MEDION]		= "medion",
8179	[ALC883_MEDION_MD2]	= "medion-md2",
8180	[ALC883_LAPTOP_EAPD]	= "laptop-eapd",
8181	[ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8182	[ALC883_LENOVO_NB0763]	= "lenovo-nb0763",
8183	[ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8184	[ALC888_LENOVO_SKY] = "lenovo-sky",
8185	[ALC883_HAIER_W66] 	= "haier-w66",
8186	[ALC888_3ST_HP]		= "3stack-hp",
8187	[ALC888_6ST_DELL]	= "6stack-dell",
8188	[ALC883_MITAC]		= "mitac",
8189	[ALC883_CLEVO_M720]	= "clevo-m720",
8190	[ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8191	[ALC883_3ST_6ch_INTEL]	= "3stack-6ch-intel",
8192	[ALC883_AUTO]		= "auto",
8193};
8194
8195static struct snd_pci_quirk alc883_cfg_tbl[] = {
8196	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
8197	SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8198	SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8199	SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8200	SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8201	SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
8202	SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8203	SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8204	SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8205	SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8206	SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8207	SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8208	SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8209	SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8210	SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8211	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
8212	SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8213	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8214	SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8215	SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8216	SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
8217	SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8218	SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8219	SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8220	SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8221	SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8222	SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8223	SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8224	SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8225	SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8226	SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8227	SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8228	SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8229	SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8230	SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8231	SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8232	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8233	SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8234	SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8235	SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8236	SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8237	SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8238	SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8239	SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8240	SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8241	SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8242	SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
8243	SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8244	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8245	SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515),
8246	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8247	SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8248	SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8249	SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8250	SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8251	SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8252	SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8253	SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8254	SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8255	SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8256	SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8257	{}
8258};
8259
8260static struct alc_config_preset alc883_presets[] = {
8261	[ALC883_3ST_2ch_DIG] = {
8262		.mixers = { alc883_3ST_2ch_mixer },
8263		.init_verbs = { alc883_init_verbs },
8264		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8265		.dac_nids = alc883_dac_nids,
8266		.dig_out_nid = ALC883_DIGOUT_NID,
8267		.dig_in_nid = ALC883_DIGIN_NID,
8268		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8269		.channel_mode = alc883_3ST_2ch_modes,
8270		.input_mux = &alc883_capture_source,
8271	},
8272	[ALC883_3ST_6ch_DIG] = {
8273		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8274		.init_verbs = { alc883_init_verbs },
8275		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8276		.dac_nids = alc883_dac_nids,
8277		.dig_out_nid = ALC883_DIGOUT_NID,
8278		.dig_in_nid = ALC883_DIGIN_NID,
8279		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8280		.channel_mode = alc883_3ST_6ch_modes,
8281		.need_dac_fix = 1,
8282		.input_mux = &alc883_capture_source,
8283	},
8284	[ALC883_3ST_6ch] = {
8285		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8286		.init_verbs = { alc883_init_verbs },
8287		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8288		.dac_nids = alc883_dac_nids,
8289		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8290		.channel_mode = alc883_3ST_6ch_modes,
8291		.need_dac_fix = 1,
8292		.input_mux = &alc883_capture_source,
8293	},
8294	[ALC883_3ST_6ch_INTEL] = {
8295		.mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8296		.init_verbs = { alc883_init_verbs },
8297		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8298		.dac_nids = alc883_dac_nids,
8299		.dig_out_nid = ALC883_DIGOUT_NID,
8300		.dig_in_nid = ALC883_DIGIN_NID,
8301		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8302		.channel_mode = alc883_3ST_6ch_intel_modes,
8303		.need_dac_fix = 1,
8304		.input_mux = &alc883_3stack_6ch_intel,
8305	},
8306	[ALC883_6ST_DIG] = {
8307		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
8308		.init_verbs = { alc883_init_verbs },
8309		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8310		.dac_nids = alc883_dac_nids,
8311		.dig_out_nid = ALC883_DIGOUT_NID,
8312		.dig_in_nid = ALC883_DIGIN_NID,
8313		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8314		.channel_mode = alc883_sixstack_modes,
8315		.input_mux = &alc883_capture_source,
8316	},
8317	[ALC883_TARGA_DIG] = {
8318		.mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8319		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8320		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8321		.dac_nids = alc883_dac_nids,
8322		.dig_out_nid = ALC883_DIGOUT_NID,
8323		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8324		.channel_mode = alc883_3ST_6ch_modes,
8325		.need_dac_fix = 1,
8326		.input_mux = &alc883_capture_source,
8327		.unsol_event = alc883_tagra_unsol_event,
8328		.init_hook = alc883_tagra_automute,
8329	},
8330	[ALC883_TARGA_2ch_DIG] = {
8331		.mixers = { alc883_tagra_2ch_mixer},
8332		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8333		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8334		.dac_nids = alc883_dac_nids,
8335		.adc_nids = alc883_adc_nids_alt,
8336		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8337		.dig_out_nid = ALC883_DIGOUT_NID,
8338		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8339		.channel_mode = alc883_3ST_2ch_modes,
8340		.input_mux = &alc883_capture_source,
8341		.unsol_event = alc883_tagra_unsol_event,
8342		.init_hook = alc883_tagra_automute,
8343	},
8344	[ALC883_ACER] = {
8345		.mixers = { alc883_base_mixer },
8346		/* On TravelMate laptops, GPIO 0 enables the internal speaker
8347		 * and the headphone jack.  Turn this on and rely on the
8348		 * standard mute methods whenever the user wants to turn
8349		 * these outputs off.
8350		 */
8351		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8352		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8353		.dac_nids = alc883_dac_nids,
8354		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8355		.channel_mode = alc883_3ST_2ch_modes,
8356		.input_mux = &alc883_capture_source,
8357	},
8358	[ALC883_ACER_ASPIRE] = {
8359		.mixers = { alc883_acer_aspire_mixer },
8360		.init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
8361		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8362		.dac_nids = alc883_dac_nids,
8363		.dig_out_nid = ALC883_DIGOUT_NID,
8364		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8365		.channel_mode = alc883_3ST_2ch_modes,
8366		.input_mux = &alc883_capture_source,
8367		.unsol_event = alc883_acer_aspire_unsol_event,
8368		.init_hook = alc883_acer_aspire_automute,
8369	},
8370	[ALC883_MEDION] = {
8371		.mixers = { alc883_fivestack_mixer,
8372			    alc883_chmode_mixer },
8373		.init_verbs = { alc883_init_verbs,
8374				alc883_medion_eapd_verbs },
8375		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8376		.dac_nids = alc883_dac_nids,
8377		.adc_nids = alc883_adc_nids_alt,
8378		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8379		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8380		.channel_mode = alc883_sixstack_modes,
8381		.input_mux = &alc883_capture_source,
8382	},
8383	[ALC883_MEDION_MD2] = {
8384		.mixers = { alc883_medion_md2_mixer},
8385		.init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8386		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8387		.dac_nids = alc883_dac_nids,
8388		.dig_out_nid = ALC883_DIGOUT_NID,
8389		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8390		.channel_mode = alc883_3ST_2ch_modes,
8391		.input_mux = &alc883_capture_source,
8392		.unsol_event = alc883_medion_md2_unsol_event,
8393		.init_hook = alc883_medion_md2_automute,
8394	},
8395	[ALC883_LAPTOP_EAPD] = {
8396		.mixers = { alc883_base_mixer },
8397		.init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8398		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8399		.dac_nids = alc883_dac_nids,
8400		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8401		.channel_mode = alc883_3ST_2ch_modes,
8402		.input_mux = &alc883_capture_source,
8403	},
8404	[ALC883_CLEVO_M720] = {
8405		.mixers = { alc883_clevo_m720_mixer },
8406		.init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
8407		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8408		.dac_nids = alc883_dac_nids,
8409		.dig_out_nid = ALC883_DIGOUT_NID,
8410		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8411		.channel_mode = alc883_3ST_2ch_modes,
8412		.input_mux = &alc883_capture_source,
8413		.unsol_event = alc883_clevo_m720_unsol_event,
8414		.init_hook = alc883_clevo_m720_automute,
8415	},
8416	[ALC883_LENOVO_101E_2ch] = {
8417		.mixers = { alc883_lenovo_101e_2ch_mixer},
8418		.init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8419		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8420		.dac_nids = alc883_dac_nids,
8421		.adc_nids = alc883_adc_nids_alt,
8422		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8423		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8424		.channel_mode = alc883_3ST_2ch_modes,
8425		.input_mux = &alc883_lenovo_101e_capture_source,
8426		.unsol_event = alc883_lenovo_101e_unsol_event,
8427		.init_hook = alc883_lenovo_101e_all_automute,
8428	},
8429	[ALC883_LENOVO_NB0763] = {
8430		.mixers = { alc883_lenovo_nb0763_mixer },
8431		.init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8432		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8433		.dac_nids = alc883_dac_nids,
8434		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8435		.channel_mode = alc883_3ST_2ch_modes,
8436		.need_dac_fix = 1,
8437		.input_mux = &alc883_lenovo_nb0763_capture_source,
8438		.unsol_event = alc883_medion_md2_unsol_event,
8439		.init_hook = alc883_medion_md2_automute,
8440	},
8441	[ALC888_LENOVO_MS7195_DIG] = {
8442		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8443		.init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8444		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8445		.dac_nids = alc883_dac_nids,
8446		.dig_out_nid = ALC883_DIGOUT_NID,
8447		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8448		.channel_mode = alc883_3ST_6ch_modes,
8449		.need_dac_fix = 1,
8450		.input_mux = &alc883_capture_source,
8451		.unsol_event = alc883_lenovo_ms7195_unsol_event,
8452		.init_hook = alc888_lenovo_ms7195_front_automute,
8453	},
8454	[ALC883_HAIER_W66] = {
8455		.mixers = { alc883_tagra_2ch_mixer},
8456		.init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8457		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8458		.dac_nids = alc883_dac_nids,
8459		.dig_out_nid = ALC883_DIGOUT_NID,
8460		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8461		.channel_mode = alc883_3ST_2ch_modes,
8462		.input_mux = &alc883_capture_source,
8463		.unsol_event = alc883_haier_w66_unsol_event,
8464		.init_hook = alc883_haier_w66_automute,
8465	},
8466	[ALC888_3ST_HP] = {
8467		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8468		.init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8469		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8470		.dac_nids = alc883_dac_nids,
8471		.num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
8472		.channel_mode = alc888_3st_hp_modes,
8473		.need_dac_fix = 1,
8474		.input_mux = &alc883_capture_source,
8475	},
8476	[ALC888_6ST_DELL] = {
8477		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
8478		.init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
8479		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8480		.dac_nids = alc883_dac_nids,
8481		.dig_out_nid = ALC883_DIGOUT_NID,
8482		.dig_in_nid = ALC883_DIGIN_NID,
8483		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8484		.channel_mode = alc883_sixstack_modes,
8485		.input_mux = &alc883_capture_source,
8486		.unsol_event = alc888_6st_dell_unsol_event,
8487		.init_hook = alc888_6st_dell_front_automute,
8488	},
8489	[ALC883_MITAC] = {
8490		.mixers = { alc883_mitac_mixer },
8491		.init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8492		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8493		.dac_nids = alc883_dac_nids,
8494		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8495		.channel_mode = alc883_3ST_2ch_modes,
8496		.input_mux = &alc883_capture_source,
8497		.unsol_event = alc883_mitac_unsol_event,
8498		.init_hook = alc883_mitac_automute,
8499	},
8500	[ALC883_FUJITSU_PI2515] = {
8501		.mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8502		.init_verbs = { alc883_init_verbs,
8503				alc883_2ch_fujitsu_pi2515_verbs},
8504		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8505		.dac_nids = alc883_dac_nids,
8506		.dig_out_nid = ALC883_DIGOUT_NID,
8507		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8508		.channel_mode = alc883_3ST_2ch_modes,
8509		.input_mux = &alc883_fujitsu_pi2515_capture_source,
8510		.unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
8511		.init_hook = alc883_2ch_fujitsu_pi2515_automute,
8512	},
8513	[ALC888_LENOVO_SKY] = {
8514		.mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
8515		.init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
8516		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8517		.dac_nids = alc883_dac_nids,
8518		.dig_out_nid = ALC883_DIGOUT_NID,
8519		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8520		.channel_mode = alc883_sixstack_modes,
8521		.need_dac_fix = 1,
8522		.input_mux = &alc883_lenovo_sky_capture_source,
8523		.unsol_event = alc883_lenovo_sky_unsol_event,
8524		.init_hook = alc888_lenovo_sky_front_automute,
8525	},
8526	[ALC888_ASUS_M90V] = {
8527		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8528		.init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
8529		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8530		.dac_nids = alc883_dac_nids,
8531		.dig_out_nid = ALC883_DIGOUT_NID,
8532		.dig_in_nid = ALC883_DIGIN_NID,
8533		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8534		.channel_mode = alc883_3ST_6ch_modes,
8535		.need_dac_fix = 1,
8536		.input_mux = &alc883_fujitsu_pi2515_capture_source,
8537		.unsol_event = alc883_mode2_unsol_event,
8538		.init_hook = alc883_mode2_inithook,
8539	},
8540	[ALC888_ASUS_EEE1601] = {
8541		.mixers = { alc883_asus_eee1601_mixer },
8542		.cap_mixer = alc883_asus_eee1601_cap_mixer,
8543		.init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
8544		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8545		.dac_nids = alc883_dac_nids,
8546		.dig_out_nid = ALC883_DIGOUT_NID,
8547		.dig_in_nid = ALC883_DIGIN_NID,
8548		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8549		.channel_mode = alc883_3ST_2ch_modes,
8550		.need_dac_fix = 1,
8551		.input_mux = &alc883_asus_eee1601_capture_source,
8552		.unsol_event = alc883_eee1601_unsol_event,
8553		.init_hook = alc883_eee1601_inithook,
8554	},
8555};
8556
8557
8558/*
8559 * BIOS auto configuration
8560 */
8561static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
8562					      hda_nid_t nid, int pin_type,
8563					      int dac_idx)
8564{
8565	/* set as output */
8566	struct alc_spec *spec = codec->spec;
8567	int idx;
8568
8569	alc_set_pin_output(codec, nid, pin_type);
8570	if (spec->multiout.dac_nids[dac_idx] == 0x25)
8571		idx = 4;
8572	else
8573		idx = spec->multiout.dac_nids[dac_idx] - 2;
8574	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
8575
8576}
8577
8578static void alc883_auto_init_multi_out(struct hda_codec *codec)
8579{
8580	struct alc_spec *spec = codec->spec;
8581	int i;
8582
8583	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
8584	for (i = 0; i <= HDA_SIDE; i++) {
8585		hda_nid_t nid = spec->autocfg.line_out_pins[i];
8586		int pin_type = get_pin_type(spec->autocfg.line_out_type);
8587		if (nid)
8588			alc883_auto_set_output_and_unmute(codec, nid, pin_type,
8589							  i);
8590	}
8591}
8592
8593static void alc883_auto_init_hp_out(struct hda_codec *codec)
8594{
8595	struct alc_spec *spec = codec->spec;
8596	hda_nid_t pin;
8597
8598	pin = spec->autocfg.hp_pins[0];
8599	if (pin) /* connect to front */
8600		/* use dac 0 */
8601		alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
8602	pin = spec->autocfg.speaker_pins[0];
8603	if (pin)
8604		alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
8605}
8606
8607#define alc883_is_input_pin(nid)	alc880_is_input_pin(nid)
8608#define ALC883_PIN_CD_NID		ALC880_PIN_CD_NID
8609
8610static void alc883_auto_init_analog_input(struct hda_codec *codec)
8611{
8612	struct alc_spec *spec = codec->spec;
8613	int i;
8614
8615	for (i = 0; i < AUTO_PIN_LAST; i++) {
8616		hda_nid_t nid = spec->autocfg.input_pins[i];
8617		if (alc883_is_input_pin(nid)) {
8618			snd_hda_codec_write(codec, nid, 0,
8619					    AC_VERB_SET_PIN_WIDGET_CONTROL,
8620					    (i <= AUTO_PIN_FRONT_MIC ?
8621					     PIN_VREF80 : PIN_IN));
8622			if (nid != ALC883_PIN_CD_NID)
8623				snd_hda_codec_write(codec, nid, 0,
8624						    AC_VERB_SET_AMP_GAIN_MUTE,
8625						    AMP_OUT_MUTE);
8626		}
8627	}
8628}
8629
8630#define alc883_auto_init_input_src	alc882_auto_init_input_src
8631
8632/* almost identical with ALC880 parser... */
8633static int alc883_parse_auto_config(struct hda_codec *codec)
8634{
8635	struct alc_spec *spec = codec->spec;
8636	int err = alc880_parse_auto_config(codec);
8637
8638	if (err < 0)
8639		return err;
8640	else if (!err)
8641		return 0; /* no config found */
8642
8643	err = alc_auto_add_mic_boost(codec);
8644	if (err < 0)
8645		return err;
8646
8647	/* hack - override the init verbs */
8648	spec->init_verbs[0] = alc883_auto_init_verbs;
8649
8650	return 1; /* config found */
8651}
8652
8653/* additional initialization for auto-configuration model */
8654static void alc883_auto_init(struct hda_codec *codec)
8655{
8656	struct alc_spec *spec = codec->spec;
8657	alc883_auto_init_multi_out(codec);
8658	alc883_auto_init_hp_out(codec);
8659	alc883_auto_init_analog_input(codec);
8660	alc883_auto_init_input_src(codec);
8661	if (spec->unsol_event)
8662		alc_inithook(codec);
8663}
8664
8665static int patch_alc883(struct hda_codec *codec)
8666{
8667	struct alc_spec *spec;
8668	int err, board_config;
8669
8670	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8671	if (spec == NULL)
8672		return -ENOMEM;
8673
8674	codec->spec = spec;
8675
8676	alc_fix_pll_init(codec, 0x20, 0x0a, 10);
8677
8678	board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
8679						  alc883_models,
8680						  alc883_cfg_tbl);
8681	if (board_config < 0) {
8682		printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
8683		       "trying auto-probe from BIOS...\n");
8684		board_config = ALC883_AUTO;
8685	}
8686
8687	if (board_config == ALC883_AUTO) {
8688		/* automatic parse from the BIOS config */
8689		err = alc883_parse_auto_config(codec);
8690		if (err < 0) {
8691			alc_free(codec);
8692			return err;
8693		} else if (!err) {
8694			printk(KERN_INFO
8695			       "hda_codec: Cannot set up configuration "
8696			       "from BIOS.  Using base mode...\n");
8697			board_config = ALC883_3ST_2ch_DIG;
8698		}
8699	}
8700
8701	if (board_config != ALC883_AUTO)
8702		setup_preset(spec, &alc883_presets[board_config]);
8703
8704	switch (codec->vendor_id) {
8705	case 0x10ec0888:
8706		if (codec->revision_id == 0x100101) {
8707			spec->stream_name_analog = "ALC1200 Analog";
8708			spec->stream_name_digital = "ALC1200 Digital";
8709		} else {
8710			spec->stream_name_analog = "ALC888 Analog";
8711			spec->stream_name_digital = "ALC888 Digital";
8712		}
8713		break;
8714	case 0x10ec0889:
8715		spec->stream_name_analog = "ALC889 Analog";
8716		spec->stream_name_digital = "ALC889 Digital";
8717		break;
8718	default:
8719		spec->stream_name_analog = "ALC883 Analog";
8720		spec->stream_name_digital = "ALC883 Digital";
8721		break;
8722	}
8723
8724	spec->stream_analog_playback = &alc883_pcm_analog_playback;
8725	spec->stream_analog_capture = &alc883_pcm_analog_capture;
8726	spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
8727
8728	spec->stream_digital_playback = &alc883_pcm_digital_playback;
8729	spec->stream_digital_capture = &alc883_pcm_digital_capture;
8730
8731	if (!spec->num_adc_nids) {
8732		spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8733		spec->adc_nids = alc883_adc_nids;
8734	}
8735	if (!spec->capsrc_nids)
8736		spec->capsrc_nids = alc883_capsrc_nids;
8737	spec->is_mix_capture = 1; /* matrix-style capture */
8738	if (!spec->cap_mixer)
8739		set_capture_mixer(spec);
8740
8741	spec->vmaster_nid = 0x0c;
8742
8743	codec->patch_ops = alc_patch_ops;
8744	if (board_config == ALC883_AUTO)
8745		spec->init_hook = alc883_auto_init;
8746
8747#ifdef CONFIG_SND_HDA_POWER_SAVE
8748	if (!spec->loopback.amplist)
8749		spec->loopback.amplist = alc883_loopbacks;
8750#endif
8751
8752	return 0;
8753}
8754
8755/*
8756 * ALC262 support
8757 */
8758
8759#define ALC262_DIGOUT_NID	ALC880_DIGOUT_NID
8760#define ALC262_DIGIN_NID	ALC880_DIGIN_NID
8761
8762#define alc262_dac_nids		alc260_dac_nids
8763#define alc262_adc_nids		alc882_adc_nids
8764#define alc262_adc_nids_alt	alc882_adc_nids_alt
8765#define alc262_capsrc_nids	alc882_capsrc_nids
8766#define alc262_capsrc_nids_alt	alc882_capsrc_nids_alt
8767
8768#define alc262_modes		alc260_modes
8769#define alc262_capture_source	alc882_capture_source
8770
8771static hda_nid_t alc262_dmic_adc_nids[1] = {
8772	/* ADC0 */
8773	0x09
8774};
8775
8776static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
8777
8778static struct snd_kcontrol_new alc262_base_mixer[] = {
8779	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8780	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8781	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8782	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8783	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8784	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8785	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8786	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8787	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8788	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8789	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8790	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8791	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8792	   HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8793	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
8794	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8795	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8796	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
8797	{ } /* end */
8798};
8799
8800static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
8801	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8802	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8803	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8804	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8805	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8806	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8807	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8808	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8809	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8810	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8811	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8812	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8813	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8814	   HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8815	/*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
8816	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8817	{ } /* end */
8818};
8819
8820/* update HP, line and mono-out pins according to the master switch */
8821static void alc262_hp_master_update(struct hda_codec *codec)
8822{
8823	struct alc_spec *spec = codec->spec;
8824	int val = spec->master_sw;
8825
8826	/* HP & line-out */
8827	snd_hda_codec_write_cache(codec, 0x1b, 0,
8828				  AC_VERB_SET_PIN_WIDGET_CONTROL,
8829				  val ? PIN_HP : 0);
8830	snd_hda_codec_write_cache(codec, 0x15, 0,
8831				  AC_VERB_SET_PIN_WIDGET_CONTROL,
8832				  val ? PIN_HP : 0);
8833	/* mono (speaker) depending on the HP jack sense */
8834	val = val && !spec->jack_present;
8835	snd_hda_codec_write_cache(codec, 0x16, 0,
8836				  AC_VERB_SET_PIN_WIDGET_CONTROL,
8837				  val ? PIN_OUT : 0);
8838}
8839
8840static void alc262_hp_bpc_automute(struct hda_codec *codec)
8841{
8842	struct alc_spec *spec = codec->spec;
8843	unsigned int presence;
8844	presence = snd_hda_codec_read(codec, 0x1b, 0,
8845				      AC_VERB_GET_PIN_SENSE, 0);
8846	spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8847	alc262_hp_master_update(codec);
8848}
8849
8850static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
8851{
8852	if ((res >> 26) != ALC880_HP_EVENT)
8853		return;
8854	alc262_hp_bpc_automute(codec);
8855}
8856
8857static void alc262_hp_wildwest_automute(struct hda_codec *codec)
8858{
8859	struct alc_spec *spec = codec->spec;
8860	unsigned int presence;
8861	presence = snd_hda_codec_read(codec, 0x15, 0,
8862				      AC_VERB_GET_PIN_SENSE, 0);
8863	spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8864	alc262_hp_master_update(codec);
8865}
8866
8867static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
8868					   unsigned int res)
8869{
8870	if ((res >> 26) != ALC880_HP_EVENT)
8871		return;
8872	alc262_hp_wildwest_automute(codec);
8873}
8874
8875static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
8876				   struct snd_ctl_elem_value *ucontrol)
8877{
8878	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8879	struct alc_spec *spec = codec->spec;
8880	*ucontrol->value.integer.value = spec->master_sw;
8881	return 0;
8882}
8883
8884static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
8885				   struct snd_ctl_elem_value *ucontrol)
8886{
8887	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8888	struct alc_spec *spec = codec->spec;
8889	int val = !!*ucontrol->value.integer.value;
8890
8891	if (val == spec->master_sw)
8892		return 0;
8893	spec->master_sw = val;
8894	alc262_hp_master_update(codec);
8895	return 1;
8896}
8897
8898static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
8899	{
8900		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8901		.name = "Master Playback Switch",
8902		.info = snd_ctl_boolean_mono_info,
8903		.get = alc262_hp_master_sw_get,
8904		.put = alc262_hp_master_sw_put,
8905	},
8906	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8907	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8908	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8909	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8910			      HDA_OUTPUT),
8911	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8912			    HDA_OUTPUT),
8913	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8914	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8915	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8916	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8917	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8918	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8919	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8920	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8921	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8922	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8923	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8924	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8925	HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
8926	HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
8927	{ } /* end */
8928};
8929
8930static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
8931	{
8932		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8933		.name = "Master Playback Switch",
8934		.info = snd_ctl_boolean_mono_info,
8935		.get = alc262_hp_master_sw_get,
8936		.put = alc262_hp_master_sw_put,
8937	},
8938	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8939	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8940	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8941	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8942	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8943			      HDA_OUTPUT),
8944	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8945			    HDA_OUTPUT),
8946	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
8947	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
8948	HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
8949	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8950	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8951	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8952	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8953	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8954	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8955	{ } /* end */
8956};
8957
8958static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
8959	HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8960	HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8961	HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
8962	{ } /* end */
8963};
8964
8965/* mute/unmute internal speaker according to the hp jack and mute state */
8966static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
8967{
8968	struct alc_spec *spec = codec->spec;
8969
8970	if (force || !spec->sense_updated) {
8971		unsigned int present;
8972		present = snd_hda_codec_read(codec, 0x15, 0,
8973					     AC_VERB_GET_PIN_SENSE, 0);
8974		spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
8975		spec->sense_updated = 1;
8976	}
8977	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
8978				 spec->jack_present ? HDA_AMP_MUTE : 0);
8979}
8980
8981static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
8982					unsigned int res)
8983{
8984	if ((res >> 26) != ALC880_HP_EVENT)
8985		return;
8986	alc262_hp_t5735_automute(codec, 1);
8987}
8988
8989static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
8990{
8991	alc262_hp_t5735_automute(codec, 1);
8992}
8993
8994static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
8995	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8996	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8997	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8998	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8999	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9000	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9001	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9002	{ } /* end */
9003};
9004
9005static struct hda_verb alc262_hp_t5735_verbs[] = {
9006	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9007	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9008
9009	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9010	{ }
9011};
9012
9013static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
9014	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9015	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9016	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9017	HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
9018	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9019	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9020	{ } /* end */
9021};
9022
9023static struct hda_verb alc262_hp_rp5700_verbs[] = {
9024	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9025	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9026	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9027	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9028	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9029	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9030	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9031	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9032	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9033	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9034	{}
9035};
9036
9037static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9038	.num_items = 1,
9039	.items = {
9040		{ "Line", 0x1 },
9041	},
9042};
9043
9044/* bind hp and internal speaker mute (with plug check) */
9045static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
9046				     struct snd_ctl_elem_value *ucontrol)
9047{
9048	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9049	long *valp = ucontrol->value.integer.value;
9050	int change;
9051
9052	/* change hp mute */
9053	change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
9054					  HDA_AMP_MUTE,
9055					  valp[0] ? 0 : HDA_AMP_MUTE);
9056	change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
9057					   HDA_AMP_MUTE,
9058					   valp[1] ? 0 : HDA_AMP_MUTE);
9059	if (change) {
9060		/* change speaker according to HP jack state */
9061		struct alc_spec *spec = codec->spec;
9062		unsigned int mute;
9063		if (spec->jack_present)
9064			mute = HDA_AMP_MUTE;
9065		else
9066			mute = snd_hda_codec_amp_read(codec, 0x15, 0,
9067						      HDA_OUTPUT, 0);
9068		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9069					 HDA_AMP_MUTE, mute);
9070	}
9071	return change;
9072}
9073
9074static struct snd_kcontrol_new alc262_sony_mixer[] = {
9075	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9076	{
9077		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9078		.name = "Master Playback Switch",
9079		.info = snd_hda_mixer_amp_switch_info,
9080		.get = snd_hda_mixer_amp_switch_get,
9081		.put = alc262_sony_master_sw_put,
9082		.private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9083	},
9084	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9085	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9086	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9087	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9088	{ } /* end */
9089};
9090
9091static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9092	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9093	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9094	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9095	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9096	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9097	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9098	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9099	{ } /* end */
9100};
9101
9102#define alc262_capture_mixer		alc882_capture_mixer
9103#define alc262_capture_alt_mixer	alc882_capture_alt_mixer
9104
9105/*
9106 * generic initialization of ADC, input mixers and output mixers
9107 */
9108static struct hda_verb alc262_init_verbs[] = {
9109	/*
9110	 * Unmute ADC0-2 and set the default input to mic-in
9111	 */
9112	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9113	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9114	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9115	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9116	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9117	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9118
9119	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9120	 * mixer widget
9121	 * Note: PASD motherboards uses the Line In 2 as the input for
9122	 * front panel mic (mic 2)
9123	 */
9124	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9125	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9126	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9127	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9128	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9129	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9130
9131	/*
9132	 * Set up output mixers (0x0c - 0x0e)
9133	 */
9134	/* set vol=0 to output mixers */
9135	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9136	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9137	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9138	/* set up input amps for analog loopback */
9139	/* Amp Indices: DAC = 0, mixer = 1 */
9140	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9141	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9142	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9143	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9144	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9145	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9146
9147	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9148	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9149	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9150	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9151	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9152	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9153
9154	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9155	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9156	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9157	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9158	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9159
9160	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9161	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9162
9163	/* FIXME: use matrix-type input source selection */
9164	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9165	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9166	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9167	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9168	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9169	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9170	/* Input mixer2 */
9171	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9172	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9173	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9174	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9175	/* Input mixer3 */
9176	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9177	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9178	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9179	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9180
9181	{ }
9182};
9183
9184static struct hda_verb alc262_eapd_verbs[] = {
9185	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9186	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9187	{ }
9188};
9189
9190static struct hda_verb alc262_hippo_unsol_verbs[] = {
9191	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9192	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9193	{}
9194};
9195
9196static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9197	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9198	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9199	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9200
9201	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9202	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9203	{}
9204};
9205
9206static struct hda_verb alc262_sony_unsol_verbs[] = {
9207	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9208	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9209	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},	// Front Mic
9210
9211	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9212	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9213	{}
9214};
9215
9216static struct hda_input_mux alc262_dmic_capture_source = {
9217	.num_items = 2,
9218	.items = {
9219		{ "Int DMic", 0x9 },
9220		{ "Mic", 0x0 },
9221	},
9222};
9223
9224static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9225	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9226	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9227	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9228	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9229	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9230	{ } /* end */
9231};
9232
9233static struct hda_verb alc262_toshiba_s06_verbs[] = {
9234	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9235	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9236	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9237	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9238	{0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9239	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9240	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9241	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9242	{}
9243};
9244
9245static void alc262_dmic_automute(struct hda_codec *codec)
9246{
9247	unsigned int present;
9248
9249	present = snd_hda_codec_read(codec, 0x18, 0,
9250					AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9251	snd_hda_codec_write(codec, 0x22, 0,
9252				AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9253}
9254
9255/* toggle speaker-output according to the hp-jack state */
9256static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
9257{
9258	unsigned int present;
9259	unsigned char bits;
9260
9261	present = snd_hda_codec_read(codec, 0x15, 0,
9262					AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9263	bits = present ? 0 : PIN_OUT;
9264	snd_hda_codec_write(codec, 0x14, 0,
9265					AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
9266}
9267
9268
9269
9270/* unsolicited event for HP jack sensing */
9271static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9272				       unsigned int res)
9273{
9274	if ((res >> 26) == ALC880_HP_EVENT)
9275		alc262_toshiba_s06_speaker_automute(codec);
9276	if ((res >> 26) == ALC880_MIC_EVENT)
9277		alc262_dmic_automute(codec);
9278
9279}
9280
9281static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9282{
9283	alc262_toshiba_s06_speaker_automute(codec);
9284	alc262_dmic_automute(codec);
9285}
9286
9287/* mute/unmute internal speaker according to the hp jack and mute state */
9288static void alc262_hippo_automute(struct hda_codec *codec)
9289{
9290	struct alc_spec *spec = codec->spec;
9291	unsigned int mute;
9292	unsigned int present;
9293
9294	/* need to execute and sync at first */
9295	snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9296	present = snd_hda_codec_read(codec, 0x15, 0,
9297				     AC_VERB_GET_PIN_SENSE, 0);
9298	spec->jack_present = (present & 0x80000000) != 0;
9299	if (spec->jack_present) {
9300		/* mute internal speaker */
9301		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9302					 HDA_AMP_MUTE, HDA_AMP_MUTE);
9303	} else {
9304		/* unmute internal speaker if necessary */
9305		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
9306		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9307					 HDA_AMP_MUTE, mute);
9308	}
9309}
9310
9311/* unsolicited event for HP jack sensing */
9312static void alc262_hippo_unsol_event(struct hda_codec *codec,
9313				       unsigned int res)
9314{
9315	if ((res >> 26) != ALC880_HP_EVENT)
9316		return;
9317	alc262_hippo_automute(codec);
9318}
9319
9320static void alc262_hippo1_automute(struct hda_codec *codec)
9321{
9322	unsigned int mute;
9323	unsigned int present;
9324
9325	snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9326	present = snd_hda_codec_read(codec, 0x1b, 0,
9327				     AC_VERB_GET_PIN_SENSE, 0);
9328	present = (present & 0x80000000) != 0;
9329	if (present) {
9330		/* mute internal speaker */
9331		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9332					 HDA_AMP_MUTE, HDA_AMP_MUTE);
9333	} else {
9334		/* unmute internal speaker if necessary */
9335		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9336		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9337					 HDA_AMP_MUTE, mute);
9338	}
9339}
9340
9341/* unsolicited event for HP jack sensing */
9342static void alc262_hippo1_unsol_event(struct hda_codec *codec,
9343				       unsigned int res)
9344{
9345	if ((res >> 26) != ALC880_HP_EVENT)
9346		return;
9347	alc262_hippo1_automute(codec);
9348}
9349
9350/*
9351 * nec model
9352 *  0x15 = headphone
9353 *  0x16 = internal speaker
9354 *  0x18 = external mic
9355 */
9356
9357static struct snd_kcontrol_new alc262_nec_mixer[] = {
9358	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9359	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
9360
9361	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9362	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9363	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9364
9365	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9366	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9367	{ } /* end */
9368};
9369
9370static struct hda_verb alc262_nec_verbs[] = {
9371	/* Unmute Speaker */
9372	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9373
9374	/* Headphone */
9375	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9376	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9377
9378	/* External mic to headphone */
9379	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9380	/* External mic to speaker */
9381	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9382	{}
9383};
9384
9385/*
9386 * fujitsu model
9387 *  0x14 = headphone/spdif-out, 0x15 = internal speaker,
9388 *  0x1b = port replicator headphone out
9389 */
9390
9391#define ALC_HP_EVENT	0x37
9392
9393static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
9394	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9395	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9396	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9397	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9398	{}
9399};
9400
9401static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
9402	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9403	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9404	{}
9405};
9406
9407static struct hda_input_mux alc262_fujitsu_capture_source = {
9408	.num_items = 3,
9409	.items = {
9410		{ "Mic", 0x0 },
9411		{ "Int Mic", 0x1 },
9412		{ "CD", 0x4 },
9413	},
9414};
9415
9416static struct hda_input_mux alc262_HP_capture_source = {
9417	.num_items = 5,
9418	.items = {
9419		{ "Mic", 0x0 },
9420		{ "Front Mic", 0x1 },
9421		{ "Line", 0x2 },
9422		{ "CD", 0x4 },
9423		{ "AUX IN", 0x6 },
9424	},
9425};
9426
9427static struct hda_input_mux alc262_HP_D7000_capture_source = {
9428	.num_items = 4,
9429	.items = {
9430		{ "Mic", 0x0 },
9431		{ "Front Mic", 0x2 },
9432		{ "Line", 0x1 },
9433		{ "CD", 0x4 },
9434	},
9435};
9436
9437/* mute/unmute internal speaker according to the hp jacks and mute state */
9438static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
9439{
9440	struct alc_spec *spec = codec->spec;
9441	unsigned int mute;
9442
9443	if (force || !spec->sense_updated) {
9444		unsigned int present;
9445		/* need to execute and sync at first */
9446		snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
9447		/* check laptop HP jack */
9448		present = snd_hda_codec_read(codec, 0x14, 0,
9449					     AC_VERB_GET_PIN_SENSE, 0);
9450		/* need to execute and sync at first */
9451		snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9452		/* check docking HP jack */
9453		present |= snd_hda_codec_read(codec, 0x1b, 0,
9454					      AC_VERB_GET_PIN_SENSE, 0);
9455		if (present & AC_PINSENSE_PRESENCE)
9456			spec->jack_present = 1;
9457		else
9458			spec->jack_present = 0;
9459		spec->sense_updated = 1;
9460	}
9461	/* unmute internal speaker only if both HPs are unplugged and
9462	 * master switch is on
9463	 */
9464	if (spec->jack_present)
9465		mute = HDA_AMP_MUTE;
9466	else
9467		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9468	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9469				 HDA_AMP_MUTE, mute);
9470}
9471
9472/* unsolicited event for HP jack sensing */
9473static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
9474				       unsigned int res)
9475{
9476	if ((res >> 26) != ALC_HP_EVENT)
9477		return;
9478	alc262_fujitsu_automute(codec, 1);
9479}
9480
9481static void alc262_fujitsu_init_hook(struct hda_codec *codec)
9482{
9483	alc262_fujitsu_automute(codec, 1);
9484}
9485
9486/* bind volumes of both NID 0x0c and 0x0d */
9487static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
9488	.ops = &snd_hda_bind_vol,
9489	.values = {
9490		HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
9491		HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
9492		0
9493	},
9494};
9495
9496/* mute/unmute internal speaker according to the hp jack and mute state */
9497static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
9498{
9499	struct alc_spec *spec = codec->spec;
9500	unsigned int mute;
9501
9502	if (force || !spec->sense_updated) {
9503		unsigned int present_int_hp;
9504		/* need to execute and sync at first */
9505		snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9506		present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
9507					AC_VERB_GET_PIN_SENSE, 0);
9508		spec->jack_present = (present_int_hp & 0x80000000) != 0;
9509		spec->sense_updated = 1;
9510	}
9511	if (spec->jack_present) {
9512		/* mute internal speaker */
9513		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9514					 HDA_AMP_MUTE, HDA_AMP_MUTE);
9515		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9516					 HDA_AMP_MUTE, HDA_AMP_MUTE);
9517	} else {
9518		/* unmute internal speaker if necessary */
9519		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9520		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9521					 HDA_AMP_MUTE, mute);
9522		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9523					 HDA_AMP_MUTE, mute);
9524	}
9525}
9526
9527/* unsolicited event for HP jack sensing */
9528static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
9529				       unsigned int res)
9530{
9531	if ((res >> 26) != ALC_HP_EVENT)
9532		return;
9533	alc262_lenovo_3000_automute(codec, 1);
9534}
9535
9536/* bind hp and internal speaker mute (with plug check) */
9537static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
9538					 struct snd_ctl_elem_value *ucontrol)
9539{
9540	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9541	long *valp = ucontrol->value.integer.value;
9542	int change;
9543
9544	change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9545						 HDA_AMP_MUTE,
9546						 valp ? 0 : HDA_AMP_MUTE);
9547	change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9548						 HDA_AMP_MUTE,
9549						 valp ? 0 : HDA_AMP_MUTE);
9550
9551	if (change)
9552		alc262_fujitsu_automute(codec, 0);
9553	return change;
9554}
9555
9556static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
9557	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9558	{
9559		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9560		.name = "Master Playback Switch",
9561		.info = snd_hda_mixer_amp_switch_info,
9562		.get = snd_hda_mixer_amp_switch_get,
9563		.put = alc262_fujitsu_master_sw_put,
9564		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9565	},
9566	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9567	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9568	HDA_CODEC_VOLUME("PC Speaker Volume", 0x0b, 0x05, HDA_INPUT),
9569	HDA_CODEC_MUTE("PC Speaker Switch", 0x0b, 0x05, HDA_INPUT),
9570	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9571	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9572	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9573	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9574	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9575	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9576	{ } /* end */
9577};
9578
9579/* bind hp and internal speaker mute (with plug check) */
9580static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
9581					 struct snd_ctl_elem_value *ucontrol)
9582{
9583	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9584	long *valp = ucontrol->value.integer.value;
9585	int change;
9586
9587	change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9588						 HDA_AMP_MUTE,
9589						 valp ? 0 : HDA_AMP_MUTE);
9590
9591	if (change)
9592		alc262_lenovo_3000_automute(codec, 0);
9593	return change;
9594}
9595
9596static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
9597	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9598	{
9599		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9600		.name = "Master Playback Switch",
9601		.info = snd_hda_mixer_amp_switch_info,
9602		.get = snd_hda_mixer_amp_switch_get,
9603		.put = alc262_lenovo_3000_master_sw_put,
9604		.private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
9605	},
9606	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9607	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9608	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9609	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9610	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9611	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9612	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9613	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9614	{ } /* end */
9615};
9616
9617static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
9618	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9619	{
9620		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9621		.name = "Master Playback Switch",
9622		.info = snd_hda_mixer_amp_switch_info,
9623		.get = snd_hda_mixer_amp_switch_get,
9624		.put = alc262_sony_master_sw_put,
9625		.private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9626	},
9627	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9628	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9629	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9630	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9631	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9632	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9633	{ } /* end */
9634};
9635
9636/* additional init verbs for Benq laptops */
9637static struct hda_verb alc262_EAPD_verbs[] = {
9638	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9639	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
9640	{}
9641};
9642
9643static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
9644	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9645	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9646
9647	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9648	{0x20, AC_VERB_SET_PROC_COEF,  0x3050},
9649	{}
9650};
9651
9652/* Samsung Q1 Ultra Vista model setup */
9653static struct snd_kcontrol_new alc262_ultra_mixer[] = {
9654	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9655	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9656	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9657	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9658	HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
9659	HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
9660	{ } /* end */
9661};
9662
9663static struct hda_verb alc262_ultra_verbs[] = {
9664	/* output mixer */
9665	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9666	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9667	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9668	/* speaker */
9669	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9670	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9671	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9672	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9673	/* HP */
9674	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9675	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9676	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9677	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9678	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9679	/* internal mic */
9680	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9681	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9682	/* ADC, choose mic */
9683	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9684	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9685	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9686	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9687	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9688	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9689	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9690	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9691	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
9692	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
9693	{}
9694};
9695
9696/* mute/unmute internal speaker according to the hp jack and mute state */
9697static void alc262_ultra_automute(struct hda_codec *codec)
9698{
9699	struct alc_spec *spec = codec->spec;
9700	unsigned int mute;
9701
9702	mute = 0;
9703	/* auto-mute only when HP is used as HP */
9704	if (!spec->cur_mux[0]) {
9705		unsigned int present;
9706		/* need to execute and sync at first */
9707		snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9708		present = snd_hda_codec_read(codec, 0x15, 0,
9709					     AC_VERB_GET_PIN_SENSE, 0);
9710		spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9711		if (spec->jack_present)
9712			mute = HDA_AMP_MUTE;
9713	}
9714	/* mute/unmute internal speaker */
9715	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9716				 HDA_AMP_MUTE, mute);
9717	/* mute/unmute HP */
9718	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9719				 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
9720}
9721
9722/* unsolicited event for HP jack sensing */
9723static void alc262_ultra_unsol_event(struct hda_codec *codec,
9724				       unsigned int res)
9725{
9726	if ((res >> 26) != ALC880_HP_EVENT)
9727		return;
9728	alc262_ultra_automute(codec);
9729}
9730
9731static struct hda_input_mux alc262_ultra_capture_source = {
9732	.num_items = 2,
9733	.items = {
9734		{ "Mic", 0x1 },
9735		{ "Headphone", 0x7 },
9736	},
9737};
9738
9739static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
9740				     struct snd_ctl_elem_value *ucontrol)
9741{
9742	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9743	struct alc_spec *spec = codec->spec;
9744	int ret;
9745
9746	ret = alc_mux_enum_put(kcontrol, ucontrol);
9747	if (!ret)
9748		return 0;
9749	/* reprogram the HP pin as mic or HP according to the input source */
9750	snd_hda_codec_write_cache(codec, 0x15, 0,
9751				  AC_VERB_SET_PIN_WIDGET_CONTROL,
9752				  spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
9753	alc262_ultra_automute(codec); /* mute/unmute HP */
9754	return ret;
9755}
9756
9757static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
9758	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
9759	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
9760	{
9761		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9762		.name = "Capture Source",
9763		.info = alc_mux_enum_info,
9764		.get = alc_mux_enum_get,
9765		.put = alc262_ultra_mux_enum_put,
9766	},
9767	{ } /* end */
9768};
9769
9770/* add playback controls from the parsed DAC table */
9771static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
9772					     const struct auto_pin_cfg *cfg)
9773{
9774	hda_nid_t nid;
9775	int err;
9776
9777	spec->multiout.num_dacs = 1;	/* only use one dac */
9778	spec->multiout.dac_nids = spec->private_dac_nids;
9779	spec->multiout.dac_nids[0] = 2;
9780
9781	nid = cfg->line_out_pins[0];
9782	if (nid) {
9783		err = add_control(spec, ALC_CTL_WIDGET_VOL,
9784				  "Front Playback Volume",
9785				  HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
9786		if (err < 0)
9787			return err;
9788		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9789				  "Front Playback Switch",
9790				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9791		if (err < 0)
9792			return err;
9793	}
9794
9795	nid = cfg->speaker_pins[0];
9796	if (nid) {
9797		if (nid == 0x16) {
9798			err = add_control(spec, ALC_CTL_WIDGET_VOL,
9799					  "Speaker Playback Volume",
9800					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9801							      HDA_OUTPUT));
9802			if (err < 0)
9803				return err;
9804			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9805					  "Speaker Playback Switch",
9806					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9807							      HDA_OUTPUT));
9808			if (err < 0)
9809				return err;
9810		} else {
9811			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9812					  "Speaker Playback Switch",
9813					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9814							      HDA_OUTPUT));
9815			if (err < 0)
9816				return err;
9817		}
9818	}
9819	nid = cfg->hp_pins[0];
9820	if (nid) {
9821		/* spec->multiout.hp_nid = 2; */
9822		if (nid == 0x16) {
9823			err = add_control(spec, ALC_CTL_WIDGET_VOL,
9824					  "Headphone Playback Volume",
9825					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9826							      HDA_OUTPUT));
9827			if (err < 0)
9828				return err;
9829			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9830					  "Headphone Playback Switch",
9831					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9832							      HDA_OUTPUT));
9833			if (err < 0)
9834				return err;
9835		} else {
9836			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9837					  "Headphone Playback Switch",
9838					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9839							      HDA_OUTPUT));
9840			if (err < 0)
9841				return err;
9842		}
9843	}
9844	return 0;
9845}
9846
9847/* identical with ALC880 */
9848#define alc262_auto_create_analog_input_ctls \
9849	alc880_auto_create_analog_input_ctls
9850
9851/*
9852 * generic initialization of ADC, input mixers and output mixers
9853 */
9854static struct hda_verb alc262_volume_init_verbs[] = {
9855	/*
9856	 * Unmute ADC0-2 and set the default input to mic-in
9857	 */
9858	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9859	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9860	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9861	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9862	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9863	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9864
9865	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9866	 * mixer widget
9867	 * Note: PASD motherboards uses the Line In 2 as the input for
9868	 * front panel mic (mic 2)
9869	 */
9870	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9871	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9872	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9873	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9874	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9875	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9876
9877	/*
9878	 * Set up output mixers (0x0c - 0x0f)
9879	 */
9880	/* set vol=0 to output mixers */
9881	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9882	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9883	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9884
9885	/* set up input amps for analog loopback */
9886	/* Amp Indices: DAC = 0, mixer = 1 */
9887	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9888	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9889	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9890	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9891	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9892	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9893
9894	/* FIXME: use matrix-type input source selection */
9895	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9896	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9897	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9898	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9899	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9900	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9901	/* Input mixer2 */
9902	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9903	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9904	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9905	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9906	/* Input mixer3 */
9907	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9908	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9909	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9910	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9911
9912	{ }
9913};
9914
9915static struct hda_verb alc262_HP_BPC_init_verbs[] = {
9916	/*
9917	 * Unmute ADC0-2 and set the default input to mic-in
9918	 */
9919	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9920	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9921	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9922	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9923	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9924	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9925
9926	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9927	 * mixer widget
9928	 * Note: PASD motherboards uses the Line In 2 as the input for
9929	 * front panel mic (mic 2)
9930	 */
9931	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9932	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9933	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9934	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9935	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9936	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9937	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9938        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9939
9940	/*
9941	 * Set up output mixers (0x0c - 0x0e)
9942	 */
9943	/* set vol=0 to output mixers */
9944	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9945	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9946	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9947
9948	/* set up input amps for analog loopback */
9949	/* Amp Indices: DAC = 0, mixer = 1 */
9950	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9951	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9952	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9953	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9954	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9955	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9956
9957	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9958	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9959	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9960
9961	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9962	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9963
9964	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9965	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9966
9967	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9968	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9969        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9970	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9971	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9972
9973	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9974	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9975        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9976	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9977	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9978	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9979
9980
9981	/* FIXME: use matrix-type input source selection */
9982	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9983	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9984	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9985	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9986	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9987	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9988	/* Input mixer2 */
9989	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9990	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9991	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9992	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9993	/* Input mixer3 */
9994	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9995	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9996	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9997	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9998
9999	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10000
10001	{ }
10002};
10003
10004static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10005	/*
10006	 * Unmute ADC0-2 and set the default input to mic-in
10007	 */
10008	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10009	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10010	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10011	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10012	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10013	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10014
10015	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10016	 * mixer widget
10017	 * Note: PASD motherboards uses the Line In 2 as the input for front
10018	 * panel mic (mic 2)
10019	 */
10020	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10021	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10022	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10023	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10024	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10025	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10026	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10027	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10028	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10029	/*
10030	 * Set up output mixers (0x0c - 0x0e)
10031	 */
10032	/* set vol=0 to output mixers */
10033	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10034	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10035	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10036
10037	/* set up input amps for analog loopback */
10038	/* Amp Indices: DAC = 0, mixer = 1 */
10039	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10040	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10041	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10042	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10043	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10044	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10045
10046
10047	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },	/* HP */
10048	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Mono */
10049	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* rear MIC */
10050	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* Line in */
10051	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* Front MIC */
10052	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Line out */
10053	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* CD in */
10054
10055	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10056	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10057
10058	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10059	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10060
10061	/* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10062	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10063	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10064	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10065	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10066	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10067
10068	/* FIXME: use matrix-type input source selection */
10069	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10070	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10071	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10072	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10073	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10074	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10075	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10076        /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
10077	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10078	/* Input mixer2 */
10079	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10080	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10081	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10082	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10083	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10084        /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10085	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10086	/* Input mixer3 */
10087	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10088	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10089	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10090	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10091	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10092        /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10093	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10094
10095	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10096
10097	{ }
10098};
10099
10100static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10101
10102	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Front Speaker */
10103	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10104	{0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10105
10106	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* MIC jack */
10107	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* Front MIC */
10108	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10109	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10110
10111	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },	/* HP  jack */
10112	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10113	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10114	{}
10115};
10116
10117
10118#ifdef CONFIG_SND_HDA_POWER_SAVE
10119#define alc262_loopbacks	alc880_loopbacks
10120#endif
10121
10122/* pcm configuration: identiacal with ALC880 */
10123#define alc262_pcm_analog_playback	alc880_pcm_analog_playback
10124#define alc262_pcm_analog_capture	alc880_pcm_analog_capture
10125#define alc262_pcm_digital_playback	alc880_pcm_digital_playback
10126#define alc262_pcm_digital_capture	alc880_pcm_digital_capture
10127
10128/*
10129 * BIOS auto configuration
10130 */
10131static int alc262_parse_auto_config(struct hda_codec *codec)
10132{
10133	struct alc_spec *spec = codec->spec;
10134	int err;
10135	static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10136
10137	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10138					   alc262_ignore);
10139	if (err < 0)
10140		return err;
10141	if (!spec->autocfg.line_outs)
10142		return 0; /* can't find valid BIOS pin config */
10143	err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10144	if (err < 0)
10145		return err;
10146	err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10147	if (err < 0)
10148		return err;
10149
10150	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10151
10152	if (spec->autocfg.dig_out_pin)
10153		spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10154	if (spec->autocfg.dig_in_pin)
10155		spec->dig_in_nid = ALC262_DIGIN_NID;
10156
10157	if (spec->kctls.list)
10158		add_mixer(spec, spec->kctls.list);
10159
10160	add_verb(spec, alc262_volume_init_verbs);
10161	spec->num_mux_defs = 1;
10162	spec->input_mux = &spec->private_imux;
10163
10164	err = alc_auto_add_mic_boost(codec);
10165	if (err < 0)
10166		return err;
10167
10168	store_pin_configs(codec);
10169	return 1;
10170}
10171
10172#define alc262_auto_init_multi_out	alc882_auto_init_multi_out
10173#define alc262_auto_init_hp_out		alc882_auto_init_hp_out
10174#define alc262_auto_init_analog_input	alc882_auto_init_analog_input
10175#define alc262_auto_init_input_src	alc882_auto_init_input_src
10176
10177
10178/* init callback for auto-configuration model -- overriding the default init */
10179static void alc262_auto_init(struct hda_codec *codec)
10180{
10181	struct alc_spec *spec = codec->spec;
10182	alc262_auto_init_multi_out(codec);
10183	alc262_auto_init_hp_out(codec);
10184	alc262_auto_init_analog_input(codec);
10185	alc262_auto_init_input_src(codec);
10186	if (spec->unsol_event)
10187		alc_inithook(codec);
10188}
10189
10190/*
10191 * configuration and preset
10192 */
10193static const char *alc262_models[ALC262_MODEL_LAST] = {
10194	[ALC262_BASIC]		= "basic",
10195	[ALC262_HIPPO]		= "hippo",
10196	[ALC262_HIPPO_1]	= "hippo_1",
10197	[ALC262_FUJITSU]	= "fujitsu",
10198	[ALC262_HP_BPC]		= "hp-bpc",
10199	[ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
10200	[ALC262_HP_TC_T5735]	= "hp-tc-t5735",
10201	[ALC262_HP_RP5700]	= "hp-rp5700",
10202	[ALC262_BENQ_ED8]	= "benq",
10203	[ALC262_BENQ_T31]	= "benq-t31",
10204	[ALC262_SONY_ASSAMD]	= "sony-assamd",
10205	[ALC262_TOSHIBA_S06]	= "toshiba-s06",
10206	[ALC262_TOSHIBA_RX1]	= "toshiba-rx1",
10207	[ALC262_ULTRA]		= "ultra",
10208	[ALC262_LENOVO_3000]	= "lenovo-3000",
10209	[ALC262_NEC]		= "nec",
10210	[ALC262_AUTO]		= "auto",
10211};
10212
10213static struct snd_pci_quirk alc262_cfg_tbl[] = {
10214	SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10215	SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
10216	SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
10217	SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
10218	SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
10219	SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
10220	SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
10221	SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
10222	SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
10223	SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
10224	SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
10225	SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
10226	SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
10227	SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
10228	SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
10229	SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
10230	SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
10231	SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
10232	SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10233	SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10234	SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
10235	SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10236		      ALC262_HP_TC_T5735),
10237	SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
10238	SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10239	SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
10240	SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10241	SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10242	SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
10243	SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10244		      ALC262_TOSHIBA_RX1),
10245	SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
10246	SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
10247	SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
10248	SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
10249	SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA),
10250	SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
10251	SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10252	SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10253	SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
10254	{}
10255};
10256
10257static struct alc_config_preset alc262_presets[] = {
10258	[ALC262_BASIC] = {
10259		.mixers = { alc262_base_mixer },
10260		.init_verbs = { alc262_init_verbs },
10261		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10262		.dac_nids = alc262_dac_nids,
10263		.hp_nid = 0x03,
10264		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10265		.channel_mode = alc262_modes,
10266		.input_mux = &alc262_capture_source,
10267	},
10268	[ALC262_HIPPO] = {
10269		.mixers = { alc262_base_mixer },
10270		.init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10271		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10272		.dac_nids = alc262_dac_nids,
10273		.hp_nid = 0x03,
10274		.dig_out_nid = ALC262_DIGOUT_NID,
10275		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10276		.channel_mode = alc262_modes,
10277		.input_mux = &alc262_capture_source,
10278		.unsol_event = alc262_hippo_unsol_event,
10279		.init_hook = alc262_hippo_automute,
10280	},
10281	[ALC262_HIPPO_1] = {
10282		.mixers = { alc262_hippo1_mixer },
10283		.init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10284		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10285		.dac_nids = alc262_dac_nids,
10286		.hp_nid = 0x02,
10287		.dig_out_nid = ALC262_DIGOUT_NID,
10288		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10289		.channel_mode = alc262_modes,
10290		.input_mux = &alc262_capture_source,
10291		.unsol_event = alc262_hippo1_unsol_event,
10292		.init_hook = alc262_hippo1_automute,
10293	},
10294	[ALC262_FUJITSU] = {
10295		.mixers = { alc262_fujitsu_mixer },
10296		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10297				alc262_fujitsu_unsol_verbs },
10298		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10299		.dac_nids = alc262_dac_nids,
10300		.hp_nid = 0x03,
10301		.dig_out_nid = ALC262_DIGOUT_NID,
10302		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10303		.channel_mode = alc262_modes,
10304		.input_mux = &alc262_fujitsu_capture_source,
10305		.unsol_event = alc262_fujitsu_unsol_event,
10306		.init_hook = alc262_fujitsu_init_hook,
10307	},
10308	[ALC262_HP_BPC] = {
10309		.mixers = { alc262_HP_BPC_mixer },
10310		.init_verbs = { alc262_HP_BPC_init_verbs },
10311		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10312		.dac_nids = alc262_dac_nids,
10313		.hp_nid = 0x03,
10314		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10315		.channel_mode = alc262_modes,
10316		.input_mux = &alc262_HP_capture_source,
10317		.unsol_event = alc262_hp_bpc_unsol_event,
10318		.init_hook = alc262_hp_bpc_automute,
10319	},
10320	[ALC262_HP_BPC_D7000_WF] = {
10321		.mixers = { alc262_HP_BPC_WildWest_mixer },
10322		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10323		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10324		.dac_nids = alc262_dac_nids,
10325		.hp_nid = 0x03,
10326		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10327		.channel_mode = alc262_modes,
10328		.input_mux = &alc262_HP_D7000_capture_source,
10329		.unsol_event = alc262_hp_wildwest_unsol_event,
10330		.init_hook = alc262_hp_wildwest_automute,
10331	},
10332	[ALC262_HP_BPC_D7000_WL] = {
10333		.mixers = { alc262_HP_BPC_WildWest_mixer,
10334			    alc262_HP_BPC_WildWest_option_mixer },
10335		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10336		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10337		.dac_nids = alc262_dac_nids,
10338		.hp_nid = 0x03,
10339		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10340		.channel_mode = alc262_modes,
10341		.input_mux = &alc262_HP_D7000_capture_source,
10342		.unsol_event = alc262_hp_wildwest_unsol_event,
10343		.init_hook = alc262_hp_wildwest_automute,
10344	},
10345	[ALC262_HP_TC_T5735] = {
10346		.mixers = { alc262_hp_t5735_mixer },
10347		.init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
10348		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10349		.dac_nids = alc262_dac_nids,
10350		.hp_nid = 0x03,
10351		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10352		.channel_mode = alc262_modes,
10353		.input_mux = &alc262_capture_source,
10354		.unsol_event = alc262_hp_t5735_unsol_event,
10355		.init_hook = alc262_hp_t5735_init_hook,
10356	},
10357	[ALC262_HP_RP5700] = {
10358		.mixers = { alc262_hp_rp5700_mixer },
10359		.init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
10360		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10361		.dac_nids = alc262_dac_nids,
10362		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10363		.channel_mode = alc262_modes,
10364		.input_mux = &alc262_hp_rp5700_capture_source,
10365        },
10366	[ALC262_BENQ_ED8] = {
10367		.mixers = { alc262_base_mixer },
10368		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
10369		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10370		.dac_nids = alc262_dac_nids,
10371		.hp_nid = 0x03,
10372		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10373		.channel_mode = alc262_modes,
10374		.input_mux = &alc262_capture_source,
10375	},
10376	[ALC262_SONY_ASSAMD] = {
10377		.mixers = { alc262_sony_mixer },
10378		.init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
10379		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10380		.dac_nids = alc262_dac_nids,
10381		.hp_nid = 0x02,
10382		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10383		.channel_mode = alc262_modes,
10384		.input_mux = &alc262_capture_source,
10385		.unsol_event = alc262_hippo_unsol_event,
10386		.init_hook = alc262_hippo_automute,
10387	},
10388	[ALC262_BENQ_T31] = {
10389		.mixers = { alc262_benq_t31_mixer },
10390		.init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
10391		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10392		.dac_nids = alc262_dac_nids,
10393		.hp_nid = 0x03,
10394		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10395		.channel_mode = alc262_modes,
10396		.input_mux = &alc262_capture_source,
10397		.unsol_event = alc262_hippo_unsol_event,
10398		.init_hook = alc262_hippo_automute,
10399	},
10400	[ALC262_ULTRA] = {
10401		.mixers = { alc262_ultra_mixer },
10402		.cap_mixer = alc262_ultra_capture_mixer,
10403		.init_verbs = { alc262_ultra_verbs },
10404		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10405		.dac_nids = alc262_dac_nids,
10406		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10407		.channel_mode = alc262_modes,
10408		.input_mux = &alc262_ultra_capture_source,
10409		.adc_nids = alc262_adc_nids, /* ADC0 */
10410		.capsrc_nids = alc262_capsrc_nids,
10411		.num_adc_nids = 1, /* single ADC */
10412		.unsol_event = alc262_ultra_unsol_event,
10413		.init_hook = alc262_ultra_automute,
10414	},
10415	[ALC262_LENOVO_3000] = {
10416		.mixers = { alc262_lenovo_3000_mixer },
10417		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10418				alc262_lenovo_3000_unsol_verbs },
10419		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10420		.dac_nids = alc262_dac_nids,
10421		.hp_nid = 0x03,
10422		.dig_out_nid = ALC262_DIGOUT_NID,
10423		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10424		.channel_mode = alc262_modes,
10425		.input_mux = &alc262_fujitsu_capture_source,
10426		.unsol_event = alc262_lenovo_3000_unsol_event,
10427	},
10428	[ALC262_NEC] = {
10429		.mixers = { alc262_nec_mixer },
10430		.init_verbs = { alc262_nec_verbs },
10431		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10432		.dac_nids = alc262_dac_nids,
10433		.hp_nid = 0x03,
10434		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10435		.channel_mode = alc262_modes,
10436		.input_mux = &alc262_capture_source,
10437	},
10438	[ALC262_TOSHIBA_S06] = {
10439		.mixers = { alc262_toshiba_s06_mixer },
10440		.init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
10441							alc262_eapd_verbs },
10442		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10443		.capsrc_nids = alc262_dmic_capsrc_nids,
10444		.dac_nids = alc262_dac_nids,
10445		.adc_nids = alc262_dmic_adc_nids, /* ADC0 */
10446		.dig_out_nid = ALC262_DIGOUT_NID,
10447		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10448		.channel_mode = alc262_modes,
10449		.input_mux = &alc262_dmic_capture_source,
10450		.unsol_event = alc262_toshiba_s06_unsol_event,
10451		.init_hook = alc262_toshiba_s06_init_hook,
10452	},
10453	[ALC262_TOSHIBA_RX1] = {
10454		.mixers = { alc262_toshiba_rx1_mixer },
10455		.init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
10456		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10457		.dac_nids = alc262_dac_nids,
10458		.hp_nid = 0x03,
10459		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10460		.channel_mode = alc262_modes,
10461		.input_mux = &alc262_capture_source,
10462		.unsol_event = alc262_hippo_unsol_event,
10463		.init_hook = alc262_hippo_automute,
10464	},
10465};
10466
10467static int patch_alc262(struct hda_codec *codec)
10468{
10469	struct alc_spec *spec;
10470	int board_config;
10471	int err;
10472
10473	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10474	if (spec == NULL)
10475		return -ENOMEM;
10476
10477	codec->spec = spec;
10478#if 0
10479	/* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
10480	 * under-run
10481	 */
10482	{
10483	int tmp;
10484	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10485	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
10486	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10487	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
10488	}
10489#endif
10490
10491	alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10492
10493	board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
10494						  alc262_models,
10495						  alc262_cfg_tbl);
10496
10497	if (board_config < 0) {
10498		printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
10499		       "trying auto-probe from BIOS...\n");
10500		board_config = ALC262_AUTO;
10501	}
10502
10503	if (board_config == ALC262_AUTO) {
10504		/* automatic parse from the BIOS config */
10505		err = alc262_parse_auto_config(codec);
10506		if (err < 0) {
10507			alc_free(codec);
10508			return err;
10509		} else if (!err) {
10510			printk(KERN_INFO
10511			       "hda_codec: Cannot set up configuration "
10512			       "from BIOS.  Using base mode...\n");
10513			board_config = ALC262_BASIC;
10514		}
10515	}
10516
10517	if (board_config != ALC262_AUTO)
10518		setup_preset(spec, &alc262_presets[board_config]);
10519
10520	spec->stream_name_analog = "ALC262 Analog";
10521	spec->stream_analog_playback = &alc262_pcm_analog_playback;
10522	spec->stream_analog_capture = &alc262_pcm_analog_capture;
10523
10524	spec->stream_name_digital = "ALC262 Digital";
10525	spec->stream_digital_playback = &alc262_pcm_digital_playback;
10526	spec->stream_digital_capture = &alc262_pcm_digital_capture;
10527
10528	spec->is_mix_capture = 1;
10529	if (!spec->adc_nids && spec->input_mux) {
10530		/* check whether NID 0x07 is valid */
10531		unsigned int wcap = get_wcaps(codec, 0x07);
10532
10533		/* get type */
10534		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
10535		if (wcap != AC_WID_AUD_IN) {
10536			spec->adc_nids = alc262_adc_nids_alt;
10537			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
10538			spec->capsrc_nids = alc262_capsrc_nids_alt;
10539		} else {
10540			spec->adc_nids = alc262_adc_nids;
10541			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
10542			spec->capsrc_nids = alc262_capsrc_nids;
10543		}
10544	}
10545	if (!spec->cap_mixer)
10546		set_capture_mixer(spec);
10547
10548	spec->vmaster_nid = 0x0c;
10549
10550	codec->patch_ops = alc_patch_ops;
10551	if (board_config == ALC262_AUTO)
10552		spec->init_hook = alc262_auto_init;
10553#ifdef CONFIG_SND_HDA_POWER_SAVE
10554	if (!spec->loopback.amplist)
10555		spec->loopback.amplist = alc262_loopbacks;
10556#endif
10557
10558	return 0;
10559}
10560
10561/*
10562 *  ALC268 channel source setting (2 channel)
10563 */
10564#define ALC268_DIGOUT_NID	ALC880_DIGOUT_NID
10565#define alc268_modes		alc260_modes
10566
10567static hda_nid_t alc268_dac_nids[2] = {
10568	/* front, hp */
10569	0x02, 0x03
10570};
10571
10572static hda_nid_t alc268_adc_nids[2] = {
10573	/* ADC0-1 */
10574	0x08, 0x07
10575};
10576
10577static hda_nid_t alc268_adc_nids_alt[1] = {
10578	/* ADC0 */
10579	0x08
10580};
10581
10582static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
10583
10584static struct snd_kcontrol_new alc268_base_mixer[] = {
10585	/* output mixer control */
10586	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10587	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10588	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10589	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10590	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10591	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10592	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10593	{ }
10594};
10595
10596/* bind Beep switches of both NID 0x0f and 0x10 */
10597static struct hda_bind_ctls alc268_bind_beep_sw = {
10598	.ops = &snd_hda_bind_sw,
10599	.values = {
10600		HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
10601		HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
10602		0
10603	},
10604};
10605
10606static struct snd_kcontrol_new alc268_beep_mixer[] = {
10607	HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
10608	HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
10609	{ }
10610};
10611
10612static struct hda_verb alc268_eapd_verbs[] = {
10613	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10614	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10615	{ }
10616};
10617
10618/* Toshiba specific */
10619#define alc268_toshiba_automute	alc262_hippo_automute
10620
10621static struct hda_verb alc268_toshiba_verbs[] = {
10622	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10623	{ } /* end */
10624};
10625
10626static struct hda_input_mux alc268_acer_lc_capture_source = {
10627	.num_items = 2,
10628	.items = {
10629		{ "i-Mic", 0x6 },
10630		{ "E-Mic", 0x0 },
10631	},
10632};
10633
10634/* Acer specific */
10635/* bind volumes of both NID 0x02 and 0x03 */
10636static struct hda_bind_ctls alc268_acer_bind_master_vol = {
10637	.ops = &snd_hda_bind_vol,
10638	.values = {
10639		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
10640		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
10641		0
10642	},
10643};
10644
10645/* mute/unmute internal speaker according to the hp jack and mute state */
10646static void alc268_acer_automute(struct hda_codec *codec, int force)
10647{
10648	struct alc_spec *spec = codec->spec;
10649	unsigned int mute;
10650
10651	if (force || !spec->sense_updated) {
10652		unsigned int present;
10653		present = snd_hda_codec_read(codec, 0x14, 0,
10654				    	 AC_VERB_GET_PIN_SENSE, 0);
10655		spec->jack_present = (present & 0x80000000) != 0;
10656		spec->sense_updated = 1;
10657	}
10658	if (spec->jack_present)
10659		mute = HDA_AMP_MUTE; /* mute internal speaker */
10660	else /* unmute internal speaker if necessary */
10661		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10662	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10663				 HDA_AMP_MUTE, mute);
10664}
10665
10666
10667/* bind hp and internal speaker mute (with plug check) */
10668static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
10669				     struct snd_ctl_elem_value *ucontrol)
10670{
10671	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10672	long *valp = ucontrol->value.integer.value;
10673	int change;
10674
10675	change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10676					  HDA_AMP_MUTE,
10677					  valp[0] ? 0 : HDA_AMP_MUTE);
10678	change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10679					   HDA_AMP_MUTE,
10680					   valp[1] ? 0 : HDA_AMP_MUTE);
10681	if (change)
10682		alc268_acer_automute(codec, 0);
10683	return change;
10684}
10685
10686static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
10687	/* output mixer control */
10688	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10689	{
10690		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10691		.name = "Master Playback Switch",
10692		.info = snd_hda_mixer_amp_switch_info,
10693		.get = snd_hda_mixer_amp_switch_get,
10694		.put = alc268_acer_master_sw_put,
10695		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10696	},
10697	HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
10698	{ }
10699};
10700
10701static struct snd_kcontrol_new alc268_acer_mixer[] = {
10702	/* output mixer control */
10703	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10704	{
10705		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10706		.name = "Master Playback Switch",
10707		.info = snd_hda_mixer_amp_switch_info,
10708		.get = snd_hda_mixer_amp_switch_get,
10709		.put = alc268_acer_master_sw_put,
10710		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10711	},
10712	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10713	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10714	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10715	{ }
10716};
10717
10718static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
10719	/* output mixer control */
10720	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10721	{
10722		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10723		.name = "Master Playback Switch",
10724		.info = snd_hda_mixer_amp_switch_info,
10725		.get = snd_hda_mixer_amp_switch_get,
10726		.put = alc268_acer_master_sw_put,
10727		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10728	},
10729	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10730	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10731	{ }
10732};
10733
10734static struct hda_verb alc268_acer_aspire_one_verbs[] = {
10735	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10736	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10737	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10738	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10739	{0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
10740	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
10741	{ }
10742};
10743
10744static struct hda_verb alc268_acer_verbs[] = {
10745	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
10746	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10747	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10748	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10749	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10750	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10751	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10752	{ }
10753};
10754
10755/* unsolicited event for HP jack sensing */
10756static void alc268_toshiba_unsol_event(struct hda_codec *codec,
10757				       unsigned int res)
10758{
10759	if ((res >> 26) != ALC880_HP_EVENT)
10760		return;
10761	alc268_toshiba_automute(codec);
10762}
10763
10764static void alc268_acer_unsol_event(struct hda_codec *codec,
10765				       unsigned int res)
10766{
10767	if ((res >> 26) != ALC880_HP_EVENT)
10768		return;
10769	alc268_acer_automute(codec, 1);
10770}
10771
10772static void alc268_acer_init_hook(struct hda_codec *codec)
10773{
10774	alc268_acer_automute(codec, 1);
10775}
10776
10777/* toggle speaker-output according to the hp-jack state */
10778static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
10779{
10780	unsigned int present;
10781	unsigned char bits;
10782
10783	present = snd_hda_codec_read(codec, 0x15, 0,
10784				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10785	bits = present ? AMP_IN_MUTE(0) : 0;
10786	snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
10787				AMP_IN_MUTE(0), bits);
10788	snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
10789				AMP_IN_MUTE(0), bits);
10790}
10791
10792
10793static void alc268_acer_mic_automute(struct hda_codec *codec)
10794{
10795	unsigned int present;
10796
10797	present = snd_hda_codec_read(codec, 0x18, 0,
10798				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10799	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
10800			    present ? 0x0 : 0x6);
10801}
10802
10803static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
10804				    unsigned int res)
10805{
10806	if ((res >> 26) == ALC880_HP_EVENT)
10807		alc268_aspire_one_speaker_automute(codec);
10808	if ((res >> 26) == ALC880_MIC_EVENT)
10809		alc268_acer_mic_automute(codec);
10810}
10811
10812static void alc268_acer_lc_init_hook(struct hda_codec *codec)
10813{
10814	alc268_aspire_one_speaker_automute(codec);
10815	alc268_acer_mic_automute(codec);
10816}
10817
10818static struct snd_kcontrol_new alc268_dell_mixer[] = {
10819	/* output mixer control */
10820	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10821	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10822	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10823	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10824	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10825	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10826	{ }
10827};
10828
10829static struct hda_verb alc268_dell_verbs[] = {
10830	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10831	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10832	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10833	{ }
10834};
10835
10836/* mute/unmute internal speaker according to the hp jack and mute state */
10837static void alc268_dell_automute(struct hda_codec *codec)
10838{
10839	unsigned int present;
10840	unsigned int mute;
10841
10842	present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
10843	if (present & 0x80000000)
10844		mute = HDA_AMP_MUTE;
10845	else
10846		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
10847	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10848				 HDA_AMP_MUTE, mute);
10849}
10850
10851static void alc268_dell_unsol_event(struct hda_codec *codec,
10852				    unsigned int res)
10853{
10854	if ((res >> 26) != ALC880_HP_EVENT)
10855		return;
10856	alc268_dell_automute(codec);
10857}
10858
10859#define alc268_dell_init_hook	alc268_dell_automute
10860
10861static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
10862	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10863	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10864	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10865	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10866	HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10867	HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
10868	HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
10869	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10870	{ }
10871};
10872
10873static struct hda_verb alc267_quanta_il1_verbs[] = {
10874	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10875	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
10876	{ }
10877};
10878
10879static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
10880{
10881	unsigned int present;
10882
10883	present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
10884		& AC_PINSENSE_PRESENCE;
10885	snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
10886			    present ? 0 : PIN_OUT);
10887}
10888
10889static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
10890{
10891	unsigned int present;
10892
10893	present = snd_hda_codec_read(codec, 0x18, 0,
10894				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10895	snd_hda_codec_write(codec, 0x23, 0,
10896			    AC_VERB_SET_CONNECT_SEL,
10897			    present ? 0x00 : 0x01);
10898}
10899
10900static void alc267_quanta_il1_automute(struct hda_codec *codec)
10901{
10902	alc267_quanta_il1_hp_automute(codec);
10903	alc267_quanta_il1_mic_automute(codec);
10904}
10905
10906static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
10907					   unsigned int res)
10908{
10909	switch (res >> 26) {
10910	case ALC880_HP_EVENT:
10911		alc267_quanta_il1_hp_automute(codec);
10912		break;
10913	case ALC880_MIC_EVENT:
10914		alc267_quanta_il1_mic_automute(codec);
10915		break;
10916	}
10917}
10918
10919/*
10920 * generic initialization of ADC, input mixers and output mixers
10921 */
10922static struct hda_verb alc268_base_init_verbs[] = {
10923	/* Unmute DAC0-1 and set vol = 0 */
10924	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10925	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10926	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10927	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10928	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10929	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10930
10931	/*
10932	 * Set up output mixers (0x0c - 0x0e)
10933	 */
10934	/* set vol=0 to output mixers */
10935	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10936	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10937	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10938        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
10939
10940	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10941	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10942
10943	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10944	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10945	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10946	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10947	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10948	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10949	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10950	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10951
10952	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10953	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10954	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10955	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10956	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10957	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10958	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10959
10960	/* set PCBEEP vol = 0, mute connections */
10961	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10962	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10963	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10964
10965	/* Unmute Selector 23h,24h and set the default input to mic-in */
10966
10967	{0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
10968	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10969	{0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
10970	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10971
10972	{ }
10973};
10974
10975/*
10976 * generic initialization of ADC, input mixers and output mixers
10977 */
10978static struct hda_verb alc268_volume_init_verbs[] = {
10979	/* set output DAC */
10980	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10981	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10982	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10983	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10984
10985	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10986	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10987	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10988	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10989	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10990
10991	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10992	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10993	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10994	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10995	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10996
10997	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10998	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10999	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11000	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11001
11002	/* set PCBEEP vol = 0, mute connections */
11003	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11004	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11005	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11006
11007	{ }
11008};
11009
11010static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11011	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11012	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11013	{
11014		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11015		/* The multiple "Capture Source" controls confuse alsamixer
11016		 * So call somewhat different..
11017		 */
11018		/* .name = "Capture Source", */
11019		.name = "Input Source",
11020		.count = 1,
11021		.info = alc_mux_enum_info,
11022		.get = alc_mux_enum_get,
11023		.put = alc_mux_enum_put,
11024	},
11025	{ } /* end */
11026};
11027
11028static struct snd_kcontrol_new alc268_capture_mixer[] = {
11029	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11030	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11031	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11032	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11033	{
11034		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11035		/* The multiple "Capture Source" controls confuse alsamixer
11036		 * So call somewhat different..
11037		 */
11038		/* .name = "Capture Source", */
11039		.name = "Input Source",
11040		.count = 2,
11041		.info = alc_mux_enum_info,
11042		.get = alc_mux_enum_get,
11043		.put = alc_mux_enum_put,
11044	},
11045	{ } /* end */
11046};
11047
11048static struct hda_input_mux alc268_capture_source = {
11049	.num_items = 4,
11050	.items = {
11051		{ "Mic", 0x0 },
11052		{ "Front Mic", 0x1 },
11053		{ "Line", 0x2 },
11054		{ "CD", 0x3 },
11055	},
11056};
11057
11058static struct hda_input_mux alc268_acer_capture_source = {
11059	.num_items = 3,
11060	.items = {
11061		{ "Mic", 0x0 },
11062		{ "Internal Mic", 0x1 },
11063		{ "Line", 0x2 },
11064	},
11065};
11066
11067static struct hda_input_mux alc268_acer_dmic_capture_source = {
11068	.num_items = 3,
11069	.items = {
11070		{ "Mic", 0x0 },
11071		{ "Internal Mic", 0x6 },
11072		{ "Line", 0x2 },
11073	},
11074};
11075
11076#ifdef CONFIG_SND_DEBUG
11077static struct snd_kcontrol_new alc268_test_mixer[] = {
11078	/* Volume widgets */
11079	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11080	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11081	HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11082	HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11083	HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11084	HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11085	HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11086	HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11087	HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11088	HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11089	HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11090	HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11091	HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11092	/* The below appears problematic on some hardwares */
11093	/*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11094	HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11095	HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11096	HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11097	HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11098
11099	/* Modes for retasking pin widgets */
11100	ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11101	ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11102	ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11103	ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11104
11105	/* Controls for GPIO pins, assuming they are configured as outputs */
11106	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11107	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11108	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11109	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11110
11111	/* Switches to allow the digital SPDIF output pin to be enabled.
11112	 * The ALC268 does not have an SPDIF input.
11113	 */
11114	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11115
11116	/* A switch allowing EAPD to be enabled.  Some laptops seem to use
11117	 * this output to turn on an external amplifier.
11118	 */
11119	ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11120	ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11121
11122	{ } /* end */
11123};
11124#endif
11125
11126/* create input playback/capture controls for the given pin */
11127static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11128				    const char *ctlname, int idx)
11129{
11130	char name[32];
11131	int err;
11132
11133	sprintf(name, "%s Playback Volume", ctlname);
11134	if (nid == 0x14) {
11135		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11136				  HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11137						      HDA_OUTPUT));
11138		if (err < 0)
11139			return err;
11140	} else if (nid == 0x15) {
11141		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11142				  HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11143						      HDA_OUTPUT));
11144		if (err < 0)
11145			return err;
11146	} else
11147		return -1;
11148	sprintf(name, "%s Playback Switch", ctlname);
11149	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11150			  HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11151	if (err < 0)
11152		return err;
11153	return 0;
11154}
11155
11156/* add playback controls from the parsed DAC table */
11157static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11158					     const struct auto_pin_cfg *cfg)
11159{
11160	hda_nid_t nid;
11161	int err;
11162
11163	spec->multiout.num_dacs = 2;	/* only use one dac */
11164	spec->multiout.dac_nids = spec->private_dac_nids;
11165	spec->multiout.dac_nids[0] = 2;
11166	spec->multiout.dac_nids[1] = 3;
11167
11168	nid = cfg->line_out_pins[0];
11169	if (nid)
11170		alc268_new_analog_output(spec, nid, "Front", 0);
11171
11172	nid = cfg->speaker_pins[0];
11173	if (nid == 0x1d) {
11174		err = add_control(spec, ALC_CTL_WIDGET_VOL,
11175				  "Speaker Playback Volume",
11176				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11177		if (err < 0)
11178			return err;
11179	}
11180	nid = cfg->hp_pins[0];
11181	if (nid)
11182		alc268_new_analog_output(spec, nid, "Headphone", 0);
11183
11184	nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11185	if (nid == 0x16) {
11186		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11187				  "Mono Playback Switch",
11188				  HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11189		if (err < 0)
11190			return err;
11191	}
11192	return 0;
11193}
11194
11195/* create playback/capture controls for input pins */
11196static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11197						const struct auto_pin_cfg *cfg)
11198{
11199	struct hda_input_mux *imux = &spec->private_imux;
11200	int i, idx1;
11201
11202	for (i = 0; i < AUTO_PIN_LAST; i++) {
11203		switch(cfg->input_pins[i]) {
11204		case 0x18:
11205			idx1 = 0;	/* Mic 1 */
11206			break;
11207		case 0x19:
11208			idx1 = 1;	/* Mic 2 */
11209			break;
11210		case 0x1a:
11211			idx1 = 2;	/* Line In */
11212			break;
11213		case 0x1c:
11214			idx1 = 3;	/* CD */
11215			break;
11216		case 0x12:
11217		case 0x13:
11218			idx1 = 6;	/* digital mics */
11219			break;
11220		default:
11221			continue;
11222		}
11223		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11224		imux->items[imux->num_items].index = idx1;
11225		imux->num_items++;
11226	}
11227	return 0;
11228}
11229
11230static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11231{
11232	struct alc_spec *spec = codec->spec;
11233	hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11234	hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11235	hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11236	unsigned int	dac_vol1, dac_vol2;
11237
11238	if (speaker_nid) {
11239		snd_hda_codec_write(codec, speaker_nid, 0,
11240				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11241		snd_hda_codec_write(codec, 0x0f, 0,
11242				    AC_VERB_SET_AMP_GAIN_MUTE,
11243				    AMP_IN_UNMUTE(1));
11244		snd_hda_codec_write(codec, 0x10, 0,
11245				    AC_VERB_SET_AMP_GAIN_MUTE,
11246				    AMP_IN_UNMUTE(1));
11247	} else {
11248		snd_hda_codec_write(codec, 0x0f, 0,
11249				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11250		snd_hda_codec_write(codec, 0x10, 0,
11251				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11252	}
11253
11254	dac_vol1 = dac_vol2 = 0xb000 | 0x40;	/* set max volume  */
11255	if (line_nid == 0x14)
11256		dac_vol2 = AMP_OUT_ZERO;
11257	else if (line_nid == 0x15)
11258		dac_vol1 = AMP_OUT_ZERO;
11259	if (hp_nid == 0x14)
11260		dac_vol2 = AMP_OUT_ZERO;
11261	else if (hp_nid == 0x15)
11262		dac_vol1 = AMP_OUT_ZERO;
11263	if (line_nid != 0x16 || hp_nid != 0x16 ||
11264	    spec->autocfg.line_out_pins[1] != 0x16 ||
11265	    spec->autocfg.line_out_pins[2] != 0x16)
11266		dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11267
11268	snd_hda_codec_write(codec, 0x02, 0,
11269			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11270	snd_hda_codec_write(codec, 0x03, 0,
11271			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11272}
11273
11274/* pcm configuration: identiacal with ALC880 */
11275#define alc268_pcm_analog_playback	alc880_pcm_analog_playback
11276#define alc268_pcm_analog_capture	alc880_pcm_analog_capture
11277#define alc268_pcm_analog_alt_capture	alc880_pcm_analog_alt_capture
11278#define alc268_pcm_digital_playback	alc880_pcm_digital_playback
11279
11280/*
11281 * BIOS auto configuration
11282 */
11283static int alc268_parse_auto_config(struct hda_codec *codec)
11284{
11285	struct alc_spec *spec = codec->spec;
11286	int err;
11287	static hda_nid_t alc268_ignore[] = { 0 };
11288
11289	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11290					   alc268_ignore);
11291	if (err < 0)
11292		return err;
11293	if (!spec->autocfg.line_outs)
11294		return 0; /* can't find valid BIOS pin config */
11295
11296	err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11297	if (err < 0)
11298		return err;
11299	err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11300	if (err < 0)
11301		return err;
11302
11303	spec->multiout.max_channels = 2;
11304
11305	/* digital only support output */
11306	if (spec->autocfg.dig_out_pin)
11307		spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
11308
11309	if (spec->kctls.list)
11310		add_mixer(spec, spec->kctls.list);
11311
11312	if (spec->autocfg.speaker_pins[0] != 0x1d)
11313		add_mixer(spec, alc268_beep_mixer);
11314
11315	add_verb(spec, alc268_volume_init_verbs);
11316	spec->num_mux_defs = 1;
11317	spec->input_mux = &spec->private_imux;
11318
11319	err = alc_auto_add_mic_boost(codec);
11320	if (err < 0)
11321		return err;
11322
11323	store_pin_configs(codec);
11324	return 1;
11325}
11326
11327#define alc268_auto_init_multi_out	alc882_auto_init_multi_out
11328#define alc268_auto_init_hp_out		alc882_auto_init_hp_out
11329#define alc268_auto_init_analog_input	alc882_auto_init_analog_input
11330
11331/* init callback for auto-configuration model -- overriding the default init */
11332static void alc268_auto_init(struct hda_codec *codec)
11333{
11334	struct alc_spec *spec = codec->spec;
11335	alc268_auto_init_multi_out(codec);
11336	alc268_auto_init_hp_out(codec);
11337	alc268_auto_init_mono_speaker_out(codec);
11338	alc268_auto_init_analog_input(codec);
11339	if (spec->unsol_event)
11340		alc_inithook(codec);
11341}
11342
11343/*
11344 * configuration and preset
11345 */
11346static const char *alc268_models[ALC268_MODEL_LAST] = {
11347	[ALC267_QUANTA_IL1]	= "quanta-il1",
11348	[ALC268_3ST]		= "3stack",
11349	[ALC268_TOSHIBA]	= "toshiba",
11350	[ALC268_ACER]		= "acer",
11351	[ALC268_ACER_DMIC]	= "acer-dmic",
11352	[ALC268_ACER_ASPIRE_ONE]	= "acer-aspire",
11353	[ALC268_DELL]		= "dell",
11354	[ALC268_ZEPTO]		= "zepto",
11355#ifdef CONFIG_SND_DEBUG
11356	[ALC268_TEST]		= "test",
11357#endif
11358	[ALC268_AUTO]		= "auto",
11359};
11360
11361static struct snd_pci_quirk alc268_cfg_tbl[] = {
11362	SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
11363	SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
11364	SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
11365	SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
11366	SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
11367	SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
11368						ALC268_ACER_ASPIRE_ONE),
11369	SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
11370	SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
11371	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
11372	SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
11373	SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
11374	SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
11375	SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
11376	SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
11377	SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
11378	SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
11379	{}
11380};
11381
11382static struct alc_config_preset alc268_presets[] = {
11383	[ALC267_QUANTA_IL1] = {
11384		.mixers = { alc267_quanta_il1_mixer },
11385		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11386				alc267_quanta_il1_verbs },
11387		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11388		.dac_nids = alc268_dac_nids,
11389		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11390		.adc_nids = alc268_adc_nids_alt,
11391		.hp_nid = 0x03,
11392		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11393		.channel_mode = alc268_modes,
11394		.input_mux = &alc268_capture_source,
11395		.unsol_event = alc267_quanta_il1_unsol_event,
11396		.init_hook = alc267_quanta_il1_automute,
11397	},
11398	[ALC268_3ST] = {
11399		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11400			    alc268_beep_mixer },
11401		.init_verbs = { alc268_base_init_verbs },
11402		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11403		.dac_nids = alc268_dac_nids,
11404                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11405                .adc_nids = alc268_adc_nids_alt,
11406		.capsrc_nids = alc268_capsrc_nids,
11407		.hp_nid = 0x03,
11408		.dig_out_nid = ALC268_DIGOUT_NID,
11409		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11410		.channel_mode = alc268_modes,
11411		.input_mux = &alc268_capture_source,
11412	},
11413	[ALC268_TOSHIBA] = {
11414		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11415			    alc268_beep_mixer },
11416		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11417				alc268_toshiba_verbs },
11418		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11419		.dac_nids = alc268_dac_nids,
11420		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11421		.adc_nids = alc268_adc_nids_alt,
11422		.capsrc_nids = alc268_capsrc_nids,
11423		.hp_nid = 0x03,
11424		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11425		.channel_mode = alc268_modes,
11426		.input_mux = &alc268_capture_source,
11427		.unsol_event = alc268_toshiba_unsol_event,
11428		.init_hook = alc268_toshiba_automute,
11429	},
11430	[ALC268_ACER] = {
11431		.mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
11432			    alc268_beep_mixer },
11433		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11434				alc268_acer_verbs },
11435		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11436		.dac_nids = alc268_dac_nids,
11437		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11438		.adc_nids = alc268_adc_nids_alt,
11439		.capsrc_nids = alc268_capsrc_nids,
11440		.hp_nid = 0x02,
11441		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11442		.channel_mode = alc268_modes,
11443		.input_mux = &alc268_acer_capture_source,
11444		.unsol_event = alc268_acer_unsol_event,
11445		.init_hook = alc268_acer_init_hook,
11446	},
11447	[ALC268_ACER_DMIC] = {
11448		.mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
11449			    alc268_beep_mixer },
11450		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11451				alc268_acer_verbs },
11452		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11453		.dac_nids = alc268_dac_nids,
11454		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11455		.adc_nids = alc268_adc_nids_alt,
11456		.capsrc_nids = alc268_capsrc_nids,
11457		.hp_nid = 0x02,
11458		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11459		.channel_mode = alc268_modes,
11460		.input_mux = &alc268_acer_dmic_capture_source,
11461		.unsol_event = alc268_acer_unsol_event,
11462		.init_hook = alc268_acer_init_hook,
11463	},
11464	[ALC268_ACER_ASPIRE_ONE] = {
11465		.mixers = { alc268_acer_aspire_one_mixer,
11466				alc268_capture_alt_mixer },
11467		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11468				alc268_acer_aspire_one_verbs },
11469		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11470		.dac_nids = alc268_dac_nids,
11471		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11472		.adc_nids = alc268_adc_nids_alt,
11473		.capsrc_nids = alc268_capsrc_nids,
11474		.hp_nid = 0x03,
11475		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11476		.channel_mode = alc268_modes,
11477		.input_mux = &alc268_acer_lc_capture_source,
11478		.unsol_event = alc268_acer_lc_unsol_event,
11479		.init_hook = alc268_acer_lc_init_hook,
11480	},
11481	[ALC268_DELL] = {
11482		.mixers = { alc268_dell_mixer, alc268_beep_mixer },
11483		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11484				alc268_dell_verbs },
11485		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11486		.dac_nids = alc268_dac_nids,
11487		.hp_nid = 0x02,
11488		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11489		.channel_mode = alc268_modes,
11490		.unsol_event = alc268_dell_unsol_event,
11491		.init_hook = alc268_dell_init_hook,
11492		.input_mux = &alc268_capture_source,
11493	},
11494	[ALC268_ZEPTO] = {
11495		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11496			    alc268_beep_mixer },
11497		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11498				alc268_toshiba_verbs },
11499		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11500		.dac_nids = alc268_dac_nids,
11501		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11502		.adc_nids = alc268_adc_nids_alt,
11503		.capsrc_nids = alc268_capsrc_nids,
11504		.hp_nid = 0x03,
11505		.dig_out_nid = ALC268_DIGOUT_NID,
11506		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11507		.channel_mode = alc268_modes,
11508		.input_mux = &alc268_capture_source,
11509		.unsol_event = alc268_toshiba_unsol_event,
11510		.init_hook = alc268_toshiba_automute
11511	},
11512#ifdef CONFIG_SND_DEBUG
11513	[ALC268_TEST] = {
11514		.mixers = { alc268_test_mixer, alc268_capture_mixer },
11515		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11516				alc268_volume_init_verbs },
11517		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11518		.dac_nids = alc268_dac_nids,
11519		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11520		.adc_nids = alc268_adc_nids_alt,
11521		.capsrc_nids = alc268_capsrc_nids,
11522		.hp_nid = 0x03,
11523		.dig_out_nid = ALC268_DIGOUT_NID,
11524		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11525		.channel_mode = alc268_modes,
11526		.input_mux = &alc268_capture_source,
11527	},
11528#endif
11529};
11530
11531static int patch_alc268(struct hda_codec *codec)
11532{
11533	struct alc_spec *spec;
11534	int board_config;
11535	int err;
11536
11537	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
11538	if (spec == NULL)
11539		return -ENOMEM;
11540
11541	codec->spec = spec;
11542
11543	board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
11544						  alc268_models,
11545						  alc268_cfg_tbl);
11546
11547	if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
11548		printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
11549		       "trying auto-probe from BIOS...\n");
11550		board_config = ALC268_AUTO;
11551	}
11552
11553	if (board_config == ALC268_AUTO) {
11554		/* automatic parse from the BIOS config */
11555		err = alc268_parse_auto_config(codec);
11556		if (err < 0) {
11557			alc_free(codec);
11558			return err;
11559		} else if (!err) {
11560			printk(KERN_INFO
11561			       "hda_codec: Cannot set up configuration "
11562			       "from BIOS.  Using base mode...\n");
11563			board_config = ALC268_3ST;
11564		}
11565	}
11566
11567	if (board_config != ALC268_AUTO)
11568		setup_preset(spec, &alc268_presets[board_config]);
11569
11570	if (codec->vendor_id == 0x10ec0267) {
11571		spec->stream_name_analog = "ALC267 Analog";
11572		spec->stream_name_digital = "ALC267 Digital";
11573	} else {
11574		spec->stream_name_analog = "ALC268 Analog";
11575		spec->stream_name_digital = "ALC268 Digital";
11576	}
11577
11578	spec->stream_analog_playback = &alc268_pcm_analog_playback;
11579	spec->stream_analog_capture = &alc268_pcm_analog_capture;
11580	spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
11581
11582	spec->stream_digital_playback = &alc268_pcm_digital_playback;
11583
11584	if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
11585		/* override the amp caps for beep generator */
11586		snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
11587					  (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
11588					  (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
11589					  (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
11590					  (0 << AC_AMPCAP_MUTE_SHIFT));
11591
11592	if (!spec->adc_nids && spec->input_mux) {
11593		/* check whether NID 0x07 is valid */
11594		unsigned int wcap = get_wcaps(codec, 0x07);
11595		int i;
11596
11597		/* get type */
11598		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11599		if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
11600			spec->adc_nids = alc268_adc_nids_alt;
11601			spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
11602			add_mixer(spec, alc268_capture_alt_mixer);
11603		} else {
11604			spec->adc_nids = alc268_adc_nids;
11605			spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
11606			add_mixer(spec, alc268_capture_mixer);
11607		}
11608		spec->capsrc_nids = alc268_capsrc_nids;
11609		/* set default input source */
11610		for (i = 0; i < spec->num_adc_nids; i++)
11611			snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
11612				0, AC_VERB_SET_CONNECT_SEL,
11613				spec->input_mux->items[0].index);
11614	}
11615
11616	spec->vmaster_nid = 0x02;
11617
11618	codec->patch_ops = alc_patch_ops;
11619	if (board_config == ALC268_AUTO)
11620		spec->init_hook = alc268_auto_init;
11621
11622	return 0;
11623}
11624
11625/*
11626 *  ALC269 channel source setting (2 channel)
11627 */
11628#define ALC269_DIGOUT_NID	ALC880_DIGOUT_NID
11629
11630#define alc269_dac_nids		alc260_dac_nids
11631
11632static hda_nid_t alc269_adc_nids[1] = {
11633	/* ADC1 */
11634	0x08,
11635};
11636
11637static hda_nid_t alc269_capsrc_nids[1] = {
11638	0x23,
11639};
11640
11641/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
11642 *       not a mux!
11643 */
11644
11645static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
11646	.num_items = 2,
11647	.items = {
11648		{ "i-Mic", 0x5 },
11649		{ "e-Mic", 0x0 },
11650	},
11651};
11652
11653static struct hda_input_mux alc269_eeepc_amic_capture_source = {
11654	.num_items = 2,
11655	.items = {
11656		{ "i-Mic", 0x1 },
11657		{ "e-Mic", 0x0 },
11658	},
11659};
11660
11661#define alc269_modes		alc260_modes
11662#define alc269_capture_source	alc880_lg_lw_capture_source
11663
11664static struct snd_kcontrol_new alc269_base_mixer[] = {
11665	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11666	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11667	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11668	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11669	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11670	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11671	HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11672	HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11673	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11674	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11675	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11676	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11677	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11678	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11679	{ } /* end */
11680};
11681
11682static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
11683	/* output mixer control */
11684	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11685	{
11686		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11687		.name = "Master Playback Switch",
11688		.info = snd_hda_mixer_amp_switch_info,
11689		.get = snd_hda_mixer_amp_switch_get,
11690		.put = alc268_acer_master_sw_put,
11691		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11692	},
11693	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11694	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11695	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11696	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11697	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11698	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11699	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
11700	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
11701	{ }
11702};
11703
11704/* bind volumes of both NID 0x0c and 0x0d */
11705static struct hda_bind_ctls alc269_epc_bind_vol = {
11706	.ops = &snd_hda_bind_vol,
11707	.values = {
11708		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11709		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11710		0
11711	},
11712};
11713
11714static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
11715	HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11716	HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
11717	HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11718	{ } /* end */
11719};
11720
11721/* capture mixer elements */
11722static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
11723	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11724	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11725	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11726	{ } /* end */
11727};
11728
11729/* FSC amilo */
11730static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
11731	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11732	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11733	HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol),
11734	{ } /* end */
11735};
11736
11737/* beep control */
11738static struct snd_kcontrol_new alc269_beep_mixer[] = {
11739	HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11740	HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11741	{ } /* end */
11742};
11743
11744static struct hda_verb alc269_quanta_fl1_verbs[] = {
11745	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11746	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11747	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11748	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11749	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11750	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11751	{ }
11752};
11753
11754/* toggle speaker-output according to the hp-jack state */
11755static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
11756{
11757	unsigned int present;
11758	unsigned char bits;
11759
11760	present = snd_hda_codec_read(codec, 0x15, 0,
11761			AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11762	bits = present ? AMP_IN_MUTE(0) : 0;
11763	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11764			AMP_IN_MUTE(0), bits);
11765	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11766			AMP_IN_MUTE(0), bits);
11767
11768	snd_hda_codec_write(codec, 0x20, 0,
11769			AC_VERB_SET_COEF_INDEX, 0x0c);
11770	snd_hda_codec_write(codec, 0x20, 0,
11771			AC_VERB_SET_PROC_COEF, 0x680);
11772
11773	snd_hda_codec_write(codec, 0x20, 0,
11774			AC_VERB_SET_COEF_INDEX, 0x0c);
11775	snd_hda_codec_write(codec, 0x20, 0,
11776			AC_VERB_SET_PROC_COEF, 0x480);
11777}
11778
11779static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
11780{
11781	unsigned int present;
11782
11783	present = snd_hda_codec_read(codec, 0x18, 0,
11784				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11785	snd_hda_codec_write(codec, 0x23, 0,
11786			    AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
11787}
11788
11789static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
11790				    unsigned int res)
11791{
11792	if ((res >> 26) == ALC880_HP_EVENT)
11793		alc269_quanta_fl1_speaker_automute(codec);
11794	if ((res >> 26) == ALC880_MIC_EVENT)
11795		alc269_quanta_fl1_mic_automute(codec);
11796}
11797
11798static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
11799{
11800	alc269_quanta_fl1_speaker_automute(codec);
11801	alc269_quanta_fl1_mic_automute(codec);
11802}
11803
11804static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
11805	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11806	{0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
11807	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11808	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
11809	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11810	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11811	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11812	{}
11813};
11814
11815static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
11816	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11817	{0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
11818	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11819	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
11820	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11821	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11822	{}
11823};
11824
11825/* toggle speaker-output according to the hp-jack state */
11826static void alc269_speaker_automute(struct hda_codec *codec)
11827{
11828	unsigned int present;
11829	unsigned char bits;
11830
11831	present = snd_hda_codec_read(codec, 0x15, 0,
11832				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11833	bits = present ? AMP_IN_MUTE(0) : 0;
11834	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11835				AMP_IN_MUTE(0), bits);
11836	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11837				AMP_IN_MUTE(0), bits);
11838}
11839
11840static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
11841{
11842	unsigned int present;
11843
11844	present = snd_hda_codec_read(codec, 0x18, 0,
11845				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11846	snd_hda_codec_write(codec, 0x23, 0,
11847				AC_VERB_SET_CONNECT_SEL,  (present ? 0 : 5));
11848}
11849
11850static void alc269_eeepc_amic_automute(struct hda_codec *codec)
11851{
11852	unsigned int present;
11853
11854	present = snd_hda_codec_read(codec, 0x18, 0,
11855				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11856	snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11857				0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
11858	snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11859				0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
11860}
11861
11862/* unsolicited event for HP jack sensing */
11863static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
11864				     unsigned int res)
11865{
11866	if ((res >> 26) == ALC880_HP_EVENT)
11867		alc269_speaker_automute(codec);
11868
11869	if ((res >> 26) == ALC880_MIC_EVENT)
11870		alc269_eeepc_dmic_automute(codec);
11871}
11872
11873static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
11874{
11875	alc269_speaker_automute(codec);
11876	alc269_eeepc_dmic_automute(codec);
11877}
11878
11879/* unsolicited event for HP jack sensing */
11880static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
11881				     unsigned int res)
11882{
11883	if ((res >> 26) == ALC880_HP_EVENT)
11884		alc269_speaker_automute(codec);
11885
11886	if ((res >> 26) == ALC880_MIC_EVENT)
11887		alc269_eeepc_amic_automute(codec);
11888}
11889
11890static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
11891{
11892	alc269_speaker_automute(codec);
11893	alc269_eeepc_amic_automute(codec);
11894}
11895
11896/*
11897 * generic initialization of ADC, input mixers and output mixers
11898 */
11899static struct hda_verb alc269_init_verbs[] = {
11900	/*
11901	 * Unmute ADC0 and set the default input to mic-in
11902	 */
11903	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11904
11905	/* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
11906	 * analog-loopback mixer widget
11907	 * Note: PASD motherboards uses the Line In 2 as the input for
11908	 * front panel mic (mic 2)
11909	 */
11910	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11911	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11912	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11913	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11914	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11915	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11916
11917	/*
11918	 * Set up output mixers (0x0c - 0x0e)
11919	 */
11920	/* set vol=0 to output mixers */
11921	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11922	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11923
11924	/* set up input amps for analog loopback */
11925	/* Amp Indices: DAC = 0, mixer = 1 */
11926	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11927	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11928	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11929	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11930	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11931	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11932
11933	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11934	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11935	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11936	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11937	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11938	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11939	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11940
11941	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11942	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11943	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11944	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11945	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11946	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11947	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11948
11949	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11950	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11951
11952	/* FIXME: use matrix-type input source selection */
11953	/* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
11954	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11955	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11956	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11957	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11958	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11959
11960	/* set EAPD */
11961	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11962	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11963	{ }
11964};
11965
11966/* add playback controls from the parsed DAC table */
11967static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
11968					     const struct auto_pin_cfg *cfg)
11969{
11970	hda_nid_t nid;
11971	int err;
11972
11973	spec->multiout.num_dacs = 1;	/* only use one dac */
11974	spec->multiout.dac_nids = spec->private_dac_nids;
11975	spec->multiout.dac_nids[0] = 2;
11976
11977	nid = cfg->line_out_pins[0];
11978	if (nid) {
11979		err = add_control(spec, ALC_CTL_WIDGET_VOL,
11980				  "Front Playback Volume",
11981				  HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
11982		if (err < 0)
11983			return err;
11984		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11985				  "Front Playback Switch",
11986				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
11987		if (err < 0)
11988			return err;
11989	}
11990
11991	nid = cfg->speaker_pins[0];
11992	if (nid) {
11993		if (!cfg->line_out_pins[0]) {
11994			err = add_control(spec, ALC_CTL_WIDGET_VOL,
11995					  "Speaker Playback Volume",
11996					  HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
11997							      HDA_OUTPUT));
11998			if (err < 0)
11999				return err;
12000		}
12001		if (nid == 0x16) {
12002			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12003					  "Speaker Playback Switch",
12004					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12005							      HDA_OUTPUT));
12006			if (err < 0)
12007				return err;
12008		} else {
12009			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12010					  "Speaker Playback Switch",
12011					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12012							      HDA_OUTPUT));
12013			if (err < 0)
12014				return err;
12015		}
12016	}
12017	nid = cfg->hp_pins[0];
12018	if (nid) {
12019		/* spec->multiout.hp_nid = 2; */
12020		if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12021			err = add_control(spec, ALC_CTL_WIDGET_VOL,
12022					  "Headphone Playback Volume",
12023					  HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12024							      HDA_OUTPUT));
12025			if (err < 0)
12026				return err;
12027		}
12028		if (nid == 0x16) {
12029			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12030					  "Headphone Playback Switch",
12031					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12032							      HDA_OUTPUT));
12033			if (err < 0)
12034				return err;
12035		} else {
12036			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12037					  "Headphone Playback Switch",
12038					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12039							      HDA_OUTPUT));
12040			if (err < 0)
12041				return err;
12042		}
12043	}
12044	return 0;
12045}
12046
12047static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
12048						const struct auto_pin_cfg *cfg)
12049{
12050	int err;
12051
12052	err = alc880_auto_create_analog_input_ctls(spec, cfg);
12053	if (err < 0)
12054		return err;
12055	/* digital-mic input pin is excluded in alc880_auto_create..()
12056	 * because it's under 0x18
12057	 */
12058	if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
12059	    cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
12060		struct hda_input_mux *imux = &spec->private_imux;
12061		imux->items[imux->num_items].label = "Int Mic";
12062		imux->items[imux->num_items].index = 0x05;
12063		imux->num_items++;
12064	}
12065	return 0;
12066}
12067
12068#ifdef CONFIG_SND_HDA_POWER_SAVE
12069#define alc269_loopbacks	alc880_loopbacks
12070#endif
12071
12072/* pcm configuration: identiacal with ALC880 */
12073#define alc269_pcm_analog_playback	alc880_pcm_analog_playback
12074#define alc269_pcm_analog_capture	alc880_pcm_analog_capture
12075#define alc269_pcm_digital_playback	alc880_pcm_digital_playback
12076#define alc269_pcm_digital_capture	alc880_pcm_digital_capture
12077
12078/*
12079 * BIOS auto configuration
12080 */
12081static int alc269_parse_auto_config(struct hda_codec *codec)
12082{
12083	struct alc_spec *spec = codec->spec;
12084	int i, err;
12085	static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12086
12087	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12088					   alc269_ignore);
12089	if (err < 0)
12090		return err;
12091
12092	err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12093	if (err < 0)
12094		return err;
12095	err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12096	if (err < 0)
12097		return err;
12098
12099	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12100
12101	if (spec->autocfg.dig_out_pin)
12102		spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12103
12104	if (spec->kctls.list)
12105		add_mixer(spec, spec->kctls.list);
12106
12107	/* create a beep mixer control if the pin 0x1d isn't assigned */
12108	for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++)
12109		if (spec->autocfg.input_pins[i] == 0x1d)
12110			break;
12111	if (i >= ARRAY_SIZE(spec->autocfg.input_pins))
12112		add_mixer(spec, alc269_beep_mixer);
12113
12114	add_verb(spec, alc269_init_verbs);
12115	spec->num_mux_defs = 1;
12116	spec->input_mux = &spec->private_imux;
12117	/* set default input source */
12118	snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12119				  0, AC_VERB_SET_CONNECT_SEL,
12120				  spec->input_mux->items[0].index);
12121
12122	err = alc_auto_add_mic_boost(codec);
12123	if (err < 0)
12124		return err;
12125
12126	if (!spec->cap_mixer)
12127		set_capture_mixer(spec);
12128
12129	store_pin_configs(codec);
12130	return 1;
12131}
12132
12133#define alc269_auto_init_multi_out	alc882_auto_init_multi_out
12134#define alc269_auto_init_hp_out		alc882_auto_init_hp_out
12135#define alc269_auto_init_analog_input	alc882_auto_init_analog_input
12136
12137
12138/* init callback for auto-configuration model -- overriding the default init */
12139static void alc269_auto_init(struct hda_codec *codec)
12140{
12141	struct alc_spec *spec = codec->spec;
12142	alc269_auto_init_multi_out(codec);
12143	alc269_auto_init_hp_out(codec);
12144	alc269_auto_init_analog_input(codec);
12145	if (spec->unsol_event)
12146		alc_inithook(codec);
12147}
12148
12149/*
12150 * configuration and preset
12151 */
12152static const char *alc269_models[ALC269_MODEL_LAST] = {
12153	[ALC269_BASIC]			= "basic",
12154	[ALC269_QUANTA_FL1]		= "quanta",
12155	[ALC269_ASUS_EEEPC_P703]	= "eeepc-p703",
12156	[ALC269_ASUS_EEEPC_P901]	= "eeepc-p901",
12157	[ALC269_FUJITSU]		= "fujitsu"
12158};
12159
12160static struct snd_pci_quirk alc269_cfg_tbl[] = {
12161	SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
12162	SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12163		      ALC269_ASUS_EEEPC_P703),
12164	SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12165		      ALC269_ASUS_EEEPC_P901),
12166	SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12167		      ALC269_ASUS_EEEPC_P901),
12168	SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
12169	{}
12170};
12171
12172static struct alc_config_preset alc269_presets[] = {
12173	[ALC269_BASIC] = {
12174		.mixers = { alc269_base_mixer },
12175		.init_verbs = { alc269_init_verbs },
12176		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
12177		.dac_nids = alc269_dac_nids,
12178		.hp_nid = 0x03,
12179		.num_channel_mode = ARRAY_SIZE(alc269_modes),
12180		.channel_mode = alc269_modes,
12181		.input_mux = &alc269_capture_source,
12182	},
12183	[ALC269_QUANTA_FL1] = {
12184		.mixers = { alc269_quanta_fl1_mixer },
12185		.init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
12186		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
12187		.dac_nids = alc269_dac_nids,
12188		.hp_nid = 0x03,
12189		.num_channel_mode = ARRAY_SIZE(alc269_modes),
12190		.channel_mode = alc269_modes,
12191		.input_mux = &alc269_capture_source,
12192		.unsol_event = alc269_quanta_fl1_unsol_event,
12193		.init_hook = alc269_quanta_fl1_init_hook,
12194	},
12195	[ALC269_ASUS_EEEPC_P703] = {
12196		.mixers = { alc269_eeepc_mixer },
12197		.cap_mixer = alc269_epc_capture_mixer,
12198		.init_verbs = { alc269_init_verbs,
12199				alc269_eeepc_amic_init_verbs },
12200		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
12201		.dac_nids = alc269_dac_nids,
12202		.hp_nid = 0x03,
12203		.num_channel_mode = ARRAY_SIZE(alc269_modes),
12204		.channel_mode = alc269_modes,
12205		.input_mux = &alc269_eeepc_amic_capture_source,
12206		.unsol_event = alc269_eeepc_amic_unsol_event,
12207		.init_hook = alc269_eeepc_amic_inithook,
12208	},
12209	[ALC269_ASUS_EEEPC_P901] = {
12210		.mixers = { alc269_eeepc_mixer },
12211		.cap_mixer = alc269_epc_capture_mixer,
12212		.init_verbs = { alc269_init_verbs,
12213				alc269_eeepc_dmic_init_verbs },
12214		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
12215		.dac_nids = alc269_dac_nids,
12216		.hp_nid = 0x03,
12217		.num_channel_mode = ARRAY_SIZE(alc269_modes),
12218		.channel_mode = alc269_modes,
12219		.input_mux = &alc269_eeepc_dmic_capture_source,
12220		.unsol_event = alc269_eeepc_dmic_unsol_event,
12221		.init_hook = alc269_eeepc_dmic_inithook,
12222	},
12223	[ALC269_FUJITSU] = {
12224		.mixers = { alc269_fujitsu_mixer, alc269_beep_mixer },
12225		.cap_mixer = alc269_epc_capture_mixer,
12226		.init_verbs = { alc269_init_verbs,
12227				alc269_eeepc_dmic_init_verbs },
12228		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
12229		.dac_nids = alc269_dac_nids,
12230		.hp_nid = 0x03,
12231		.num_channel_mode = ARRAY_SIZE(alc269_modes),
12232		.channel_mode = alc269_modes,
12233		.input_mux = &alc269_eeepc_dmic_capture_source,
12234		.unsol_event = alc269_eeepc_dmic_unsol_event,
12235		.init_hook = alc269_eeepc_dmic_inithook,
12236	},
12237};
12238
12239static int patch_alc269(struct hda_codec *codec)
12240{
12241	struct alc_spec *spec;
12242	int board_config;
12243	int err;
12244
12245	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12246	if (spec == NULL)
12247		return -ENOMEM;
12248
12249	codec->spec = spec;
12250
12251	alc_fix_pll_init(codec, 0x20, 0x04, 15);
12252
12253	board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
12254						  alc269_models,
12255						  alc269_cfg_tbl);
12256
12257	if (board_config < 0) {
12258		printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
12259		       "trying auto-probe from BIOS...\n");
12260		board_config = ALC269_AUTO;
12261	}
12262
12263	if (board_config == ALC269_AUTO) {
12264		/* automatic parse from the BIOS config */
12265		err = alc269_parse_auto_config(codec);
12266		if (err < 0) {
12267			alc_free(codec);
12268			return err;
12269		} else if (!err) {
12270			printk(KERN_INFO
12271			       "hda_codec: Cannot set up configuration "
12272			       "from BIOS.  Using base mode...\n");
12273			board_config = ALC269_BASIC;
12274		}
12275	}
12276
12277	if (board_config != ALC269_AUTO)
12278		setup_preset(spec, &alc269_presets[board_config]);
12279
12280	spec->stream_name_analog = "ALC269 Analog";
12281	spec->stream_analog_playback = &alc269_pcm_analog_playback;
12282	spec->stream_analog_capture = &alc269_pcm_analog_capture;
12283
12284	spec->stream_name_digital = "ALC269 Digital";
12285	spec->stream_digital_playback = &alc269_pcm_digital_playback;
12286	spec->stream_digital_capture = &alc269_pcm_digital_capture;
12287
12288	spec->adc_nids = alc269_adc_nids;
12289	spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
12290	spec->capsrc_nids = alc269_capsrc_nids;
12291	if (!spec->cap_mixer)
12292		set_capture_mixer(spec);
12293
12294	codec->patch_ops = alc_patch_ops;
12295	if (board_config == ALC269_AUTO)
12296		spec->init_hook = alc269_auto_init;
12297#ifdef CONFIG_SND_HDA_POWER_SAVE
12298	if (!spec->loopback.amplist)
12299		spec->loopback.amplist = alc269_loopbacks;
12300#endif
12301
12302	return 0;
12303}
12304
12305/*
12306 *  ALC861 channel source setting (2/6 channel selection for 3-stack)
12307 */
12308
12309/*
12310 * set the path ways for 2 channel output
12311 * need to set the codec line out and mic 1 pin widgets to inputs
12312 */
12313static struct hda_verb alc861_threestack_ch2_init[] = {
12314	/* set pin widget 1Ah (line in) for input */
12315	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12316	/* set pin widget 18h (mic1/2) for input, for mic also enable
12317	 * the vref
12318	 */
12319	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12320
12321	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12322#if 0
12323	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12324	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12325#endif
12326	{ } /* end */
12327};
12328/*
12329 * 6ch mode
12330 * need to set the codec line out and mic 1 pin widgets to outputs
12331 */
12332static struct hda_verb alc861_threestack_ch6_init[] = {
12333	/* set pin widget 1Ah (line in) for output (Back Surround)*/
12334	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12335	/* set pin widget 18h (mic1) for output (CLFE)*/
12336	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12337
12338	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12339	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12340
12341	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12342#if 0
12343	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12344	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12345#endif
12346	{ } /* end */
12347};
12348
12349static struct hda_channel_mode alc861_threestack_modes[2] = {
12350	{ 2, alc861_threestack_ch2_init },
12351	{ 6, alc861_threestack_ch6_init },
12352};
12353/* Set mic1 as input and unmute the mixer */
12354static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
12355	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12356	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12357	{ } /* end */
12358};
12359/* Set mic1 as output and mute mixer */
12360static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
12361	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12362	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12363	{ } /* end */
12364};
12365
12366static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
12367	{ 2, alc861_uniwill_m31_ch2_init },
12368	{ 4, alc861_uniwill_m31_ch4_init },
12369};
12370
12371/* Set mic1 and line-in as input and unmute the mixer */
12372static struct hda_verb alc861_asus_ch2_init[] = {
12373	/* set pin widget 1Ah (line in) for input */
12374	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12375	/* set pin widget 18h (mic1/2) for input, for mic also enable
12376	 * the vref
12377	 */
12378	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12379
12380	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12381#if 0
12382	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12383	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12384#endif
12385	{ } /* end */
12386};
12387/* Set mic1 nad line-in as output and mute mixer */
12388static struct hda_verb alc861_asus_ch6_init[] = {
12389	/* set pin widget 1Ah (line in) for output (Back Surround)*/
12390	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12391	/* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12392	/* set pin widget 18h (mic1) for output (CLFE)*/
12393	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12394	/* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12395	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12396	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12397
12398	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12399#if 0
12400	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12401	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12402#endif
12403	{ } /* end */
12404};
12405
12406static struct hda_channel_mode alc861_asus_modes[2] = {
12407	{ 2, alc861_asus_ch2_init },
12408	{ 6, alc861_asus_ch6_init },
12409};
12410
12411/* patch-ALC861 */
12412
12413static struct snd_kcontrol_new alc861_base_mixer[] = {
12414        /* output mixer control */
12415	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12416	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12417	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12418	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12419	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12420
12421        /*Input mixer control */
12422	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12423	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12424	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12425	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12426	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12427	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12428	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12429	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12430	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12431	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12432
12433	{ } /* end */
12434};
12435
12436static struct snd_kcontrol_new alc861_3ST_mixer[] = {
12437        /* output mixer control */
12438	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12439	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12440	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12441	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12442	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12443
12444	/* Input mixer control */
12445	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12446	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12447	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12448	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12449	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12450	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12451	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12452	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12453	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12454	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12455
12456	{
12457		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12458		.name = "Channel Mode",
12459		.info = alc_ch_mode_info,
12460		.get = alc_ch_mode_get,
12461		.put = alc_ch_mode_put,
12462                .private_value = ARRAY_SIZE(alc861_threestack_modes),
12463	},
12464	{ } /* end */
12465};
12466
12467static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
12468        /* output mixer control */
12469	HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12470	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12471	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12472
12473	{ } /* end */
12474};
12475
12476static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
12477        /* output mixer control */
12478	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12479	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12480	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12481	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12482	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12483
12484	/* Input mixer control */
12485	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12486	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12487	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12488	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12489	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12490	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12491	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12492	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12493	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12494	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12495
12496	{
12497		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12498		.name = "Channel Mode",
12499		.info = alc_ch_mode_info,
12500		.get = alc_ch_mode_get,
12501		.put = alc_ch_mode_put,
12502                .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
12503	},
12504	{ } /* end */
12505};
12506
12507static struct snd_kcontrol_new alc861_asus_mixer[] = {
12508        /* output mixer control */
12509	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12510	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12511	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12512	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12513	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12514
12515	/* Input mixer control */
12516	HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12517	HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12518	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12519	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12520	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12521	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12522	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12523	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12524	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12525	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
12526
12527	{
12528		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12529		.name = "Channel Mode",
12530		.info = alc_ch_mode_info,
12531		.get = alc_ch_mode_get,
12532		.put = alc_ch_mode_put,
12533                .private_value = ARRAY_SIZE(alc861_asus_modes),
12534	},
12535	{ }
12536};
12537
12538/* additional mixer */
12539static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
12540	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12541	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12542	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
12543	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
12544	{ }
12545};
12546
12547/*
12548 * generic initialization of ADC, input mixers and output mixers
12549 */
12550static struct hda_verb alc861_base_init_verbs[] = {
12551	/*
12552	 * Unmute ADC0 and set the default input to mic-in
12553	 */
12554	/* port-A for surround (rear panel) */
12555	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12556	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
12557	/* port-B for mic-in (rear panel) with vref */
12558	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12559	/* port-C for line-in (rear panel) */
12560	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12561	/* port-D for Front */
12562	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12563	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12564	/* port-E for HP out (front panel) */
12565	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12566	/* route front PCM to HP */
12567	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12568	/* port-F for mic-in (front panel) with vref */
12569	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12570	/* port-G for CLFE (rear panel) */
12571	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12572	{ 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12573	/* port-H for side (rear panel) */
12574	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12575	{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
12576	/* CD-in */
12577	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12578	/* route front mic to ADC1*/
12579	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12580	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12581
12582	/* Unmute DAC0~3 & spdif out*/
12583	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12584	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12585	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12586	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12587	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12588
12589	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12590	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12591        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12592	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12593        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12594
12595	/* Unmute Stereo Mixer 15 */
12596	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12597	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12598	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12599	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12600
12601	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12602	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12603	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12604	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12605	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12606	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12607	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12608	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12609	/* hp used DAC 3 (Front) */
12610	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12611        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12612
12613	{ }
12614};
12615
12616static struct hda_verb alc861_threestack_init_verbs[] = {
12617	/*
12618	 * Unmute ADC0 and set the default input to mic-in
12619	 */
12620	/* port-A for surround (rear panel) */
12621	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12622	/* port-B for mic-in (rear panel) with vref */
12623	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12624	/* port-C for line-in (rear panel) */
12625	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12626	/* port-D for Front */
12627	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12628	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12629	/* port-E for HP out (front panel) */
12630	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12631	/* route front PCM to HP */
12632	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12633	/* port-F for mic-in (front panel) with vref */
12634	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12635	/* port-G for CLFE (rear panel) */
12636	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12637	/* port-H for side (rear panel) */
12638	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12639	/* CD-in */
12640	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12641	/* route front mic to ADC1*/
12642	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12643	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12644	/* Unmute DAC0~3 & spdif out*/
12645	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12646	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12647	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12648	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12649	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12650
12651	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12652	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12653        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12654	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12655        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12656
12657	/* Unmute Stereo Mixer 15 */
12658	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12659	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12660	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12661	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12662
12663	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12664	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12665	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12666	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12667	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12668	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12669	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12670	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12671	/* hp used DAC 3 (Front) */
12672	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12673        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12674	{ }
12675};
12676
12677static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
12678	/*
12679	 * Unmute ADC0 and set the default input to mic-in
12680	 */
12681	/* port-A for surround (rear panel) */
12682	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12683	/* port-B for mic-in (rear panel) with vref */
12684	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12685	/* port-C for line-in (rear panel) */
12686	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12687	/* port-D for Front */
12688	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12689	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12690	/* port-E for HP out (front panel) */
12691	/* this has to be set to VREF80 */
12692	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12693	/* route front PCM to HP */
12694	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12695	/* port-F for mic-in (front panel) with vref */
12696	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12697	/* port-G for CLFE (rear panel) */
12698	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12699	/* port-H for side (rear panel) */
12700	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12701	/* CD-in */
12702	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12703	/* route front mic to ADC1*/
12704	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12705	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12706	/* Unmute DAC0~3 & spdif out*/
12707	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12708	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12709	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12710	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12711	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12712
12713	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12714	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12715        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12716	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12717        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12718
12719	/* Unmute Stereo Mixer 15 */
12720	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12721	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12722	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12723	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12724
12725	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12726	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12727	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12728	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12729	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12730	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12731	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12732	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12733	/* hp used DAC 3 (Front) */
12734	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12735        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12736	{ }
12737};
12738
12739static struct hda_verb alc861_asus_init_verbs[] = {
12740	/*
12741	 * Unmute ADC0 and set the default input to mic-in
12742	 */
12743	/* port-A for surround (rear panel)
12744	 * according to codec#0 this is the HP jack
12745	 */
12746	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
12747	/* route front PCM to HP */
12748	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
12749	/* port-B for mic-in (rear panel) with vref */
12750	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12751	/* port-C for line-in (rear panel) */
12752	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12753	/* port-D for Front */
12754	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12755	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12756	/* port-E for HP out (front panel) */
12757	/* this has to be set to VREF80 */
12758	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12759	/* route front PCM to HP */
12760	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12761	/* port-F for mic-in (front panel) with vref */
12762	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12763	/* port-G for CLFE (rear panel) */
12764	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12765	/* port-H for side (rear panel) */
12766	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12767	/* CD-in */
12768	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12769	/* route front mic to ADC1*/
12770	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12771	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12772	/* Unmute DAC0~3 & spdif out*/
12773	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12774	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12775	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12776	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12777	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12778	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12779	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12780        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12781	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12782        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12783
12784	/* Unmute Stereo Mixer 15 */
12785	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12786	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12787	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12788	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12789
12790	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12791	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12792	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12793	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12794	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12795	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12796	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12797	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12798	/* hp used DAC 3 (Front) */
12799	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12800	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12801	{ }
12802};
12803
12804/* additional init verbs for ASUS laptops */
12805static struct hda_verb alc861_asus_laptop_init_verbs[] = {
12806	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
12807	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
12808	{ }
12809};
12810
12811/*
12812 * generic initialization of ADC, input mixers and output mixers
12813 */
12814static struct hda_verb alc861_auto_init_verbs[] = {
12815	/*
12816	 * Unmute ADC0 and set the default input to mic-in
12817	 */
12818	/* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
12819	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12820
12821	/* Unmute DAC0~3 & spdif out*/
12822	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12823	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12824	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12825	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12826	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12827
12828	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12829	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12830	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12831	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12832	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12833
12834	/* Unmute Stereo Mixer 15 */
12835	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12836	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12837	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12838	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
12839
12840	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12841	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12842	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12843	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12844	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12845	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12846	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12847	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12848
12849	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12850	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12851	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12852	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12853	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12854	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12855	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12856	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12857
12858	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},	/* set Mic 1 */
12859
12860	{ }
12861};
12862
12863static struct hda_verb alc861_toshiba_init_verbs[] = {
12864	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12865
12866	{ }
12867};
12868
12869/* toggle speaker-output according to the hp-jack state */
12870static void alc861_toshiba_automute(struct hda_codec *codec)
12871{
12872	unsigned int present;
12873
12874	present = snd_hda_codec_read(codec, 0x0f, 0,
12875				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12876	snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
12877				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
12878	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
12879				 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
12880}
12881
12882static void alc861_toshiba_unsol_event(struct hda_codec *codec,
12883				       unsigned int res)
12884{
12885	if ((res >> 26) == ALC880_HP_EVENT)
12886		alc861_toshiba_automute(codec);
12887}
12888
12889/* pcm configuration: identiacal with ALC880 */
12890#define alc861_pcm_analog_playback	alc880_pcm_analog_playback
12891#define alc861_pcm_analog_capture	alc880_pcm_analog_capture
12892#define alc861_pcm_digital_playback	alc880_pcm_digital_playback
12893#define alc861_pcm_digital_capture	alc880_pcm_digital_capture
12894
12895
12896#define ALC861_DIGOUT_NID	0x07
12897
12898static struct hda_channel_mode alc861_8ch_modes[1] = {
12899	{ 8, NULL }
12900};
12901
12902static hda_nid_t alc861_dac_nids[4] = {
12903	/* front, surround, clfe, side */
12904	0x03, 0x06, 0x05, 0x04
12905};
12906
12907static hda_nid_t alc660_dac_nids[3] = {
12908	/* front, clfe, surround */
12909	0x03, 0x05, 0x06
12910};
12911
12912static hda_nid_t alc861_adc_nids[1] = {
12913	/* ADC0-2 */
12914	0x08,
12915};
12916
12917static struct hda_input_mux alc861_capture_source = {
12918	.num_items = 5,
12919	.items = {
12920		{ "Mic", 0x0 },
12921		{ "Front Mic", 0x3 },
12922		{ "Line", 0x1 },
12923		{ "CD", 0x4 },
12924		{ "Mixer", 0x5 },
12925	},
12926};
12927
12928/* fill in the dac_nids table from the parsed pin configuration */
12929static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
12930				     const struct auto_pin_cfg *cfg)
12931{
12932	int i;
12933	hda_nid_t nid;
12934
12935	spec->multiout.dac_nids = spec->private_dac_nids;
12936	for (i = 0; i < cfg->line_outs; i++) {
12937		nid = cfg->line_out_pins[i];
12938		if (nid) {
12939			if (i >= ARRAY_SIZE(alc861_dac_nids))
12940				continue;
12941			spec->multiout.dac_nids[i] = alc861_dac_nids[i];
12942		}
12943	}
12944	spec->multiout.num_dacs = cfg->line_outs;
12945	return 0;
12946}
12947
12948/* add playback controls from the parsed DAC table */
12949static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
12950					     const struct auto_pin_cfg *cfg)
12951{
12952	char name[32];
12953	static const char *chname[4] = {
12954		"Front", "Surround", NULL /*CLFE*/, "Side"
12955	};
12956	hda_nid_t nid;
12957	int i, idx, err;
12958
12959	for (i = 0; i < cfg->line_outs; i++) {
12960		nid = spec->multiout.dac_nids[i];
12961		if (!nid)
12962			continue;
12963		if (nid == 0x05) {
12964			/* Center/LFE */
12965			err = add_control(spec, ALC_CTL_BIND_MUTE,
12966					  "Center Playback Switch",
12967					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
12968							      HDA_OUTPUT));
12969			if (err < 0)
12970				return err;
12971			err = add_control(spec, ALC_CTL_BIND_MUTE,
12972					  "LFE Playback Switch",
12973					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12974							      HDA_OUTPUT));
12975			if (err < 0)
12976				return err;
12977		} else {
12978			for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
12979			     idx++)
12980				if (nid == alc861_dac_nids[idx])
12981					break;
12982			sprintf(name, "%s Playback Switch", chname[idx]);
12983			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12984					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12985							      HDA_OUTPUT));
12986			if (err < 0)
12987				return err;
12988		}
12989	}
12990	return 0;
12991}
12992
12993static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
12994{
12995	int err;
12996	hda_nid_t nid;
12997
12998	if (!pin)
12999		return 0;
13000
13001	if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13002		nid = 0x03;
13003		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13004				  "Headphone Playback Switch",
13005				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13006		if (err < 0)
13007			return err;
13008		spec->multiout.hp_nid = nid;
13009	}
13010	return 0;
13011}
13012
13013/* create playback/capture controls for input pins */
13014static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13015						const struct auto_pin_cfg *cfg)
13016{
13017	struct hda_input_mux *imux = &spec->private_imux;
13018	int i, err, idx, idx1;
13019
13020	for (i = 0; i < AUTO_PIN_LAST; i++) {
13021		switch (cfg->input_pins[i]) {
13022		case 0x0c:
13023			idx1 = 1;
13024			idx = 2;	/* Line In */
13025			break;
13026		case 0x0f:
13027			idx1 = 2;
13028			idx = 2;	/* Line In */
13029			break;
13030		case 0x0d:
13031			idx1 = 0;
13032			idx = 1;	/* Mic In */
13033			break;
13034		case 0x10:
13035			idx1 = 3;
13036			idx = 1;	/* Mic In */
13037			break;
13038		case 0x11:
13039			idx1 = 4;
13040			idx = 0;	/* CD */
13041			break;
13042		default:
13043			continue;
13044		}
13045
13046		err = new_analog_input(spec, cfg->input_pins[i],
13047				       auto_pin_cfg_labels[i], idx, 0x15);
13048		if (err < 0)
13049			return err;
13050
13051		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
13052		imux->items[imux->num_items].index = idx1;
13053		imux->num_items++;
13054	}
13055	return 0;
13056}
13057
13058static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13059					      hda_nid_t nid,
13060					      int pin_type, int dac_idx)
13061{
13062	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13063			    pin_type);
13064	snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13065			    AMP_OUT_UNMUTE);
13066}
13067
13068static void alc861_auto_init_multi_out(struct hda_codec *codec)
13069{
13070	struct alc_spec *spec = codec->spec;
13071	int i;
13072
13073	alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
13074	for (i = 0; i < spec->autocfg.line_outs; i++) {
13075		hda_nid_t nid = spec->autocfg.line_out_pins[i];
13076		int pin_type = get_pin_type(spec->autocfg.line_out_type);
13077		if (nid)
13078			alc861_auto_set_output_and_unmute(codec, nid, pin_type,
13079							  spec->multiout.dac_nids[i]);
13080	}
13081}
13082
13083static void alc861_auto_init_hp_out(struct hda_codec *codec)
13084{
13085	struct alc_spec *spec = codec->spec;
13086	hda_nid_t pin;
13087
13088	pin = spec->autocfg.hp_pins[0];
13089	if (pin) /* connect to front */
13090		alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13091						  spec->multiout.dac_nids[0]);
13092	pin = spec->autocfg.speaker_pins[0];
13093	if (pin)
13094		alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13095}
13096
13097static void alc861_auto_init_analog_input(struct hda_codec *codec)
13098{
13099	struct alc_spec *spec = codec->spec;
13100	int i;
13101
13102	for (i = 0; i < AUTO_PIN_LAST; i++) {
13103		hda_nid_t nid = spec->autocfg.input_pins[i];
13104		if (nid >= 0x0c && nid <= 0x11) {
13105			snd_hda_codec_write(codec, nid, 0,
13106					    AC_VERB_SET_PIN_WIDGET_CONTROL,
13107					    i <= AUTO_PIN_FRONT_MIC ?
13108					    PIN_VREF80 : PIN_IN);
13109		}
13110	}
13111}
13112
13113/* parse the BIOS configuration and set up the alc_spec */
13114/* return 1 if successful, 0 if the proper config is not found,
13115 * or a negative error code
13116 */
13117static int alc861_parse_auto_config(struct hda_codec *codec)
13118{
13119	struct alc_spec *spec = codec->spec;
13120	int err;
13121	static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13122
13123	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13124					   alc861_ignore);
13125	if (err < 0)
13126		return err;
13127	if (!spec->autocfg.line_outs)
13128		return 0; /* can't find valid BIOS pin config */
13129
13130	err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13131	if (err < 0)
13132		return err;
13133	err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13134	if (err < 0)
13135		return err;
13136	err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13137	if (err < 0)
13138		return err;
13139	err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13140	if (err < 0)
13141		return err;
13142
13143	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13144
13145	if (spec->autocfg.dig_out_pin)
13146		spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13147
13148	if (spec->kctls.list)
13149		add_mixer(spec, spec->kctls.list);
13150
13151	add_verb(spec, alc861_auto_init_verbs);
13152
13153	spec->num_mux_defs = 1;
13154	spec->input_mux = &spec->private_imux;
13155
13156	spec->adc_nids = alc861_adc_nids;
13157	spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
13158	set_capture_mixer(spec);
13159
13160	store_pin_configs(codec);
13161	return 1;
13162}
13163
13164/* additional initialization for auto-configuration model */
13165static void alc861_auto_init(struct hda_codec *codec)
13166{
13167	struct alc_spec *spec = codec->spec;
13168	alc861_auto_init_multi_out(codec);
13169	alc861_auto_init_hp_out(codec);
13170	alc861_auto_init_analog_input(codec);
13171	if (spec->unsol_event)
13172		alc_inithook(codec);
13173}
13174
13175#ifdef CONFIG_SND_HDA_POWER_SAVE
13176static struct hda_amp_list alc861_loopbacks[] = {
13177	{ 0x15, HDA_INPUT, 0 },
13178	{ 0x15, HDA_INPUT, 1 },
13179	{ 0x15, HDA_INPUT, 2 },
13180	{ 0x15, HDA_INPUT, 3 },
13181	{ } /* end */
13182};
13183#endif
13184
13185
13186/*
13187 * configuration and preset
13188 */
13189static const char *alc861_models[ALC861_MODEL_LAST] = {
13190	[ALC861_3ST]		= "3stack",
13191	[ALC660_3ST]		= "3stack-660",
13192	[ALC861_3ST_DIG]	= "3stack-dig",
13193	[ALC861_6ST_DIG]	= "6stack-dig",
13194	[ALC861_UNIWILL_M31]	= "uniwill-m31",
13195	[ALC861_TOSHIBA]	= "toshiba",
13196	[ALC861_ASUS]		= "asus",
13197	[ALC861_ASUS_LAPTOP]	= "asus-laptop",
13198	[ALC861_AUTO]		= "auto",
13199};
13200
13201static struct snd_pci_quirk alc861_cfg_tbl[] = {
13202	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
13203	SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13204	SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13205	SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
13206	SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
13207	SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
13208	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
13209	/* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
13210	 *        Any other models that need this preset?
13211	 */
13212	/* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
13213	SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
13214	SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
13215	SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
13216	SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
13217	SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
13218	/* FIXME: the below seems conflict */
13219	/* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
13220	SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
13221	SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
13222	{}
13223};
13224
13225static struct alc_config_preset alc861_presets[] = {
13226	[ALC861_3ST] = {
13227		.mixers = { alc861_3ST_mixer },
13228		.init_verbs = { alc861_threestack_init_verbs },
13229		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13230		.dac_nids = alc861_dac_nids,
13231		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13232		.channel_mode = alc861_threestack_modes,
13233		.need_dac_fix = 1,
13234		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13235		.adc_nids = alc861_adc_nids,
13236		.input_mux = &alc861_capture_source,
13237	},
13238	[ALC861_3ST_DIG] = {
13239		.mixers = { alc861_base_mixer },
13240		.init_verbs = { alc861_threestack_init_verbs },
13241		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13242		.dac_nids = alc861_dac_nids,
13243		.dig_out_nid = ALC861_DIGOUT_NID,
13244		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13245		.channel_mode = alc861_threestack_modes,
13246		.need_dac_fix = 1,
13247		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13248		.adc_nids = alc861_adc_nids,
13249		.input_mux = &alc861_capture_source,
13250	},
13251	[ALC861_6ST_DIG] = {
13252		.mixers = { alc861_base_mixer },
13253		.init_verbs = { alc861_base_init_verbs },
13254		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13255		.dac_nids = alc861_dac_nids,
13256		.dig_out_nid = ALC861_DIGOUT_NID,
13257		.num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
13258		.channel_mode = alc861_8ch_modes,
13259		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13260		.adc_nids = alc861_adc_nids,
13261		.input_mux = &alc861_capture_source,
13262	},
13263	[ALC660_3ST] = {
13264		.mixers = { alc861_3ST_mixer },
13265		.init_verbs = { alc861_threestack_init_verbs },
13266		.num_dacs = ARRAY_SIZE(alc660_dac_nids),
13267		.dac_nids = alc660_dac_nids,
13268		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13269		.channel_mode = alc861_threestack_modes,
13270		.need_dac_fix = 1,
13271		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13272		.adc_nids = alc861_adc_nids,
13273		.input_mux = &alc861_capture_source,
13274	},
13275	[ALC861_UNIWILL_M31] = {
13276		.mixers = { alc861_uniwill_m31_mixer },
13277		.init_verbs = { alc861_uniwill_m31_init_verbs },
13278		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13279		.dac_nids = alc861_dac_nids,
13280		.dig_out_nid = ALC861_DIGOUT_NID,
13281		.num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
13282		.channel_mode = alc861_uniwill_m31_modes,
13283		.need_dac_fix = 1,
13284		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13285		.adc_nids = alc861_adc_nids,
13286		.input_mux = &alc861_capture_source,
13287	},
13288	[ALC861_TOSHIBA] = {
13289		.mixers = { alc861_toshiba_mixer },
13290		.init_verbs = { alc861_base_init_verbs,
13291				alc861_toshiba_init_verbs },
13292		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13293		.dac_nids = alc861_dac_nids,
13294		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13295		.channel_mode = alc883_3ST_2ch_modes,
13296		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13297		.adc_nids = alc861_adc_nids,
13298		.input_mux = &alc861_capture_source,
13299		.unsol_event = alc861_toshiba_unsol_event,
13300		.init_hook = alc861_toshiba_automute,
13301	},
13302	[ALC861_ASUS] = {
13303		.mixers = { alc861_asus_mixer },
13304		.init_verbs = { alc861_asus_init_verbs },
13305		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13306		.dac_nids = alc861_dac_nids,
13307		.dig_out_nid = ALC861_DIGOUT_NID,
13308		.num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
13309		.channel_mode = alc861_asus_modes,
13310		.need_dac_fix = 1,
13311		.hp_nid = 0x06,
13312		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13313		.adc_nids = alc861_adc_nids,
13314		.input_mux = &alc861_capture_source,
13315	},
13316	[ALC861_ASUS_LAPTOP] = {
13317		.mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
13318		.init_verbs = { alc861_asus_init_verbs,
13319				alc861_asus_laptop_init_verbs },
13320		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13321		.dac_nids = alc861_dac_nids,
13322		.dig_out_nid = ALC861_DIGOUT_NID,
13323		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13324		.channel_mode = alc883_3ST_2ch_modes,
13325		.need_dac_fix = 1,
13326		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13327		.adc_nids = alc861_adc_nids,
13328		.input_mux = &alc861_capture_source,
13329	},
13330};
13331
13332
13333static int patch_alc861(struct hda_codec *codec)
13334{
13335	struct alc_spec *spec;
13336	int board_config;
13337	int err;
13338
13339	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13340	if (spec == NULL)
13341		return -ENOMEM;
13342
13343	codec->spec = spec;
13344
13345        board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
13346						  alc861_models,
13347						  alc861_cfg_tbl);
13348
13349	if (board_config < 0) {
13350		printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
13351		       "trying auto-probe from BIOS...\n");
13352		board_config = ALC861_AUTO;
13353	}
13354
13355	if (board_config == ALC861_AUTO) {
13356		/* automatic parse from the BIOS config */
13357		err = alc861_parse_auto_config(codec);
13358		if (err < 0) {
13359			alc_free(codec);
13360			return err;
13361		} else if (!err) {
13362			printk(KERN_INFO
13363			       "hda_codec: Cannot set up configuration "
13364			       "from BIOS.  Using base mode...\n");
13365		   board_config = ALC861_3ST_DIG;
13366		}
13367	}
13368
13369	if (board_config != ALC861_AUTO)
13370		setup_preset(spec, &alc861_presets[board_config]);
13371
13372	spec->stream_name_analog = "ALC861 Analog";
13373	spec->stream_analog_playback = &alc861_pcm_analog_playback;
13374	spec->stream_analog_capture = &alc861_pcm_analog_capture;
13375
13376	spec->stream_name_digital = "ALC861 Digital";
13377	spec->stream_digital_playback = &alc861_pcm_digital_playback;
13378	spec->stream_digital_capture = &alc861_pcm_digital_capture;
13379
13380	spec->vmaster_nid = 0x03;
13381
13382	codec->patch_ops = alc_patch_ops;
13383	if (board_config == ALC861_AUTO)
13384		spec->init_hook = alc861_auto_init;
13385#ifdef CONFIG_SND_HDA_POWER_SAVE
13386	if (!spec->loopback.amplist)
13387		spec->loopback.amplist = alc861_loopbacks;
13388#endif
13389
13390	return 0;
13391}
13392
13393/*
13394 * ALC861-VD support
13395 *
13396 * Based on ALC882
13397 *
13398 * In addition, an independent DAC
13399 */
13400#define ALC861VD_DIGOUT_NID	0x06
13401
13402static hda_nid_t alc861vd_dac_nids[4] = {
13403	/* front, surr, clfe, side surr */
13404	0x02, 0x03, 0x04, 0x05
13405};
13406
13407/* dac_nids for ALC660vd are in a different order - according to
13408 * Realtek's driver.
13409 * This should probably tesult in a different mixer for 6stack models
13410 * of ALC660vd codecs, but for now there is only 3stack mixer
13411 * - and it is the same as in 861vd.
13412 * adc_nids in ALC660vd are (is) the same as in 861vd
13413 */
13414static hda_nid_t alc660vd_dac_nids[3] = {
13415	/* front, rear, clfe, rear_surr */
13416	0x02, 0x04, 0x03
13417};
13418
13419static hda_nid_t alc861vd_adc_nids[1] = {
13420	/* ADC0 */
13421	0x09,
13422};
13423
13424static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
13425
13426/* input MUX */
13427/* FIXME: should be a matrix-type input source selection */
13428static struct hda_input_mux alc861vd_capture_source = {
13429	.num_items = 4,
13430	.items = {
13431		{ "Mic", 0x0 },
13432		{ "Front Mic", 0x1 },
13433		{ "Line", 0x2 },
13434		{ "CD", 0x4 },
13435	},
13436};
13437
13438static struct hda_input_mux alc861vd_dallas_capture_source = {
13439	.num_items = 2,
13440	.items = {
13441		{ "Ext Mic", 0x0 },
13442		{ "Int Mic", 0x1 },
13443	},
13444};
13445
13446static struct hda_input_mux alc861vd_hp_capture_source = {
13447	.num_items = 2,
13448	.items = {
13449		{ "Front Mic", 0x0 },
13450		{ "ATAPI Mic", 0x1 },
13451	},
13452};
13453
13454/*
13455 * 2ch mode
13456 */
13457static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
13458	{ 2, NULL }
13459};
13460
13461/*
13462 * 6ch mode
13463 */
13464static struct hda_verb alc861vd_6stack_ch6_init[] = {
13465	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13466	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13467	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13468	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13469	{ } /* end */
13470};
13471
13472/*
13473 * 8ch mode
13474 */
13475static struct hda_verb alc861vd_6stack_ch8_init[] = {
13476	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13477	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13478	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13479	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13480	{ } /* end */
13481};
13482
13483static struct hda_channel_mode alc861vd_6stack_modes[2] = {
13484	{ 6, alc861vd_6stack_ch6_init },
13485	{ 8, alc861vd_6stack_ch8_init },
13486};
13487
13488static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
13489	{
13490		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13491		.name = "Channel Mode",
13492		.info = alc_ch_mode_info,
13493		.get = alc_ch_mode_get,
13494		.put = alc_ch_mode_put,
13495	},
13496	{ } /* end */
13497};
13498
13499/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
13500 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
13501 */
13502static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
13503	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13504	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13505
13506	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13507	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
13508
13509	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
13510				HDA_OUTPUT),
13511	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
13512				HDA_OUTPUT),
13513	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13514	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
13515
13516	HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
13517	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
13518
13519	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13520
13521	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13522	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13523	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13524
13525	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13526	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13527	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13528
13529	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13530	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13531
13532	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13533	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13534
13535	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13536	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13537
13538	{ } /* end */
13539};
13540
13541static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
13542	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13543	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13544
13545	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13546
13547	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13548	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13549	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13550
13551	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13552	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13553	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13554
13555	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13556	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13557
13558	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13559	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13560
13561	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13562	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13563
13564	{ } /* end */
13565};
13566
13567static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
13568	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13569	/*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
13570	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13571
13572	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13573
13574	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13575	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13576	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13577
13578	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13579	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13580	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13581
13582	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13583	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13584
13585	{ } /* end */
13586};
13587
13588/* Pin assignment: Speaker=0x14, HP = 0x15,
13589 *                 Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
13590 */
13591static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
13592	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13593	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
13594	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13595	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13596	HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
13597	HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13598	HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13599	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
13600	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13601	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13602	HDA_CODEC_VOLUME("PC Beep Volume", 0x0b, 0x05, HDA_INPUT),
13603	HDA_CODEC_MUTE("PC Beep Switch", 0x0b, 0x05, HDA_INPUT),
13604	{ } /* end */
13605};
13606
13607/* Pin assignment: Speaker=0x14, Line-out = 0x15,
13608 *                 Front Mic=0x18, ATAPI Mic = 0x19,
13609 */
13610static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
13611	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13612	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13613	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13614	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13615	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13616	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13617	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13618	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13619
13620	{ } /* end */
13621};
13622
13623/*
13624 * generic initialization of ADC, input mixers and output mixers
13625 */
13626static struct hda_verb alc861vd_volume_init_verbs[] = {
13627	/*
13628	 * Unmute ADC0 and set the default input to mic-in
13629	 */
13630	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13631	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13632
13633	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
13634	 * the analog-loopback mixer widget
13635	 */
13636	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13637	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13638	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13639	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13640	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13641	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13642
13643	/* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
13644	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13645	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13646	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13647	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
13648
13649	/*
13650	 * Set up output mixers (0x02 - 0x05)
13651	 */
13652	/* set vol=0 to output mixers */
13653	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13654	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13655	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13656	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13657
13658	/* set up input amps for analog loopback */
13659	/* Amp Indices: DAC = 0, mixer = 1 */
13660	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13661	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13662	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13663	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13664	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13665	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13666	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13667	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13668
13669	{ }
13670};
13671
13672/*
13673 * 3-stack pin configuration:
13674 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
13675 */
13676static struct hda_verb alc861vd_3stack_init_verbs[] = {
13677	/*
13678	 * Set pin mode and muting
13679	 */
13680	/* set front pin widgets 0x14 for output */
13681	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13682	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13683	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13684
13685	/* Mic (rear) pin: input vref at 80% */
13686	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13687	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13688	/* Front Mic pin: input vref at 80% */
13689	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13690	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13691	/* Line In pin: input */
13692	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13693	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13694	/* Line-2 In: Headphone output (output 0 - 0x0c) */
13695	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13696	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13697	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13698	/* CD pin widget for input */
13699	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13700
13701	{ }
13702};
13703
13704/*
13705 * 6-stack pin configuration:
13706 */
13707static struct hda_verb alc861vd_6stack_init_verbs[] = {
13708	/*
13709	 * Set pin mode and muting
13710	 */
13711	/* set front pin widgets 0x14 for output */
13712	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13713	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13714	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13715
13716	/* Rear Pin: output 1 (0x0d) */
13717	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13718	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13719	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13720	/* CLFE Pin: output 2 (0x0e) */
13721	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13722	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13723	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
13724	/* Side Pin: output 3 (0x0f) */
13725	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13726	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13727	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
13728
13729	/* Mic (rear) pin: input vref at 80% */
13730	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13731	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13732	/* Front Mic pin: input vref at 80% */
13733	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13734	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13735	/* Line In pin: input */
13736	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13737	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13738	/* Line-2 In: Headphone output (output 0 - 0x0c) */
13739	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13740	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13741	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13742	/* CD pin widget for input */
13743	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13744
13745	{ }
13746};
13747
13748static struct hda_verb alc861vd_eapd_verbs[] = {
13749	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13750	{ }
13751};
13752
13753static struct hda_verb alc660vd_eapd_verbs[] = {
13754	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13755	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13756	{ }
13757};
13758
13759static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
13760	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13761	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13762	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
13763	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13764	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13765	{}
13766};
13767
13768/* toggle speaker-output according to the hp-jack state */
13769static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
13770{
13771	unsigned int present;
13772	unsigned char bits;
13773
13774	present = snd_hda_codec_read(codec, 0x1b, 0,
13775				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13776	bits = present ? HDA_AMP_MUTE : 0;
13777	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13778				 HDA_AMP_MUTE, bits);
13779}
13780
13781static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
13782{
13783	unsigned int present;
13784	unsigned char bits;
13785
13786	present = snd_hda_codec_read(codec, 0x18, 0,
13787				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13788	bits = present ? HDA_AMP_MUTE : 0;
13789	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
13790				 HDA_AMP_MUTE, bits);
13791}
13792
13793static void alc861vd_lenovo_automute(struct hda_codec *codec)
13794{
13795	alc861vd_lenovo_hp_automute(codec);
13796	alc861vd_lenovo_mic_automute(codec);
13797}
13798
13799static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
13800					unsigned int res)
13801{
13802	switch (res >> 26) {
13803	case ALC880_HP_EVENT:
13804		alc861vd_lenovo_hp_automute(codec);
13805		break;
13806	case ALC880_MIC_EVENT:
13807		alc861vd_lenovo_mic_automute(codec);
13808		break;
13809	}
13810}
13811
13812static struct hda_verb alc861vd_dallas_verbs[] = {
13813	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13814	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13815	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13816	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13817
13818	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13819	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13820	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13821	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13822	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13823	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13824	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13825	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13826
13827	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13828	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13829	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13830	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13831	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13832	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13833	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13834	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13835
13836	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
13837	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13838	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
13839	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13840	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13841	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13842	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13843	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13844
13845	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13846	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13847	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13848	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13849
13850	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13851	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13852	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13853
13854	{ } /* end */
13855};
13856
13857/* toggle speaker-output according to the hp-jack state */
13858static void alc861vd_dallas_automute(struct hda_codec *codec)
13859{
13860	unsigned int present;
13861
13862	present = snd_hda_codec_read(codec, 0x15, 0,
13863				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13864	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13865				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13866}
13867
13868static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
13869{
13870	if ((res >> 26) == ALC880_HP_EVENT)
13871		alc861vd_dallas_automute(codec);
13872}
13873
13874#ifdef CONFIG_SND_HDA_POWER_SAVE
13875#define alc861vd_loopbacks	alc880_loopbacks
13876#endif
13877
13878/* pcm configuration: identiacal with ALC880 */
13879#define alc861vd_pcm_analog_playback	alc880_pcm_analog_playback
13880#define alc861vd_pcm_analog_capture	alc880_pcm_analog_capture
13881#define alc861vd_pcm_digital_playback	alc880_pcm_digital_playback
13882#define alc861vd_pcm_digital_capture	alc880_pcm_digital_capture
13883
13884/*
13885 * configuration and preset
13886 */
13887static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
13888	[ALC660VD_3ST]		= "3stack-660",
13889	[ALC660VD_3ST_DIG]	= "3stack-660-digout",
13890	[ALC660VD_ASUS_V1S]	= "asus-v1s",
13891	[ALC861VD_3ST]		= "3stack",
13892	[ALC861VD_3ST_DIG]	= "3stack-digout",
13893	[ALC861VD_6ST_DIG]	= "6stack-digout",
13894	[ALC861VD_LENOVO]	= "lenovo",
13895	[ALC861VD_DALLAS]	= "dallas",
13896	[ALC861VD_HP]		= "hp",
13897	[ALC861VD_AUTO]		= "auto",
13898};
13899
13900static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
13901	SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
13902	SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
13903	SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
13904	SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
13905	SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
13906	SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
13907	SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
13908	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
13909	/*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
13910	SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
13911	SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
13912	SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
13913	SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
13914	SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
13915	SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
13916	SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO),
13917	SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
13918	{}
13919};
13920
13921static struct alc_config_preset alc861vd_presets[] = {
13922	[ALC660VD_3ST] = {
13923		.mixers = { alc861vd_3st_mixer },
13924		.init_verbs = { alc861vd_volume_init_verbs,
13925				 alc861vd_3stack_init_verbs },
13926		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
13927		.dac_nids = alc660vd_dac_nids,
13928		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13929		.channel_mode = alc861vd_3stack_2ch_modes,
13930		.input_mux = &alc861vd_capture_source,
13931	},
13932	[ALC660VD_3ST_DIG] = {
13933		.mixers = { alc861vd_3st_mixer },
13934		.init_verbs = { alc861vd_volume_init_verbs,
13935				 alc861vd_3stack_init_verbs },
13936		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
13937		.dac_nids = alc660vd_dac_nids,
13938		.dig_out_nid = ALC861VD_DIGOUT_NID,
13939		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13940		.channel_mode = alc861vd_3stack_2ch_modes,
13941		.input_mux = &alc861vd_capture_source,
13942	},
13943	[ALC861VD_3ST] = {
13944		.mixers = { alc861vd_3st_mixer },
13945		.init_verbs = { alc861vd_volume_init_verbs,
13946				 alc861vd_3stack_init_verbs },
13947		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
13948		.dac_nids = alc861vd_dac_nids,
13949		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13950		.channel_mode = alc861vd_3stack_2ch_modes,
13951		.input_mux = &alc861vd_capture_source,
13952	},
13953	[ALC861VD_3ST_DIG] = {
13954		.mixers = { alc861vd_3st_mixer },
13955		.init_verbs = { alc861vd_volume_init_verbs,
13956		 		 alc861vd_3stack_init_verbs },
13957		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
13958		.dac_nids = alc861vd_dac_nids,
13959		.dig_out_nid = ALC861VD_DIGOUT_NID,
13960		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13961		.channel_mode = alc861vd_3stack_2ch_modes,
13962		.input_mux = &alc861vd_capture_source,
13963	},
13964	[ALC861VD_6ST_DIG] = {
13965		.mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
13966		.init_verbs = { alc861vd_volume_init_verbs,
13967				alc861vd_6stack_init_verbs },
13968		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
13969		.dac_nids = alc861vd_dac_nids,
13970		.dig_out_nid = ALC861VD_DIGOUT_NID,
13971		.num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
13972		.channel_mode = alc861vd_6stack_modes,
13973		.input_mux = &alc861vd_capture_source,
13974	},
13975	[ALC861VD_LENOVO] = {
13976		.mixers = { alc861vd_lenovo_mixer },
13977		.init_verbs = { alc861vd_volume_init_verbs,
13978				alc861vd_3stack_init_verbs,
13979				alc861vd_eapd_verbs,
13980				alc861vd_lenovo_unsol_verbs },
13981		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
13982		.dac_nids = alc660vd_dac_nids,
13983		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13984		.channel_mode = alc861vd_3stack_2ch_modes,
13985		.input_mux = &alc861vd_capture_source,
13986		.unsol_event = alc861vd_lenovo_unsol_event,
13987		.init_hook = alc861vd_lenovo_automute,
13988	},
13989	[ALC861VD_DALLAS] = {
13990		.mixers = { alc861vd_dallas_mixer },
13991		.init_verbs = { alc861vd_dallas_verbs },
13992		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
13993		.dac_nids = alc861vd_dac_nids,
13994		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13995		.channel_mode = alc861vd_3stack_2ch_modes,
13996		.input_mux = &alc861vd_dallas_capture_source,
13997		.unsol_event = alc861vd_dallas_unsol_event,
13998		.init_hook = alc861vd_dallas_automute,
13999	},
14000	[ALC861VD_HP] = {
14001		.mixers = { alc861vd_hp_mixer },
14002		.init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14003		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14004		.dac_nids = alc861vd_dac_nids,
14005		.dig_out_nid = ALC861VD_DIGOUT_NID,
14006		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14007		.channel_mode = alc861vd_3stack_2ch_modes,
14008		.input_mux = &alc861vd_hp_capture_source,
14009		.unsol_event = alc861vd_dallas_unsol_event,
14010		.init_hook = alc861vd_dallas_automute,
14011	},
14012	[ALC660VD_ASUS_V1S] = {
14013		.mixers = { alc861vd_lenovo_mixer },
14014		.init_verbs = { alc861vd_volume_init_verbs,
14015				alc861vd_3stack_init_verbs,
14016				alc861vd_eapd_verbs,
14017				alc861vd_lenovo_unsol_verbs },
14018		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14019		.dac_nids = alc660vd_dac_nids,
14020		.dig_out_nid = ALC861VD_DIGOUT_NID,
14021		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14022		.channel_mode = alc861vd_3stack_2ch_modes,
14023		.input_mux = &alc861vd_capture_source,
14024		.unsol_event = alc861vd_lenovo_unsol_event,
14025		.init_hook = alc861vd_lenovo_automute,
14026	},
14027};
14028
14029/*
14030 * BIOS auto configuration
14031 */
14032static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14033				hda_nid_t nid, int pin_type, int dac_idx)
14034{
14035	alc_set_pin_output(codec, nid, pin_type);
14036}
14037
14038static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14039{
14040	struct alc_spec *spec = codec->spec;
14041	int i;
14042
14043	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
14044	for (i = 0; i <= HDA_SIDE; i++) {
14045		hda_nid_t nid = spec->autocfg.line_out_pins[i];
14046		int pin_type = get_pin_type(spec->autocfg.line_out_type);
14047		if (nid)
14048			alc861vd_auto_set_output_and_unmute(codec, nid,
14049							    pin_type, i);
14050	}
14051}
14052
14053
14054static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14055{
14056	struct alc_spec *spec = codec->spec;
14057	hda_nid_t pin;
14058
14059	pin = spec->autocfg.hp_pins[0];
14060	if (pin) /* connect to front and  use dac 0 */
14061		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
14062	pin = spec->autocfg.speaker_pins[0];
14063	if (pin)
14064		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14065}
14066
14067#define alc861vd_is_input_pin(nid)	alc880_is_input_pin(nid)
14068#define ALC861VD_PIN_CD_NID		ALC880_PIN_CD_NID
14069
14070static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14071{
14072	struct alc_spec *spec = codec->spec;
14073	int i;
14074
14075	for (i = 0; i < AUTO_PIN_LAST; i++) {
14076		hda_nid_t nid = spec->autocfg.input_pins[i];
14077		if (alc861vd_is_input_pin(nid)) {
14078			snd_hda_codec_write(codec, nid, 0,
14079					AC_VERB_SET_PIN_WIDGET_CONTROL,
14080					i <= AUTO_PIN_FRONT_MIC ?
14081							PIN_VREF80 : PIN_IN);
14082			if (nid != ALC861VD_PIN_CD_NID)
14083				snd_hda_codec_write(codec, nid, 0,
14084						AC_VERB_SET_AMP_GAIN_MUTE,
14085						AMP_OUT_MUTE);
14086		}
14087	}
14088}
14089
14090#define alc861vd_auto_init_input_src	alc882_auto_init_input_src
14091
14092#define alc861vd_idx_to_mixer_vol(nid)		((nid) + 0x02)
14093#define alc861vd_idx_to_mixer_switch(nid)	((nid) + 0x0c)
14094
14095/* add playback controls from the parsed DAC table */
14096/* Based on ALC880 version. But ALC861VD has separate,
14097 * different NIDs for mute/unmute switch and volume control */
14098static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14099					     const struct auto_pin_cfg *cfg)
14100{
14101	char name[32];
14102	static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14103	hda_nid_t nid_v, nid_s;
14104	int i, err;
14105
14106	for (i = 0; i < cfg->line_outs; i++) {
14107		if (!spec->multiout.dac_nids[i])
14108			continue;
14109		nid_v = alc861vd_idx_to_mixer_vol(
14110				alc880_dac_to_idx(
14111					spec->multiout.dac_nids[i]));
14112		nid_s = alc861vd_idx_to_mixer_switch(
14113				alc880_dac_to_idx(
14114					spec->multiout.dac_nids[i]));
14115
14116		if (i == 2) {
14117			/* Center/LFE */
14118			err = add_control(spec, ALC_CTL_WIDGET_VOL,
14119					  "Center Playback Volume",
14120					  HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14121							      HDA_OUTPUT));
14122			if (err < 0)
14123				return err;
14124			err = add_control(spec, ALC_CTL_WIDGET_VOL,
14125					  "LFE Playback Volume",
14126					  HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14127							      HDA_OUTPUT));
14128			if (err < 0)
14129				return err;
14130			err = add_control(spec, ALC_CTL_BIND_MUTE,
14131					  "Center Playback Switch",
14132					  HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14133							      HDA_INPUT));
14134			if (err < 0)
14135				return err;
14136			err = add_control(spec, ALC_CTL_BIND_MUTE,
14137					  "LFE Playback Switch",
14138					  HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14139							      HDA_INPUT));
14140			if (err < 0)
14141				return err;
14142		} else {
14143			sprintf(name, "%s Playback Volume", chname[i]);
14144			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14145					  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14146							      HDA_OUTPUT));
14147			if (err < 0)
14148				return err;
14149			sprintf(name, "%s Playback Switch", chname[i]);
14150			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14151					  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
14152							      HDA_INPUT));
14153			if (err < 0)
14154				return err;
14155		}
14156	}
14157	return 0;
14158}
14159
14160/* add playback controls for speaker and HP outputs */
14161/* Based on ALC880 version. But ALC861VD has separate,
14162 * different NIDs for mute/unmute switch and volume control */
14163static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
14164					hda_nid_t pin, const char *pfx)
14165{
14166	hda_nid_t nid_v, nid_s;
14167	int err;
14168	char name[32];
14169
14170	if (!pin)
14171		return 0;
14172
14173	if (alc880_is_fixed_pin(pin)) {
14174		nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14175		/* specify the DAC as the extra output */
14176		if (!spec->multiout.hp_nid)
14177			spec->multiout.hp_nid = nid_v;
14178		else
14179			spec->multiout.extra_out_nid[0] = nid_v;
14180		/* control HP volume/switch on the output mixer amp */
14181		nid_v = alc861vd_idx_to_mixer_vol(
14182				alc880_fixed_pin_idx(pin));
14183		nid_s = alc861vd_idx_to_mixer_switch(
14184				alc880_fixed_pin_idx(pin));
14185
14186		sprintf(name, "%s Playback Volume", pfx);
14187		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14188				  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
14189		if (err < 0)
14190			return err;
14191		sprintf(name, "%s Playback Switch", pfx);
14192		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14193				  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
14194		if (err < 0)
14195			return err;
14196	} else if (alc880_is_multi_pin(pin)) {
14197		/* set manual connection */
14198		/* we have only a switch on HP-out PIN */
14199		sprintf(name, "%s Playback Switch", pfx);
14200		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14201				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
14202		if (err < 0)
14203			return err;
14204	}
14205	return 0;
14206}
14207
14208/* parse the BIOS configuration and set up the alc_spec
14209 * return 1 if successful, 0 if the proper config is not found,
14210 * or a negative error code
14211 * Based on ALC880 version - had to change it to override
14212 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
14213static int alc861vd_parse_auto_config(struct hda_codec *codec)
14214{
14215	struct alc_spec *spec = codec->spec;
14216	int err;
14217	static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
14218
14219	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14220					   alc861vd_ignore);
14221	if (err < 0)
14222		return err;
14223	if (!spec->autocfg.line_outs)
14224		return 0; /* can't find valid BIOS pin config */
14225
14226	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
14227	if (err < 0)
14228		return err;
14229	err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
14230	if (err < 0)
14231		return err;
14232	err = alc861vd_auto_create_extra_out(spec,
14233					     spec->autocfg.speaker_pins[0],
14234					     "Speaker");
14235	if (err < 0)
14236		return err;
14237	err = alc861vd_auto_create_extra_out(spec,
14238					     spec->autocfg.hp_pins[0],
14239					     "Headphone");
14240	if (err < 0)
14241		return err;
14242	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
14243	if (err < 0)
14244		return err;
14245
14246	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14247
14248	if (spec->autocfg.dig_out_pin)
14249		spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
14250
14251	if (spec->kctls.list)
14252		add_mixer(spec, spec->kctls.list);
14253
14254	add_verb(spec, alc861vd_volume_init_verbs);
14255
14256	spec->num_mux_defs = 1;
14257	spec->input_mux = &spec->private_imux;
14258
14259	err = alc_auto_add_mic_boost(codec);
14260	if (err < 0)
14261		return err;
14262
14263	store_pin_configs(codec);
14264	return 1;
14265}
14266
14267/* additional initialization for auto-configuration model */
14268static void alc861vd_auto_init(struct hda_codec *codec)
14269{
14270	struct alc_spec *spec = codec->spec;
14271	alc861vd_auto_init_multi_out(codec);
14272	alc861vd_auto_init_hp_out(codec);
14273	alc861vd_auto_init_analog_input(codec);
14274	alc861vd_auto_init_input_src(codec);
14275	if (spec->unsol_event)
14276		alc_inithook(codec);
14277}
14278
14279static int patch_alc861vd(struct hda_codec *codec)
14280{
14281	struct alc_spec *spec;
14282	int err, board_config;
14283
14284	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14285	if (spec == NULL)
14286		return -ENOMEM;
14287
14288	codec->spec = spec;
14289
14290	board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
14291						  alc861vd_models,
14292						  alc861vd_cfg_tbl);
14293
14294	if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
14295		printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
14296			"ALC861VD, trying auto-probe from BIOS...\n");
14297		board_config = ALC861VD_AUTO;
14298	}
14299
14300	if (board_config == ALC861VD_AUTO) {
14301		/* automatic parse from the BIOS config */
14302		err = alc861vd_parse_auto_config(codec);
14303		if (err < 0) {
14304			alc_free(codec);
14305			return err;
14306		} else if (!err) {
14307			printk(KERN_INFO
14308			       "hda_codec: Cannot set up configuration "
14309			       "from BIOS.  Using base mode...\n");
14310			board_config = ALC861VD_3ST;
14311		}
14312	}
14313
14314	if (board_config != ALC861VD_AUTO)
14315		setup_preset(spec, &alc861vd_presets[board_config]);
14316
14317	if (codec->vendor_id == 0x10ec0660) {
14318		spec->stream_name_analog = "ALC660-VD Analog";
14319		spec->stream_name_digital = "ALC660-VD Digital";
14320		/* always turn on EAPD */
14321		add_verb(spec, alc660vd_eapd_verbs);
14322	} else {
14323		spec->stream_name_analog = "ALC861VD Analog";
14324		spec->stream_name_digital = "ALC861VD Digital";
14325	}
14326
14327	spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
14328	spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
14329
14330	spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
14331	spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
14332
14333	spec->adc_nids = alc861vd_adc_nids;
14334	spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
14335	spec->capsrc_nids = alc861vd_capsrc_nids;
14336	spec->is_mix_capture = 1;
14337
14338	set_capture_mixer(spec);
14339
14340	spec->vmaster_nid = 0x02;
14341
14342	codec->patch_ops = alc_patch_ops;
14343
14344	if (board_config == ALC861VD_AUTO)
14345		spec->init_hook = alc861vd_auto_init;
14346#ifdef CONFIG_SND_HDA_POWER_SAVE
14347	if (!spec->loopback.amplist)
14348		spec->loopback.amplist = alc861vd_loopbacks;
14349#endif
14350
14351	return 0;
14352}
14353
14354/*
14355 * ALC662 support
14356 *
14357 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
14358 * configuration.  Each pin widget can choose any input DACs and a mixer.
14359 * Each ADC is connected from a mixer of all inputs.  This makes possible
14360 * 6-channel independent captures.
14361 *
14362 * In addition, an independent DAC for the multi-playback (not used in this
14363 * driver yet).
14364 */
14365#define ALC662_DIGOUT_NID	0x06
14366#define ALC662_DIGIN_NID	0x0a
14367
14368static hda_nid_t alc662_dac_nids[4] = {
14369	/* front, rear, clfe, rear_surr */
14370	0x02, 0x03, 0x04
14371};
14372
14373static hda_nid_t alc662_adc_nids[1] = {
14374	/* ADC1-2 */
14375	0x09,
14376};
14377
14378static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
14379
14380/* input MUX */
14381/* FIXME: should be a matrix-type input source selection */
14382static struct hda_input_mux alc662_capture_source = {
14383	.num_items = 4,
14384	.items = {
14385		{ "Mic", 0x0 },
14386		{ "Front Mic", 0x1 },
14387		{ "Line", 0x2 },
14388		{ "CD", 0x4 },
14389	},
14390};
14391
14392static struct hda_input_mux alc662_lenovo_101e_capture_source = {
14393	.num_items = 2,
14394	.items = {
14395		{ "Mic", 0x1 },
14396		{ "Line", 0x2 },
14397	},
14398};
14399
14400static struct hda_input_mux alc662_eeepc_capture_source = {
14401	.num_items = 2,
14402	.items = {
14403		{ "i-Mic", 0x1 },
14404		{ "e-Mic", 0x0 },
14405	},
14406};
14407
14408static struct hda_input_mux alc663_capture_source = {
14409	.num_items = 3,
14410	.items = {
14411		{ "Mic", 0x0 },
14412		{ "Front Mic", 0x1 },
14413		{ "Line", 0x2 },
14414	},
14415};
14416
14417static struct hda_input_mux alc663_m51va_capture_source = {
14418	.num_items = 2,
14419	.items = {
14420		{ "Ext-Mic", 0x0 },
14421		{ "D-Mic", 0x9 },
14422	},
14423};
14424
14425/*
14426 * 2ch mode
14427 */
14428static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
14429	{ 2, NULL }
14430};
14431
14432/*
14433 * 2ch mode
14434 */
14435static struct hda_verb alc662_3ST_ch2_init[] = {
14436	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
14437	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14438	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
14439	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14440	{ } /* end */
14441};
14442
14443/*
14444 * 6ch mode
14445 */
14446static struct hda_verb alc662_3ST_ch6_init[] = {
14447	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14448	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14449	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
14450	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14451	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14452	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
14453	{ } /* end */
14454};
14455
14456static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
14457	{ 2, alc662_3ST_ch2_init },
14458	{ 6, alc662_3ST_ch6_init },
14459};
14460
14461/*
14462 * 2ch mode
14463 */
14464static struct hda_verb alc662_sixstack_ch6_init[] = {
14465	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14466	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14467	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14468	{ } /* end */
14469};
14470
14471/*
14472 * 6ch mode
14473 */
14474static struct hda_verb alc662_sixstack_ch8_init[] = {
14475	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14476	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14477	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14478	{ } /* end */
14479};
14480
14481static struct hda_channel_mode alc662_5stack_modes[2] = {
14482	{ 2, alc662_sixstack_ch6_init },
14483	{ 6, alc662_sixstack_ch8_init },
14484};
14485
14486/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14487 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14488 */
14489
14490static struct snd_kcontrol_new alc662_base_mixer[] = {
14491	/* output mixer control */
14492	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
14493	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14494	HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
14495	HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14496	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14497	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14498	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14499	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14500	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14501
14502	/*Input mixer control */
14503	HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
14504	HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
14505	HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
14506	HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
14507	HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
14508	HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
14509	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
14510	HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
14511	{ } /* end */
14512};
14513
14514static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
14515	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14516	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14517	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14518	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14519	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14520	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14521	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14522	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14523	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14524	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14525	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14526	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14527	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14528	{ } /* end */
14529};
14530
14531static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
14532	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14533	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14534	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14535	HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14536	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14537	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14538	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14539	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14540	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14541	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14542	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14543	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14544	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14545	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14546	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14547	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14548	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14549	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14550	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14551	{ } /* end */
14552};
14553
14554static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
14555	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14556	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
14557	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14558	HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
14559	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14560	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14561	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14562	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14563	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14564	{ } /* end */
14565};
14566
14567static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
14568	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14569
14570	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14571	HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14572
14573	HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
14574	HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14575	HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14576
14577	HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
14578	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14579	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14580	{ } /* end */
14581};
14582
14583static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
14584	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14585	HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14586	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14587	HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
14588	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14589	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14590	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
14591	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
14592	HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14593	HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
14594	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14595	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14596	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14597	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14598	{ } /* end */
14599};
14600
14601static struct hda_bind_ctls alc663_asus_bind_master_vol = {
14602	.ops = &snd_hda_bind_vol,
14603	.values = {
14604		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14605		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
14606		0
14607	},
14608};
14609
14610static struct hda_bind_ctls alc663_asus_one_bind_switch = {
14611	.ops = &snd_hda_bind_sw,
14612	.values = {
14613		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14614		HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14615		0
14616	},
14617};
14618
14619static struct snd_kcontrol_new alc663_m51va_mixer[] = {
14620	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14621	HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
14622	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14623	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14624	{ } /* end */
14625};
14626
14627static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
14628	.ops = &snd_hda_bind_sw,
14629	.values = {
14630		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14631		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14632		HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14633		0
14634	},
14635};
14636
14637static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
14638	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14639	HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
14640	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14641	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14642	HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14643	HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14644
14645	{ } /* end */
14646};
14647
14648static struct hda_bind_ctls alc663_asus_four_bind_switch = {
14649	.ops = &snd_hda_bind_sw,
14650	.values = {
14651		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14652		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14653		HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
14654		0
14655	},
14656};
14657
14658static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
14659	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14660	HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
14661	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14662	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14663	HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14664	HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14665	{ } /* end */
14666};
14667
14668static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
14669	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14670	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14671	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14672	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14673	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14674	HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14675	HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14676	{ } /* end */
14677};
14678
14679static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
14680	.ops = &snd_hda_bind_vol,
14681	.values = {
14682		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14683		HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
14684		0
14685	},
14686};
14687
14688static struct hda_bind_ctls alc663_asus_two_bind_switch = {
14689	.ops = &snd_hda_bind_sw,
14690	.values = {
14691		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14692		HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
14693		0
14694	},
14695};
14696
14697static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
14698	HDA_BIND_VOL("Master Playback Volume",
14699				&alc663_asus_two_bind_master_vol),
14700	HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14701	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14702	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14703	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14704	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14705	{ } /* end */
14706};
14707
14708static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
14709	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14710	HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14711	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14712	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14713	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14714	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14715	{ } /* end */
14716};
14717
14718static struct snd_kcontrol_new alc663_g71v_mixer[] = {
14719	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14720	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14721	HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14722	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14723	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14724
14725	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14726	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14727	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14728	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14729	{ } /* end */
14730};
14731
14732static struct snd_kcontrol_new alc663_g50v_mixer[] = {
14733	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14734	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14735	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14736
14737	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14738	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14739	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14740	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14741	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14742	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14743	{ } /* end */
14744};
14745
14746static struct snd_kcontrol_new alc662_chmode_mixer[] = {
14747	{
14748		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14749		.name = "Channel Mode",
14750		.info = alc_ch_mode_info,
14751		.get = alc_ch_mode_get,
14752		.put = alc_ch_mode_put,
14753	},
14754	{ } /* end */
14755};
14756
14757static struct hda_verb alc662_init_verbs[] = {
14758	/* ADC: mute amp left and right */
14759	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14760	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14761	/* Front mixer: unmute input/output amp left and right (volume = 0) */
14762
14763	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14764	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14765	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14766	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14767	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14768
14769	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14770	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14771	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14772	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14773	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14774	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14775
14776	/* Front Pin: output 0 (0x0c) */
14777	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14778	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14779
14780	/* Rear Pin: output 1 (0x0d) */
14781	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14782	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14783
14784	/* CLFE Pin: output 2 (0x0e) */
14785	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14786	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14787
14788	/* Mic (rear) pin: input vref at 80% */
14789	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14790	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14791	/* Front Mic pin: input vref at 80% */
14792	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14793	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14794	/* Line In pin: input */
14795	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14796	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14797	/* Line-2 In: Headphone output (output 0 - 0x0c) */
14798	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14799	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14800	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14801	/* CD pin widget for input */
14802	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14803
14804	/* FIXME: use matrix-type input source selection */
14805	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
14806	/* Input mixer */
14807	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14808	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14809	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14810	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14811
14812	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14813	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14814	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14815	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14816
14817	/* always trun on EAPD */
14818	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14819	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14820
14821	{ }
14822};
14823
14824static struct hda_verb alc662_sue_init_verbs[] = {
14825	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
14826	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
14827	{}
14828};
14829
14830static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
14831	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14832	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14833	{}
14834};
14835
14836/* Set Unsolicited Event*/
14837static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
14838	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14839	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14840	{}
14841};
14842
14843/*
14844 * generic initialization of ADC, input mixers and output mixers
14845 */
14846static struct hda_verb alc662_auto_init_verbs[] = {
14847	/*
14848	 * Unmute ADC and set the default input to mic-in
14849	 */
14850	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14851	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14852
14853	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
14854	 * mixer widget
14855	 * Note: PASD motherboards uses the Line In 2 as the input for front
14856	 * panel mic (mic 2)
14857	 */
14858	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14859	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14860	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14861	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14862	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14863	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14864
14865	/*
14866	 * Set up output mixers (0x0c - 0x0f)
14867	 */
14868	/* set vol=0 to output mixers */
14869	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14870	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14871	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14872
14873	/* set up input amps for analog loopback */
14874	/* Amp Indices: DAC = 0, mixer = 1 */
14875	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14876	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14877	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14878	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14879	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14880	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14881
14882
14883	/* FIXME: use matrix-type input source selection */
14884	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
14885	/* Input mixer */
14886	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14887	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14888	{ }
14889};
14890
14891/* additional verbs for ALC663 */
14892static struct hda_verb alc663_auto_init_verbs[] = {
14893	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14894	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14895	{ }
14896};
14897
14898static struct hda_verb alc663_m51va_init_verbs[] = {
14899	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14900	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14901	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14902	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14903	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
14904	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14905	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
14906	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14907	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14908	{}
14909};
14910
14911static struct hda_verb alc663_21jd_amic_init_verbs[] = {
14912	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14913	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14914	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
14915	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14916	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14917	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14918	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14919	{}
14920};
14921
14922static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
14923	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14924	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14925	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14926	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
14927	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14928	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14929	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14930	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14931	{}
14932};
14933
14934static struct hda_verb alc663_15jd_amic_init_verbs[] = {
14935	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14936	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14937	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
14938	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14939	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14940	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14941	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14942	{}
14943};
14944
14945static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
14946	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14947	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14948	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14949	{0x21, AC_VERB_SET_CONNECT_SEL, 0x0},	/* Headphone */
14950	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14951	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14952	{0x15, AC_VERB_SET_CONNECT_SEL, 0x0},	/* Headphone */
14953	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14954	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14955	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14956	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14957	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14958	{}
14959};
14960
14961static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
14962	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14963	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14964	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14965	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
14966	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14967	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14968	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
14969	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14970	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14971	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14972	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14973	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14974	{}
14975};
14976
14977static struct hda_verb alc663_g71v_init_verbs[] = {
14978	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14979	/* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
14980	/* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
14981
14982	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14983	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14984	{0x21, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
14985
14986	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
14987	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
14988	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
14989	{}
14990};
14991
14992static struct hda_verb alc663_g50v_init_verbs[] = {
14993	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14994	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14995	{0x21, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
14996
14997	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14998	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14999	{}
15000};
15001
15002static struct hda_verb alc662_ecs_init_verbs[] = {
15003	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15004	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15005	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15006	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15007	{}
15008};
15009
15010static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15011	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15012	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15013	{ } /* end */
15014};
15015
15016static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15017{
15018	unsigned int present;
15019	unsigned char bits;
15020
15021	present = snd_hda_codec_read(codec, 0x14, 0,
15022				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15023	bits = present ? HDA_AMP_MUTE : 0;
15024	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15025				 HDA_AMP_MUTE, bits);
15026}
15027
15028static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15029{
15030	unsigned int present;
15031	unsigned char bits;
15032
15033 	present = snd_hda_codec_read(codec, 0x1b, 0,
15034				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15035	bits = present ? HDA_AMP_MUTE : 0;
15036	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15037				 HDA_AMP_MUTE, bits);
15038	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15039				 HDA_AMP_MUTE, bits);
15040}
15041
15042static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15043					   unsigned int res)
15044{
15045	if ((res >> 26) == ALC880_HP_EVENT)
15046		alc662_lenovo_101e_all_automute(codec);
15047	if ((res >> 26) == ALC880_FRONT_EVENT)
15048		alc662_lenovo_101e_ispeaker_automute(codec);
15049}
15050
15051static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15052{
15053	unsigned int present;
15054
15055	present = snd_hda_codec_read(codec, 0x18, 0,
15056				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15057	snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15058			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15059	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15060			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15061	snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15062			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15063	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15064			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15065}
15066
15067/* unsolicited event for HP jack sensing */
15068static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15069				     unsigned int res)
15070{
15071	if ((res >> 26) == ALC880_HP_EVENT)
15072		alc262_hippo1_automute( codec );
15073
15074	if ((res >> 26) == ALC880_MIC_EVENT)
15075		alc662_eeepc_mic_automute(codec);
15076}
15077
15078static void alc662_eeepc_inithook(struct hda_codec *codec)
15079{
15080	alc262_hippo1_automute( codec );
15081	alc662_eeepc_mic_automute(codec);
15082}
15083
15084static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
15085{
15086	unsigned int mute;
15087	unsigned int present;
15088
15089	snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
15090	present = snd_hda_codec_read(codec, 0x14, 0,
15091				     AC_VERB_GET_PIN_SENSE, 0);
15092	present = (present & 0x80000000) != 0;
15093	if (present) {
15094		/* mute internal speaker */
15095		snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15096					HDA_AMP_MUTE, HDA_AMP_MUTE);
15097	} else {
15098		/* unmute internal speaker if necessary */
15099		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
15100		snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15101					HDA_AMP_MUTE, mute);
15102	}
15103}
15104
15105/* unsolicited event for HP jack sensing */
15106static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
15107					  unsigned int res)
15108{
15109	if ((res >> 26) == ALC880_HP_EVENT)
15110		alc662_eeepc_ep20_automute(codec);
15111}
15112
15113static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
15114{
15115	alc662_eeepc_ep20_automute(codec);
15116}
15117
15118static void alc663_m51va_speaker_automute(struct hda_codec *codec)
15119{
15120	unsigned int present;
15121	unsigned char bits;
15122
15123	present = snd_hda_codec_read(codec, 0x21, 0,
15124			AC_VERB_GET_PIN_SENSE, 0)
15125			& AC_PINSENSE_PRESENCE;
15126	bits = present ? HDA_AMP_MUTE : 0;
15127	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15128				AMP_IN_MUTE(0), bits);
15129	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15130				AMP_IN_MUTE(0), bits);
15131}
15132
15133static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
15134{
15135	unsigned int present;
15136	unsigned char bits;
15137
15138	present = snd_hda_codec_read(codec, 0x21, 0,
15139			AC_VERB_GET_PIN_SENSE, 0)
15140			& AC_PINSENSE_PRESENCE;
15141	bits = present ? HDA_AMP_MUTE : 0;
15142	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15143				AMP_IN_MUTE(0), bits);
15144	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15145				AMP_IN_MUTE(0), bits);
15146	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15147				AMP_IN_MUTE(0), bits);
15148	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15149				AMP_IN_MUTE(0), bits);
15150}
15151
15152static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
15153{
15154	unsigned int present;
15155	unsigned char bits;
15156
15157	present = snd_hda_codec_read(codec, 0x15, 0,
15158			AC_VERB_GET_PIN_SENSE, 0)
15159			& AC_PINSENSE_PRESENCE;
15160	bits = present ? HDA_AMP_MUTE : 0;
15161	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15162				AMP_IN_MUTE(0), bits);
15163	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15164				AMP_IN_MUTE(0), bits);
15165	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15166				AMP_IN_MUTE(0), bits);
15167	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15168				AMP_IN_MUTE(0), bits);
15169}
15170
15171static void alc662_f5z_speaker_automute(struct hda_codec *codec)
15172{
15173	unsigned int present;
15174	unsigned char bits;
15175
15176	present = snd_hda_codec_read(codec, 0x1b, 0,
15177			AC_VERB_GET_PIN_SENSE, 0)
15178			& AC_PINSENSE_PRESENCE;
15179	bits = present ? 0 : PIN_OUT;
15180	snd_hda_codec_write(codec, 0x14, 0,
15181			 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
15182}
15183
15184static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
15185{
15186	unsigned int present1, present2;
15187
15188	present1 = snd_hda_codec_read(codec, 0x21, 0,
15189			AC_VERB_GET_PIN_SENSE, 0)
15190			& AC_PINSENSE_PRESENCE;
15191	present2 = snd_hda_codec_read(codec, 0x15, 0,
15192			AC_VERB_GET_PIN_SENSE, 0)
15193			& AC_PINSENSE_PRESENCE;
15194
15195	if (present1 || present2) {
15196		snd_hda_codec_write_cache(codec, 0x14, 0,
15197			AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
15198	} else {
15199		snd_hda_codec_write_cache(codec, 0x14, 0,
15200			AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
15201	}
15202}
15203
15204static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
15205{
15206	unsigned int present1, present2;
15207
15208	present1 = snd_hda_codec_read(codec, 0x1b, 0,
15209				AC_VERB_GET_PIN_SENSE, 0)
15210				& AC_PINSENSE_PRESENCE;
15211	present2 = snd_hda_codec_read(codec, 0x15, 0,
15212				AC_VERB_GET_PIN_SENSE, 0)
15213				& AC_PINSENSE_PRESENCE;
15214
15215	if (present1 || present2) {
15216		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15217				AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15218		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15219				AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15220	} else {
15221		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15222				AMP_IN_MUTE(0), 0);
15223		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15224				AMP_IN_MUTE(0), 0);
15225	}
15226}
15227
15228static void alc663_m51va_mic_automute(struct hda_codec *codec)
15229{
15230	unsigned int present;
15231
15232	present = snd_hda_codec_read(codec, 0x18, 0,
15233			AC_VERB_GET_PIN_SENSE, 0)
15234			& AC_PINSENSE_PRESENCE;
15235	snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15236			0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15237	snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15238			0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15239	snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15240			0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15241	snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15242			0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15243}
15244
15245static void alc663_m51va_unsol_event(struct hda_codec *codec,
15246					   unsigned int res)
15247{
15248	switch (res >> 26) {
15249	case ALC880_HP_EVENT:
15250		alc663_m51va_speaker_automute(codec);
15251		break;
15252	case ALC880_MIC_EVENT:
15253		alc663_m51va_mic_automute(codec);
15254		break;
15255	}
15256}
15257
15258static void alc663_m51va_inithook(struct hda_codec *codec)
15259{
15260	alc663_m51va_speaker_automute(codec);
15261	alc663_m51va_mic_automute(codec);
15262}
15263
15264/* ***************** Mode1 ******************************/
15265static void alc663_mode1_unsol_event(struct hda_codec *codec,
15266					   unsigned int res)
15267{
15268	switch (res >> 26) {
15269	case ALC880_HP_EVENT:
15270		alc663_m51va_speaker_automute(codec);
15271		break;
15272	case ALC880_MIC_EVENT:
15273		alc662_eeepc_mic_automute(codec);
15274		break;
15275	}
15276}
15277
15278static void alc663_mode1_inithook(struct hda_codec *codec)
15279{
15280	alc663_m51va_speaker_automute(codec);
15281	alc662_eeepc_mic_automute(codec);
15282}
15283/* ***************** Mode2 ******************************/
15284static void alc662_mode2_unsol_event(struct hda_codec *codec,
15285					   unsigned int res)
15286{
15287	switch (res >> 26) {
15288	case ALC880_HP_EVENT:
15289		alc662_f5z_speaker_automute(codec);
15290		break;
15291	case ALC880_MIC_EVENT:
15292		alc662_eeepc_mic_automute(codec);
15293		break;
15294	}
15295}
15296
15297static void alc662_mode2_inithook(struct hda_codec *codec)
15298{
15299	alc662_f5z_speaker_automute(codec);
15300	alc662_eeepc_mic_automute(codec);
15301}
15302/* ***************** Mode3 ******************************/
15303static void alc663_mode3_unsol_event(struct hda_codec *codec,
15304					   unsigned int res)
15305{
15306	switch (res >> 26) {
15307	case ALC880_HP_EVENT:
15308		alc663_two_hp_m1_speaker_automute(codec);
15309		break;
15310	case ALC880_MIC_EVENT:
15311		alc662_eeepc_mic_automute(codec);
15312		break;
15313	}
15314}
15315
15316static void alc663_mode3_inithook(struct hda_codec *codec)
15317{
15318	alc663_two_hp_m1_speaker_automute(codec);
15319	alc662_eeepc_mic_automute(codec);
15320}
15321/* ***************** Mode4 ******************************/
15322static void alc663_mode4_unsol_event(struct hda_codec *codec,
15323					   unsigned int res)
15324{
15325	switch (res >> 26) {
15326	case ALC880_HP_EVENT:
15327		alc663_21jd_two_speaker_automute(codec);
15328		break;
15329	case ALC880_MIC_EVENT:
15330		alc662_eeepc_mic_automute(codec);
15331		break;
15332	}
15333}
15334
15335static void alc663_mode4_inithook(struct hda_codec *codec)
15336{
15337	alc663_21jd_two_speaker_automute(codec);
15338	alc662_eeepc_mic_automute(codec);
15339}
15340/* ***************** Mode5 ******************************/
15341static void alc663_mode5_unsol_event(struct hda_codec *codec,
15342					   unsigned int res)
15343{
15344	switch (res >> 26) {
15345	case ALC880_HP_EVENT:
15346		alc663_15jd_two_speaker_automute(codec);
15347		break;
15348	case ALC880_MIC_EVENT:
15349		alc662_eeepc_mic_automute(codec);
15350		break;
15351	}
15352}
15353
15354static void alc663_mode5_inithook(struct hda_codec *codec)
15355{
15356	alc663_15jd_two_speaker_automute(codec);
15357	alc662_eeepc_mic_automute(codec);
15358}
15359/* ***************** Mode6 ******************************/
15360static void alc663_mode6_unsol_event(struct hda_codec *codec,
15361					   unsigned int res)
15362{
15363	switch (res >> 26) {
15364	case ALC880_HP_EVENT:
15365		alc663_two_hp_m2_speaker_automute(codec);
15366		break;
15367	case ALC880_MIC_EVENT:
15368		alc662_eeepc_mic_automute(codec);
15369		break;
15370	}
15371}
15372
15373static void alc663_mode6_inithook(struct hda_codec *codec)
15374{
15375	alc663_two_hp_m2_speaker_automute(codec);
15376	alc662_eeepc_mic_automute(codec);
15377}
15378
15379static void alc663_g71v_hp_automute(struct hda_codec *codec)
15380{
15381	unsigned int present;
15382	unsigned char bits;
15383
15384	present = snd_hda_codec_read(codec, 0x21, 0,
15385				     AC_VERB_GET_PIN_SENSE, 0)
15386		& AC_PINSENSE_PRESENCE;
15387	bits = present ? HDA_AMP_MUTE : 0;
15388	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15389				 HDA_AMP_MUTE, bits);
15390	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15391				 HDA_AMP_MUTE, bits);
15392}
15393
15394static void alc663_g71v_front_automute(struct hda_codec *codec)
15395{
15396	unsigned int present;
15397	unsigned char bits;
15398
15399	present = snd_hda_codec_read(codec, 0x15, 0,
15400				     AC_VERB_GET_PIN_SENSE, 0)
15401		& AC_PINSENSE_PRESENCE;
15402	bits = present ? HDA_AMP_MUTE : 0;
15403	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15404				 HDA_AMP_MUTE, bits);
15405}
15406
15407static void alc663_g71v_unsol_event(struct hda_codec *codec,
15408					   unsigned int res)
15409{
15410	switch (res >> 26) {
15411	case ALC880_HP_EVENT:
15412		alc663_g71v_hp_automute(codec);
15413		break;
15414	case ALC880_FRONT_EVENT:
15415		alc663_g71v_front_automute(codec);
15416		break;
15417	case ALC880_MIC_EVENT:
15418		alc662_eeepc_mic_automute(codec);
15419		break;
15420	}
15421}
15422
15423static void alc663_g71v_inithook(struct hda_codec *codec)
15424{
15425	alc663_g71v_front_automute(codec);
15426	alc663_g71v_hp_automute(codec);
15427	alc662_eeepc_mic_automute(codec);
15428}
15429
15430static void alc663_g50v_unsol_event(struct hda_codec *codec,
15431					   unsigned int res)
15432{
15433	switch (res >> 26) {
15434	case ALC880_HP_EVENT:
15435		alc663_m51va_speaker_automute(codec);
15436		break;
15437	case ALC880_MIC_EVENT:
15438		alc662_eeepc_mic_automute(codec);
15439		break;
15440	}
15441}
15442
15443static void alc663_g50v_inithook(struct hda_codec *codec)
15444{
15445	alc663_m51va_speaker_automute(codec);
15446	alc662_eeepc_mic_automute(codec);
15447}
15448
15449/* bind hp and internal speaker mute (with plug check) */
15450static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol,
15451				     struct snd_ctl_elem_value *ucontrol)
15452{
15453	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
15454	long *valp = ucontrol->value.integer.value;
15455	int change;
15456
15457	change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
15458					  HDA_AMP_MUTE,
15459					  valp[0] ? 0 : HDA_AMP_MUTE);
15460	change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
15461					   HDA_AMP_MUTE,
15462					   valp[1] ? 0 : HDA_AMP_MUTE);
15463	if (change)
15464		alc262_hippo1_automute(codec);
15465	return change;
15466}
15467
15468static struct snd_kcontrol_new alc662_ecs_mixer[] = {
15469	HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15470	{
15471		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15472		.name = "Master Playback Switch",
15473		.info = snd_hda_mixer_amp_switch_info,
15474		.get = snd_hda_mixer_amp_switch_get,
15475		.put = alc662_ecs_master_sw_put,
15476		.private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15477	},
15478
15479	HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
15480	HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
15481	HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
15482
15483	HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15484	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15485	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15486	{ } /* end */
15487};
15488
15489#ifdef CONFIG_SND_HDA_POWER_SAVE
15490#define alc662_loopbacks	alc880_loopbacks
15491#endif
15492
15493
15494/* pcm configuration: identiacal with ALC880 */
15495#define alc662_pcm_analog_playback	alc880_pcm_analog_playback
15496#define alc662_pcm_analog_capture	alc880_pcm_analog_capture
15497#define alc662_pcm_digital_playback	alc880_pcm_digital_playback
15498#define alc662_pcm_digital_capture	alc880_pcm_digital_capture
15499
15500/*
15501 * configuration and preset
15502 */
15503static const char *alc662_models[ALC662_MODEL_LAST] = {
15504	[ALC662_3ST_2ch_DIG]	= "3stack-dig",
15505	[ALC662_3ST_6ch_DIG]	= "3stack-6ch-dig",
15506	[ALC662_3ST_6ch]	= "3stack-6ch",
15507	[ALC662_5ST_DIG]	= "6stack-dig",
15508	[ALC662_LENOVO_101E]	= "lenovo-101e",
15509	[ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
15510	[ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
15511	[ALC662_ECS] = "ecs",
15512	[ALC663_ASUS_M51VA] = "m51va",
15513	[ALC663_ASUS_G71V] = "g71v",
15514	[ALC663_ASUS_H13] = "h13",
15515	[ALC663_ASUS_G50V] = "g50v",
15516	[ALC663_ASUS_MODE1] = "asus-mode1",
15517	[ALC662_ASUS_MODE2] = "asus-mode2",
15518	[ALC663_ASUS_MODE3] = "asus-mode3",
15519	[ALC663_ASUS_MODE4] = "asus-mode4",
15520	[ALC663_ASUS_MODE5] = "asus-mode5",
15521	[ALC663_ASUS_MODE6] = "asus-mode6",
15522	[ALC662_AUTO]		= "auto",
15523};
15524
15525static struct snd_pci_quirk alc662_cfg_tbl[] = {
15526	SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
15527	SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
15528	SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
15529	SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
15530	SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
15531	SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
15532	SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),
15533	SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
15534	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
15535	SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
15536	SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),
15537	SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
15538	SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
15539	SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
15540	SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
15541	SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
15542	SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
15543	SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
15544	SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
15545	SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
15546	SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
15547	SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
15548	SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
15549	SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
15550	SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
15551	SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
15552	SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
15553	SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
15554	SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
15555	SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
15556	SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
15557	SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
15558	SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
15559	SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
15560	SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
15561	SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
15562	SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
15563	SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
15564		      ALC662_3ST_6ch_DIG),
15565	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
15566	SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
15567	SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
15568	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
15569		      ALC662_3ST_6ch_DIG),
15570	SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
15571	SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
15572					ALC662_3ST_6ch_DIG),
15573	SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13),
15574	SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13),
15575	SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13),
15576	{}
15577};
15578
15579static struct alc_config_preset alc662_presets[] = {
15580	[ALC662_3ST_2ch_DIG] = {
15581		.mixers = { alc662_3ST_2ch_mixer },
15582		.init_verbs = { alc662_init_verbs },
15583		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15584		.dac_nids = alc662_dac_nids,
15585		.dig_out_nid = ALC662_DIGOUT_NID,
15586		.dig_in_nid = ALC662_DIGIN_NID,
15587		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15588		.channel_mode = alc662_3ST_2ch_modes,
15589		.input_mux = &alc662_capture_source,
15590	},
15591	[ALC662_3ST_6ch_DIG] = {
15592		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
15593		.init_verbs = { alc662_init_verbs },
15594		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15595		.dac_nids = alc662_dac_nids,
15596		.dig_out_nid = ALC662_DIGOUT_NID,
15597		.dig_in_nid = ALC662_DIGIN_NID,
15598		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15599		.channel_mode = alc662_3ST_6ch_modes,
15600		.need_dac_fix = 1,
15601		.input_mux = &alc662_capture_source,
15602	},
15603	[ALC662_3ST_6ch] = {
15604		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
15605		.init_verbs = { alc662_init_verbs },
15606		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15607		.dac_nids = alc662_dac_nids,
15608		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15609		.channel_mode = alc662_3ST_6ch_modes,
15610		.need_dac_fix = 1,
15611		.input_mux = &alc662_capture_source,
15612	},
15613	[ALC662_5ST_DIG] = {
15614		.mixers = { alc662_base_mixer, alc662_chmode_mixer },
15615		.init_verbs = { alc662_init_verbs },
15616		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15617		.dac_nids = alc662_dac_nids,
15618		.dig_out_nid = ALC662_DIGOUT_NID,
15619		.dig_in_nid = ALC662_DIGIN_NID,
15620		.num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
15621		.channel_mode = alc662_5stack_modes,
15622		.input_mux = &alc662_capture_source,
15623	},
15624	[ALC662_LENOVO_101E] = {
15625		.mixers = { alc662_lenovo_101e_mixer },
15626		.init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
15627		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15628		.dac_nids = alc662_dac_nids,
15629		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15630		.channel_mode = alc662_3ST_2ch_modes,
15631		.input_mux = &alc662_lenovo_101e_capture_source,
15632		.unsol_event = alc662_lenovo_101e_unsol_event,
15633		.init_hook = alc662_lenovo_101e_all_automute,
15634	},
15635	[ALC662_ASUS_EEEPC_P701] = {
15636		.mixers = { alc662_eeepc_p701_mixer },
15637		.init_verbs = { alc662_init_verbs,
15638				alc662_eeepc_sue_init_verbs },
15639		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15640		.dac_nids = alc662_dac_nids,
15641		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15642		.channel_mode = alc662_3ST_2ch_modes,
15643		.input_mux = &alc662_eeepc_capture_source,
15644		.unsol_event = alc662_eeepc_unsol_event,
15645		.init_hook = alc662_eeepc_inithook,
15646	},
15647	[ALC662_ASUS_EEEPC_EP20] = {
15648		.mixers = { alc662_eeepc_ep20_mixer,
15649			    alc662_chmode_mixer },
15650		.init_verbs = { alc662_init_verbs,
15651				alc662_eeepc_ep20_sue_init_verbs },
15652		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15653		.dac_nids = alc662_dac_nids,
15654		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15655		.channel_mode = alc662_3ST_6ch_modes,
15656		.input_mux = &alc662_lenovo_101e_capture_source,
15657		.unsol_event = alc662_eeepc_ep20_unsol_event,
15658		.init_hook = alc662_eeepc_ep20_inithook,
15659	},
15660	[ALC662_ECS] = {
15661		.mixers = { alc662_ecs_mixer },
15662		.init_verbs = { alc662_init_verbs,
15663				alc662_ecs_init_verbs },
15664		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15665		.dac_nids = alc662_dac_nids,
15666		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15667		.channel_mode = alc662_3ST_2ch_modes,
15668		.input_mux = &alc662_eeepc_capture_source,
15669		.unsol_event = alc662_eeepc_unsol_event,
15670		.init_hook = alc662_eeepc_inithook,
15671	},
15672	[ALC663_ASUS_M51VA] = {
15673		.mixers = { alc663_m51va_mixer },
15674		.init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15675		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15676		.dac_nids = alc662_dac_nids,
15677		.dig_out_nid = ALC662_DIGOUT_NID,
15678		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15679		.channel_mode = alc662_3ST_2ch_modes,
15680		.input_mux = &alc663_m51va_capture_source,
15681		.unsol_event = alc663_m51va_unsol_event,
15682		.init_hook = alc663_m51va_inithook,
15683	},
15684	[ALC663_ASUS_G71V] = {
15685		.mixers = { alc663_g71v_mixer },
15686		.init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
15687		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15688		.dac_nids = alc662_dac_nids,
15689		.dig_out_nid = ALC662_DIGOUT_NID,
15690		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15691		.channel_mode = alc662_3ST_2ch_modes,
15692		.input_mux = &alc662_eeepc_capture_source,
15693		.unsol_event = alc663_g71v_unsol_event,
15694		.init_hook = alc663_g71v_inithook,
15695	},
15696	[ALC663_ASUS_H13] = {
15697		.mixers = { alc663_m51va_mixer },
15698		.init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15699		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15700		.dac_nids = alc662_dac_nids,
15701		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15702		.channel_mode = alc662_3ST_2ch_modes,
15703		.input_mux = &alc663_m51va_capture_source,
15704		.unsol_event = alc663_m51va_unsol_event,
15705		.init_hook = alc663_m51va_inithook,
15706	},
15707	[ALC663_ASUS_G50V] = {
15708		.mixers = { alc663_g50v_mixer },
15709		.init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
15710		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15711		.dac_nids = alc662_dac_nids,
15712		.dig_out_nid = ALC662_DIGOUT_NID,
15713		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15714		.channel_mode = alc662_3ST_6ch_modes,
15715		.input_mux = &alc663_capture_source,
15716		.unsol_event = alc663_g50v_unsol_event,
15717		.init_hook = alc663_g50v_inithook,
15718	},
15719	[ALC663_ASUS_MODE1] = {
15720		.mixers = { alc663_m51va_mixer },
15721		.cap_mixer = alc662_auto_capture_mixer,
15722		.init_verbs = { alc662_init_verbs,
15723				alc663_21jd_amic_init_verbs },
15724		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15725		.hp_nid = 0x03,
15726		.dac_nids = alc662_dac_nids,
15727		.dig_out_nid = ALC662_DIGOUT_NID,
15728		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15729		.channel_mode = alc662_3ST_2ch_modes,
15730		.input_mux = &alc662_eeepc_capture_source,
15731		.unsol_event = alc663_mode1_unsol_event,
15732		.init_hook = alc663_mode1_inithook,
15733	},
15734	[ALC662_ASUS_MODE2] = {
15735		.mixers = { alc662_1bjd_mixer },
15736		.cap_mixer = alc662_auto_capture_mixer,
15737		.init_verbs = { alc662_init_verbs,
15738				alc662_1bjd_amic_init_verbs },
15739		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15740		.dac_nids = alc662_dac_nids,
15741		.dig_out_nid = ALC662_DIGOUT_NID,
15742		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15743		.channel_mode = alc662_3ST_2ch_modes,
15744		.input_mux = &alc662_eeepc_capture_source,
15745		.unsol_event = alc662_mode2_unsol_event,
15746		.init_hook = alc662_mode2_inithook,
15747	},
15748	[ALC663_ASUS_MODE3] = {
15749		.mixers = { alc663_two_hp_m1_mixer },
15750		.cap_mixer = alc662_auto_capture_mixer,
15751		.init_verbs = { alc662_init_verbs,
15752				alc663_two_hp_amic_m1_init_verbs },
15753		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15754		.hp_nid = 0x03,
15755		.dac_nids = alc662_dac_nids,
15756		.dig_out_nid = ALC662_DIGOUT_NID,
15757		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15758		.channel_mode = alc662_3ST_2ch_modes,
15759		.input_mux = &alc662_eeepc_capture_source,
15760		.unsol_event = alc663_mode3_unsol_event,
15761		.init_hook = alc663_mode3_inithook,
15762	},
15763	[ALC663_ASUS_MODE4] = {
15764		.mixers = { alc663_asus_21jd_clfe_mixer },
15765		.cap_mixer = alc662_auto_capture_mixer,
15766		.init_verbs = { alc662_init_verbs,
15767				alc663_21jd_amic_init_verbs},
15768		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15769		.hp_nid = 0x03,
15770		.dac_nids = alc662_dac_nids,
15771		.dig_out_nid = ALC662_DIGOUT_NID,
15772		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15773		.channel_mode = alc662_3ST_2ch_modes,
15774		.input_mux = &alc662_eeepc_capture_source,
15775		.unsol_event = alc663_mode4_unsol_event,
15776		.init_hook = alc663_mode4_inithook,
15777	},
15778	[ALC663_ASUS_MODE5] = {
15779		.mixers = { alc663_asus_15jd_clfe_mixer },
15780		.cap_mixer = alc662_auto_capture_mixer,
15781		.init_verbs = { alc662_init_verbs,
15782				alc663_15jd_amic_init_verbs },
15783		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15784		.hp_nid = 0x03,
15785		.dac_nids = alc662_dac_nids,
15786		.dig_out_nid = ALC662_DIGOUT_NID,
15787		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15788		.channel_mode = alc662_3ST_2ch_modes,
15789		.input_mux = &alc662_eeepc_capture_source,
15790		.unsol_event = alc663_mode5_unsol_event,
15791		.init_hook = alc663_mode5_inithook,
15792	},
15793	[ALC663_ASUS_MODE6] = {
15794		.mixers = { alc663_two_hp_m2_mixer },
15795		.cap_mixer = alc662_auto_capture_mixer,
15796		.init_verbs = { alc662_init_verbs,
15797				alc663_two_hp_amic_m2_init_verbs },
15798		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15799		.hp_nid = 0x03,
15800		.dac_nids = alc662_dac_nids,
15801		.dig_out_nid = ALC662_DIGOUT_NID,
15802		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15803		.channel_mode = alc662_3ST_2ch_modes,
15804		.input_mux = &alc662_eeepc_capture_source,
15805		.unsol_event = alc663_mode6_unsol_event,
15806		.init_hook = alc663_mode6_inithook,
15807	},
15808};
15809
15810
15811/*
15812 * BIOS auto configuration
15813 */
15814
15815/* add playback controls from the parsed DAC table */
15816static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
15817					     const struct auto_pin_cfg *cfg)
15818{
15819	char name[32];
15820	static const char *chname[4] = {
15821		"Front", "Surround", NULL /*CLFE*/, "Side"
15822	};
15823	hda_nid_t nid;
15824	int i, err;
15825
15826	for (i = 0; i < cfg->line_outs; i++) {
15827		if (!spec->multiout.dac_nids[i])
15828			continue;
15829		nid = alc880_idx_to_dac(i);
15830		if (i == 2) {
15831			/* Center/LFE */
15832			err = add_control(spec, ALC_CTL_WIDGET_VOL,
15833					  "Center Playback Volume",
15834					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
15835							      HDA_OUTPUT));
15836			if (err < 0)
15837				return err;
15838			err = add_control(spec, ALC_CTL_WIDGET_VOL,
15839					  "LFE Playback Volume",
15840					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
15841							      HDA_OUTPUT));
15842			if (err < 0)
15843				return err;
15844			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
15845					  "Center Playback Switch",
15846					  HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
15847							      HDA_INPUT));
15848			if (err < 0)
15849				return err;
15850			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
15851					  "LFE Playback Switch",
15852					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
15853							      HDA_INPUT));
15854			if (err < 0)
15855				return err;
15856		} else {
15857			sprintf(name, "%s Playback Volume", chname[i]);
15858			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15859					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
15860							      HDA_OUTPUT));
15861			if (err < 0)
15862				return err;
15863			sprintf(name, "%s Playback Switch", chname[i]);
15864			err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15865				HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
15866						    3, 0, HDA_INPUT));
15867			if (err < 0)
15868				return err;
15869		}
15870	}
15871	return 0;
15872}
15873
15874/* add playback controls for speaker and HP outputs */
15875static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
15876					const char *pfx)
15877{
15878	hda_nid_t nid;
15879	int err;
15880	char name[32];
15881
15882	if (!pin)
15883		return 0;
15884
15885	if (pin == 0x17) {
15886		/* ALC663 has a mono output pin on 0x17 */
15887		sprintf(name, "%s Playback Switch", pfx);
15888		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15889				  HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
15890		return err;
15891	}
15892
15893	if (alc880_is_fixed_pin(pin)) {
15894		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15895                /* printk("DAC nid=%x\n",nid); */
15896		/* specify the DAC as the extra output */
15897		if (!spec->multiout.hp_nid)
15898			spec->multiout.hp_nid = nid;
15899		else
15900			spec->multiout.extra_out_nid[0] = nid;
15901		/* control HP volume/switch on the output mixer amp */
15902		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15903		sprintf(name, "%s Playback Volume", pfx);
15904		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15905				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
15906		if (err < 0)
15907			return err;
15908		sprintf(name, "%s Playback Switch", pfx);
15909		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15910				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
15911		if (err < 0)
15912			return err;
15913	} else if (alc880_is_multi_pin(pin)) {
15914		/* set manual connection */
15915		/* we have only a switch on HP-out PIN */
15916		sprintf(name, "%s Playback Switch", pfx);
15917		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15918				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
15919		if (err < 0)
15920			return err;
15921	}
15922	return 0;
15923}
15924
15925/* create playback/capture controls for input pins */
15926static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
15927						const struct auto_pin_cfg *cfg)
15928{
15929	struct hda_input_mux *imux = &spec->private_imux;
15930	int i, err, idx;
15931
15932	for (i = 0; i < AUTO_PIN_LAST; i++) {
15933		if (alc880_is_input_pin(cfg->input_pins[i])) {
15934			idx = alc880_input_pin_idx(cfg->input_pins[i]);
15935			err = new_analog_input(spec, cfg->input_pins[i],
15936					       auto_pin_cfg_labels[i],
15937					       idx, 0x0b);
15938			if (err < 0)
15939				return err;
15940			imux->items[imux->num_items].label =
15941				auto_pin_cfg_labels[i];
15942			imux->items[imux->num_items].index =
15943				alc880_input_pin_idx(cfg->input_pins[i]);
15944			imux->num_items++;
15945		}
15946	}
15947	return 0;
15948}
15949
15950static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
15951					      hda_nid_t nid, int pin_type,
15952					      int dac_idx)
15953{
15954	alc_set_pin_output(codec, nid, pin_type);
15955	/* need the manual connection? */
15956	if (alc880_is_multi_pin(nid)) {
15957		struct alc_spec *spec = codec->spec;
15958		int idx = alc880_multi_pin_idx(nid);
15959		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
15960				    AC_VERB_SET_CONNECT_SEL,
15961				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
15962	}
15963}
15964
15965static void alc662_auto_init_multi_out(struct hda_codec *codec)
15966{
15967	struct alc_spec *spec = codec->spec;
15968	int i;
15969
15970	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
15971	for (i = 0; i <= HDA_SIDE; i++) {
15972		hda_nid_t nid = spec->autocfg.line_out_pins[i];
15973		int pin_type = get_pin_type(spec->autocfg.line_out_type);
15974		if (nid)
15975			alc662_auto_set_output_and_unmute(codec, nid, pin_type,
15976							  i);
15977	}
15978}
15979
15980static void alc662_auto_init_hp_out(struct hda_codec *codec)
15981{
15982	struct alc_spec *spec = codec->spec;
15983	hda_nid_t pin;
15984
15985	pin = spec->autocfg.hp_pins[0];
15986	if (pin) /* connect to front */
15987		/* use dac 0 */
15988		alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
15989	pin = spec->autocfg.speaker_pins[0];
15990	if (pin)
15991		alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
15992}
15993
15994#define alc662_is_input_pin(nid)	alc880_is_input_pin(nid)
15995#define ALC662_PIN_CD_NID		ALC880_PIN_CD_NID
15996
15997static void alc662_auto_init_analog_input(struct hda_codec *codec)
15998{
15999	struct alc_spec *spec = codec->spec;
16000	int i;
16001
16002	for (i = 0; i < AUTO_PIN_LAST; i++) {
16003		hda_nid_t nid = spec->autocfg.input_pins[i];
16004		if (alc662_is_input_pin(nid)) {
16005			snd_hda_codec_write(codec, nid, 0,
16006					    AC_VERB_SET_PIN_WIDGET_CONTROL,
16007					    (i <= AUTO_PIN_FRONT_MIC ?
16008					     PIN_VREF80 : PIN_IN));
16009			if (nid != ALC662_PIN_CD_NID)
16010				snd_hda_codec_write(codec, nid, 0,
16011						    AC_VERB_SET_AMP_GAIN_MUTE,
16012						    AMP_OUT_MUTE);
16013		}
16014	}
16015}
16016
16017#define alc662_auto_init_input_src	alc882_auto_init_input_src
16018
16019static int alc662_parse_auto_config(struct hda_codec *codec)
16020{
16021	struct alc_spec *spec = codec->spec;
16022	int err;
16023	static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
16024
16025	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16026					   alc662_ignore);
16027	if (err < 0)
16028		return err;
16029	if (!spec->autocfg.line_outs)
16030		return 0; /* can't find valid BIOS pin config */
16031
16032	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16033	if (err < 0)
16034		return err;
16035	err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
16036	if (err < 0)
16037		return err;
16038	err = alc662_auto_create_extra_out(spec,
16039					   spec->autocfg.speaker_pins[0],
16040					   "Speaker");
16041	if (err < 0)
16042		return err;
16043	err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
16044					   "Headphone");
16045	if (err < 0)
16046		return err;
16047	err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
16048	if (err < 0)
16049		return err;
16050
16051	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16052
16053	if (spec->autocfg.dig_out_pin)
16054		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
16055
16056	if (spec->kctls.list)
16057		add_mixer(spec, spec->kctls.list);
16058
16059	spec->num_mux_defs = 1;
16060	spec->input_mux = &spec->private_imux;
16061
16062	add_verb(spec, alc662_auto_init_verbs);
16063	if (codec->vendor_id == 0x10ec0663)
16064		add_verb(spec, alc663_auto_init_verbs);
16065
16066	err = alc_auto_add_mic_boost(codec);
16067	if (err < 0)
16068		return err;
16069
16070	store_pin_configs(codec);
16071	return 1;
16072}
16073
16074/* additional initialization for auto-configuration model */
16075static void alc662_auto_init(struct hda_codec *codec)
16076{
16077	struct alc_spec *spec = codec->spec;
16078	alc662_auto_init_multi_out(codec);
16079	alc662_auto_init_hp_out(codec);
16080	alc662_auto_init_analog_input(codec);
16081	alc662_auto_init_input_src(codec);
16082	if (spec->unsol_event)
16083		alc_inithook(codec);
16084}
16085
16086static int patch_alc662(struct hda_codec *codec)
16087{
16088	struct alc_spec *spec;
16089	int err, board_config;
16090
16091	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16092	if (!spec)
16093		return -ENOMEM;
16094
16095	codec->spec = spec;
16096
16097	alc_fix_pll_init(codec, 0x20, 0x04, 15);
16098
16099	board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
16100						  alc662_models,
16101			  	                  alc662_cfg_tbl);
16102	if (board_config < 0) {
16103		printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
16104		       "trying auto-probe from BIOS...\n");
16105		board_config = ALC662_AUTO;
16106	}
16107
16108	if (board_config == ALC662_AUTO) {
16109		/* automatic parse from the BIOS config */
16110		err = alc662_parse_auto_config(codec);
16111		if (err < 0) {
16112			alc_free(codec);
16113			return err;
16114		} else if (!err) {
16115			printk(KERN_INFO
16116			       "hda_codec: Cannot set up configuration "
16117			       "from BIOS.  Using base mode...\n");
16118			board_config = ALC662_3ST_2ch_DIG;
16119		}
16120	}
16121
16122	if (board_config != ALC662_AUTO)
16123		setup_preset(spec, &alc662_presets[board_config]);
16124
16125	if (codec->vendor_id == 0x10ec0663) {
16126		spec->stream_name_analog = "ALC663 Analog";
16127		spec->stream_name_digital = "ALC663 Digital";
16128	} else if (codec->vendor_id == 0x10ec0272) {
16129		spec->stream_name_analog = "ALC272 Analog";
16130		spec->stream_name_digital = "ALC272 Digital";
16131	} else {
16132		spec->stream_name_analog = "ALC662 Analog";
16133		spec->stream_name_digital = "ALC662 Digital";
16134	}
16135
16136	spec->stream_analog_playback = &alc662_pcm_analog_playback;
16137	spec->stream_analog_capture = &alc662_pcm_analog_capture;
16138
16139	spec->stream_digital_playback = &alc662_pcm_digital_playback;
16140	spec->stream_digital_capture = &alc662_pcm_digital_capture;
16141
16142	spec->adc_nids = alc662_adc_nids;
16143	spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
16144	spec->capsrc_nids = alc662_capsrc_nids;
16145	spec->is_mix_capture = 1;
16146
16147	if (!spec->cap_mixer)
16148		set_capture_mixer(spec);
16149
16150	spec->vmaster_nid = 0x02;
16151
16152	codec->patch_ops = alc_patch_ops;
16153	if (board_config == ALC662_AUTO)
16154		spec->init_hook = alc662_auto_init;
16155#ifdef CONFIG_SND_HDA_POWER_SAVE
16156	if (!spec->loopback.amplist)
16157		spec->loopback.amplist = alc662_loopbacks;
16158#endif
16159
16160	return 0;
16161}
16162
16163/*
16164 * patch entries
16165 */
16166struct hda_codec_preset snd_hda_preset_realtek[] = {
16167	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
16168	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
16169	{ .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
16170	{ .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
16171	{ .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
16172	{ .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
16173	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
16174	  .patch = patch_alc861 },
16175	{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
16176	{ .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
16177	{ .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
16178	{ .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
16179	  .patch = patch_alc883 },
16180	{ .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
16181	  .patch = patch_alc662 },
16182	{ .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
16183	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
16184	{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
16185	{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
16186	{ .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
16187	  .patch = patch_alc882 }, /* should be patch_alc883() in future */
16188	{ .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
16189	  .patch = patch_alc882 }, /* should be patch_alc883() in future */
16190	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
16191	{ .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
16192	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
16193	{ .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
16194	  .patch = patch_alc883 },
16195	{ .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
16196	{} /* terminator */
16197};
16198