patch_realtek.c revision 26f5df265f06b8c8fe9f5d0942b7d8df00e5edec
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_ASPIRE_ONE,
118	ALC268_DELL,
119	ALC268_ZEPTO,
120#ifdef CONFIG_SND_DEBUG
121	ALC268_TEST,
122#endif
123	ALC268_AUTO,
124	ALC268_MODEL_LAST /* last tag */
125};
126
127/* ALC269 models */
128enum {
129	ALC269_BASIC,
130	ALC269_QUANTA_FL1,
131	ALC269_ASUS_EEEPC_P703,
132	ALC269_ASUS_EEEPC_P901,
133	ALC269_FUJITSU,
134	ALC269_AUTO,
135	ALC269_MODEL_LAST /* last tag */
136};
137
138/* ALC861 models */
139enum {
140	ALC861_3ST,
141	ALC660_3ST,
142	ALC861_3ST_DIG,
143	ALC861_6ST_DIG,
144	ALC861_UNIWILL_M31,
145	ALC861_TOSHIBA,
146	ALC861_ASUS,
147	ALC861_ASUS_LAPTOP,
148	ALC861_AUTO,
149	ALC861_MODEL_LAST,
150};
151
152/* ALC861-VD models */
153enum {
154	ALC660VD_3ST,
155	ALC660VD_3ST_DIG,
156	ALC861VD_3ST,
157	ALC861VD_3ST_DIG,
158	ALC861VD_6ST_DIG,
159	ALC861VD_LENOVO,
160	ALC861VD_DALLAS,
161	ALC861VD_HP,
162	ALC861VD_AUTO,
163	ALC861VD_MODEL_LAST,
164};
165
166/* ALC662 models */
167enum {
168	ALC662_3ST_2ch_DIG,
169	ALC662_3ST_6ch_DIG,
170	ALC662_3ST_6ch,
171	ALC662_5ST_DIG,
172	ALC662_LENOVO_101E,
173	ALC662_ASUS_EEEPC_P701,
174	ALC662_ASUS_EEEPC_EP20,
175	ALC663_ASUS_M51VA,
176	ALC663_ASUS_G71V,
177	ALC663_ASUS_H13,
178	ALC663_ASUS_G50V,
179	ALC662_ECS,
180	ALC663_ASUS_MODE1,
181	ALC662_ASUS_MODE2,
182	ALC663_ASUS_MODE3,
183	ALC663_ASUS_MODE4,
184	ALC663_ASUS_MODE5,
185	ALC663_ASUS_MODE6,
186	ALC662_AUTO,
187	ALC662_MODEL_LAST,
188};
189
190/* ALC882 models */
191enum {
192	ALC882_3ST_DIG,
193	ALC882_6ST_DIG,
194	ALC882_ARIMA,
195	ALC882_W2JC,
196	ALC882_TARGA,
197	ALC882_ASUS_A7J,
198	ALC882_ASUS_A7M,
199	ALC885_MACPRO,
200	ALC885_MBP3,
201	ALC885_IMAC24,
202	ALC882_AUTO,
203	ALC882_MODEL_LAST,
204};
205
206/* ALC883 models */
207enum {
208	ALC883_3ST_2ch_DIG,
209	ALC883_3ST_6ch_DIG,
210	ALC883_3ST_6ch,
211	ALC883_6ST_DIG,
212	ALC883_TARGA_DIG,
213	ALC883_TARGA_2ch_DIG,
214	ALC883_ACER,
215	ALC883_ACER_ASPIRE,
216	ALC883_MEDION,
217	ALC883_MEDION_MD2,
218	ALC883_LAPTOP_EAPD,
219	ALC883_LENOVO_101E_2ch,
220	ALC883_LENOVO_NB0763,
221	ALC888_LENOVO_MS7195_DIG,
222	ALC888_LENOVO_SKY,
223	ALC883_HAIER_W66,
224	ALC888_3ST_HP,
225	ALC888_6ST_DELL,
226	ALC883_MITAC,
227	ALC883_CLEVO_M720,
228	ALC883_FUJITSU_PI2515,
229	ALC883_3ST_6ch_INTEL,
230	ALC888_ASUS_M90V,
231	ALC888_ASUS_EEE1601,
232	ALC883_AUTO,
233	ALC883_MODEL_LAST,
234};
235
236/* for GPIO Poll */
237#define GPIO_MASK	0x03
238
239struct alc_spec {
240	/* codec parameterization */
241	struct snd_kcontrol_new *mixers[5];	/* mixer arrays */
242	unsigned int num_mixers;
243	struct snd_kcontrol_new *cap_mixer;	/* capture mixer */
244
245	const struct hda_verb *init_verbs[5];	/* initialization verbs
246						 * don't forget NULL
247						 * termination!
248						 */
249	unsigned int num_init_verbs;
250
251	char *stream_name_analog;	/* analog PCM stream */
252	struct hda_pcm_stream *stream_analog_playback;
253	struct hda_pcm_stream *stream_analog_capture;
254	struct hda_pcm_stream *stream_analog_alt_playback;
255	struct hda_pcm_stream *stream_analog_alt_capture;
256
257	char *stream_name_digital;	/* digital PCM stream */
258	struct hda_pcm_stream *stream_digital_playback;
259	struct hda_pcm_stream *stream_digital_capture;
260
261	/* playback */
262	struct hda_multi_out multiout;	/* playback set-up
263					 * max_channels, dacs must be set
264					 * dig_out_nid and hp_nid are optional
265					 */
266	hda_nid_t alt_dac_nid;
267
268	/* capture */
269	unsigned int num_adc_nids;
270	hda_nid_t *adc_nids;
271	hda_nid_t *capsrc_nids;
272	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
273	unsigned char is_mix_capture;	/* matrix-style capture (non-mux) */
274
275	/* capture source */
276	unsigned int num_mux_defs;
277	const struct hda_input_mux *input_mux;
278	unsigned int cur_mux[3];
279
280	/* channel model */
281	const struct hda_channel_mode *channel_mode;
282	int num_channel_mode;
283	int need_dac_fix;
284
285	/* PCM information */
286	struct hda_pcm pcm_rec[3];	/* used in alc_build_pcms() */
287
288	/* dynamic controls, init_verbs and input_mux */
289	struct auto_pin_cfg autocfg;
290	struct snd_array kctls;
291	struct hda_input_mux private_imux;
292	hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
293
294	/* hooks */
295	void (*init_hook)(struct hda_codec *codec);
296	void (*unsol_event)(struct hda_codec *codec, unsigned int res);
297
298	/* for pin sensing */
299	unsigned int sense_updated: 1;
300	unsigned int jack_present: 1;
301	unsigned int master_sw: 1;
302
303	/* for virtual master */
304	hda_nid_t vmaster_nid;
305#ifdef CONFIG_SND_HDA_POWER_SAVE
306	struct hda_loopback_check loopback;
307#endif
308
309	/* for PLL fix */
310	hda_nid_t pll_nid;
311	unsigned int pll_coef_idx, pll_coef_bit;
312
313#ifdef SND_HDA_NEEDS_RESUME
314#define ALC_MAX_PINS	16
315	unsigned int num_pins;
316	hda_nid_t pin_nids[ALC_MAX_PINS];
317	unsigned int pin_cfgs[ALC_MAX_PINS];
318#endif
319};
320
321/*
322 * configuration template - to be copied to the spec instance
323 */
324struct alc_config_preset {
325	struct snd_kcontrol_new *mixers[5]; /* should be identical size
326					     * with spec
327					     */
328	struct snd_kcontrol_new *cap_mixer; /* capture mixer */
329	const struct hda_verb *init_verbs[5];
330	unsigned int num_dacs;
331	hda_nid_t *dac_nids;
332	hda_nid_t dig_out_nid;		/* optional */
333	hda_nid_t hp_nid;		/* optional */
334	unsigned int num_adc_nids;
335	hda_nid_t *adc_nids;
336	hda_nid_t *capsrc_nids;
337	hda_nid_t dig_in_nid;
338	unsigned int num_channel_mode;
339	const struct hda_channel_mode *channel_mode;
340	int need_dac_fix;
341	unsigned int num_mux_defs;
342	const struct hda_input_mux *input_mux;
343	void (*unsol_event)(struct hda_codec *, unsigned int);
344	void (*init_hook)(struct hda_codec *);
345#ifdef CONFIG_SND_HDA_POWER_SAVE
346	struct hda_amp_list *loopbacks;
347#endif
348};
349
350
351/*
352 * input MUX handling
353 */
354static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
355			     struct snd_ctl_elem_info *uinfo)
356{
357	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
358	struct alc_spec *spec = codec->spec;
359	unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
360	if (mux_idx >= spec->num_mux_defs)
361		mux_idx = 0;
362	return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
363}
364
365static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
366			    struct snd_ctl_elem_value *ucontrol)
367{
368	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
369	struct alc_spec *spec = codec->spec;
370	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
371
372	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
373	return 0;
374}
375
376static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
377			    struct snd_ctl_elem_value *ucontrol)
378{
379	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
380	struct alc_spec *spec = codec->spec;
381	const struct hda_input_mux *imux = spec->input_mux;
382	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
383	hda_nid_t nid = spec->capsrc_nids ?
384		spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
385
386	if (spec->is_mix_capture) {
387		/* Matrix-mixer style (e.g. ALC882) */
388		unsigned int *cur_val = &spec->cur_mux[adc_idx];
389		unsigned int i, idx;
390
391		idx = ucontrol->value.enumerated.item[0];
392		if (idx >= imux->num_items)
393			idx = imux->num_items - 1;
394		if (*cur_val == idx)
395			return 0;
396		for (i = 0; i < imux->num_items; i++) {
397			unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
398			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
399						 imux->items[i].index,
400						 HDA_AMP_MUTE, v);
401		}
402		*cur_val = idx;
403		return 1;
404	} else {
405		/* MUX style (e.g. ALC880) */
406		unsigned int mux_idx;
407		mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
408		return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx],
409					     ucontrol, nid,
410					     &spec->cur_mux[adc_idx]);
411	}
412}
413
414/*
415 * channel mode setting
416 */
417static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
418			    struct snd_ctl_elem_info *uinfo)
419{
420	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
421	struct alc_spec *spec = codec->spec;
422	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
423				    spec->num_channel_mode);
424}
425
426static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
427			   struct snd_ctl_elem_value *ucontrol)
428{
429	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
430	struct alc_spec *spec = codec->spec;
431	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
432				   spec->num_channel_mode,
433				   spec->multiout.max_channels);
434}
435
436static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
437			   struct snd_ctl_elem_value *ucontrol)
438{
439	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
440	struct alc_spec *spec = codec->spec;
441	int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
442				      spec->num_channel_mode,
443				      &spec->multiout.max_channels);
444	if (err >= 0 && spec->need_dac_fix)
445		spec->multiout.num_dacs = spec->multiout.max_channels / 2;
446	return err;
447}
448
449/*
450 * Control the mode of pin widget settings via the mixer.  "pc" is used
451 * instead of "%" to avoid consequences of accidently treating the % as
452 * being part of a format specifier.  Maximum allowed length of a value is
453 * 63 characters plus NULL terminator.
454 *
455 * Note: some retasking pin complexes seem to ignore requests for input
456 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
457 * are requested.  Therefore order this list so that this behaviour will not
458 * cause problems when mixer clients move through the enum sequentially.
459 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
460 * March 2006.
461 */
462static char *alc_pin_mode_names[] = {
463	"Mic 50pc bias", "Mic 80pc bias",
464	"Line in", "Line out", "Headphone out",
465};
466static unsigned char alc_pin_mode_values[] = {
467	PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
468};
469/* The control can present all 5 options, or it can limit the options based
470 * in the pin being assumed to be exclusively an input or an output pin.  In
471 * addition, "input" pins may or may not process the mic bias option
472 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
473 * accept requests for bias as of chip versions up to March 2006) and/or
474 * wiring in the computer.
475 */
476#define ALC_PIN_DIR_IN              0x00
477#define ALC_PIN_DIR_OUT             0x01
478#define ALC_PIN_DIR_INOUT           0x02
479#define ALC_PIN_DIR_IN_NOMICBIAS    0x03
480#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
481
482/* Info about the pin modes supported by the different pin direction modes.
483 * For each direction the minimum and maximum values are given.
484 */
485static signed char alc_pin_mode_dir_info[5][2] = {
486	{ 0, 2 },    /* ALC_PIN_DIR_IN */
487	{ 3, 4 },    /* ALC_PIN_DIR_OUT */
488	{ 0, 4 },    /* ALC_PIN_DIR_INOUT */
489	{ 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
490	{ 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
491};
492#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
493#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
494#define alc_pin_mode_n_items(_dir) \
495	(alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
496
497static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
498			     struct snd_ctl_elem_info *uinfo)
499{
500	unsigned int item_num = uinfo->value.enumerated.item;
501	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
502
503	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
504	uinfo->count = 1;
505	uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
506
507	if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
508		item_num = alc_pin_mode_min(dir);
509	strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
510	return 0;
511}
512
513static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
514			    struct snd_ctl_elem_value *ucontrol)
515{
516	unsigned int i;
517	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
518	hda_nid_t nid = kcontrol->private_value & 0xffff;
519	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
520	long *valp = ucontrol->value.integer.value;
521	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
522						 AC_VERB_GET_PIN_WIDGET_CONTROL,
523						 0x00);
524
525	/* Find enumerated value for current pinctl setting */
526	i = alc_pin_mode_min(dir);
527	while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
528		i++;
529	*valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
530	return 0;
531}
532
533static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
534			    struct snd_ctl_elem_value *ucontrol)
535{
536	signed int change;
537	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
538	hda_nid_t nid = kcontrol->private_value & 0xffff;
539	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
540	long val = *ucontrol->value.integer.value;
541	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
542						 AC_VERB_GET_PIN_WIDGET_CONTROL,
543						 0x00);
544
545	if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
546		val = alc_pin_mode_min(dir);
547
548	change = pinctl != alc_pin_mode_values[val];
549	if (change) {
550		/* Set pin mode to that requested */
551		snd_hda_codec_write_cache(codec, nid, 0,
552					  AC_VERB_SET_PIN_WIDGET_CONTROL,
553					  alc_pin_mode_values[val]);
554
555		/* Also enable the retasking pin's input/output as required
556		 * for the requested pin mode.  Enum values of 2 or less are
557		 * input modes.
558		 *
559		 * Dynamically switching the input/output buffers probably
560		 * reduces noise slightly (particularly on input) so we'll
561		 * do it.  However, having both input and output buffers
562		 * enabled simultaneously doesn't seem to be problematic if
563		 * this turns out to be necessary in the future.
564		 */
565		if (val <= 2) {
566			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
567						 HDA_AMP_MUTE, HDA_AMP_MUTE);
568			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
569						 HDA_AMP_MUTE, 0);
570		} else {
571			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
572						 HDA_AMP_MUTE, HDA_AMP_MUTE);
573			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
574						 HDA_AMP_MUTE, 0);
575		}
576	}
577	return change;
578}
579
580#define ALC_PIN_MODE(xname, nid, dir) \
581	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
582	  .info = alc_pin_mode_info, \
583	  .get = alc_pin_mode_get, \
584	  .put = alc_pin_mode_put, \
585	  .private_value = nid | (dir<<16) }
586
587/* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
588 * together using a mask with more than one bit set.  This control is
589 * currently used only by the ALC260 test model.  At this stage they are not
590 * needed for any "production" models.
591 */
592#ifdef CONFIG_SND_DEBUG
593#define alc_gpio_data_info	snd_ctl_boolean_mono_info
594
595static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
596			     struct snd_ctl_elem_value *ucontrol)
597{
598	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
599	hda_nid_t nid = kcontrol->private_value & 0xffff;
600	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
601	long *valp = ucontrol->value.integer.value;
602	unsigned int val = snd_hda_codec_read(codec, nid, 0,
603					      AC_VERB_GET_GPIO_DATA, 0x00);
604
605	*valp = (val & mask) != 0;
606	return 0;
607}
608static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
609			     struct snd_ctl_elem_value *ucontrol)
610{
611	signed int change;
612	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
613	hda_nid_t nid = kcontrol->private_value & 0xffff;
614	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
615	long val = *ucontrol->value.integer.value;
616	unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
617						    AC_VERB_GET_GPIO_DATA,
618						    0x00);
619
620	/* Set/unset the masked GPIO bit(s) as needed */
621	change = (val == 0 ? 0 : mask) != (gpio_data & mask);
622	if (val == 0)
623		gpio_data &= ~mask;
624	else
625		gpio_data |= mask;
626	snd_hda_codec_write_cache(codec, nid, 0,
627				  AC_VERB_SET_GPIO_DATA, gpio_data);
628
629	return change;
630}
631#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
632	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
633	  .info = alc_gpio_data_info, \
634	  .get = alc_gpio_data_get, \
635	  .put = alc_gpio_data_put, \
636	  .private_value = nid | (mask<<16) }
637#endif   /* CONFIG_SND_DEBUG */
638
639/* A switch control to allow the enabling of the digital IO pins on the
640 * ALC260.  This is incredibly simplistic; the intention of this control is
641 * to provide something in the test model allowing digital outputs to be
642 * identified if present.  If models are found which can utilise these
643 * outputs a more complete mixer control can be devised for those models if
644 * necessary.
645 */
646#ifdef CONFIG_SND_DEBUG
647#define alc_spdif_ctrl_info	snd_ctl_boolean_mono_info
648
649static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
650			      struct snd_ctl_elem_value *ucontrol)
651{
652	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
653	hda_nid_t nid = kcontrol->private_value & 0xffff;
654	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
655	long *valp = ucontrol->value.integer.value;
656	unsigned int val = snd_hda_codec_read(codec, nid, 0,
657					      AC_VERB_GET_DIGI_CONVERT_1, 0x00);
658
659	*valp = (val & mask) != 0;
660	return 0;
661}
662static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
663			      struct snd_ctl_elem_value *ucontrol)
664{
665	signed int change;
666	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
667	hda_nid_t nid = kcontrol->private_value & 0xffff;
668	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
669	long val = *ucontrol->value.integer.value;
670	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
671						    AC_VERB_GET_DIGI_CONVERT_1,
672						    0x00);
673
674	/* Set/unset the masked control bit(s) as needed */
675	change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
676	if (val==0)
677		ctrl_data &= ~mask;
678	else
679		ctrl_data |= mask;
680	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
681				  ctrl_data);
682
683	return change;
684}
685#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
686	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
687	  .info = alc_spdif_ctrl_info, \
688	  .get = alc_spdif_ctrl_get, \
689	  .put = alc_spdif_ctrl_put, \
690	  .private_value = nid | (mask<<16) }
691#endif   /* CONFIG_SND_DEBUG */
692
693/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
694 * Again, this is only used in the ALC26x test models to help identify when
695 * the EAPD line must be asserted for features to work.
696 */
697#ifdef CONFIG_SND_DEBUG
698#define alc_eapd_ctrl_info	snd_ctl_boolean_mono_info
699
700static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
701			      struct snd_ctl_elem_value *ucontrol)
702{
703	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
704	hda_nid_t nid = kcontrol->private_value & 0xffff;
705	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
706	long *valp = ucontrol->value.integer.value;
707	unsigned int val = snd_hda_codec_read(codec, nid, 0,
708					      AC_VERB_GET_EAPD_BTLENABLE, 0x00);
709
710	*valp = (val & mask) != 0;
711	return 0;
712}
713
714static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
715			      struct snd_ctl_elem_value *ucontrol)
716{
717	int change;
718	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
719	hda_nid_t nid = kcontrol->private_value & 0xffff;
720	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
721	long val = *ucontrol->value.integer.value;
722	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
723						    AC_VERB_GET_EAPD_BTLENABLE,
724						    0x00);
725
726	/* Set/unset the masked control bit(s) as needed */
727	change = (!val ? 0 : mask) != (ctrl_data & mask);
728	if (!val)
729		ctrl_data &= ~mask;
730	else
731		ctrl_data |= mask;
732	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
733				  ctrl_data);
734
735	return change;
736}
737
738#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
739	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
740	  .info = alc_eapd_ctrl_info, \
741	  .get = alc_eapd_ctrl_get, \
742	  .put = alc_eapd_ctrl_put, \
743	  .private_value = nid | (mask<<16) }
744#endif   /* CONFIG_SND_DEBUG */
745
746/*
747 */
748static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
749{
750	if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
751		return;
752	spec->mixers[spec->num_mixers++] = mix;
753}
754
755static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
756{
757	if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
758		return;
759	spec->init_verbs[spec->num_init_verbs++] = verb;
760}
761
762/*
763 * set up from the preset table
764 */
765static void setup_preset(struct alc_spec *spec,
766			 const struct alc_config_preset *preset)
767{
768	int i;
769
770	for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
771		add_mixer(spec, preset->mixers[i]);
772	spec->cap_mixer = preset->cap_mixer;
773	for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
774	     i++)
775		add_verb(spec, preset->init_verbs[i]);
776
777	spec->channel_mode = preset->channel_mode;
778	spec->num_channel_mode = preset->num_channel_mode;
779	spec->need_dac_fix = preset->need_dac_fix;
780
781	spec->multiout.max_channels = spec->channel_mode[0].channels;
782
783	spec->multiout.num_dacs = preset->num_dacs;
784	spec->multiout.dac_nids = preset->dac_nids;
785	spec->multiout.dig_out_nid = preset->dig_out_nid;
786	spec->multiout.hp_nid = preset->hp_nid;
787
788	spec->num_mux_defs = preset->num_mux_defs;
789	if (!spec->num_mux_defs)
790		spec->num_mux_defs = 1;
791	spec->input_mux = preset->input_mux;
792
793	spec->num_adc_nids = preset->num_adc_nids;
794	spec->adc_nids = preset->adc_nids;
795	spec->capsrc_nids = preset->capsrc_nids;
796	spec->dig_in_nid = preset->dig_in_nid;
797
798	spec->unsol_event = preset->unsol_event;
799	spec->init_hook = preset->init_hook;
800#ifdef CONFIG_SND_HDA_POWER_SAVE
801	spec->loopback.amplist = preset->loopbacks;
802#endif
803}
804
805/* Enable GPIO mask and set output */
806static struct hda_verb alc_gpio1_init_verbs[] = {
807	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
808	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
809	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
810	{ }
811};
812
813static struct hda_verb alc_gpio2_init_verbs[] = {
814	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
815	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
816	{0x01, AC_VERB_SET_GPIO_DATA, 0x02},
817	{ }
818};
819
820static struct hda_verb alc_gpio3_init_verbs[] = {
821	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
822	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
823	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
824	{ }
825};
826
827/*
828 * Fix hardware PLL issue
829 * On some codecs, the analog PLL gating control must be off while
830 * the default value is 1.
831 */
832static void alc_fix_pll(struct hda_codec *codec)
833{
834	struct alc_spec *spec = codec->spec;
835	unsigned int val;
836
837	if (!spec->pll_nid)
838		return;
839	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
840			    spec->pll_coef_idx);
841	val = snd_hda_codec_read(codec, spec->pll_nid, 0,
842				 AC_VERB_GET_PROC_COEF, 0);
843	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
844			    spec->pll_coef_idx);
845	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
846			    val & ~(1 << spec->pll_coef_bit));
847}
848
849static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
850			     unsigned int coef_idx, unsigned int coef_bit)
851{
852	struct alc_spec *spec = codec->spec;
853	spec->pll_nid = nid;
854	spec->pll_coef_idx = coef_idx;
855	spec->pll_coef_bit = coef_bit;
856	alc_fix_pll(codec);
857}
858
859static void alc_sku_automute(struct hda_codec *codec)
860{
861	struct alc_spec *spec = codec->spec;
862	unsigned int present;
863	unsigned int hp_nid = spec->autocfg.hp_pins[0];
864	unsigned int sp_nid = spec->autocfg.speaker_pins[0];
865
866	/* need to execute and sync at first */
867	snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
868	present = snd_hda_codec_read(codec, hp_nid, 0,
869				     AC_VERB_GET_PIN_SENSE, 0);
870	spec->jack_present = (present & 0x80000000) != 0;
871	snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
872			    spec->jack_present ? 0 : PIN_OUT);
873}
874
875#if 0 /* it's broken in some acses -- temporarily disabled */
876static void alc_mic_automute(struct hda_codec *codec)
877{
878	struct alc_spec *spec = codec->spec;
879	unsigned int present;
880	unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
881	unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
882	unsigned int mix_nid = spec->capsrc_nids[0];
883	unsigned int capsrc_idx_mic, capsrc_idx_fmic;
884
885	capsrc_idx_mic = mic_nid - 0x18;
886	capsrc_idx_fmic = fmic_nid - 0x18;
887	present = snd_hda_codec_read(codec, mic_nid, 0,
888				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
889	snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
890		    0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
891	snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
892		    0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
893	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
894			 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
895}
896#else
897#define alc_mic_automute(codec) /* NOP */
898#endif /* disabled */
899
900/* unsolicited event for HP jack sensing */
901static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
902{
903	if (codec->vendor_id == 0x10ec0880)
904		res >>= 28;
905	else
906		res >>= 26;
907	if (res == ALC880_HP_EVENT)
908		alc_sku_automute(codec);
909
910	if (res == ALC880_MIC_EVENT)
911		alc_mic_automute(codec);
912}
913
914static void alc_inithook(struct hda_codec *codec)
915{
916	alc_sku_automute(codec);
917	alc_mic_automute(codec);
918}
919
920/* additional initialization for ALC888 variants */
921static void alc888_coef_init(struct hda_codec *codec)
922{
923	unsigned int tmp;
924
925	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
926	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
927	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
928	if ((tmp & 0xf0) == 2)
929		/* alc888S-VC */
930		snd_hda_codec_read(codec, 0x20, 0,
931				   AC_VERB_SET_PROC_COEF, 0x830);
932	 else
933		 /* alc888-VB */
934		 snd_hda_codec_read(codec, 0x20, 0,
935				    AC_VERB_SET_PROC_COEF, 0x3030);
936}
937
938/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
939 *	31 ~ 16 :	Manufacture ID
940 *	15 ~ 8	:	SKU ID
941 *	7  ~ 0	:	Assembly ID
942 *	port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
943 */
944static void alc_subsystem_id(struct hda_codec *codec,
945			     unsigned int porta, unsigned int porte,
946			     unsigned int portd)
947{
948	unsigned int ass, tmp, i;
949	unsigned nid;
950	struct alc_spec *spec = codec->spec;
951
952	ass = codec->subsystem_id & 0xffff;
953	if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
954		goto do_sku;
955
956	/*
957	 * 31~30	: port conetcivity
958	 * 29~21	: reserve
959	 * 20		: PCBEEP input
960	 * 19~16	: Check sum (15:1)
961	 * 15~1		: Custom
962	 * 0		: override
963	*/
964	nid = 0x1d;
965	if (codec->vendor_id == 0x10ec0260)
966		nid = 0x17;
967	ass = snd_hda_codec_read(codec, nid, 0,
968				 AC_VERB_GET_CONFIG_DEFAULT, 0);
969	if (!(ass & 1) && !(ass & 0x100000))
970		return;
971	if ((ass >> 30) != 1)	/* no physical connection */
972		return;
973
974	/* check sum */
975	tmp = 0;
976	for (i = 1; i < 16; i++) {
977		if ((ass >> i) & 1)
978			tmp++;
979	}
980	if (((ass >> 16) & 0xf) != tmp)
981		return;
982do_sku:
983	/*
984	 * 0 : override
985	 * 1 :	Swap Jack
986	 * 2 : 0 --> Desktop, 1 --> Laptop
987	 * 3~5 : External Amplifier control
988	 * 7~6 : Reserved
989	*/
990	tmp = (ass & 0x38) >> 3;	/* external Amp control */
991	switch (tmp) {
992	case 1:
993		snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
994		break;
995	case 3:
996		snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
997		break;
998	case 7:
999		snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1000		break;
1001	case 5:	/* set EAPD output high */
1002		switch (codec->vendor_id) {
1003		case 0x10ec0260:
1004			snd_hda_codec_write(codec, 0x0f, 0,
1005					    AC_VERB_SET_EAPD_BTLENABLE, 2);
1006			snd_hda_codec_write(codec, 0x10, 0,
1007					    AC_VERB_SET_EAPD_BTLENABLE, 2);
1008			break;
1009		case 0x10ec0262:
1010		case 0x10ec0267:
1011		case 0x10ec0268:
1012		case 0x10ec0269:
1013		case 0x10ec0660:
1014		case 0x10ec0662:
1015		case 0x10ec0663:
1016		case 0x10ec0862:
1017		case 0x10ec0889:
1018			snd_hda_codec_write(codec, 0x14, 0,
1019					    AC_VERB_SET_EAPD_BTLENABLE, 2);
1020			snd_hda_codec_write(codec, 0x15, 0,
1021					    AC_VERB_SET_EAPD_BTLENABLE, 2);
1022			break;
1023		}
1024		switch (codec->vendor_id) {
1025		case 0x10ec0260:
1026			snd_hda_codec_write(codec, 0x1a, 0,
1027					    AC_VERB_SET_COEF_INDEX, 7);
1028			tmp = snd_hda_codec_read(codec, 0x1a, 0,
1029						 AC_VERB_GET_PROC_COEF, 0);
1030			snd_hda_codec_write(codec, 0x1a, 0,
1031					    AC_VERB_SET_COEF_INDEX, 7);
1032			snd_hda_codec_write(codec, 0x1a, 0,
1033					    AC_VERB_SET_PROC_COEF,
1034					    tmp | 0x2010);
1035			break;
1036		case 0x10ec0262:
1037		case 0x10ec0880:
1038		case 0x10ec0882:
1039		case 0x10ec0883:
1040		case 0x10ec0885:
1041		case 0x10ec0889:
1042			snd_hda_codec_write(codec, 0x20, 0,
1043					    AC_VERB_SET_COEF_INDEX, 7);
1044			tmp = snd_hda_codec_read(codec, 0x20, 0,
1045						 AC_VERB_GET_PROC_COEF, 0);
1046			snd_hda_codec_write(codec, 0x20, 0,
1047					    AC_VERB_SET_COEF_INDEX, 7);
1048			snd_hda_codec_write(codec, 0x20, 0,
1049					    AC_VERB_SET_PROC_COEF,
1050					    tmp | 0x2010);
1051			break;
1052		case 0x10ec0888:
1053			/*alc888_coef_init(codec);*/ /* called in alc_init() */
1054			break;
1055		case 0x10ec0267:
1056		case 0x10ec0268:
1057			snd_hda_codec_write(codec, 0x20, 0,
1058					    AC_VERB_SET_COEF_INDEX, 7);
1059			tmp = snd_hda_codec_read(codec, 0x20, 0,
1060						 AC_VERB_GET_PROC_COEF, 0);
1061			snd_hda_codec_write(codec, 0x20, 0,
1062					    AC_VERB_SET_COEF_INDEX, 7);
1063			snd_hda_codec_write(codec, 0x20, 0,
1064					    AC_VERB_SET_PROC_COEF,
1065					    tmp | 0x3000);
1066			break;
1067		}
1068	default:
1069		break;
1070	}
1071
1072	/* is laptop or Desktop and enable the function "Mute internal speaker
1073	 * when the external headphone out jack is plugged"
1074	 */
1075	if (!(ass & 0x8000))
1076		return;
1077	/*
1078	 * 10~8 : Jack location
1079	 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1080	 * 14~13: Resvered
1081	 * 15   : 1 --> enable the function "Mute internal speaker
1082	 *	        when the external headphone out jack is plugged"
1083	 */
1084	if (!spec->autocfg.speaker_pins[0]) {
1085		if (spec->autocfg.line_out_pins[0])
1086			spec->autocfg.speaker_pins[0] =
1087				spec->autocfg.line_out_pins[0];
1088		else
1089			return;
1090	}
1091
1092	if (!spec->autocfg.hp_pins[0]) {
1093		tmp = (ass >> 11) & 0x3;	/* HP to chassis */
1094		if (tmp == 0)
1095			spec->autocfg.hp_pins[0] = porta;
1096		else if (tmp == 1)
1097			spec->autocfg.hp_pins[0] = porte;
1098		else if (tmp == 2)
1099			spec->autocfg.hp_pins[0] = portd;
1100		else
1101			return;
1102	}
1103	if (spec->autocfg.hp_pins[0])
1104		snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
1105			AC_VERB_SET_UNSOLICITED_ENABLE,
1106			AC_USRSP_EN | ALC880_HP_EVENT);
1107
1108#if 0 /* it's broken in some acses -- temporarily disabled */
1109	if (spec->autocfg.input_pins[AUTO_PIN_MIC] &&
1110		spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC])
1111		snd_hda_codec_write(codec,
1112			spec->autocfg.input_pins[AUTO_PIN_MIC], 0,
1113			AC_VERB_SET_UNSOLICITED_ENABLE,
1114			AC_USRSP_EN | ALC880_MIC_EVENT);
1115#endif /* disabled */
1116
1117	spec->unsol_event = alc_sku_unsol_event;
1118}
1119
1120/*
1121 * Fix-up pin default configurations
1122 */
1123
1124struct alc_pincfg {
1125	hda_nid_t nid;
1126	u32 val;
1127};
1128
1129static void alc_fix_pincfg(struct hda_codec *codec,
1130			   const struct snd_pci_quirk *quirk,
1131			   const struct alc_pincfg **pinfix)
1132{
1133	const struct alc_pincfg *cfg;
1134
1135	quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1136	if (!quirk)
1137		return;
1138
1139	cfg = pinfix[quirk->value];
1140	for (; cfg->nid; cfg++) {
1141		int i;
1142		u32 val = cfg->val;
1143		for (i = 0; i < 4; i++) {
1144			snd_hda_codec_write(codec, cfg->nid, 0,
1145				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
1146				    val & 0xff);
1147			val >>= 8;
1148		}
1149	}
1150}
1151
1152/*
1153 * ALC880 3-stack model
1154 *
1155 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1156 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1157 *                 F-Mic = 0x1b, HP = 0x19
1158 */
1159
1160static hda_nid_t alc880_dac_nids[4] = {
1161	/* front, rear, clfe, rear_surr */
1162	0x02, 0x05, 0x04, 0x03
1163};
1164
1165static hda_nid_t alc880_adc_nids[3] = {
1166	/* ADC0-2 */
1167	0x07, 0x08, 0x09,
1168};
1169
1170/* The datasheet says the node 0x07 is connected from inputs,
1171 * but it shows zero connection in the real implementation on some devices.
1172 * Note: this is a 915GAV bug, fixed on 915GLV
1173 */
1174static hda_nid_t alc880_adc_nids_alt[2] = {
1175	/* ADC1-2 */
1176	0x08, 0x09,
1177};
1178
1179#define ALC880_DIGOUT_NID	0x06
1180#define ALC880_DIGIN_NID	0x0a
1181
1182static struct hda_input_mux alc880_capture_source = {
1183	.num_items = 4,
1184	.items = {
1185		{ "Mic", 0x0 },
1186		{ "Front Mic", 0x3 },
1187		{ "Line", 0x2 },
1188		{ "CD", 0x4 },
1189	},
1190};
1191
1192/* channel source setting (2/6 channel selection for 3-stack) */
1193/* 2ch mode */
1194static struct hda_verb alc880_threestack_ch2_init[] = {
1195	/* set line-in to input, mute it */
1196	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1197	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1198	/* set mic-in to input vref 80%, mute it */
1199	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1200	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1201	{ } /* end */
1202};
1203
1204/* 6ch mode */
1205static struct hda_verb alc880_threestack_ch6_init[] = {
1206	/* set line-in to output, unmute it */
1207	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1208	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1209	/* set mic-in to output, unmute it */
1210	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1211	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1212	{ } /* end */
1213};
1214
1215static struct hda_channel_mode alc880_threestack_modes[2] = {
1216	{ 2, alc880_threestack_ch2_init },
1217	{ 6, alc880_threestack_ch6_init },
1218};
1219
1220static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1221	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1222	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1223	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1224	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1225	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1226	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1227	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1228	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1229	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1230	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1231	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1232	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1233	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1234	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1235	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1236	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1237	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1238	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1239	HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1240	{
1241		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1242		.name = "Channel Mode",
1243		.info = alc_ch_mode_info,
1244		.get = alc_ch_mode_get,
1245		.put = alc_ch_mode_put,
1246	},
1247	{ } /* end */
1248};
1249
1250/* capture mixer elements */
1251static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1252			    struct snd_ctl_elem_info *uinfo)
1253{
1254	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1255	struct alc_spec *spec = codec->spec;
1256	int err;
1257
1258	mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
1259	kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1260						      HDA_INPUT);
1261	err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1262	mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */
1263	return err;
1264}
1265
1266static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1267			   unsigned int size, unsigned int __user *tlv)
1268{
1269	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1270	struct alc_spec *spec = codec->spec;
1271	int err;
1272
1273	mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
1274	kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1275						      HDA_INPUT);
1276	err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1277	mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */
1278	return err;
1279}
1280
1281typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1282			     struct snd_ctl_elem_value *ucontrol);
1283
1284static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1285				 struct snd_ctl_elem_value *ucontrol,
1286				 getput_call_t func)
1287{
1288	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1289	struct alc_spec *spec = codec->spec;
1290	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1291	int err;
1292
1293	mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
1294	kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1295						      3, 0, HDA_INPUT);
1296	err = func(kcontrol, ucontrol);
1297	mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */
1298	return err;
1299}
1300
1301static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1302			   struct snd_ctl_elem_value *ucontrol)
1303{
1304	return alc_cap_getput_caller(kcontrol, ucontrol,
1305				     snd_hda_mixer_amp_volume_get);
1306}
1307
1308static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1309			   struct snd_ctl_elem_value *ucontrol)
1310{
1311	return alc_cap_getput_caller(kcontrol, ucontrol,
1312				     snd_hda_mixer_amp_volume_put);
1313}
1314
1315/* capture mixer elements */
1316#define alc_cap_sw_info		snd_ctl_boolean_stereo_info
1317
1318static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1319			  struct snd_ctl_elem_value *ucontrol)
1320{
1321	return alc_cap_getput_caller(kcontrol, ucontrol,
1322				     snd_hda_mixer_amp_switch_get);
1323}
1324
1325static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1326			  struct snd_ctl_elem_value *ucontrol)
1327{
1328	return alc_cap_getput_caller(kcontrol, ucontrol,
1329				     snd_hda_mixer_amp_switch_put);
1330}
1331
1332#define DEFINE_CAPMIX(num) \
1333static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
1334	{ \
1335		.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1336		.name = "Capture Switch", \
1337		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1338		.count = num, \
1339		.info = alc_cap_sw_info, \
1340		.get = alc_cap_sw_get, \
1341		.put = alc_cap_sw_put, \
1342	}, \
1343	{ \
1344		.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1345		.name = "Capture Volume", \
1346		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1347			   SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1348			   SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1349		.count = num, \
1350		.info = alc_cap_vol_info, \
1351		.get = alc_cap_vol_get, \
1352		.put = alc_cap_vol_put, \
1353		.tlv = { .c = alc_cap_vol_tlv }, \
1354	}, \
1355	{ \
1356		.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1357		/* .name = "Capture Source", */ \
1358		.name = "Input Source", \
1359		.count = num, \
1360		.info = alc_mux_enum_info, \
1361		.get = alc_mux_enum_get, \
1362		.put = alc_mux_enum_put, \
1363	}, \
1364	{ } /* end */ \
1365}
1366
1367/* up to three ADCs */
1368DEFINE_CAPMIX(1);
1369DEFINE_CAPMIX(2);
1370DEFINE_CAPMIX(3);
1371
1372
1373/*
1374 * ALC880 5-stack model
1375 *
1376 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1377 *      Side = 0x02 (0xd)
1378 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1379 *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1380 */
1381
1382/* additional mixers to alc880_three_stack_mixer */
1383static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1384	HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1385	HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1386	{ } /* end */
1387};
1388
1389/* channel source setting (6/8 channel selection for 5-stack) */
1390/* 6ch mode */
1391static struct hda_verb alc880_fivestack_ch6_init[] = {
1392	/* set line-in to input, mute it */
1393	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1394	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1395	{ } /* end */
1396};
1397
1398/* 8ch mode */
1399static struct hda_verb alc880_fivestack_ch8_init[] = {
1400	/* set line-in to output, unmute it */
1401	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1402	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1403	{ } /* end */
1404};
1405
1406static struct hda_channel_mode alc880_fivestack_modes[2] = {
1407	{ 6, alc880_fivestack_ch6_init },
1408	{ 8, alc880_fivestack_ch8_init },
1409};
1410
1411
1412/*
1413 * ALC880 6-stack model
1414 *
1415 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1416 *      Side = 0x05 (0x0f)
1417 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1418 *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1419 */
1420
1421static hda_nid_t alc880_6st_dac_nids[4] = {
1422	/* front, rear, clfe, rear_surr */
1423	0x02, 0x03, 0x04, 0x05
1424};
1425
1426static struct hda_input_mux alc880_6stack_capture_source = {
1427	.num_items = 4,
1428	.items = {
1429		{ "Mic", 0x0 },
1430		{ "Front Mic", 0x1 },
1431		{ "Line", 0x2 },
1432		{ "CD", 0x4 },
1433	},
1434};
1435
1436/* fixed 8-channels */
1437static struct hda_channel_mode alc880_sixstack_modes[1] = {
1438	{ 8, NULL },
1439};
1440
1441static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1442	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1443	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1444	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1445	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1446	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1447	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1448	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1449	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1450	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1451	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1452	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1453	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1454	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1455	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1456	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1457	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1458	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1459	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1460	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1461	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1462	{
1463		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1464		.name = "Channel Mode",
1465		.info = alc_ch_mode_info,
1466		.get = alc_ch_mode_get,
1467		.put = alc_ch_mode_put,
1468	},
1469	{ } /* end */
1470};
1471
1472
1473/*
1474 * ALC880 W810 model
1475 *
1476 * W810 has rear IO for:
1477 * Front (DAC 02)
1478 * Surround (DAC 03)
1479 * Center/LFE (DAC 04)
1480 * Digital out (06)
1481 *
1482 * The system also has a pair of internal speakers, and a headphone jack.
1483 * These are both connected to Line2 on the codec, hence to DAC 02.
1484 *
1485 * There is a variable resistor to control the speaker or headphone
1486 * volume. This is a hardware-only device without a software API.
1487 *
1488 * Plugging headphones in will disable the internal speakers. This is
1489 * implemented in hardware, not via the driver using jack sense. In
1490 * a similar fashion, plugging into the rear socket marked "front" will
1491 * disable both the speakers and headphones.
1492 *
1493 * For input, there's a microphone jack, and an "audio in" jack.
1494 * These may not do anything useful with this driver yet, because I
1495 * haven't setup any initialization verbs for these yet...
1496 */
1497
1498static hda_nid_t alc880_w810_dac_nids[3] = {
1499	/* front, rear/surround, clfe */
1500	0x02, 0x03, 0x04
1501};
1502
1503/* fixed 6 channels */
1504static struct hda_channel_mode alc880_w810_modes[1] = {
1505	{ 6, NULL }
1506};
1507
1508/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1509static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1510	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1511	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1512	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1513	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1514	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1515	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1516	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1517	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1518	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1519	{ } /* end */
1520};
1521
1522
1523/*
1524 * Z710V model
1525 *
1526 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1527 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1528 *                 Line = 0x1a
1529 */
1530
1531static hda_nid_t alc880_z71v_dac_nids[1] = {
1532	0x02
1533};
1534#define ALC880_Z71V_HP_DAC	0x03
1535
1536/* fixed 2 channels */
1537static struct hda_channel_mode alc880_2_jack_modes[1] = {
1538	{ 2, NULL }
1539};
1540
1541static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1542	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1543	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1544	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1545	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1546	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1547	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1548	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1549	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1550	{ } /* end */
1551};
1552
1553
1554/*
1555 * ALC880 F1734 model
1556 *
1557 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1558 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1559 */
1560
1561static hda_nid_t alc880_f1734_dac_nids[1] = {
1562	0x03
1563};
1564#define ALC880_F1734_HP_DAC	0x02
1565
1566static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1567	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1568	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1569	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1570	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1571	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1572	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1573	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1574	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1575	{ } /* end */
1576};
1577
1578static struct hda_input_mux alc880_f1734_capture_source = {
1579	.num_items = 2,
1580	.items = {
1581		{ "Mic", 0x1 },
1582		{ "CD", 0x4 },
1583	},
1584};
1585
1586
1587/*
1588 * ALC880 ASUS model
1589 *
1590 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1591 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1592 *  Mic = 0x18, Line = 0x1a
1593 */
1594
1595#define alc880_asus_dac_nids	alc880_w810_dac_nids	/* identical with w810 */
1596#define alc880_asus_modes	alc880_threestack_modes	/* 2/6 channel mode */
1597
1598static struct snd_kcontrol_new alc880_asus_mixer[] = {
1599	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1600	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1601	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1602	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1603	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1604	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1605	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1606	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1607	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1608	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1609	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1610	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1611	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1612	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1613	{
1614		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1615		.name = "Channel Mode",
1616		.info = alc_ch_mode_info,
1617		.get = alc_ch_mode_get,
1618		.put = alc_ch_mode_put,
1619	},
1620	{ } /* end */
1621};
1622
1623/*
1624 * ALC880 ASUS W1V model
1625 *
1626 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1627 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1628 *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1629 */
1630
1631/* additional mixers to alc880_asus_mixer */
1632static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1633	HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1634	HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1635	{ } /* end */
1636};
1637
1638/* additional mixers to alc880_asus_mixer */
1639static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1640	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1641	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1642	{ } /* end */
1643};
1644
1645/* TCL S700 */
1646static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1647	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1648	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1649	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1650	HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1651	HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1652	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1653	HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1654	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1655	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1656	{ } /* end */
1657};
1658
1659/* Uniwill */
1660static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1661	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1662	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1663	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1664	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1665	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1666	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1667	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1668	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1669	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1670	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1671	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1672	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1673	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1674	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1675	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1676	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1677	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1678	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1679	{
1680		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1681		.name = "Channel Mode",
1682		.info = alc_ch_mode_info,
1683		.get = alc_ch_mode_get,
1684		.put = alc_ch_mode_put,
1685	},
1686	{ } /* end */
1687};
1688
1689static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1690	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1691	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1692	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1693	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1694	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1695	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1696	HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1697	HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1698	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1699	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1700	{ } /* end */
1701};
1702
1703static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1704	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1705	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1706	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1707	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1708	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1709	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1710	{ } /* end */
1711};
1712
1713/*
1714 * virtual master controls
1715 */
1716
1717/*
1718 * slave controls for virtual master
1719 */
1720static const char *alc_slave_vols[] = {
1721	"Front Playback Volume",
1722	"Surround Playback Volume",
1723	"Center Playback Volume",
1724	"LFE Playback Volume",
1725	"Side Playback Volume",
1726	"Headphone Playback Volume",
1727	"Speaker Playback Volume",
1728	"Mono Playback Volume",
1729	"Line-Out Playback Volume",
1730	"PCM Playback Volume",
1731	NULL,
1732};
1733
1734static const char *alc_slave_sws[] = {
1735	"Front Playback Switch",
1736	"Surround Playback Switch",
1737	"Center Playback Switch",
1738	"LFE Playback Switch",
1739	"Side Playback Switch",
1740	"Headphone Playback Switch",
1741	"Speaker Playback Switch",
1742	"Mono Playback Switch",
1743	"IEC958 Playback Switch",
1744	NULL,
1745};
1746
1747/*
1748 * build control elements
1749 */
1750
1751static void alc_free_kctls(struct hda_codec *codec);
1752
1753static int alc_build_controls(struct hda_codec *codec)
1754{
1755	struct alc_spec *spec = codec->spec;
1756	int err;
1757	int i;
1758
1759	for (i = 0; i < spec->num_mixers; i++) {
1760		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1761		if (err < 0)
1762			return err;
1763	}
1764	if (spec->cap_mixer) {
1765		err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
1766		if (err < 0)
1767			return err;
1768	}
1769	if (spec->multiout.dig_out_nid) {
1770		err = snd_hda_create_spdif_out_ctls(codec,
1771						    spec->multiout.dig_out_nid);
1772		if (err < 0)
1773			return err;
1774		err = snd_hda_create_spdif_share_sw(codec,
1775						    &spec->multiout);
1776		if (err < 0)
1777			return err;
1778		spec->multiout.share_spdif = 1;
1779	}
1780	if (spec->dig_in_nid) {
1781		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1782		if (err < 0)
1783			return err;
1784	}
1785
1786	/* if we have no master control, let's create it */
1787	if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1788		unsigned int vmaster_tlv[4];
1789		snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1790					HDA_OUTPUT, vmaster_tlv);
1791		err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1792					  vmaster_tlv, alc_slave_vols);
1793		if (err < 0)
1794			return err;
1795	}
1796	if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1797		err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1798					  NULL, alc_slave_sws);
1799		if (err < 0)
1800			return err;
1801	}
1802
1803	alc_free_kctls(codec); /* no longer needed */
1804	return 0;
1805}
1806
1807
1808/*
1809 * initialize the codec volumes, etc
1810 */
1811
1812/*
1813 * generic initialization of ADC, input mixers and output mixers
1814 */
1815static struct hda_verb alc880_volume_init_verbs[] = {
1816	/*
1817	 * Unmute ADC0-2 and set the default input to mic-in
1818	 */
1819	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1820	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1821	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1822	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1823	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1824	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1825
1826	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1827	 * mixer widget
1828	 * Note: PASD motherboards uses the Line In 2 as the input for front
1829	 * panel mic (mic 2)
1830	 */
1831	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1832	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1833	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1834	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1835	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1836	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1837	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1838	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1839
1840	/*
1841	 * Set up output mixers (0x0c - 0x0f)
1842	 */
1843	/* set vol=0 to output mixers */
1844	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1845	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1846	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1847	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1848	/* set up input amps for analog loopback */
1849	/* Amp Indices: DAC = 0, mixer = 1 */
1850	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1851	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1852	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1853	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1854	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1855	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1856	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1857	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1858
1859	{ }
1860};
1861
1862/*
1863 * 3-stack pin configuration:
1864 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1865 */
1866static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1867	/*
1868	 * preset connection lists of input pins
1869	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1870	 */
1871	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1872	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1873	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1874
1875	/*
1876	 * Set pin mode and muting
1877	 */
1878	/* set front pin widgets 0x14 for output */
1879	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1880	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1881	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1882	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1883	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1884	/* Mic2 (as headphone out) for HP output */
1885	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1886	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1887	/* Line In pin widget for input */
1888	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1889	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1890	/* Line2 (as front mic) pin widget for input and vref at 80% */
1891	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1892	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1893	/* CD pin widget for input */
1894	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1895
1896	{ }
1897};
1898
1899/*
1900 * 5-stack pin configuration:
1901 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1902 * line-in/side = 0x1a, f-mic = 0x1b
1903 */
1904static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1905	/*
1906	 * preset connection lists of input pins
1907	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1908	 */
1909	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1910	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1911
1912	/*
1913	 * Set pin mode and muting
1914	 */
1915	/* set pin widgets 0x14-0x17 for output */
1916	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1917	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1918	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1919	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1920	/* unmute pins for output (no gain on this amp) */
1921	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1922	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1923	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1924	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1925
1926	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1927	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1928	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1929	/* Mic2 (as headphone out) for HP output */
1930	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1931	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1932	/* Line In pin widget for input */
1933	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1934	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1935	/* Line2 (as front mic) pin widget for input and vref at 80% */
1936	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1937	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1938	/* CD pin widget for input */
1939	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1940
1941	{ }
1942};
1943
1944/*
1945 * W810 pin configuration:
1946 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1947 */
1948static struct hda_verb alc880_pin_w810_init_verbs[] = {
1949	/* hphone/speaker input selector: front DAC */
1950	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1951
1952	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1953	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1954	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1955	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1956	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1957	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1958
1959	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1960	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1961
1962	{ }
1963};
1964
1965/*
1966 * Z71V pin configuration:
1967 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1968 */
1969static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1970	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1971	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1972	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1973	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1974
1975	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1976	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1977	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1978	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1979
1980	{ }
1981};
1982
1983/*
1984 * 6-stack pin configuration:
1985 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1986 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1987 */
1988static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1989	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1990
1991	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1992	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1993	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1994	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1995	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1996	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1997	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1998	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1999
2000	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2001	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2002	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2003	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2004	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2005	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2006	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2007	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2008	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2009
2010	{ }
2011};
2012
2013/*
2014 * Uniwill pin configuration:
2015 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2016 * line = 0x1a
2017 */
2018static struct hda_verb alc880_uniwill_init_verbs[] = {
2019	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2020
2021	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2022	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2023	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2024	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2025	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2026	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2027	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2028	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2029	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2030	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2031	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2032	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2033	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2034	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2035
2036	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2037	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2038	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2039	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2040	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2041	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2042	/* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2043	/* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2044	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2045
2046	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2047	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2048
2049	{ }
2050};
2051
2052/*
2053* Uniwill P53
2054* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
2055 */
2056static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2057	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2058
2059	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2060	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2061	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2062	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2063	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2064	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2065	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2066	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2067	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2068	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2069	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2070	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2071
2072	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2073	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2074	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2075	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2076	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2077	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2078
2079	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2080	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2081
2082	{ }
2083};
2084
2085static struct hda_verb alc880_beep_init_verbs[] = {
2086	{ 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2087	{ }
2088};
2089
2090/* toggle speaker-output according to the hp-jack state */
2091static void alc880_uniwill_hp_automute(struct hda_codec *codec)
2092{
2093 	unsigned int present;
2094	unsigned char bits;
2095
2096 	present = snd_hda_codec_read(codec, 0x14, 0,
2097				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2098	bits = present ? HDA_AMP_MUTE : 0;
2099	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
2100				 HDA_AMP_MUTE, bits);
2101	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
2102				 HDA_AMP_MUTE, bits);
2103}
2104
2105/* auto-toggle front mic */
2106static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2107{
2108 	unsigned int present;
2109	unsigned char bits;
2110
2111	present = snd_hda_codec_read(codec, 0x18, 0,
2112				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2113	bits = present ? HDA_AMP_MUTE : 0;
2114	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2115}
2116
2117static void alc880_uniwill_automute(struct hda_codec *codec)
2118{
2119	alc880_uniwill_hp_automute(codec);
2120	alc880_uniwill_mic_automute(codec);
2121}
2122
2123static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2124				       unsigned int res)
2125{
2126	/* Looks like the unsol event is incompatible with the standard
2127	 * definition.  4bit tag is placed at 28 bit!
2128	 */
2129	switch (res >> 28) {
2130	case ALC880_HP_EVENT:
2131		alc880_uniwill_hp_automute(codec);
2132		break;
2133	case ALC880_MIC_EVENT:
2134		alc880_uniwill_mic_automute(codec);
2135		break;
2136	}
2137}
2138
2139static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
2140{
2141 	unsigned int present;
2142	unsigned char bits;
2143
2144 	present = snd_hda_codec_read(codec, 0x14, 0,
2145				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2146	bits = present ? HDA_AMP_MUTE : 0;
2147	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
2148}
2149
2150static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2151{
2152	unsigned int present;
2153
2154	present = snd_hda_codec_read(codec, 0x21, 0,
2155				     AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2156	present &= HDA_AMP_VOLMASK;
2157	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2158				 HDA_AMP_VOLMASK, present);
2159	snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2160				 HDA_AMP_VOLMASK, present);
2161}
2162
2163static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2164					   unsigned int res)
2165{
2166	/* Looks like the unsol event is incompatible with the standard
2167	 * definition.  4bit tag is placed at 28 bit!
2168	 */
2169	if ((res >> 28) == ALC880_HP_EVENT)
2170		alc880_uniwill_p53_hp_automute(codec);
2171	if ((res >> 28) == ALC880_DCVOL_EVENT)
2172		alc880_uniwill_p53_dcvol_automute(codec);
2173}
2174
2175/*
2176 * F1734 pin configuration:
2177 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2178 */
2179static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2180	{0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2181	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2182	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2183	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2184	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2185
2186	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2187	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2188	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2189	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2190
2191	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2192	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2193	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2194	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2195	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2196	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2197	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2198	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2199	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2200
2201	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2202	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2203
2204	{ }
2205};
2206
2207/*
2208 * ASUS pin configuration:
2209 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2210 */
2211static struct hda_verb alc880_pin_asus_init_verbs[] = {
2212	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2213	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2214	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2215	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2216
2217	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2218	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2219	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2220	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2221	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2222	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2223	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2224	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2225
2226	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2227	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2228	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2229	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2230	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2231	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2232	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2233	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2234	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2235
2236	{ }
2237};
2238
2239/* Enable GPIO mask and set output */
2240#define alc880_gpio1_init_verbs	alc_gpio1_init_verbs
2241#define alc880_gpio2_init_verbs	alc_gpio2_init_verbs
2242
2243/* Clevo m520g init */
2244static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2245	/* headphone output */
2246	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2247	/* line-out */
2248	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2249	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2250	/* Line-in */
2251	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2252	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2253	/* CD */
2254	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2255	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2256	/* Mic1 (rear panel) */
2257	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2258	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2259	/* Mic2 (front panel) */
2260	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2261	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2262	/* headphone */
2263	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2264	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2265        /* change to EAPD mode */
2266	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2267	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2268
2269	{ }
2270};
2271
2272static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2273	/* change to EAPD mode */
2274	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2275	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2276
2277	/* Headphone output */
2278	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2279	/* Front output*/
2280	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2281	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2282
2283	/* Line In pin widget for input */
2284	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2285	/* CD pin widget for input */
2286	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2287	/* Mic1 (rear panel) pin widget for input and vref at 80% */
2288	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2289
2290	/* change to EAPD mode */
2291	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2292	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
2293
2294	{ }
2295};
2296
2297/*
2298 * LG m1 express dual
2299 *
2300 * Pin assignment:
2301 *   Rear Line-In/Out (blue): 0x14
2302 *   Build-in Mic-In: 0x15
2303 *   Speaker-out: 0x17
2304 *   HP-Out (green): 0x1b
2305 *   Mic-In/Out (red): 0x19
2306 *   SPDIF-Out: 0x1e
2307 */
2308
2309/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2310static hda_nid_t alc880_lg_dac_nids[3] = {
2311	0x05, 0x02, 0x03
2312};
2313
2314/* seems analog CD is not working */
2315static struct hda_input_mux alc880_lg_capture_source = {
2316	.num_items = 3,
2317	.items = {
2318		{ "Mic", 0x1 },
2319		{ "Line", 0x5 },
2320		{ "Internal Mic", 0x6 },
2321	},
2322};
2323
2324/* 2,4,6 channel modes */
2325static struct hda_verb alc880_lg_ch2_init[] = {
2326	/* set line-in and mic-in to input */
2327	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2328	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2329	{ }
2330};
2331
2332static struct hda_verb alc880_lg_ch4_init[] = {
2333	/* set line-in to out and mic-in to input */
2334	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2335	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2336	{ }
2337};
2338
2339static struct hda_verb alc880_lg_ch6_init[] = {
2340	/* set line-in and mic-in to output */
2341	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2342	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2343	{ }
2344};
2345
2346static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2347	{ 2, alc880_lg_ch2_init },
2348	{ 4, alc880_lg_ch4_init },
2349	{ 6, alc880_lg_ch6_init },
2350};
2351
2352static struct snd_kcontrol_new alc880_lg_mixer[] = {
2353	HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2354	HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2355	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2356	HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2357	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2358	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2359	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2360	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2361	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2362	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2363	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2364	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2365	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2366	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2367	{
2368		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2369		.name = "Channel Mode",
2370		.info = alc_ch_mode_info,
2371		.get = alc_ch_mode_get,
2372		.put = alc_ch_mode_put,
2373	},
2374	{ } /* end */
2375};
2376
2377static struct hda_verb alc880_lg_init_verbs[] = {
2378	/* set capture source to mic-in */
2379	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2380	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2381	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2382	/* mute all amp mixer inputs */
2383	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2384	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2385	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2386	/* line-in to input */
2387	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2388	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2389	/* built-in mic */
2390	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2391	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2392	/* speaker-out */
2393	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2394	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2395	/* mic-in to input */
2396	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2397	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2398	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2399	/* HP-out */
2400	{0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2401	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2402	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2403	/* jack sense */
2404	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2405	{ }
2406};
2407
2408/* toggle speaker-output according to the hp-jack state */
2409static void alc880_lg_automute(struct hda_codec *codec)
2410{
2411	unsigned int present;
2412	unsigned char bits;
2413
2414	present = snd_hda_codec_read(codec, 0x1b, 0,
2415				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2416	bits = present ? HDA_AMP_MUTE : 0;
2417	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2418				 HDA_AMP_MUTE, bits);
2419}
2420
2421static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2422{
2423	/* Looks like the unsol event is incompatible with the standard
2424	 * definition.  4bit tag is placed at 28 bit!
2425	 */
2426	if ((res >> 28) == 0x01)
2427		alc880_lg_automute(codec);
2428}
2429
2430/*
2431 * LG LW20
2432 *
2433 * Pin assignment:
2434 *   Speaker-out: 0x14
2435 *   Mic-In: 0x18
2436 *   Built-in Mic-In: 0x19
2437 *   Line-In: 0x1b
2438 *   HP-Out: 0x1a
2439 *   SPDIF-Out: 0x1e
2440 */
2441
2442static struct hda_input_mux alc880_lg_lw_capture_source = {
2443	.num_items = 3,
2444	.items = {
2445		{ "Mic", 0x0 },
2446		{ "Internal Mic", 0x1 },
2447		{ "Line In", 0x2 },
2448	},
2449};
2450
2451#define alc880_lg_lw_modes alc880_threestack_modes
2452
2453static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2454	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2455	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2456	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2457	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2458	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2459	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2460	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2461	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2462	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2463	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2464	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2465	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2466	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2467	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2468	{
2469		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2470		.name = "Channel Mode",
2471		.info = alc_ch_mode_info,
2472		.get = alc_ch_mode_get,
2473		.put = alc_ch_mode_put,
2474	},
2475	{ } /* end */
2476};
2477
2478static struct hda_verb alc880_lg_lw_init_verbs[] = {
2479	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2480	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2481	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2482
2483	/* set capture source to mic-in */
2484	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2485	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2486	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2487	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2488	/* speaker-out */
2489	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2490	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2491	/* HP-out */
2492	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2493	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2494	/* mic-in to input */
2495	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2496	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2497	/* built-in mic */
2498	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2499	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2500	/* jack sense */
2501	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2502	{ }
2503};
2504
2505/* toggle speaker-output according to the hp-jack state */
2506static void alc880_lg_lw_automute(struct hda_codec *codec)
2507{
2508	unsigned int present;
2509	unsigned char bits;
2510
2511	present = snd_hda_codec_read(codec, 0x1b, 0,
2512				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2513	bits = present ? HDA_AMP_MUTE : 0;
2514	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2515				 HDA_AMP_MUTE, bits);
2516}
2517
2518static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2519{
2520	/* Looks like the unsol event is incompatible with the standard
2521	 * definition.  4bit tag is placed at 28 bit!
2522	 */
2523	if ((res >> 28) == 0x01)
2524		alc880_lg_lw_automute(codec);
2525}
2526
2527static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2528	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2529	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2530	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2531	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2532	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2533	HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2534	{ } /* end */
2535};
2536
2537static struct hda_input_mux alc880_medion_rim_capture_source = {
2538	.num_items = 2,
2539	.items = {
2540		{ "Mic", 0x0 },
2541		{ "Internal Mic", 0x1 },
2542	},
2543};
2544
2545static struct hda_verb alc880_medion_rim_init_verbs[] = {
2546	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2547
2548	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2549	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2550
2551	/* Mic1 (rear panel) pin widget for input and vref at 80% */
2552	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2553	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2554	/* Mic2 (as headphone out) for HP output */
2555	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2556	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2557	/* Internal Speaker */
2558	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2559	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2560
2561	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2562	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2563
2564	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2565	{ }
2566};
2567
2568/* toggle speaker-output according to the hp-jack state */
2569static void alc880_medion_rim_automute(struct hda_codec *codec)
2570{
2571	unsigned int present;
2572	unsigned char bits;
2573
2574	present = snd_hda_codec_read(codec, 0x14, 0,
2575				     AC_VERB_GET_PIN_SENSE, 0)
2576		& AC_PINSENSE_PRESENCE;
2577	bits = present ? HDA_AMP_MUTE : 0;
2578	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
2579				 HDA_AMP_MUTE, bits);
2580	if (present)
2581		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2582	else
2583		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2584}
2585
2586static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2587					  unsigned int res)
2588{
2589	/* Looks like the unsol event is incompatible with the standard
2590	 * definition.  4bit tag is placed at 28 bit!
2591	 */
2592	if ((res >> 28) == ALC880_HP_EVENT)
2593		alc880_medion_rim_automute(codec);
2594}
2595
2596#ifdef CONFIG_SND_HDA_POWER_SAVE
2597static struct hda_amp_list alc880_loopbacks[] = {
2598	{ 0x0b, HDA_INPUT, 0 },
2599	{ 0x0b, HDA_INPUT, 1 },
2600	{ 0x0b, HDA_INPUT, 2 },
2601	{ 0x0b, HDA_INPUT, 3 },
2602	{ 0x0b, HDA_INPUT, 4 },
2603	{ } /* end */
2604};
2605
2606static struct hda_amp_list alc880_lg_loopbacks[] = {
2607	{ 0x0b, HDA_INPUT, 1 },
2608	{ 0x0b, HDA_INPUT, 6 },
2609	{ 0x0b, HDA_INPUT, 7 },
2610	{ } /* end */
2611};
2612#endif
2613
2614/*
2615 * Common callbacks
2616 */
2617
2618static int alc_init(struct hda_codec *codec)
2619{
2620	struct alc_spec *spec = codec->spec;
2621	unsigned int i;
2622
2623	alc_fix_pll(codec);
2624	if (codec->vendor_id == 0x10ec0888)
2625		alc888_coef_init(codec);
2626
2627	for (i = 0; i < spec->num_init_verbs; i++)
2628		snd_hda_sequence_write(codec, spec->init_verbs[i]);
2629
2630	if (spec->init_hook)
2631		spec->init_hook(codec);
2632
2633	return 0;
2634}
2635
2636static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2637{
2638	struct alc_spec *spec = codec->spec;
2639
2640	if (spec->unsol_event)
2641		spec->unsol_event(codec, res);
2642}
2643
2644#ifdef CONFIG_SND_HDA_POWER_SAVE
2645static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2646{
2647	struct alc_spec *spec = codec->spec;
2648	return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2649}
2650#endif
2651
2652/*
2653 * Analog playback callbacks
2654 */
2655static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2656				    struct hda_codec *codec,
2657				    struct snd_pcm_substream *substream)
2658{
2659	struct alc_spec *spec = codec->spec;
2660	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2661					     hinfo);
2662}
2663
2664static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2665				       struct hda_codec *codec,
2666				       unsigned int stream_tag,
2667				       unsigned int format,
2668				       struct snd_pcm_substream *substream)
2669{
2670	struct alc_spec *spec = codec->spec;
2671	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2672						stream_tag, format, substream);
2673}
2674
2675static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2676				       struct hda_codec *codec,
2677				       struct snd_pcm_substream *substream)
2678{
2679	struct alc_spec *spec = codec->spec;
2680	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2681}
2682
2683/*
2684 * Digital out
2685 */
2686static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2687					struct hda_codec *codec,
2688					struct snd_pcm_substream *substream)
2689{
2690	struct alc_spec *spec = codec->spec;
2691	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2692}
2693
2694static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2695					   struct hda_codec *codec,
2696					   unsigned int stream_tag,
2697					   unsigned int format,
2698					   struct snd_pcm_substream *substream)
2699{
2700	struct alc_spec *spec = codec->spec;
2701	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2702					     stream_tag, format, substream);
2703}
2704
2705static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2706					 struct hda_codec *codec,
2707					 struct snd_pcm_substream *substream)
2708{
2709	struct alc_spec *spec = codec->spec;
2710	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2711}
2712
2713/*
2714 * Analog capture
2715 */
2716static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2717				      struct hda_codec *codec,
2718				      unsigned int stream_tag,
2719				      unsigned int format,
2720				      struct snd_pcm_substream *substream)
2721{
2722	struct alc_spec *spec = codec->spec;
2723
2724	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
2725				   stream_tag, 0, format);
2726	return 0;
2727}
2728
2729static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2730				      struct hda_codec *codec,
2731				      struct snd_pcm_substream *substream)
2732{
2733	struct alc_spec *spec = codec->spec;
2734
2735	snd_hda_codec_cleanup_stream(codec,
2736				     spec->adc_nids[substream->number + 1]);
2737	return 0;
2738}
2739
2740
2741/*
2742 */
2743static struct hda_pcm_stream alc880_pcm_analog_playback = {
2744	.substreams = 1,
2745	.channels_min = 2,
2746	.channels_max = 8,
2747	/* NID is set in alc_build_pcms */
2748	.ops = {
2749		.open = alc880_playback_pcm_open,
2750		.prepare = alc880_playback_pcm_prepare,
2751		.cleanup = alc880_playback_pcm_cleanup
2752	},
2753};
2754
2755static struct hda_pcm_stream alc880_pcm_analog_capture = {
2756	.substreams = 1,
2757	.channels_min = 2,
2758	.channels_max = 2,
2759	/* NID is set in alc_build_pcms */
2760};
2761
2762static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
2763	.substreams = 1,
2764	.channels_min = 2,
2765	.channels_max = 2,
2766	/* NID is set in alc_build_pcms */
2767};
2768
2769static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
2770	.substreams = 2, /* can be overridden */
2771	.channels_min = 2,
2772	.channels_max = 2,
2773	/* NID is set in alc_build_pcms */
2774	.ops = {
2775		.prepare = alc880_alt_capture_pcm_prepare,
2776		.cleanup = alc880_alt_capture_pcm_cleanup
2777	},
2778};
2779
2780static struct hda_pcm_stream alc880_pcm_digital_playback = {
2781	.substreams = 1,
2782	.channels_min = 2,
2783	.channels_max = 2,
2784	/* NID is set in alc_build_pcms */
2785	.ops = {
2786		.open = alc880_dig_playback_pcm_open,
2787		.close = alc880_dig_playback_pcm_close,
2788		.prepare = alc880_dig_playback_pcm_prepare
2789	},
2790};
2791
2792static struct hda_pcm_stream alc880_pcm_digital_capture = {
2793	.substreams = 1,
2794	.channels_min = 2,
2795	.channels_max = 2,
2796	/* NID is set in alc_build_pcms */
2797};
2798
2799/* Used by alc_build_pcms to flag that a PCM has no playback stream */
2800static struct hda_pcm_stream alc_pcm_null_stream = {
2801	.substreams = 0,
2802	.channels_min = 0,
2803	.channels_max = 0,
2804};
2805
2806static int alc_build_pcms(struct hda_codec *codec)
2807{
2808	struct alc_spec *spec = codec->spec;
2809	struct hda_pcm *info = spec->pcm_rec;
2810	int i;
2811
2812	codec->num_pcms = 1;
2813	codec->pcm_info = info;
2814
2815	info->name = spec->stream_name_analog;
2816	if (spec->stream_analog_playback) {
2817		if (snd_BUG_ON(!spec->multiout.dac_nids))
2818			return -EINVAL;
2819		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2820		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2821	}
2822	if (spec->stream_analog_capture) {
2823		if (snd_BUG_ON(!spec->adc_nids))
2824			return -EINVAL;
2825		info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2826		info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2827	}
2828
2829	if (spec->channel_mode) {
2830		info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2831		for (i = 0; i < spec->num_channel_mode; i++) {
2832			if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2833				info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2834			}
2835		}
2836	}
2837
2838	/* SPDIF for stream index #1 */
2839	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2840		codec->num_pcms = 2;
2841		info = spec->pcm_rec + 1;
2842		info->name = spec->stream_name_digital;
2843		info->pcm_type = HDA_PCM_TYPE_SPDIF;
2844		if (spec->multiout.dig_out_nid &&
2845		    spec->stream_digital_playback) {
2846			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2847			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2848		}
2849		if (spec->dig_in_nid &&
2850		    spec->stream_digital_capture) {
2851			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2852			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2853		}
2854		/* FIXME: do we need this for all Realtek codec models? */
2855		codec->spdif_status_reset = 1;
2856	}
2857
2858	/* If the use of more than one ADC is requested for the current
2859	 * model, configure a second analog capture-only PCM.
2860	 */
2861	/* Additional Analaog capture for index #2 */
2862	if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
2863	    (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
2864		codec->num_pcms = 3;
2865		info = spec->pcm_rec + 2;
2866		info->name = spec->stream_name_analog;
2867		if (spec->alt_dac_nid) {
2868			info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2869				*spec->stream_analog_alt_playback;
2870			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2871				spec->alt_dac_nid;
2872		} else {
2873			info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2874				alc_pcm_null_stream;
2875			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2876		}
2877		if (spec->num_adc_nids > 1) {
2878			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2879				*spec->stream_analog_alt_capture;
2880			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
2881				spec->adc_nids[1];
2882			info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
2883				spec->num_adc_nids - 1;
2884		} else {
2885			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2886				alc_pcm_null_stream;
2887			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
2888		}
2889	}
2890
2891	return 0;
2892}
2893
2894static void alc_free_kctls(struct hda_codec *codec)
2895{
2896	struct alc_spec *spec = codec->spec;
2897
2898	if (spec->kctls.list) {
2899		struct snd_kcontrol_new *kctl = spec->kctls.list;
2900		int i;
2901		for (i = 0; i < spec->kctls.used; i++)
2902			kfree(kctl[i].name);
2903	}
2904	snd_array_free(&spec->kctls);
2905}
2906
2907static void alc_free(struct hda_codec *codec)
2908{
2909	struct alc_spec *spec = codec->spec;
2910
2911	if (!spec)
2912		return;
2913
2914	alc_free_kctls(codec);
2915	kfree(spec);
2916	codec->spec = NULL; /* to be sure */
2917}
2918
2919#ifdef SND_HDA_NEEDS_RESUME
2920static void store_pin_configs(struct hda_codec *codec)
2921{
2922	struct alc_spec *spec = codec->spec;
2923	hda_nid_t nid, end_nid;
2924
2925	end_nid = codec->start_nid + codec->num_nodes;
2926	for (nid = codec->start_nid; nid < end_nid; nid++) {
2927		unsigned int wid_caps = get_wcaps(codec, nid);
2928		unsigned int wid_type =
2929			(wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
2930		if (wid_type != AC_WID_PIN)
2931			continue;
2932		if (spec->num_pins >= ARRAY_SIZE(spec->pin_nids))
2933			break;
2934		spec->pin_nids[spec->num_pins] = nid;
2935		spec->pin_cfgs[spec->num_pins] =
2936			snd_hda_codec_read(codec, nid, 0,
2937					   AC_VERB_GET_CONFIG_DEFAULT, 0);
2938		spec->num_pins++;
2939	}
2940}
2941
2942static void resume_pin_configs(struct hda_codec *codec)
2943{
2944	struct alc_spec *spec = codec->spec;
2945	int i;
2946
2947	for (i = 0; i < spec->num_pins; i++) {
2948		hda_nid_t pin_nid = spec->pin_nids[i];
2949		unsigned int pin_config = spec->pin_cfgs[i];
2950		snd_hda_codec_write(codec, pin_nid, 0,
2951				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
2952				    pin_config & 0x000000ff);
2953		snd_hda_codec_write(codec, pin_nid, 0,
2954				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
2955				    (pin_config & 0x0000ff00) >> 8);
2956		snd_hda_codec_write(codec, pin_nid, 0,
2957				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
2958				    (pin_config & 0x00ff0000) >> 16);
2959		snd_hda_codec_write(codec, pin_nid, 0,
2960				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
2961				    pin_config >> 24);
2962	}
2963}
2964
2965static int alc_resume(struct hda_codec *codec)
2966{
2967	resume_pin_configs(codec);
2968	codec->patch_ops.init(codec);
2969	snd_hda_codec_resume_amp(codec);
2970	snd_hda_codec_resume_cache(codec);
2971	return 0;
2972}
2973#else
2974#define store_pin_configs(codec)
2975#endif
2976
2977/*
2978 */
2979static struct hda_codec_ops alc_patch_ops = {
2980	.build_controls = alc_build_controls,
2981	.build_pcms = alc_build_pcms,
2982	.init = alc_init,
2983	.free = alc_free,
2984	.unsol_event = alc_unsol_event,
2985#ifdef SND_HDA_NEEDS_RESUME
2986	.resume = alc_resume,
2987#endif
2988#ifdef CONFIG_SND_HDA_POWER_SAVE
2989	.check_power_status = alc_check_power_status,
2990#endif
2991};
2992
2993
2994/*
2995 * Test configuration for debugging
2996 *
2997 * Almost all inputs/outputs are enabled.  I/O pins can be configured via
2998 * enum controls.
2999 */
3000#ifdef CONFIG_SND_DEBUG
3001static hda_nid_t alc880_test_dac_nids[4] = {
3002	0x02, 0x03, 0x04, 0x05
3003};
3004
3005static struct hda_input_mux alc880_test_capture_source = {
3006	.num_items = 7,
3007	.items = {
3008		{ "In-1", 0x0 },
3009		{ "In-2", 0x1 },
3010		{ "In-3", 0x2 },
3011		{ "In-4", 0x3 },
3012		{ "CD", 0x4 },
3013		{ "Front", 0x5 },
3014		{ "Surround", 0x6 },
3015	},
3016};
3017
3018static struct hda_channel_mode alc880_test_modes[4] = {
3019	{ 2, NULL },
3020	{ 4, NULL },
3021	{ 6, NULL },
3022	{ 8, NULL },
3023};
3024
3025static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3026				 struct snd_ctl_elem_info *uinfo)
3027{
3028	static char *texts[] = {
3029		"N/A", "Line Out", "HP Out",
3030		"In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3031	};
3032	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3033	uinfo->count = 1;
3034	uinfo->value.enumerated.items = 8;
3035	if (uinfo->value.enumerated.item >= 8)
3036		uinfo->value.enumerated.item = 7;
3037	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3038	return 0;
3039}
3040
3041static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3042				struct snd_ctl_elem_value *ucontrol)
3043{
3044	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3045	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3046	unsigned int pin_ctl, item = 0;
3047
3048	pin_ctl = snd_hda_codec_read(codec, nid, 0,
3049				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3050	if (pin_ctl & AC_PINCTL_OUT_EN) {
3051		if (pin_ctl & AC_PINCTL_HP_EN)
3052			item = 2;
3053		else
3054			item = 1;
3055	} else if (pin_ctl & AC_PINCTL_IN_EN) {
3056		switch (pin_ctl & AC_PINCTL_VREFEN) {
3057		case AC_PINCTL_VREF_HIZ: item = 3; break;
3058		case AC_PINCTL_VREF_50:  item = 4; break;
3059		case AC_PINCTL_VREF_GRD: item = 5; break;
3060		case AC_PINCTL_VREF_80:  item = 6; break;
3061		case AC_PINCTL_VREF_100: item = 7; break;
3062		}
3063	}
3064	ucontrol->value.enumerated.item[0] = item;
3065	return 0;
3066}
3067
3068static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3069				struct snd_ctl_elem_value *ucontrol)
3070{
3071	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3072	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3073	static unsigned int ctls[] = {
3074		0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3075		AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3076		AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3077		AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3078		AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3079		AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3080	};
3081	unsigned int old_ctl, new_ctl;
3082
3083	old_ctl = snd_hda_codec_read(codec, nid, 0,
3084				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3085	new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3086	if (old_ctl != new_ctl) {
3087		int val;
3088		snd_hda_codec_write_cache(codec, nid, 0,
3089					  AC_VERB_SET_PIN_WIDGET_CONTROL,
3090					  new_ctl);
3091		val = ucontrol->value.enumerated.item[0] >= 3 ?
3092			HDA_AMP_MUTE : 0;
3093		snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3094					 HDA_AMP_MUTE, val);
3095		return 1;
3096	}
3097	return 0;
3098}
3099
3100static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3101				 struct snd_ctl_elem_info *uinfo)
3102{
3103	static char *texts[] = {
3104		"Front", "Surround", "CLFE", "Side"
3105	};
3106	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3107	uinfo->count = 1;
3108	uinfo->value.enumerated.items = 4;
3109	if (uinfo->value.enumerated.item >= 4)
3110		uinfo->value.enumerated.item = 3;
3111	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3112	return 0;
3113}
3114
3115static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3116				struct snd_ctl_elem_value *ucontrol)
3117{
3118	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3119	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3120	unsigned int sel;
3121
3122	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3123	ucontrol->value.enumerated.item[0] = sel & 3;
3124	return 0;
3125}
3126
3127static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3128				struct snd_ctl_elem_value *ucontrol)
3129{
3130	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3131	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3132	unsigned int sel;
3133
3134	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3135	if (ucontrol->value.enumerated.item[0] != sel) {
3136		sel = ucontrol->value.enumerated.item[0] & 3;
3137		snd_hda_codec_write_cache(codec, nid, 0,
3138					  AC_VERB_SET_CONNECT_SEL, sel);
3139		return 1;
3140	}
3141	return 0;
3142}
3143
3144#define PIN_CTL_TEST(xname,nid) {			\
3145		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
3146			.name = xname,		       \
3147			.info = alc_test_pin_ctl_info, \
3148			.get = alc_test_pin_ctl_get,   \
3149			.put = alc_test_pin_ctl_put,   \
3150			.private_value = nid	       \
3151			}
3152
3153#define PIN_SRC_TEST(xname,nid) {			\
3154		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
3155			.name = xname,		       \
3156			.info = alc_test_pin_src_info, \
3157			.get = alc_test_pin_src_get,   \
3158			.put = alc_test_pin_src_put,   \
3159			.private_value = nid	       \
3160			}
3161
3162static struct snd_kcontrol_new alc880_test_mixer[] = {
3163	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3164	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3165	HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3166	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3167	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3168	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3169	HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3170	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
3171	PIN_CTL_TEST("Front Pin Mode", 0x14),
3172	PIN_CTL_TEST("Surround Pin Mode", 0x15),
3173	PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3174	PIN_CTL_TEST("Side Pin Mode", 0x17),
3175	PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3176	PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3177	PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3178	PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3179	PIN_SRC_TEST("In-1 Pin Source", 0x18),
3180	PIN_SRC_TEST("In-2 Pin Source", 0x19),
3181	PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3182	PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3183	HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3184	HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3185	HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3186	HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3187	HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3188	HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3189	HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3190	HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3191	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3192	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
3193	{
3194		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3195		.name = "Channel Mode",
3196		.info = alc_ch_mode_info,
3197		.get = alc_ch_mode_get,
3198		.put = alc_ch_mode_put,
3199	},
3200	{ } /* end */
3201};
3202
3203static struct hda_verb alc880_test_init_verbs[] = {
3204	/* Unmute inputs of 0x0c - 0x0f */
3205	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3206	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3207	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3208	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3209	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3210	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3211	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3212	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3213	/* Vol output for 0x0c-0x0f */
3214	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3215	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3216	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3217	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3218	/* Set output pins 0x14-0x17 */
3219	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3220	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3221	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3222	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3223	/* Unmute output pins 0x14-0x17 */
3224	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3225	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3226	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3227	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3228	/* Set input pins 0x18-0x1c */
3229	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3230	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3231	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3232	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3233	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3234	/* Mute input pins 0x18-0x1b */
3235	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3236	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3237	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3238	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3239	/* ADC set up */
3240	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3241	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3242	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3243	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3244	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3245	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3246	/* Analog input/passthru */
3247	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3248	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3249	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3250	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3251	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3252	{ }
3253};
3254#endif
3255
3256/*
3257 */
3258
3259static const char *alc880_models[ALC880_MODEL_LAST] = {
3260	[ALC880_3ST]		= "3stack",
3261	[ALC880_TCL_S700]	= "tcl",
3262	[ALC880_3ST_DIG]	= "3stack-digout",
3263	[ALC880_CLEVO]		= "clevo",
3264	[ALC880_5ST]		= "5stack",
3265	[ALC880_5ST_DIG]	= "5stack-digout",
3266	[ALC880_W810]		= "w810",
3267	[ALC880_Z71V]		= "z71v",
3268	[ALC880_6ST]		= "6stack",
3269	[ALC880_6ST_DIG]	= "6stack-digout",
3270	[ALC880_ASUS]		= "asus",
3271	[ALC880_ASUS_W1V]	= "asus-w1v",
3272	[ALC880_ASUS_DIG]	= "asus-dig",
3273	[ALC880_ASUS_DIG2]	= "asus-dig2",
3274	[ALC880_UNIWILL_DIG]	= "uniwill",
3275	[ALC880_UNIWILL_P53]	= "uniwill-p53",
3276	[ALC880_FUJITSU]	= "fujitsu",
3277	[ALC880_F1734]		= "F1734",
3278	[ALC880_LG]		= "lg",
3279	[ALC880_LG_LW]		= "lg-lw",
3280	[ALC880_MEDION_RIM]	= "medion",
3281#ifdef CONFIG_SND_DEBUG
3282	[ALC880_TEST]		= "test",
3283#endif
3284	[ALC880_AUTO]		= "auto",
3285};
3286
3287static struct snd_pci_quirk alc880_cfg_tbl[] = {
3288	SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3289	SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3290	SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3291	SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3292	SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3293	SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3294	SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3295	SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3296	SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3297	SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3298	SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3299	SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3300	SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3301	SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3302	SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3303	SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3304	SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3305	SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3306	/* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3307	SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3308	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3309	SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3310	SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3311	SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3312	SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3313	SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
3314	SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3315	SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3316	SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3317	SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3318	SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3319	SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3320	SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3321	SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3322	SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3323	SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3324	SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3325	SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3326	SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3327	SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3328	SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3329	SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3330	SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3331	SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3332	SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3333	SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3334	SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3335	SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3336	SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3337	SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3338	SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3339	SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3340	SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3341	SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3342	SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3343	SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3344	SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3345	SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3346	SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3347	SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3348	SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3349	SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3350	SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3351	SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3352	SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3353	SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3354	SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3355	SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3356	SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
3357	SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3358	SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3359	{}
3360};
3361
3362/*
3363 * ALC880 codec presets
3364 */
3365static struct alc_config_preset alc880_presets[] = {
3366	[ALC880_3ST] = {
3367		.mixers = { alc880_three_stack_mixer },
3368		.init_verbs = { alc880_volume_init_verbs,
3369				alc880_pin_3stack_init_verbs },
3370		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3371		.dac_nids = alc880_dac_nids,
3372		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3373		.channel_mode = alc880_threestack_modes,
3374		.need_dac_fix = 1,
3375		.input_mux = &alc880_capture_source,
3376	},
3377	[ALC880_3ST_DIG] = {
3378		.mixers = { alc880_three_stack_mixer },
3379		.init_verbs = { alc880_volume_init_verbs,
3380				alc880_pin_3stack_init_verbs },
3381		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3382		.dac_nids = alc880_dac_nids,
3383		.dig_out_nid = ALC880_DIGOUT_NID,
3384		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3385		.channel_mode = alc880_threestack_modes,
3386		.need_dac_fix = 1,
3387		.input_mux = &alc880_capture_source,
3388	},
3389	[ALC880_TCL_S700] = {
3390		.mixers = { alc880_tcl_s700_mixer },
3391		.init_verbs = { alc880_volume_init_verbs,
3392				alc880_pin_tcl_S700_init_verbs,
3393				alc880_gpio2_init_verbs },
3394		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3395		.dac_nids = alc880_dac_nids,
3396		.adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
3397		.num_adc_nids = 1, /* single ADC */
3398		.hp_nid = 0x03,
3399		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3400		.channel_mode = alc880_2_jack_modes,
3401		.input_mux = &alc880_capture_source,
3402	},
3403	[ALC880_5ST] = {
3404		.mixers = { alc880_three_stack_mixer,
3405			    alc880_five_stack_mixer},
3406		.init_verbs = { alc880_volume_init_verbs,
3407				alc880_pin_5stack_init_verbs },
3408		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3409		.dac_nids = alc880_dac_nids,
3410		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3411		.channel_mode = alc880_fivestack_modes,
3412		.input_mux = &alc880_capture_source,
3413	},
3414	[ALC880_5ST_DIG] = {
3415		.mixers = { alc880_three_stack_mixer,
3416			    alc880_five_stack_mixer },
3417		.init_verbs = { alc880_volume_init_verbs,
3418				alc880_pin_5stack_init_verbs },
3419		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3420		.dac_nids = alc880_dac_nids,
3421		.dig_out_nid = ALC880_DIGOUT_NID,
3422		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3423		.channel_mode = alc880_fivestack_modes,
3424		.input_mux = &alc880_capture_source,
3425	},
3426	[ALC880_6ST] = {
3427		.mixers = { alc880_six_stack_mixer },
3428		.init_verbs = { alc880_volume_init_verbs,
3429				alc880_pin_6stack_init_verbs },
3430		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3431		.dac_nids = alc880_6st_dac_nids,
3432		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3433		.channel_mode = alc880_sixstack_modes,
3434		.input_mux = &alc880_6stack_capture_source,
3435	},
3436	[ALC880_6ST_DIG] = {
3437		.mixers = { alc880_six_stack_mixer },
3438		.init_verbs = { alc880_volume_init_verbs,
3439				alc880_pin_6stack_init_verbs },
3440		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3441		.dac_nids = alc880_6st_dac_nids,
3442		.dig_out_nid = ALC880_DIGOUT_NID,
3443		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3444		.channel_mode = alc880_sixstack_modes,
3445		.input_mux = &alc880_6stack_capture_source,
3446	},
3447	[ALC880_W810] = {
3448		.mixers = { alc880_w810_base_mixer },
3449		.init_verbs = { alc880_volume_init_verbs,
3450				alc880_pin_w810_init_verbs,
3451				alc880_gpio2_init_verbs },
3452		.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3453		.dac_nids = alc880_w810_dac_nids,
3454		.dig_out_nid = ALC880_DIGOUT_NID,
3455		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3456		.channel_mode = alc880_w810_modes,
3457		.input_mux = &alc880_capture_source,
3458	},
3459	[ALC880_Z71V] = {
3460		.mixers = { alc880_z71v_mixer },
3461		.init_verbs = { alc880_volume_init_verbs,
3462				alc880_pin_z71v_init_verbs },
3463		.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3464		.dac_nids = alc880_z71v_dac_nids,
3465		.dig_out_nid = ALC880_DIGOUT_NID,
3466		.hp_nid = 0x03,
3467		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3468		.channel_mode = alc880_2_jack_modes,
3469		.input_mux = &alc880_capture_source,
3470	},
3471	[ALC880_F1734] = {
3472		.mixers = { alc880_f1734_mixer },
3473		.init_verbs = { alc880_volume_init_verbs,
3474				alc880_pin_f1734_init_verbs },
3475		.num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3476		.dac_nids = alc880_f1734_dac_nids,
3477		.hp_nid = 0x02,
3478		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3479		.channel_mode = alc880_2_jack_modes,
3480		.input_mux = &alc880_f1734_capture_source,
3481		.unsol_event = alc880_uniwill_p53_unsol_event,
3482		.init_hook = alc880_uniwill_p53_hp_automute,
3483	},
3484	[ALC880_ASUS] = {
3485		.mixers = { alc880_asus_mixer },
3486		.init_verbs = { alc880_volume_init_verbs,
3487				alc880_pin_asus_init_verbs,
3488				alc880_gpio1_init_verbs },
3489		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3490		.dac_nids = alc880_asus_dac_nids,
3491		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3492		.channel_mode = alc880_asus_modes,
3493		.need_dac_fix = 1,
3494		.input_mux = &alc880_capture_source,
3495	},
3496	[ALC880_ASUS_DIG] = {
3497		.mixers = { alc880_asus_mixer },
3498		.init_verbs = { alc880_volume_init_verbs,
3499				alc880_pin_asus_init_verbs,
3500				alc880_gpio1_init_verbs },
3501		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3502		.dac_nids = alc880_asus_dac_nids,
3503		.dig_out_nid = ALC880_DIGOUT_NID,
3504		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3505		.channel_mode = alc880_asus_modes,
3506		.need_dac_fix = 1,
3507		.input_mux = &alc880_capture_source,
3508	},
3509	[ALC880_ASUS_DIG2] = {
3510		.mixers = { alc880_asus_mixer },
3511		.init_verbs = { alc880_volume_init_verbs,
3512				alc880_pin_asus_init_verbs,
3513				alc880_gpio2_init_verbs }, /* use GPIO2 */
3514		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3515		.dac_nids = alc880_asus_dac_nids,
3516		.dig_out_nid = ALC880_DIGOUT_NID,
3517		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3518		.channel_mode = alc880_asus_modes,
3519		.need_dac_fix = 1,
3520		.input_mux = &alc880_capture_source,
3521	},
3522	[ALC880_ASUS_W1V] = {
3523		.mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3524		.init_verbs = { alc880_volume_init_verbs,
3525				alc880_pin_asus_init_verbs,
3526				alc880_gpio1_init_verbs },
3527		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3528		.dac_nids = alc880_asus_dac_nids,
3529		.dig_out_nid = ALC880_DIGOUT_NID,
3530		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3531		.channel_mode = alc880_asus_modes,
3532		.need_dac_fix = 1,
3533		.input_mux = &alc880_capture_source,
3534	},
3535	[ALC880_UNIWILL_DIG] = {
3536		.mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
3537		.init_verbs = { alc880_volume_init_verbs,
3538				alc880_pin_asus_init_verbs },
3539		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3540		.dac_nids = alc880_asus_dac_nids,
3541		.dig_out_nid = ALC880_DIGOUT_NID,
3542		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3543		.channel_mode = alc880_asus_modes,
3544		.need_dac_fix = 1,
3545		.input_mux = &alc880_capture_source,
3546	},
3547	[ALC880_UNIWILL] = {
3548		.mixers = { alc880_uniwill_mixer },
3549		.init_verbs = { alc880_volume_init_verbs,
3550				alc880_uniwill_init_verbs },
3551		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3552		.dac_nids = alc880_asus_dac_nids,
3553		.dig_out_nid = ALC880_DIGOUT_NID,
3554		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3555		.channel_mode = alc880_threestack_modes,
3556		.need_dac_fix = 1,
3557		.input_mux = &alc880_capture_source,
3558		.unsol_event = alc880_uniwill_unsol_event,
3559		.init_hook = alc880_uniwill_automute,
3560	},
3561	[ALC880_UNIWILL_P53] = {
3562		.mixers = { alc880_uniwill_p53_mixer },
3563		.init_verbs = { alc880_volume_init_verbs,
3564				alc880_uniwill_p53_init_verbs },
3565		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3566		.dac_nids = alc880_asus_dac_nids,
3567		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3568		.channel_mode = alc880_threestack_modes,
3569		.input_mux = &alc880_capture_source,
3570		.unsol_event = alc880_uniwill_p53_unsol_event,
3571		.init_hook = alc880_uniwill_p53_hp_automute,
3572	},
3573	[ALC880_FUJITSU] = {
3574		.mixers = { alc880_fujitsu_mixer,
3575			    alc880_pcbeep_mixer, },
3576		.init_verbs = { alc880_volume_init_verbs,
3577				alc880_uniwill_p53_init_verbs,
3578	       			alc880_beep_init_verbs },
3579		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3580		.dac_nids = alc880_dac_nids,
3581		.dig_out_nid = ALC880_DIGOUT_NID,
3582		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3583		.channel_mode = alc880_2_jack_modes,
3584		.input_mux = &alc880_capture_source,
3585		.unsol_event = alc880_uniwill_p53_unsol_event,
3586		.init_hook = alc880_uniwill_p53_hp_automute,
3587	},
3588	[ALC880_CLEVO] = {
3589		.mixers = { alc880_three_stack_mixer },
3590		.init_verbs = { alc880_volume_init_verbs,
3591				alc880_pin_clevo_init_verbs },
3592		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3593		.dac_nids = alc880_dac_nids,
3594		.hp_nid = 0x03,
3595		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3596		.channel_mode = alc880_threestack_modes,
3597		.need_dac_fix = 1,
3598		.input_mux = &alc880_capture_source,
3599	},
3600	[ALC880_LG] = {
3601		.mixers = { alc880_lg_mixer },
3602		.init_verbs = { alc880_volume_init_verbs,
3603				alc880_lg_init_verbs },
3604		.num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3605		.dac_nids = alc880_lg_dac_nids,
3606		.dig_out_nid = ALC880_DIGOUT_NID,
3607		.num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3608		.channel_mode = alc880_lg_ch_modes,
3609		.need_dac_fix = 1,
3610		.input_mux = &alc880_lg_capture_source,
3611		.unsol_event = alc880_lg_unsol_event,
3612		.init_hook = alc880_lg_automute,
3613#ifdef CONFIG_SND_HDA_POWER_SAVE
3614		.loopbacks = alc880_lg_loopbacks,
3615#endif
3616	},
3617	[ALC880_LG_LW] = {
3618		.mixers = { alc880_lg_lw_mixer },
3619		.init_verbs = { alc880_volume_init_verbs,
3620				alc880_lg_lw_init_verbs },
3621		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3622		.dac_nids = alc880_dac_nids,
3623		.dig_out_nid = ALC880_DIGOUT_NID,
3624		.num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3625		.channel_mode = alc880_lg_lw_modes,
3626		.input_mux = &alc880_lg_lw_capture_source,
3627		.unsol_event = alc880_lg_lw_unsol_event,
3628		.init_hook = alc880_lg_lw_automute,
3629	},
3630	[ALC880_MEDION_RIM] = {
3631		.mixers = { alc880_medion_rim_mixer },
3632		.init_verbs = { alc880_volume_init_verbs,
3633				alc880_medion_rim_init_verbs,
3634				alc_gpio2_init_verbs },
3635		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3636		.dac_nids = alc880_dac_nids,
3637		.dig_out_nid = ALC880_DIGOUT_NID,
3638		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3639		.channel_mode = alc880_2_jack_modes,
3640		.input_mux = &alc880_medion_rim_capture_source,
3641		.unsol_event = alc880_medion_rim_unsol_event,
3642		.init_hook = alc880_medion_rim_automute,
3643	},
3644#ifdef CONFIG_SND_DEBUG
3645	[ALC880_TEST] = {
3646		.mixers = { alc880_test_mixer },
3647		.init_verbs = { alc880_test_init_verbs },
3648		.num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3649		.dac_nids = alc880_test_dac_nids,
3650		.dig_out_nid = ALC880_DIGOUT_NID,
3651		.num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3652		.channel_mode = alc880_test_modes,
3653		.input_mux = &alc880_test_capture_source,
3654	},
3655#endif
3656};
3657
3658/*
3659 * Automatic parse of I/O pins from the BIOS configuration
3660 */
3661
3662enum {
3663	ALC_CTL_WIDGET_VOL,
3664	ALC_CTL_WIDGET_MUTE,
3665	ALC_CTL_BIND_MUTE,
3666};
3667static struct snd_kcontrol_new alc880_control_templates[] = {
3668	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3669	HDA_CODEC_MUTE(NULL, 0, 0, 0),
3670	HDA_BIND_MUTE(NULL, 0, 0, 0),
3671};
3672
3673/* add dynamic controls */
3674static int add_control(struct alc_spec *spec, int type, const char *name,
3675		       unsigned long val)
3676{
3677	struct snd_kcontrol_new *knew;
3678
3679	snd_array_init(&spec->kctls, sizeof(*knew), 32);
3680	knew = snd_array_new(&spec->kctls);
3681	if (!knew)
3682		return -ENOMEM;
3683	*knew = alc880_control_templates[type];
3684	knew->name = kstrdup(name, GFP_KERNEL);
3685	if (!knew->name)
3686		return -ENOMEM;
3687	knew->private_value = val;
3688	return 0;
3689}
3690
3691#define alc880_is_fixed_pin(nid)	((nid) >= 0x14 && (nid) <= 0x17)
3692#define alc880_fixed_pin_idx(nid)	((nid) - 0x14)
3693#define alc880_is_multi_pin(nid)	((nid) >= 0x18)
3694#define alc880_multi_pin_idx(nid)	((nid) - 0x18)
3695#define alc880_is_input_pin(nid)	((nid) >= 0x18)
3696#define alc880_input_pin_idx(nid)	((nid) - 0x18)
3697#define alc880_idx_to_dac(nid)		((nid) + 0x02)
3698#define alc880_dac_to_idx(nid)		((nid) - 0x02)
3699#define alc880_idx_to_mixer(nid)	((nid) + 0x0c)
3700#define alc880_idx_to_selector(nid)	((nid) + 0x10)
3701#define ALC880_PIN_CD_NID		0x1c
3702
3703/* fill in the dac_nids table from the parsed pin configuration */
3704static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3705				     const struct auto_pin_cfg *cfg)
3706{
3707	hda_nid_t nid;
3708	int assigned[4];
3709	int i, j;
3710
3711	memset(assigned, 0, sizeof(assigned));
3712	spec->multiout.dac_nids = spec->private_dac_nids;
3713
3714	/* check the pins hardwired to audio widget */
3715	for (i = 0; i < cfg->line_outs; i++) {
3716		nid = cfg->line_out_pins[i];
3717		if (alc880_is_fixed_pin(nid)) {
3718			int idx = alc880_fixed_pin_idx(nid);
3719			spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3720			assigned[idx] = 1;
3721		}
3722	}
3723	/* left pins can be connect to any audio widget */
3724	for (i = 0; i < cfg->line_outs; i++) {
3725		nid = cfg->line_out_pins[i];
3726		if (alc880_is_fixed_pin(nid))
3727			continue;
3728		/* search for an empty channel */
3729		for (j = 0; j < cfg->line_outs; j++) {
3730			if (!assigned[j]) {
3731				spec->multiout.dac_nids[i] =
3732					alc880_idx_to_dac(j);
3733				assigned[j] = 1;
3734				break;
3735			}
3736		}
3737	}
3738	spec->multiout.num_dacs = cfg->line_outs;
3739	return 0;
3740}
3741
3742/* add playback controls from the parsed DAC table */
3743static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3744					     const struct auto_pin_cfg *cfg)
3745{
3746	char name[32];
3747	static const char *chname[4] = {
3748		"Front", "Surround", NULL /*CLFE*/, "Side"
3749	};
3750	hda_nid_t nid;
3751	int i, err;
3752
3753	for (i = 0; i < cfg->line_outs; i++) {
3754		if (!spec->multiout.dac_nids[i])
3755			continue;
3756		nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3757		if (i == 2) {
3758			/* Center/LFE */
3759			err = add_control(spec, ALC_CTL_WIDGET_VOL,
3760					  "Center Playback Volume",
3761					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3762							      HDA_OUTPUT));
3763			if (err < 0)
3764				return err;
3765			err = add_control(spec, ALC_CTL_WIDGET_VOL,
3766					  "LFE Playback Volume",
3767					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3768							      HDA_OUTPUT));
3769			if (err < 0)
3770				return err;
3771			err = add_control(spec, ALC_CTL_BIND_MUTE,
3772					  "Center Playback Switch",
3773					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3774							      HDA_INPUT));
3775			if (err < 0)
3776				return err;
3777			err = add_control(spec, ALC_CTL_BIND_MUTE,
3778					  "LFE Playback Switch",
3779					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3780							      HDA_INPUT));
3781			if (err < 0)
3782				return err;
3783		} else {
3784			sprintf(name, "%s Playback Volume", chname[i]);
3785			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3786					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3787							      HDA_OUTPUT));
3788			if (err < 0)
3789				return err;
3790			sprintf(name, "%s Playback Switch", chname[i]);
3791			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3792					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3793							      HDA_INPUT));
3794			if (err < 0)
3795				return err;
3796		}
3797	}
3798	return 0;
3799}
3800
3801/* add playback controls for speaker and HP outputs */
3802static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3803					const char *pfx)
3804{
3805	hda_nid_t nid;
3806	int err;
3807	char name[32];
3808
3809	if (!pin)
3810		return 0;
3811
3812	if (alc880_is_fixed_pin(pin)) {
3813		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3814		/* specify the DAC as the extra output */
3815		if (!spec->multiout.hp_nid)
3816			spec->multiout.hp_nid = nid;
3817		else
3818			spec->multiout.extra_out_nid[0] = nid;
3819		/* control HP volume/switch on the output mixer amp */
3820		nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3821		sprintf(name, "%s Playback Volume", pfx);
3822		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3823				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3824		if (err < 0)
3825			return err;
3826		sprintf(name, "%s Playback Switch", pfx);
3827		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3828				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3829		if (err < 0)
3830			return err;
3831	} else if (alc880_is_multi_pin(pin)) {
3832		/* set manual connection */
3833		/* we have only a switch on HP-out PIN */
3834		sprintf(name, "%s Playback Switch", pfx);
3835		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3836				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3837		if (err < 0)
3838			return err;
3839	}
3840	return 0;
3841}
3842
3843/* create input playback/capture controls for the given pin */
3844static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3845			    const char *ctlname,
3846			    int idx, hda_nid_t mix_nid)
3847{
3848	char name[32];
3849	int err;
3850
3851	sprintf(name, "%s Playback Volume", ctlname);
3852	err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3853			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3854	if (err < 0)
3855		return err;
3856	sprintf(name, "%s Playback Switch", ctlname);
3857	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3858			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3859	if (err < 0)
3860		return err;
3861	return 0;
3862}
3863
3864/* create playback/capture controls for input pins */
3865static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3866						const struct auto_pin_cfg *cfg)
3867{
3868	struct hda_input_mux *imux = &spec->private_imux;
3869	int i, err, idx;
3870
3871	for (i = 0; i < AUTO_PIN_LAST; i++) {
3872		if (alc880_is_input_pin(cfg->input_pins[i])) {
3873			idx = alc880_input_pin_idx(cfg->input_pins[i]);
3874			err = new_analog_input(spec, cfg->input_pins[i],
3875					       auto_pin_cfg_labels[i],
3876					       idx, 0x0b);
3877			if (err < 0)
3878				return err;
3879			imux->items[imux->num_items].label =
3880				auto_pin_cfg_labels[i];
3881			imux->items[imux->num_items].index =
3882				alc880_input_pin_idx(cfg->input_pins[i]);
3883			imux->num_items++;
3884		}
3885	}
3886	return 0;
3887}
3888
3889static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
3890			       unsigned int pin_type)
3891{
3892	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3893			    pin_type);
3894	/* unmute pin */
3895	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3896			    AMP_OUT_UNMUTE);
3897}
3898
3899static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3900					      hda_nid_t nid, int pin_type,
3901					      int dac_idx)
3902{
3903	alc_set_pin_output(codec, nid, pin_type);
3904	/* need the manual connection? */
3905	if (alc880_is_multi_pin(nid)) {
3906		struct alc_spec *spec = codec->spec;
3907		int idx = alc880_multi_pin_idx(nid);
3908		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3909				    AC_VERB_SET_CONNECT_SEL,
3910				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3911	}
3912}
3913
3914static int get_pin_type(int line_out_type)
3915{
3916	if (line_out_type == AUTO_PIN_HP_OUT)
3917		return PIN_HP;
3918	else
3919		return PIN_OUT;
3920}
3921
3922static void alc880_auto_init_multi_out(struct hda_codec *codec)
3923{
3924	struct alc_spec *spec = codec->spec;
3925	int i;
3926
3927	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3928	for (i = 0; i < spec->autocfg.line_outs; i++) {
3929		hda_nid_t nid = spec->autocfg.line_out_pins[i];
3930		int pin_type = get_pin_type(spec->autocfg.line_out_type);
3931		alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3932	}
3933}
3934
3935static void alc880_auto_init_extra_out(struct hda_codec *codec)
3936{
3937	struct alc_spec *spec = codec->spec;
3938	hda_nid_t pin;
3939
3940	pin = spec->autocfg.speaker_pins[0];
3941	if (pin) /* connect to front */
3942		alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3943	pin = spec->autocfg.hp_pins[0];
3944	if (pin) /* connect to front */
3945		alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3946}
3947
3948static void alc880_auto_init_analog_input(struct hda_codec *codec)
3949{
3950	struct alc_spec *spec = codec->spec;
3951	int i;
3952
3953	for (i = 0; i < AUTO_PIN_LAST; i++) {
3954		hda_nid_t nid = spec->autocfg.input_pins[i];
3955		if (alc880_is_input_pin(nid)) {
3956			snd_hda_codec_write(codec, nid, 0,
3957					    AC_VERB_SET_PIN_WIDGET_CONTROL,
3958					    i <= AUTO_PIN_FRONT_MIC ?
3959					    PIN_VREF80 : PIN_IN);
3960			if (nid != ALC880_PIN_CD_NID)
3961				snd_hda_codec_write(codec, nid, 0,
3962						    AC_VERB_SET_AMP_GAIN_MUTE,
3963						    AMP_OUT_MUTE);
3964		}
3965	}
3966}
3967
3968/* parse the BIOS configuration and set up the alc_spec */
3969/* return 1 if successful, 0 if the proper config is not found,
3970 * or a negative error code
3971 */
3972static int alc880_parse_auto_config(struct hda_codec *codec)
3973{
3974	struct alc_spec *spec = codec->spec;
3975	int err;
3976	static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3977
3978	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3979					   alc880_ignore);
3980	if (err < 0)
3981		return err;
3982	if (!spec->autocfg.line_outs)
3983		return 0; /* can't find valid BIOS pin config */
3984
3985	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3986	if (err < 0)
3987		return err;
3988	err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3989	if (err < 0)
3990		return err;
3991	err = alc880_auto_create_extra_out(spec,
3992					   spec->autocfg.speaker_pins[0],
3993					   "Speaker");
3994	if (err < 0)
3995		return err;
3996	err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3997					   "Headphone");
3998	if (err < 0)
3999		return err;
4000	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
4001	if (err < 0)
4002		return err;
4003
4004	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4005
4006	if (spec->autocfg.dig_out_pin)
4007		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
4008	if (spec->autocfg.dig_in_pin)
4009		spec->dig_in_nid = ALC880_DIGIN_NID;
4010
4011	if (spec->kctls.list)
4012		add_mixer(spec, spec->kctls.list);
4013
4014	add_verb(spec, alc880_volume_init_verbs);
4015
4016	spec->num_mux_defs = 1;
4017	spec->input_mux = &spec->private_imux;
4018
4019	store_pin_configs(codec);
4020	return 1;
4021}
4022
4023/* additional initialization for auto-configuration model */
4024static void alc880_auto_init(struct hda_codec *codec)
4025{
4026	struct alc_spec *spec = codec->spec;
4027	alc880_auto_init_multi_out(codec);
4028	alc880_auto_init_extra_out(codec);
4029	alc880_auto_init_analog_input(codec);
4030	if (spec->unsol_event)
4031		alc_inithook(codec);
4032}
4033
4034/*
4035 * OK, here we have finally the patch for ALC880
4036 */
4037
4038static void set_capture_mixer(struct alc_spec *spec)
4039{
4040	static struct snd_kcontrol_new *caps[3] = {
4041		alc_capture_mixer1,
4042		alc_capture_mixer2,
4043		alc_capture_mixer3,
4044	};
4045	if (spec->num_adc_nids > 0 && spec->num_adc_nids < 3)
4046		spec->cap_mixer = caps[spec->num_adc_nids - 1];
4047}
4048
4049static int patch_alc880(struct hda_codec *codec)
4050{
4051	struct alc_spec *spec;
4052	int board_config;
4053	int err;
4054
4055	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4056	if (spec == NULL)
4057		return -ENOMEM;
4058
4059	codec->spec = spec;
4060
4061	board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4062						  alc880_models,
4063						  alc880_cfg_tbl);
4064	if (board_config < 0) {
4065		printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
4066		       "trying auto-probe from BIOS...\n");
4067		board_config = ALC880_AUTO;
4068	}
4069
4070	if (board_config == ALC880_AUTO) {
4071		/* automatic parse from the BIOS config */
4072		err = alc880_parse_auto_config(codec);
4073		if (err < 0) {
4074			alc_free(codec);
4075			return err;
4076		} else if (!err) {
4077			printk(KERN_INFO
4078			       "hda_codec: Cannot set up configuration "
4079			       "from BIOS.  Using 3-stack mode...\n");
4080			board_config = ALC880_3ST;
4081		}
4082	}
4083
4084	if (board_config != ALC880_AUTO)
4085		setup_preset(spec, &alc880_presets[board_config]);
4086
4087	spec->stream_name_analog = "ALC880 Analog";
4088	spec->stream_analog_playback = &alc880_pcm_analog_playback;
4089	spec->stream_analog_capture = &alc880_pcm_analog_capture;
4090	spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
4091
4092	spec->stream_name_digital = "ALC880 Digital";
4093	spec->stream_digital_playback = &alc880_pcm_digital_playback;
4094	spec->stream_digital_capture = &alc880_pcm_digital_capture;
4095
4096	if (!spec->adc_nids && spec->input_mux) {
4097		/* check whether NID 0x07 is valid */
4098		unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
4099		/* get type */
4100		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
4101		if (wcap != AC_WID_AUD_IN) {
4102			spec->adc_nids = alc880_adc_nids_alt;
4103			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
4104		} else {
4105			spec->adc_nids = alc880_adc_nids;
4106			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
4107		}
4108	}
4109	set_capture_mixer(spec);
4110
4111	spec->vmaster_nid = 0x0c;
4112
4113	codec->patch_ops = alc_patch_ops;
4114	if (board_config == ALC880_AUTO)
4115		spec->init_hook = alc880_auto_init;
4116#ifdef CONFIG_SND_HDA_POWER_SAVE
4117	if (!spec->loopback.amplist)
4118		spec->loopback.amplist = alc880_loopbacks;
4119#endif
4120
4121	return 0;
4122}
4123
4124
4125/*
4126 * ALC260 support
4127 */
4128
4129static hda_nid_t alc260_dac_nids[1] = {
4130	/* front */
4131	0x02,
4132};
4133
4134static hda_nid_t alc260_adc_nids[1] = {
4135	/* ADC0 */
4136	0x04,
4137};
4138
4139static hda_nid_t alc260_adc_nids_alt[1] = {
4140	/* ADC1 */
4141	0x05,
4142};
4143
4144/* NIDs used when simultaneous access to both ADCs makes sense.  Note that
4145 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4146 */
4147static hda_nid_t alc260_dual_adc_nids[2] = {
4148	/* ADC0, ADC1 */
4149	0x04, 0x05
4150};
4151
4152#define ALC260_DIGOUT_NID	0x03
4153#define ALC260_DIGIN_NID	0x06
4154
4155static struct hda_input_mux alc260_capture_source = {
4156	.num_items = 4,
4157	.items = {
4158		{ "Mic", 0x0 },
4159		{ "Front Mic", 0x1 },
4160		{ "Line", 0x2 },
4161		{ "CD", 0x4 },
4162	},
4163};
4164
4165/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
4166 * headphone jack and the internal CD lines since these are the only pins at
4167 * which audio can appear.  For flexibility, also allow the option of
4168 * recording the mixer output on the second ADC (ADC0 doesn't have a
4169 * connection to the mixer output).
4170 */
4171static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4172	{
4173		.num_items = 3,
4174		.items = {
4175			{ "Mic/Line", 0x0 },
4176			{ "CD", 0x4 },
4177			{ "Headphone", 0x2 },
4178		},
4179	},
4180	{
4181		.num_items = 4,
4182		.items = {
4183			{ "Mic/Line", 0x0 },
4184			{ "CD", 0x4 },
4185			{ "Headphone", 0x2 },
4186			{ "Mixer", 0x5 },
4187		},
4188	},
4189
4190};
4191
4192/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4193 * the Fujitsu S702x, but jacks are marked differently.
4194 */
4195static struct hda_input_mux alc260_acer_capture_sources[2] = {
4196	{
4197		.num_items = 4,
4198		.items = {
4199			{ "Mic", 0x0 },
4200			{ "Line", 0x2 },
4201			{ "CD", 0x4 },
4202			{ "Headphone", 0x5 },
4203		},
4204	},
4205	{
4206		.num_items = 5,
4207		.items = {
4208			{ "Mic", 0x0 },
4209			{ "Line", 0x2 },
4210			{ "CD", 0x4 },
4211			{ "Headphone", 0x6 },
4212			{ "Mixer", 0x5 },
4213		},
4214	},
4215};
4216/*
4217 * This is just place-holder, so there's something for alc_build_pcms to look
4218 * at when it calculates the maximum number of channels. ALC260 has no mixer
4219 * element which allows changing the channel mode, so the verb list is
4220 * never used.
4221 */
4222static struct hda_channel_mode alc260_modes[1] = {
4223	{ 2, NULL },
4224};
4225
4226
4227/* Mixer combinations
4228 *
4229 * basic: base_output + input + pc_beep + capture
4230 * HP: base_output + input + capture_alt
4231 * HP_3013: hp_3013 + input + capture
4232 * fujitsu: fujitsu + capture
4233 * acer: acer + capture
4234 */
4235
4236static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4237	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4238	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4239	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4240	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4241	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4242	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4243	{ } /* end */
4244};
4245
4246static struct snd_kcontrol_new alc260_input_mixer[] = {
4247	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4248	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4249	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4250	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4251	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4252	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4253	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4254	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4255	{ } /* end */
4256};
4257
4258static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
4259	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
4260	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
4261	{ } /* end */
4262};
4263
4264/* update HP, line and mono out pins according to the master switch */
4265static void alc260_hp_master_update(struct hda_codec *codec,
4266				    hda_nid_t hp, hda_nid_t line,
4267				    hda_nid_t mono)
4268{
4269	struct alc_spec *spec = codec->spec;
4270	unsigned int val = spec->master_sw ? PIN_HP : 0;
4271	/* change HP and line-out pins */
4272	snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4273			    val);
4274	snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4275			    val);
4276	/* mono (speaker) depending on the HP jack sense */
4277	val = (val && !spec->jack_present) ? PIN_OUT : 0;
4278	snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4279			    val);
4280}
4281
4282static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4283				   struct snd_ctl_elem_value *ucontrol)
4284{
4285	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4286	struct alc_spec *spec = codec->spec;
4287	*ucontrol->value.integer.value = spec->master_sw;
4288	return 0;
4289}
4290
4291static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4292				   struct snd_ctl_elem_value *ucontrol)
4293{
4294	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4295	struct alc_spec *spec = codec->spec;
4296	int val = !!*ucontrol->value.integer.value;
4297	hda_nid_t hp, line, mono;
4298
4299	if (val == spec->master_sw)
4300		return 0;
4301	spec->master_sw = val;
4302	hp = (kcontrol->private_value >> 16) & 0xff;
4303	line = (kcontrol->private_value >> 8) & 0xff;
4304	mono = kcontrol->private_value & 0xff;
4305	alc260_hp_master_update(codec, hp, line, mono);
4306	return 1;
4307}
4308
4309static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4310	{
4311		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4312		.name = "Master Playback Switch",
4313		.info = snd_ctl_boolean_mono_info,
4314		.get = alc260_hp_master_sw_get,
4315		.put = alc260_hp_master_sw_put,
4316		.private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4317	},
4318	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4319	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4320	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4321	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4322	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4323			      HDA_OUTPUT),
4324	HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4325	{ } /* end */
4326};
4327
4328static struct hda_verb alc260_hp_unsol_verbs[] = {
4329	{0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4330	{},
4331};
4332
4333static void alc260_hp_automute(struct hda_codec *codec)
4334{
4335	struct alc_spec *spec = codec->spec;
4336	unsigned int present;
4337
4338	present = snd_hda_codec_read(codec, 0x10, 0,
4339				     AC_VERB_GET_PIN_SENSE, 0);
4340	spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4341	alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4342}
4343
4344static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4345{
4346	if ((res >> 26) == ALC880_HP_EVENT)
4347		alc260_hp_automute(codec);
4348}
4349
4350static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4351	{
4352		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4353		.name = "Master Playback Switch",
4354		.info = snd_ctl_boolean_mono_info,
4355		.get = alc260_hp_master_sw_get,
4356		.put = alc260_hp_master_sw_put,
4357		.private_value = (0x10 << 16) | (0x15 << 8) | 0x11
4358	},
4359	HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4360	HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4361	HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4362	HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4363	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4364	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4365	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4366	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4367	{ } /* end */
4368};
4369
4370static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4371	.ops = &snd_hda_bind_vol,
4372	.values = {
4373		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4374		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4375		HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4376		0
4377	},
4378};
4379
4380static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4381	.ops = &snd_hda_bind_sw,
4382	.values = {
4383		HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4384		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4385		0
4386	},
4387};
4388
4389static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4390	HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4391	HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4392	HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4393	HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4394	{ } /* end */
4395};
4396
4397static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4398	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4399	{},
4400};
4401
4402static void alc260_hp_3013_automute(struct hda_codec *codec)
4403{
4404	struct alc_spec *spec = codec->spec;
4405	unsigned int present;
4406
4407	present = snd_hda_codec_read(codec, 0x15, 0,
4408				     AC_VERB_GET_PIN_SENSE, 0);
4409	spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4410	alc260_hp_master_update(codec, 0x10, 0x15, 0x11);
4411}
4412
4413static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4414				       unsigned int res)
4415{
4416	if ((res >> 26) == ALC880_HP_EVENT)
4417		alc260_hp_3013_automute(codec);
4418}
4419
4420static void alc260_hp_3012_automute(struct hda_codec *codec)
4421{
4422	unsigned int present, bits;
4423
4424	present = snd_hda_codec_read(codec, 0x10, 0,
4425			AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4426
4427	bits = present ? 0 : PIN_OUT;
4428	snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4429			    bits);
4430	snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4431			    bits);
4432	snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4433			    bits);
4434}
4435
4436static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4437				       unsigned int res)
4438{
4439	if ((res >> 26) == ALC880_HP_EVENT)
4440		alc260_hp_3012_automute(codec);
4441}
4442
4443/* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12,
4444 * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
4445 */
4446static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4447	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4448	HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4449	ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4450	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4451	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4452	HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4453	HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4454	ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4455	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4456	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4457	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4458	HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4459	{ } /* end */
4460};
4461
4462/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
4463 * versions of the ALC260 don't act on requests to enable mic bias from NID
4464 * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
4465 * datasheet doesn't mention this restriction.  At this stage it's not clear
4466 * whether this behaviour is intentional or is a hardware bug in chip
4467 * revisions available in early 2006.  Therefore for now allow the
4468 * "Headphone Jack Mode" control to span all choices, but if it turns out
4469 * that the lack of mic bias for this NID is intentional we could change the
4470 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4471 *
4472 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4473 * don't appear to make the mic bias available from the "line" jack, even
4474 * though the NID used for this jack (0x14) can supply it.  The theory is
4475 * that perhaps Acer have included blocking capacitors between the ALC260
4476 * and the output jack.  If this turns out to be the case for all such
4477 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4478 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4479 *
4480 * The C20x Tablet series have a mono internal speaker which is controlled
4481 * via the chip's Mono sum widget and pin complex, so include the necessary
4482 * controls for such models.  On models without a "mono speaker" the control
4483 * won't do anything.
4484 */
4485static struct snd_kcontrol_new alc260_acer_mixer[] = {
4486	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4487	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4488	ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4489	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4490			      HDA_OUTPUT),
4491	HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4492			   HDA_INPUT),
4493	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4494	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4495	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4496	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4497	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4498	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4499	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4500	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4501	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4502	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4503	{ } /* end */
4504};
4505
4506/* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4507 * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
4508 */
4509static struct snd_kcontrol_new alc260_will_mixer[] = {
4510	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4511	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4512	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4513	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4514	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4515	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4516	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4517	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4518	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4519	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4520	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4521	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4522	{ } /* end */
4523};
4524
4525/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4526 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4527 */
4528static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4529	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4530	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4531	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4532	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4533	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4534	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4535	HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4536	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4537	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4538	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4539	{ } /* end */
4540};
4541
4542/*
4543 * initialization verbs
4544 */
4545static struct hda_verb alc260_init_verbs[] = {
4546	/* Line In pin widget for input */
4547	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4548	/* CD pin widget for input */
4549	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4550	/* Mic1 (rear panel) pin widget for input and vref at 80% */
4551	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4552	/* Mic2 (front panel) pin widget for input and vref at 80% */
4553	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4554	/* LINE-2 is used for line-out in rear */
4555	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4556	/* select line-out */
4557	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4558	/* LINE-OUT pin */
4559	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4560	/* enable HP */
4561	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4562	/* enable Mono */
4563	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4564	/* mute capture amp left and right */
4565	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4566	/* set connection select to line in (default select for this ADC) */
4567	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4568	/* mute capture amp left and right */
4569	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4570	/* set connection select to line in (default select for this ADC) */
4571	{0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4572	/* set vol=0 Line-Out mixer amp left and right */
4573	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4574	/* unmute pin widget amp left and right (no gain on this amp) */
4575	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4576	/* set vol=0 HP mixer amp left and right */
4577	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4578	/* unmute pin widget amp left and right (no gain on this amp) */
4579	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4580	/* set vol=0 Mono mixer amp left and right */
4581	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4582	/* unmute pin widget amp left and right (no gain on this amp) */
4583	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4584	/* unmute LINE-2 out pin */
4585	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4586	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4587	 * Line In 2 = 0x03
4588	 */
4589	/* mute analog inputs */
4590	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4591	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4592	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4593	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4594	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4595	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4596	/* mute Front out path */
4597	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4598	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4599	/* mute Headphone out path */
4600	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4601	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4602	/* mute Mono out path */
4603	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4604	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4605	{ }
4606};
4607
4608#if 0 /* should be identical with alc260_init_verbs? */
4609static struct hda_verb alc260_hp_init_verbs[] = {
4610	/* Headphone and output */
4611	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4612	/* mono output */
4613	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4614	/* Mic1 (rear panel) pin widget for input and vref at 80% */
4615	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4616	/* Mic2 (front panel) pin widget for input and vref at 80% */
4617	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4618	/* Line In pin widget for input */
4619	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4620	/* Line-2 pin widget for output */
4621	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4622	/* CD pin widget for input */
4623	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4624	/* unmute amp left and right */
4625	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4626	/* set connection select to line in (default select for this ADC) */
4627	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4628	/* unmute Line-Out mixer amp left and right (volume = 0) */
4629	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4630	/* mute pin widget amp left and right (no gain on this amp) */
4631	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4632	/* unmute HP mixer amp left and right (volume = 0) */
4633	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4634	/* mute pin widget amp left and right (no gain on this amp) */
4635	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4636	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4637	 * Line In 2 = 0x03
4638	 */
4639	/* mute analog inputs */
4640	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4641	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4642	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4643	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4644	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4645	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4646	/* Unmute Front out path */
4647	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4648	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4649	/* Unmute Headphone out path */
4650	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4651	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4652	/* Unmute Mono out path */
4653	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4654	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4655	{ }
4656};
4657#endif
4658
4659static struct hda_verb alc260_hp_3013_init_verbs[] = {
4660	/* Line out and output */
4661	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4662	/* mono output */
4663	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4664	/* Mic1 (rear panel) pin widget for input and vref at 80% */
4665	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4666	/* Mic2 (front panel) pin widget for input and vref at 80% */
4667	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4668	/* Line In pin widget for input */
4669	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4670	/* Headphone pin widget for output */
4671	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4672	/* CD pin widget for input */
4673	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4674	/* unmute amp left and right */
4675	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4676	/* set connection select to line in (default select for this ADC) */
4677	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4678	/* unmute Line-Out mixer amp left and right (volume = 0) */
4679	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4680	/* mute pin widget amp left and right (no gain on this amp) */
4681	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4682	/* unmute HP mixer amp left and right (volume = 0) */
4683	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4684	/* mute pin widget amp left and right (no gain on this amp) */
4685	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4686	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4687	 * Line In 2 = 0x03
4688	 */
4689	/* mute analog inputs */
4690	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4691	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4692	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4693	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4694	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4695	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4696	/* Unmute Front out path */
4697	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4698	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4699	/* Unmute Headphone out path */
4700	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4701	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4702	/* Unmute Mono out path */
4703	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4704	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4705	{ }
4706};
4707
4708/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4709 * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4710 * audio = 0x16, internal speaker = 0x10.
4711 */
4712static struct hda_verb alc260_fujitsu_init_verbs[] = {
4713	/* Disable all GPIOs */
4714	{0x01, AC_VERB_SET_GPIO_MASK, 0},
4715	/* Internal speaker is connected to headphone pin */
4716	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4717	/* Headphone/Line-out jack connects to Line1 pin; make it an output */
4718	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4719	/* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4720	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4721	/* Ensure all other unused pins are disabled and muted. */
4722	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4723	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4724	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4725	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4726	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4727	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4728	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4729	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4730
4731	/* Disable digital (SPDIF) pins */
4732	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4733	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4734
4735	/* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4736	 * when acting as an output.
4737	 */
4738	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4739
4740	/* Start with output sum widgets muted and their output gains at min */
4741	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4742	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4743	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4744	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4745	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4746	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4747	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4748	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4749	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4750
4751	/* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4752	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4753	/* Unmute Line1 pin widget output buffer since it starts as an output.
4754	 * If the pin mode is changed by the user the pin mode control will
4755	 * take care of enabling the pin's input/output buffers as needed.
4756	 * Therefore there's no need to enable the input buffer at this
4757	 * stage.
4758	 */
4759	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4760	/* Unmute input buffer of pin widget used for Line-in (no equiv
4761	 * mixer ctrl)
4762	 */
4763	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4764
4765	/* Mute capture amp left and right */
4766	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4767	/* Set ADC connection select to match default mixer setting - line
4768	 * in (on mic1 pin)
4769	 */
4770	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4771
4772	/* Do the same for the second ADC: mute capture input amp and
4773	 * set ADC connection to line in (on mic1 pin)
4774	 */
4775	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4776	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4777
4778	/* Mute all inputs to mixer widget (even unconnected ones) */
4779	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4780	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4781	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4782	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4783	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4784	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4785	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4786	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4787
4788	{ }
4789};
4790
4791/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4792 * similar laptops (adapted from Fujitsu init verbs).
4793 */
4794static struct hda_verb alc260_acer_init_verbs[] = {
4795	/* On TravelMate laptops, GPIO 0 enables the internal speaker and
4796	 * the headphone jack.  Turn this on and rely on the standard mute
4797	 * methods whenever the user wants to turn these outputs off.
4798	 */
4799	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4800	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4801	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4802	/* Internal speaker/Headphone jack is connected to Line-out pin */
4803	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4804	/* Internal microphone/Mic jack is connected to Mic1 pin */
4805	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4806	/* Line In jack is connected to Line1 pin */
4807	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4808	/* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4809	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4810	/* Ensure all other unused pins are disabled and muted. */
4811	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4812	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4813	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4814	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4815	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4816	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4817	/* Disable digital (SPDIF) pins */
4818	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4819	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4820
4821	/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4822	 * bus when acting as outputs.
4823	 */
4824	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4825	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4826
4827	/* Start with output sum widgets muted and their output gains at min */
4828	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4829	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4830	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4831	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4832	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4833	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4834	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4835	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4836	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4837
4838	/* Unmute Line-out pin widget amp left and right
4839	 * (no equiv mixer ctrl)
4840	 */
4841	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4842	/* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4843	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4844	/* Unmute Mic1 and Line1 pin widget input buffers since they start as
4845	 * inputs. If the pin mode is changed by the user the pin mode control
4846	 * will take care of enabling the pin's input/output buffers as needed.
4847	 * Therefore there's no need to enable the input buffer at this
4848	 * stage.
4849	 */
4850	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4851	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4852
4853	/* Mute capture amp left and right */
4854	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4855	/* Set ADC connection select to match default mixer setting - mic
4856	 * (on mic1 pin)
4857	 */
4858	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4859
4860	/* Do similar with the second ADC: mute capture input amp and
4861	 * set ADC connection to mic to match ALSA's default state.
4862	 */
4863	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4864	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4865
4866	/* Mute all inputs to mixer widget (even unconnected ones) */
4867	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4868	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4869	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4870	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4871	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4872	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4873	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4874	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4875
4876	{ }
4877};
4878
4879static struct hda_verb alc260_will_verbs[] = {
4880	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4881	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4882	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4883	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4884	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4885	{0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4886	{}
4887};
4888
4889static struct hda_verb alc260_replacer_672v_verbs[] = {
4890	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4891	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4892	{0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4893
4894	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4895	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4896	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4897
4898	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4899	{}
4900};
4901
4902/* toggle speaker-output according to the hp-jack state */
4903static void alc260_replacer_672v_automute(struct hda_codec *codec)
4904{
4905        unsigned int present;
4906
4907	/* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4908        present = snd_hda_codec_read(codec, 0x0f, 0,
4909                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4910	if (present) {
4911		snd_hda_codec_write_cache(codec, 0x01, 0,
4912					  AC_VERB_SET_GPIO_DATA, 1);
4913		snd_hda_codec_write_cache(codec, 0x0f, 0,
4914					  AC_VERB_SET_PIN_WIDGET_CONTROL,
4915					  PIN_HP);
4916	} else {
4917		snd_hda_codec_write_cache(codec, 0x01, 0,
4918					  AC_VERB_SET_GPIO_DATA, 0);
4919		snd_hda_codec_write_cache(codec, 0x0f, 0,
4920					  AC_VERB_SET_PIN_WIDGET_CONTROL,
4921					  PIN_OUT);
4922	}
4923}
4924
4925static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4926                                       unsigned int res)
4927{
4928        if ((res >> 26) == ALC880_HP_EVENT)
4929                alc260_replacer_672v_automute(codec);
4930}
4931
4932static struct hda_verb alc260_hp_dc7600_verbs[] = {
4933	{0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
4934	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
4935	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4936	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4937	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4938	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4939	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4940	{0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4941	{0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4942	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4943	{}
4944};
4945
4946/* Test configuration for debugging, modelled after the ALC880 test
4947 * configuration.
4948 */
4949#ifdef CONFIG_SND_DEBUG
4950static hda_nid_t alc260_test_dac_nids[1] = {
4951	0x02,
4952};
4953static hda_nid_t alc260_test_adc_nids[2] = {
4954	0x04, 0x05,
4955};
4956/* For testing the ALC260, each input MUX needs its own definition since
4957 * the signal assignments are different.  This assumes that the first ADC
4958 * is NID 0x04.
4959 */
4960static struct hda_input_mux alc260_test_capture_sources[2] = {
4961	{
4962		.num_items = 7,
4963		.items = {
4964			{ "MIC1 pin", 0x0 },
4965			{ "MIC2 pin", 0x1 },
4966			{ "LINE1 pin", 0x2 },
4967			{ "LINE2 pin", 0x3 },
4968			{ "CD pin", 0x4 },
4969			{ "LINE-OUT pin", 0x5 },
4970			{ "HP-OUT pin", 0x6 },
4971		},
4972        },
4973	{
4974		.num_items = 8,
4975		.items = {
4976			{ "MIC1 pin", 0x0 },
4977			{ "MIC2 pin", 0x1 },
4978			{ "LINE1 pin", 0x2 },
4979			{ "LINE2 pin", 0x3 },
4980			{ "CD pin", 0x4 },
4981			{ "Mixer", 0x5 },
4982			{ "LINE-OUT pin", 0x6 },
4983			{ "HP-OUT pin", 0x7 },
4984		},
4985        },
4986};
4987static struct snd_kcontrol_new alc260_test_mixer[] = {
4988	/* Output driver widgets */
4989	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4990	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4991	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4992	HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4993	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4994	HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4995
4996	/* Modes for retasking pin widgets
4997	 * Note: the ALC260 doesn't seem to act on requests to enable mic
4998         * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
4999         * mention this restriction.  At this stage it's not clear whether
5000         * this behaviour is intentional or is a hardware bug in chip
5001         * revisions available at least up until early 2006.  Therefore for
5002         * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5003         * choices, but if it turns out that the lack of mic bias for these
5004         * NIDs is intentional we could change their modes from
5005         * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5006	 */
5007	ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5008	ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5009	ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5010	ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5011	ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5012	ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5013
5014	/* Loopback mixer controls */
5015	HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5016	HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5017	HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5018	HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5019	HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5020	HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5021	HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5022	HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5023	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5024	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5025	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
5026	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
5027	HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5028	HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5029	HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5030	HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5031
5032	/* Controls for GPIO pins, assuming they are configured as outputs */
5033	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5034	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5035	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5036	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5037
5038	/* Switches to allow the digital IO pins to be enabled.  The datasheet
5039	 * is ambigious as to which NID is which; testing on laptops which
5040	 * make this output available should provide clarification.
5041	 */
5042	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5043	ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5044
5045	/* A switch allowing EAPD to be enabled.  Some laptops seem to use
5046	 * this output to turn on an external amplifier.
5047	 */
5048	ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5049	ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5050
5051	{ } /* end */
5052};
5053static struct hda_verb alc260_test_init_verbs[] = {
5054	/* Enable all GPIOs as outputs with an initial value of 0 */
5055	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5056	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5057	{0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5058
5059	/* Enable retasking pins as output, initially without power amp */
5060	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5061	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5062	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5063	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5064	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5065	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5066
5067	/* Disable digital (SPDIF) pins initially, but users can enable
5068	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
5069	 * payload also sets the generation to 0, output to be in "consumer"
5070	 * PCM format, copyright asserted, no pre-emphasis and no validity
5071	 * control.
5072	 */
5073	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5074	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5075
5076	/* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
5077	 * OUT1 sum bus when acting as an output.
5078	 */
5079	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5080	{0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5081	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5082	{0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5083
5084	/* Start with output sum widgets muted and their output gains at min */
5085	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5086	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5087	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5088	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5089	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5090	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5091	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5092	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5093	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5094
5095	/* Unmute retasking pin widget output buffers since the default
5096	 * state appears to be output.  As the pin mode is changed by the
5097	 * user the pin mode control will take care of enabling the pin's
5098	 * input/output buffers as needed.
5099	 */
5100	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5101	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5102	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5103	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5104	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5105	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5106	/* Also unmute the mono-out pin widget */
5107	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5108
5109	/* Mute capture amp left and right */
5110	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5111	/* Set ADC connection select to match default mixer setting (mic1
5112	 * pin)
5113	 */
5114	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5115
5116	/* Do the same for the second ADC: mute capture input amp and
5117	 * set ADC connection to mic1 pin
5118	 */
5119	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5120	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5121
5122	/* Mute all inputs to mixer widget (even unconnected ones) */
5123	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5124	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5125	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5126	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5127	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5128	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5129	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5130	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5131
5132	{ }
5133};
5134#endif
5135
5136#define alc260_pcm_analog_playback	alc880_pcm_analog_alt_playback
5137#define alc260_pcm_analog_capture	alc880_pcm_analog_capture
5138
5139#define alc260_pcm_digital_playback	alc880_pcm_digital_playback
5140#define alc260_pcm_digital_capture	alc880_pcm_digital_capture
5141
5142/*
5143 * for BIOS auto-configuration
5144 */
5145
5146static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
5147					const char *pfx, int *vol_bits)
5148{
5149	hda_nid_t nid_vol;
5150	unsigned long vol_val, sw_val;
5151	char name[32];
5152	int err;
5153
5154	if (nid >= 0x0f && nid < 0x11) {
5155		nid_vol = nid - 0x7;
5156		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5157		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5158	} else if (nid == 0x11) {
5159		nid_vol = nid - 0x7;
5160		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5161		sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5162	} else if (nid >= 0x12 && nid <= 0x15) {
5163		nid_vol = 0x08;
5164		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5165		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5166	} else
5167		return 0; /* N/A */
5168
5169	if (!(*vol_bits & (1 << nid_vol))) {
5170		/* first control for the volume widget */
5171		snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5172		err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5173		if (err < 0)
5174			return err;
5175		*vol_bits |= (1 << nid_vol);
5176	}
5177	snprintf(name, sizeof(name), "%s Playback Switch", pfx);
5178	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5179	if (err < 0)
5180		return err;
5181	return 1;
5182}
5183
5184/* add playback controls from the parsed DAC table */
5185static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5186					     const struct auto_pin_cfg *cfg)
5187{
5188	hda_nid_t nid;
5189	int err;
5190	int vols = 0;
5191
5192	spec->multiout.num_dacs = 1;
5193	spec->multiout.dac_nids = spec->private_dac_nids;
5194	spec->multiout.dac_nids[0] = 0x02;
5195
5196	nid = cfg->line_out_pins[0];
5197	if (nid) {
5198		err = alc260_add_playback_controls(spec, nid, "Front", &vols);
5199		if (err < 0)
5200			return err;
5201	}
5202
5203	nid = cfg->speaker_pins[0];
5204	if (nid) {
5205		err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
5206		if (err < 0)
5207			return err;
5208	}
5209
5210	nid = cfg->hp_pins[0];
5211	if (nid) {
5212		err = alc260_add_playback_controls(spec, nid, "Headphone",
5213						   &vols);
5214		if (err < 0)
5215			return err;
5216	}
5217	return 0;
5218}
5219
5220/* create playback/capture controls for input pins */
5221static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5222						const struct auto_pin_cfg *cfg)
5223{
5224	struct hda_input_mux *imux = &spec->private_imux;
5225	int i, err, idx;
5226
5227	for (i = 0; i < AUTO_PIN_LAST; i++) {
5228		if (cfg->input_pins[i] >= 0x12) {
5229			idx = cfg->input_pins[i] - 0x12;
5230			err = new_analog_input(spec, cfg->input_pins[i],
5231					       auto_pin_cfg_labels[i], idx,
5232					       0x07);
5233			if (err < 0)
5234				return err;
5235			imux->items[imux->num_items].label =
5236				auto_pin_cfg_labels[i];
5237			imux->items[imux->num_items].index = idx;
5238			imux->num_items++;
5239		}
5240		if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
5241			idx = cfg->input_pins[i] - 0x09;
5242			err = new_analog_input(spec, cfg->input_pins[i],
5243					       auto_pin_cfg_labels[i], idx,
5244					       0x07);
5245			if (err < 0)
5246				return err;
5247			imux->items[imux->num_items].label =
5248				auto_pin_cfg_labels[i];
5249			imux->items[imux->num_items].index = idx;
5250			imux->num_items++;
5251		}
5252	}
5253	return 0;
5254}
5255
5256static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5257					      hda_nid_t nid, int pin_type,
5258					      int sel_idx)
5259{
5260	alc_set_pin_output(codec, nid, pin_type);
5261	/* need the manual connection? */
5262	if (nid >= 0x12) {
5263		int idx = nid - 0x12;
5264		snd_hda_codec_write(codec, idx + 0x0b, 0,
5265				    AC_VERB_SET_CONNECT_SEL, sel_idx);
5266	}
5267}
5268
5269static void alc260_auto_init_multi_out(struct hda_codec *codec)
5270{
5271	struct alc_spec *spec = codec->spec;
5272	hda_nid_t nid;
5273
5274	alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
5275	nid = spec->autocfg.line_out_pins[0];
5276	if (nid) {
5277		int pin_type = get_pin_type(spec->autocfg.line_out_type);
5278		alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5279	}
5280
5281	nid = spec->autocfg.speaker_pins[0];
5282	if (nid)
5283		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5284
5285	nid = spec->autocfg.hp_pins[0];
5286	if (nid)
5287		alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5288}
5289
5290#define ALC260_PIN_CD_NID		0x16
5291static void alc260_auto_init_analog_input(struct hda_codec *codec)
5292{
5293	struct alc_spec *spec = codec->spec;
5294	int i;
5295
5296	for (i = 0; i < AUTO_PIN_LAST; i++) {
5297		hda_nid_t nid = spec->autocfg.input_pins[i];
5298		if (nid >= 0x12) {
5299			snd_hda_codec_write(codec, nid, 0,
5300					    AC_VERB_SET_PIN_WIDGET_CONTROL,
5301					    i <= AUTO_PIN_FRONT_MIC ?
5302					    PIN_VREF80 : PIN_IN);
5303			if (nid != ALC260_PIN_CD_NID)
5304				snd_hda_codec_write(codec, nid, 0,
5305						    AC_VERB_SET_AMP_GAIN_MUTE,
5306						    AMP_OUT_MUTE);
5307		}
5308	}
5309}
5310
5311/*
5312 * generic initialization of ADC, input mixers and output mixers
5313 */
5314static struct hda_verb alc260_volume_init_verbs[] = {
5315	/*
5316	 * Unmute ADC0-1 and set the default input to mic-in
5317	 */
5318	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5319	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5320	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5321	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5322
5323	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5324	 * mixer widget
5325	 * Note: PASD motherboards uses the Line In 2 as the input for
5326	 * front panel mic (mic 2)
5327	 */
5328	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5329	/* mute analog inputs */
5330	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5331	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5332	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5333	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5334	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5335
5336	/*
5337	 * Set up output mixers (0x08 - 0x0a)
5338	 */
5339	/* set vol=0 to output mixers */
5340	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5341	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5342	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5343	/* set up input amps for analog loopback */
5344	/* Amp Indices: DAC = 0, mixer = 1 */
5345	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5346	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5347	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5348	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5349	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5350	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5351
5352	{ }
5353};
5354
5355static int alc260_parse_auto_config(struct hda_codec *codec)
5356{
5357	struct alc_spec *spec = codec->spec;
5358	int err;
5359	static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5360
5361	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5362					   alc260_ignore);
5363	if (err < 0)
5364		return err;
5365	err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5366	if (err < 0)
5367		return err;
5368	if (!spec->kctls.list)
5369		return 0; /* can't find valid BIOS pin config */
5370	err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5371	if (err < 0)
5372		return err;
5373
5374	spec->multiout.max_channels = 2;
5375
5376	if (spec->autocfg.dig_out_pin)
5377		spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5378	if (spec->kctls.list)
5379		add_mixer(spec, spec->kctls.list);
5380
5381	add_verb(spec, alc260_volume_init_verbs);
5382
5383	spec->num_mux_defs = 1;
5384	spec->input_mux = &spec->private_imux;
5385
5386	store_pin_configs(codec);
5387	return 1;
5388}
5389
5390/* additional initialization for auto-configuration model */
5391static void alc260_auto_init(struct hda_codec *codec)
5392{
5393	struct alc_spec *spec = codec->spec;
5394	alc260_auto_init_multi_out(codec);
5395	alc260_auto_init_analog_input(codec);
5396	if (spec->unsol_event)
5397		alc_inithook(codec);
5398}
5399
5400#ifdef CONFIG_SND_HDA_POWER_SAVE
5401static struct hda_amp_list alc260_loopbacks[] = {
5402	{ 0x07, HDA_INPUT, 0 },
5403	{ 0x07, HDA_INPUT, 1 },
5404	{ 0x07, HDA_INPUT, 2 },
5405	{ 0x07, HDA_INPUT, 3 },
5406	{ 0x07, HDA_INPUT, 4 },
5407	{ } /* end */
5408};
5409#endif
5410
5411/*
5412 * ALC260 configurations
5413 */
5414static const char *alc260_models[ALC260_MODEL_LAST] = {
5415	[ALC260_BASIC]		= "basic",
5416	[ALC260_HP]		= "hp",
5417	[ALC260_HP_3013]	= "hp-3013",
5418	[ALC260_HP_DC7600]	= "hp-dc7600",
5419	[ALC260_FUJITSU_S702X]	= "fujitsu",
5420	[ALC260_ACER]		= "acer",
5421	[ALC260_WILL]		= "will",
5422	[ALC260_REPLACER_672V]	= "replacer",
5423#ifdef CONFIG_SND_DEBUG
5424	[ALC260_TEST]		= "test",
5425#endif
5426	[ALC260_AUTO]		= "auto",
5427};
5428
5429static struct snd_pci_quirk alc260_cfg_tbl[] = {
5430	SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5431	SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5432	SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5433	SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5434	SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5435	SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5436	SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
5437	SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5438	SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5439	SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5440	SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5441	SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5442	SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5443	SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5444	SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5445	SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5446	SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5447	SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5448	{}
5449};
5450
5451static struct alc_config_preset alc260_presets[] = {
5452	[ALC260_BASIC] = {
5453		.mixers = { alc260_base_output_mixer,
5454			    alc260_input_mixer,
5455			    alc260_pc_beep_mixer },
5456		.init_verbs = { alc260_init_verbs },
5457		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5458		.dac_nids = alc260_dac_nids,
5459		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5460		.adc_nids = alc260_adc_nids,
5461		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5462		.channel_mode = alc260_modes,
5463		.input_mux = &alc260_capture_source,
5464	},
5465	[ALC260_HP] = {
5466		.mixers = { alc260_hp_output_mixer,
5467			    alc260_input_mixer },
5468		.init_verbs = { alc260_init_verbs,
5469				alc260_hp_unsol_verbs },
5470		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5471		.dac_nids = alc260_dac_nids,
5472		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5473		.adc_nids = alc260_adc_nids_alt,
5474		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5475		.channel_mode = alc260_modes,
5476		.input_mux = &alc260_capture_source,
5477		.unsol_event = alc260_hp_unsol_event,
5478		.init_hook = alc260_hp_automute,
5479	},
5480	[ALC260_HP_DC7600] = {
5481		.mixers = { alc260_hp_dc7600_mixer,
5482			    alc260_input_mixer },
5483		.init_verbs = { alc260_init_verbs,
5484				alc260_hp_dc7600_verbs },
5485		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5486		.dac_nids = alc260_dac_nids,
5487		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5488		.adc_nids = alc260_adc_nids_alt,
5489		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5490		.channel_mode = alc260_modes,
5491		.input_mux = &alc260_capture_source,
5492		.unsol_event = alc260_hp_3012_unsol_event,
5493		.init_hook = alc260_hp_3012_automute,
5494	},
5495	[ALC260_HP_3013] = {
5496		.mixers = { alc260_hp_3013_mixer,
5497			    alc260_input_mixer },
5498		.init_verbs = { alc260_hp_3013_init_verbs,
5499				alc260_hp_3013_unsol_verbs },
5500		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5501		.dac_nids = alc260_dac_nids,
5502		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5503		.adc_nids = alc260_adc_nids_alt,
5504		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5505		.channel_mode = alc260_modes,
5506		.input_mux = &alc260_capture_source,
5507		.unsol_event = alc260_hp_3013_unsol_event,
5508		.init_hook = alc260_hp_3013_automute,
5509	},
5510	[ALC260_FUJITSU_S702X] = {
5511		.mixers = { alc260_fujitsu_mixer },
5512		.init_verbs = { alc260_fujitsu_init_verbs },
5513		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5514		.dac_nids = alc260_dac_nids,
5515		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5516		.adc_nids = alc260_dual_adc_nids,
5517		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5518		.channel_mode = alc260_modes,
5519		.num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5520		.input_mux = alc260_fujitsu_capture_sources,
5521	},
5522	[ALC260_ACER] = {
5523		.mixers = { alc260_acer_mixer },
5524		.init_verbs = { alc260_acer_init_verbs },
5525		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5526		.dac_nids = alc260_dac_nids,
5527		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5528		.adc_nids = alc260_dual_adc_nids,
5529		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5530		.channel_mode = alc260_modes,
5531		.num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5532		.input_mux = alc260_acer_capture_sources,
5533	},
5534	[ALC260_WILL] = {
5535		.mixers = { alc260_will_mixer },
5536		.init_verbs = { alc260_init_verbs, alc260_will_verbs },
5537		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5538		.dac_nids = alc260_dac_nids,
5539		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5540		.adc_nids = alc260_adc_nids,
5541		.dig_out_nid = ALC260_DIGOUT_NID,
5542		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5543		.channel_mode = alc260_modes,
5544		.input_mux = &alc260_capture_source,
5545	},
5546	[ALC260_REPLACER_672V] = {
5547		.mixers = { alc260_replacer_672v_mixer },
5548		.init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5549		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5550		.dac_nids = alc260_dac_nids,
5551		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5552		.adc_nids = alc260_adc_nids,
5553		.dig_out_nid = ALC260_DIGOUT_NID,
5554		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5555		.channel_mode = alc260_modes,
5556		.input_mux = &alc260_capture_source,
5557		.unsol_event = alc260_replacer_672v_unsol_event,
5558		.init_hook = alc260_replacer_672v_automute,
5559	},
5560#ifdef CONFIG_SND_DEBUG
5561	[ALC260_TEST] = {
5562		.mixers = { alc260_test_mixer },
5563		.init_verbs = { alc260_test_init_verbs },
5564		.num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5565		.dac_nids = alc260_test_dac_nids,
5566		.num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5567		.adc_nids = alc260_test_adc_nids,
5568		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5569		.channel_mode = alc260_modes,
5570		.num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5571		.input_mux = alc260_test_capture_sources,
5572	},
5573#endif
5574};
5575
5576static int patch_alc260(struct hda_codec *codec)
5577{
5578	struct alc_spec *spec;
5579	int err, board_config;
5580
5581	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5582	if (spec == NULL)
5583		return -ENOMEM;
5584
5585	codec->spec = spec;
5586
5587	board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5588						  alc260_models,
5589						  alc260_cfg_tbl);
5590	if (board_config < 0) {
5591		snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5592			   "trying auto-probe from BIOS...\n");
5593		board_config = ALC260_AUTO;
5594	}
5595
5596	if (board_config == ALC260_AUTO) {
5597		/* automatic parse from the BIOS config */
5598		err = alc260_parse_auto_config(codec);
5599		if (err < 0) {
5600			alc_free(codec);
5601			return err;
5602		} else if (!err) {
5603			printk(KERN_INFO
5604			       "hda_codec: Cannot set up configuration "
5605			       "from BIOS.  Using base mode...\n");
5606			board_config = ALC260_BASIC;
5607		}
5608	}
5609
5610	if (board_config != ALC260_AUTO)
5611		setup_preset(spec, &alc260_presets[board_config]);
5612
5613	spec->stream_name_analog = "ALC260 Analog";
5614	spec->stream_analog_playback = &alc260_pcm_analog_playback;
5615	spec->stream_analog_capture = &alc260_pcm_analog_capture;
5616
5617	spec->stream_name_digital = "ALC260 Digital";
5618	spec->stream_digital_playback = &alc260_pcm_digital_playback;
5619	spec->stream_digital_capture = &alc260_pcm_digital_capture;
5620
5621	set_capture_mixer(spec);
5622
5623	spec->vmaster_nid = 0x08;
5624
5625	codec->patch_ops = alc_patch_ops;
5626	if (board_config == ALC260_AUTO)
5627		spec->init_hook = alc260_auto_init;
5628#ifdef CONFIG_SND_HDA_POWER_SAVE
5629	if (!spec->loopback.amplist)
5630		spec->loopback.amplist = alc260_loopbacks;
5631#endif
5632
5633	return 0;
5634}
5635
5636
5637/*
5638 * ALC882 support
5639 *
5640 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5641 * configuration.  Each pin widget can choose any input DACs and a mixer.
5642 * Each ADC is connected from a mixer of all inputs.  This makes possible
5643 * 6-channel independent captures.
5644 *
5645 * In addition, an independent DAC for the multi-playback (not used in this
5646 * driver yet).
5647 */
5648#define ALC882_DIGOUT_NID	0x06
5649#define ALC882_DIGIN_NID	0x0a
5650
5651static struct hda_channel_mode alc882_ch_modes[1] = {
5652	{ 8, NULL }
5653};
5654
5655static hda_nid_t alc882_dac_nids[4] = {
5656	/* front, rear, clfe, rear_surr */
5657	0x02, 0x03, 0x04, 0x05
5658};
5659
5660/* identical with ALC880 */
5661#define alc882_adc_nids		alc880_adc_nids
5662#define alc882_adc_nids_alt	alc880_adc_nids_alt
5663
5664static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
5665static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
5666
5667/* input MUX */
5668/* FIXME: should be a matrix-type input source selection */
5669
5670static struct hda_input_mux alc882_capture_source = {
5671	.num_items = 4,
5672	.items = {
5673		{ "Mic", 0x0 },
5674		{ "Front Mic", 0x1 },
5675		{ "Line", 0x2 },
5676		{ "CD", 0x4 },
5677	},
5678};
5679/*
5680 * 2ch mode
5681 */
5682static struct hda_verb alc882_3ST_ch2_init[] = {
5683	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5684	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5685	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5686	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5687	{ } /* end */
5688};
5689
5690/*
5691 * 6ch mode
5692 */
5693static struct hda_verb alc882_3ST_ch6_init[] = {
5694	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5695	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5696	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5697	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5698	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5699	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5700	{ } /* end */
5701};
5702
5703static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5704	{ 2, alc882_3ST_ch2_init },
5705	{ 6, alc882_3ST_ch6_init },
5706};
5707
5708/*
5709 * 6ch mode
5710 */
5711static struct hda_verb alc882_sixstack_ch6_init[] = {
5712	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5713	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5714	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5715	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5716	{ } /* end */
5717};
5718
5719/*
5720 * 8ch mode
5721 */
5722static struct hda_verb alc882_sixstack_ch8_init[] = {
5723	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5724	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5725	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5726	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5727	{ } /* end */
5728};
5729
5730static struct hda_channel_mode alc882_sixstack_modes[2] = {
5731	{ 6, alc882_sixstack_ch6_init },
5732	{ 8, alc882_sixstack_ch8_init },
5733};
5734
5735/*
5736 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5737 */
5738
5739/*
5740 * 2ch mode
5741 */
5742static struct hda_verb alc885_mbp_ch2_init[] = {
5743	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5744	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5745	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5746	{ } /* end */
5747};
5748
5749/*
5750 * 6ch mode
5751 */
5752static struct hda_verb alc885_mbp_ch6_init[] = {
5753	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5754	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5755	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5756	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5757	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5758	{ } /* end */
5759};
5760
5761static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5762	{ 2, alc885_mbp_ch2_init },
5763	{ 6, alc885_mbp_ch6_init },
5764};
5765
5766
5767/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5768 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5769 */
5770static struct snd_kcontrol_new alc882_base_mixer[] = {
5771	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5772	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5773	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5774	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5775	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5776	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5777	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5778	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5779	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5780	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5781	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5782	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5783	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5784	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5785	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5786	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5787	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5788	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5789	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5790	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5791	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5792	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5793	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5794	{ } /* end */
5795};
5796
5797static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5798	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5799	HDA_BIND_MUTE   ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
5800	HDA_CODEC_MUTE  ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
5801	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
5802	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5803	HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5804	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5805	HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5806	HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
5807	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5808	{ } /* end */
5809};
5810static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5811	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5812	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5813	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5814	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5815	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5816	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5817	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5818	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5819	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5820	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5821	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5822	{ } /* end */
5823};
5824
5825static struct snd_kcontrol_new alc882_targa_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_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5829	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5830	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5831	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5832	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5833	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5834	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5835	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5836	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5837	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5838	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5839	{ } /* end */
5840};
5841
5842/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5843 *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5844 */
5845static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5846	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5847	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5848	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5849	HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5850	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5851	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5852	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5853	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5854	HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5855	HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5856	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5857	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5858	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5859	{ } /* end */
5860};
5861
5862static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5863	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5864	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5865	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5866	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5867	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5868	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5869	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5870	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5871	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5872	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5873	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5874	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5875	{ } /* end */
5876};
5877
5878static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5879	{
5880		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5881		.name = "Channel Mode",
5882		.info = alc_ch_mode_info,
5883		.get = alc_ch_mode_get,
5884		.put = alc_ch_mode_put,
5885	},
5886	{ } /* end */
5887};
5888
5889static struct hda_verb alc882_init_verbs[] = {
5890	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5891	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5892	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5893	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5894	/* Rear mixer */
5895	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5896	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5897	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5898	/* CLFE mixer */
5899	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5900	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5901	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5902	/* Side mixer */
5903	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5904	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5905	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5906
5907	/* Front Pin: output 0 (0x0c) */
5908	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5909	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5910	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5911	/* Rear Pin: output 1 (0x0d) */
5912	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5913	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5914	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5915	/* CLFE Pin: output 2 (0x0e) */
5916	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5917	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5918	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5919	/* Side Pin: output 3 (0x0f) */
5920	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5921	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5922	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5923	/* Mic (rear) pin: input vref at 80% */
5924	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5925	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5926	/* Front Mic pin: input vref at 80% */
5927	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5928	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5929	/* Line In pin: input */
5930	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5931	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5932	/* Line-2 In: Headphone output (output 0 - 0x0c) */
5933	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5934	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5935	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5936	/* CD pin widget for input */
5937	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5938
5939	/* FIXME: use matrix-type input source selection */
5940	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5941	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5942	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5943	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5944	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5945	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5946	/* Input mixer2 */
5947	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5948	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5949	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5950	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5951	/* Input mixer3 */
5952	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5953	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5954	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5955	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5956	/* ADC1: mute amp left and right */
5957	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5958	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5959	/* ADC2: mute amp left and right */
5960	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5961	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5962	/* ADC3: mute amp left and right */
5963	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5964	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5965
5966	{ }
5967};
5968
5969static struct hda_verb alc882_eapd_verbs[] = {
5970	/* change to EAPD mode */
5971	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5972	{0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5973	{ }
5974};
5975
5976/* Mac Pro test */
5977static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5978	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5979	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5980	HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5981	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5982	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5983	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5984	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5985	{ } /* end */
5986};
5987
5988static struct hda_verb alc882_macpro_init_verbs[] = {
5989	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5990	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5991	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5992	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5993	/* Front Pin: output 0 (0x0c) */
5994	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5995	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5996	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5997	/* Front Mic pin: input vref at 80% */
5998	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5999	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6000	/* Speaker:  output */
6001	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6002	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6003	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
6004	/* Headphone output (output 0 - 0x0c) */
6005	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6006	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6007	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6008
6009	/* FIXME: use matrix-type input source selection */
6010	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6011	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6012	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6013	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6014	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6015	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6016	/* Input mixer2 */
6017	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6018	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6019	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6020	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6021	/* Input mixer3 */
6022	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6023	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6024	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6025	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6026	/* ADC1: mute amp left and right */
6027	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6028	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6029	/* ADC2: mute amp left and right */
6030	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6031	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6032	/* ADC3: mute amp left and right */
6033	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6034	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6035
6036	{ }
6037};
6038
6039/* Macbook Pro rev3 */
6040static struct hda_verb alc885_mbp3_init_verbs[] = {
6041	/* Front mixer: unmute input/output amp left and right (volume = 0) */
6042	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6043	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6044	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6045	/* Rear mixer */
6046	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6047	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6048	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6049	/* Front Pin: output 0 (0x0c) */
6050	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6051	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6052	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6053	/* HP Pin: output 0 (0x0d) */
6054	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
6055	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6056	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6057	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6058	/* Mic (rear) pin: input vref at 80% */
6059	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6060	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6061	/* Front Mic pin: input vref at 80% */
6062	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6063	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6064	/* Line In pin: use output 1 when in LineOut mode */
6065	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6066	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6067	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
6068
6069	/* FIXME: use matrix-type input source selection */
6070	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6071	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6072	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6073	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6074	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6075	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6076	/* Input mixer2 */
6077	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6078	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6079	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6080	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6081	/* Input mixer3 */
6082	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6083	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6084	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6085	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6086	/* ADC1: mute amp left and right */
6087	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6088	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6089	/* ADC2: mute amp left and right */
6090	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6091	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6092	/* ADC3: mute amp left and right */
6093	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6094	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6095
6096	{ }
6097};
6098
6099/* iMac 24 mixer. */
6100static struct snd_kcontrol_new alc885_imac24_mixer[] = {
6101	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6102	HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
6103	{ } /* end */
6104};
6105
6106/* iMac 24 init verbs. */
6107static struct hda_verb alc885_imac24_init_verbs[] = {
6108	/* Internal speakers: output 0 (0x0c) */
6109	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6110	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6111	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6112	/* Internal speakers: output 0 (0x0c) */
6113	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6114	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6115	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
6116	/* Headphone: output 0 (0x0c) */
6117	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6118	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6119	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6120	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6121	/* Front Mic: input vref at 80% */
6122	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6123	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6124	{ }
6125};
6126
6127/* Toggle speaker-output according to the hp-jack state */
6128static void alc885_imac24_automute(struct hda_codec *codec)
6129{
6130 	unsigned int present;
6131
6132 	present = snd_hda_codec_read(codec, 0x14, 0,
6133				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6134	snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
6135				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6136	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
6137				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6138}
6139
6140/* Processes unsolicited events. */
6141static void alc885_imac24_unsol_event(struct hda_codec *codec,
6142				      unsigned int res)
6143{
6144	/* Headphone insertion or removal. */
6145	if ((res >> 26) == ALC880_HP_EVENT)
6146		alc885_imac24_automute(codec);
6147}
6148
6149static void alc885_mbp3_automute(struct hda_codec *codec)
6150{
6151 	unsigned int present;
6152
6153 	present = snd_hda_codec_read(codec, 0x15, 0,
6154				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6155	snd_hda_codec_amp_stereo(codec, 0x14,  HDA_OUTPUT, 0,
6156				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6157	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6158				 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
6159
6160}
6161static void alc885_mbp3_unsol_event(struct hda_codec *codec,
6162				    unsigned int res)
6163{
6164	/* Headphone insertion or removal. */
6165	if ((res >> 26) == ALC880_HP_EVENT)
6166		alc885_mbp3_automute(codec);
6167}
6168
6169
6170static struct hda_verb alc882_targa_verbs[] = {
6171	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6172	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6173
6174	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6175	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6176
6177	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6178	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6179	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6180
6181	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6182	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6183	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6184	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6185	{ } /* end */
6186};
6187
6188/* toggle speaker-output according to the hp-jack state */
6189static void alc882_targa_automute(struct hda_codec *codec)
6190{
6191 	unsigned int present;
6192
6193 	present = snd_hda_codec_read(codec, 0x14, 0,
6194				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6195	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6196				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6197	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6198				  present ? 1 : 3);
6199}
6200
6201static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6202{
6203	/* Looks like the unsol event is incompatible with the standard
6204	 * definition.  4bit tag is placed at 26 bit!
6205	 */
6206	if (((res >> 26) == ALC880_HP_EVENT)) {
6207		alc882_targa_automute(codec);
6208	}
6209}
6210
6211static struct hda_verb alc882_asus_a7j_verbs[] = {
6212	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6213	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6214
6215	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6216	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6217	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6218
6219	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6220	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6221	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6222
6223	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6224	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6225	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6226	{ } /* end */
6227};
6228
6229static struct hda_verb alc882_asus_a7m_verbs[] = {
6230	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6231	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6232
6233	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6234	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6235	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6236
6237	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6238	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6239	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6240
6241	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6242	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6243	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6244 	{ } /* end */
6245};
6246
6247static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6248{
6249	unsigned int gpiostate, gpiomask, gpiodir;
6250
6251	gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6252				       AC_VERB_GET_GPIO_DATA, 0);
6253
6254	if (!muted)
6255		gpiostate |= (1 << pin);
6256	else
6257		gpiostate &= ~(1 << pin);
6258
6259	gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6260				      AC_VERB_GET_GPIO_MASK, 0);
6261	gpiomask |= (1 << pin);
6262
6263	gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6264				     AC_VERB_GET_GPIO_DIRECTION, 0);
6265	gpiodir |= (1 << pin);
6266
6267
6268	snd_hda_codec_write(codec, codec->afg, 0,
6269			    AC_VERB_SET_GPIO_MASK, gpiomask);
6270	snd_hda_codec_write(codec, codec->afg, 0,
6271			    AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6272
6273	msleep(1);
6274
6275	snd_hda_codec_write(codec, codec->afg, 0,
6276			    AC_VERB_SET_GPIO_DATA, gpiostate);
6277}
6278
6279/* set up GPIO at initialization */
6280static void alc885_macpro_init_hook(struct hda_codec *codec)
6281{
6282	alc882_gpio_mute(codec, 0, 0);
6283	alc882_gpio_mute(codec, 1, 0);
6284}
6285
6286/* set up GPIO and update auto-muting at initialization */
6287static void alc885_imac24_init_hook(struct hda_codec *codec)
6288{
6289	alc885_macpro_init_hook(codec);
6290	alc885_imac24_automute(codec);
6291}
6292
6293/*
6294 * generic initialization of ADC, input mixers and output mixers
6295 */
6296static struct hda_verb alc882_auto_init_verbs[] = {
6297	/*
6298	 * Unmute ADC0-2 and set the default input to mic-in
6299	 */
6300	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6301	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6302	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6303	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6304	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6305	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6306
6307	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6308	 * mixer widget
6309	 * Note: PASD motherboards uses the Line In 2 as the input for
6310	 * front panel mic (mic 2)
6311	 */
6312	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6313	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6314	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6315	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6316	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6317	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6318
6319	/*
6320	 * Set up output mixers (0x0c - 0x0f)
6321	 */
6322	/* set vol=0 to output mixers */
6323	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6324	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6325	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6326	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6327	/* set up input amps for analog loopback */
6328	/* Amp Indices: DAC = 0, mixer = 1 */
6329	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6330	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6331	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6332	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6333	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6334	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6335	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6336	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6337	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6338	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6339
6340	/* FIXME: use matrix-type input source selection */
6341	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6342	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6343	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6344	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6345	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6346	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6347	/* Input mixer2 */
6348	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6349	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6350	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6351	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6352	/* Input mixer3 */
6353	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6354	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6355	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6356	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6357
6358	{ }
6359};
6360
6361#ifdef CONFIG_SND_HDA_POWER_SAVE
6362#define alc882_loopbacks	alc880_loopbacks
6363#endif
6364
6365/* pcm configuration: identiacal with ALC880 */
6366#define alc882_pcm_analog_playback	alc880_pcm_analog_playback
6367#define alc882_pcm_analog_capture	alc880_pcm_analog_capture
6368#define alc882_pcm_digital_playback	alc880_pcm_digital_playback
6369#define alc882_pcm_digital_capture	alc880_pcm_digital_capture
6370
6371/*
6372 * configuration and preset
6373 */
6374static const char *alc882_models[ALC882_MODEL_LAST] = {
6375	[ALC882_3ST_DIG]	= "3stack-dig",
6376	[ALC882_6ST_DIG]	= "6stack-dig",
6377	[ALC882_ARIMA]		= "arima",
6378	[ALC882_W2JC]		= "w2jc",
6379	[ALC882_TARGA]		= "targa",
6380	[ALC882_ASUS_A7J]	= "asus-a7j",
6381	[ALC882_ASUS_A7M]	= "asus-a7m",
6382	[ALC885_MACPRO]		= "macpro",
6383	[ALC885_MBP3]		= "mbp3",
6384	[ALC885_IMAC24]		= "imac24",
6385	[ALC882_AUTO]		= "auto",
6386};
6387
6388static struct snd_pci_quirk alc882_cfg_tbl[] = {
6389	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6390	SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6391	SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6392	SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6393	SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6394	SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6395	SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6396	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6397	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6398	SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
6399	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6400	SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6401	{}
6402};
6403
6404static struct alc_config_preset alc882_presets[] = {
6405	[ALC882_3ST_DIG] = {
6406		.mixers = { alc882_base_mixer },
6407		.init_verbs = { alc882_init_verbs },
6408		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6409		.dac_nids = alc882_dac_nids,
6410		.dig_out_nid = ALC882_DIGOUT_NID,
6411		.dig_in_nid = ALC882_DIGIN_NID,
6412		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6413		.channel_mode = alc882_ch_modes,
6414		.need_dac_fix = 1,
6415		.input_mux = &alc882_capture_source,
6416	},
6417	[ALC882_6ST_DIG] = {
6418		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
6419		.init_verbs = { alc882_init_verbs },
6420		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6421		.dac_nids = alc882_dac_nids,
6422		.dig_out_nid = ALC882_DIGOUT_NID,
6423		.dig_in_nid = ALC882_DIGIN_NID,
6424		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6425		.channel_mode = alc882_sixstack_modes,
6426		.input_mux = &alc882_capture_source,
6427	},
6428	[ALC882_ARIMA] = {
6429		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
6430		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6431		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6432		.dac_nids = alc882_dac_nids,
6433		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6434		.channel_mode = alc882_sixstack_modes,
6435		.input_mux = &alc882_capture_source,
6436	},
6437	[ALC882_W2JC] = {
6438		.mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6439		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6440				alc880_gpio1_init_verbs },
6441		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6442		.dac_nids = alc882_dac_nids,
6443		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6444		.channel_mode = alc880_threestack_modes,
6445		.need_dac_fix = 1,
6446		.input_mux = &alc882_capture_source,
6447		.dig_out_nid = ALC882_DIGOUT_NID,
6448	},
6449	[ALC885_MBP3] = {
6450		.mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6451		.init_verbs = { alc885_mbp3_init_verbs,
6452				alc880_gpio1_init_verbs },
6453		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6454		.dac_nids = alc882_dac_nids,
6455		.channel_mode = alc885_mbp_6ch_modes,
6456		.num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6457		.input_mux = &alc882_capture_source,
6458		.dig_out_nid = ALC882_DIGOUT_NID,
6459		.dig_in_nid = ALC882_DIGIN_NID,
6460		.unsol_event = alc885_mbp3_unsol_event,
6461		.init_hook = alc885_mbp3_automute,
6462	},
6463	[ALC885_MACPRO] = {
6464		.mixers = { alc882_macpro_mixer },
6465		.init_verbs = { alc882_macpro_init_verbs },
6466		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6467		.dac_nids = alc882_dac_nids,
6468		.dig_out_nid = ALC882_DIGOUT_NID,
6469		.dig_in_nid = ALC882_DIGIN_NID,
6470		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6471		.channel_mode = alc882_ch_modes,
6472		.input_mux = &alc882_capture_source,
6473		.init_hook = alc885_macpro_init_hook,
6474	},
6475	[ALC885_IMAC24] = {
6476		.mixers = { alc885_imac24_mixer },
6477		.init_verbs = { alc885_imac24_init_verbs },
6478		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6479		.dac_nids = alc882_dac_nids,
6480		.dig_out_nid = ALC882_DIGOUT_NID,
6481		.dig_in_nid = ALC882_DIGIN_NID,
6482		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6483		.channel_mode = alc882_ch_modes,
6484		.input_mux = &alc882_capture_source,
6485		.unsol_event = alc885_imac24_unsol_event,
6486		.init_hook = alc885_imac24_init_hook,
6487	},
6488	[ALC882_TARGA] = {
6489		.mixers = { alc882_targa_mixer, alc882_chmode_mixer },
6490		.init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6491		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6492		.dac_nids = alc882_dac_nids,
6493		.dig_out_nid = ALC882_DIGOUT_NID,
6494		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6495		.adc_nids = alc882_adc_nids,
6496		.capsrc_nids = alc882_capsrc_nids,
6497		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6498		.channel_mode = alc882_3ST_6ch_modes,
6499		.need_dac_fix = 1,
6500		.input_mux = &alc882_capture_source,
6501		.unsol_event = alc882_targa_unsol_event,
6502		.init_hook = alc882_targa_automute,
6503	},
6504	[ALC882_ASUS_A7J] = {
6505		.mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
6506		.init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6507		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6508		.dac_nids = alc882_dac_nids,
6509		.dig_out_nid = ALC882_DIGOUT_NID,
6510		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6511		.adc_nids = alc882_adc_nids,
6512		.capsrc_nids = alc882_capsrc_nids,
6513		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6514		.channel_mode = alc882_3ST_6ch_modes,
6515		.need_dac_fix = 1,
6516		.input_mux = &alc882_capture_source,
6517	},
6518	[ALC882_ASUS_A7M] = {
6519		.mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6520		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6521				alc880_gpio1_init_verbs,
6522				alc882_asus_a7m_verbs },
6523		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6524		.dac_nids = alc882_dac_nids,
6525		.dig_out_nid = ALC882_DIGOUT_NID,
6526		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6527		.channel_mode = alc880_threestack_modes,
6528		.need_dac_fix = 1,
6529		.input_mux = &alc882_capture_source,
6530	},
6531};
6532
6533
6534/*
6535 * Pin config fixes
6536 */
6537enum {
6538	PINFIX_ABIT_AW9D_MAX
6539};
6540
6541static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6542	{ 0x15, 0x01080104 }, /* side */
6543	{ 0x16, 0x01011012 }, /* rear */
6544	{ 0x17, 0x01016011 }, /* clfe */
6545	{ }
6546};
6547
6548static const struct alc_pincfg *alc882_pin_fixes[] = {
6549	[PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6550};
6551
6552static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6553	SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6554	{}
6555};
6556
6557/*
6558 * BIOS auto configuration
6559 */
6560static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6561					      hda_nid_t nid, int pin_type,
6562					      int dac_idx)
6563{
6564	/* set as output */
6565	struct alc_spec *spec = codec->spec;
6566	int idx;
6567
6568	alc_set_pin_output(codec, nid, pin_type);
6569	if (spec->multiout.dac_nids[dac_idx] == 0x25)
6570		idx = 4;
6571	else
6572		idx = spec->multiout.dac_nids[dac_idx] - 2;
6573	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6574
6575}
6576
6577static void alc882_auto_init_multi_out(struct hda_codec *codec)
6578{
6579	struct alc_spec *spec = codec->spec;
6580	int i;
6581
6582	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6583	for (i = 0; i <= HDA_SIDE; i++) {
6584		hda_nid_t nid = spec->autocfg.line_out_pins[i];
6585		int pin_type = get_pin_type(spec->autocfg.line_out_type);
6586		if (nid)
6587			alc882_auto_set_output_and_unmute(codec, nid, pin_type,
6588							  i);
6589	}
6590}
6591
6592static void alc882_auto_init_hp_out(struct hda_codec *codec)
6593{
6594	struct alc_spec *spec = codec->spec;
6595	hda_nid_t pin;
6596
6597	pin = spec->autocfg.hp_pins[0];
6598	if (pin) /* connect to front */
6599		/* use dac 0 */
6600		alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6601	pin = spec->autocfg.speaker_pins[0];
6602	if (pin)
6603		alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
6604}
6605
6606#define alc882_is_input_pin(nid)	alc880_is_input_pin(nid)
6607#define ALC882_PIN_CD_NID		ALC880_PIN_CD_NID
6608
6609static void alc882_auto_init_analog_input(struct hda_codec *codec)
6610{
6611	struct alc_spec *spec = codec->spec;
6612	int i;
6613
6614	for (i = 0; i < AUTO_PIN_LAST; i++) {
6615		hda_nid_t nid = spec->autocfg.input_pins[i];
6616		unsigned int vref;
6617		if (!nid)
6618			continue;
6619		vref = PIN_IN;
6620		if (1 /*i <= AUTO_PIN_FRONT_MIC*/) {
6621			unsigned int pincap;
6622			pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
6623			if ((pincap >> AC_PINCAP_VREF_SHIFT) &
6624			    AC_PINCAP_VREF_80)
6625				vref = PIN_VREF80;
6626		}
6627		snd_hda_codec_write(codec, nid, 0,
6628				    AC_VERB_SET_PIN_WIDGET_CONTROL, vref);
6629		if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
6630			snd_hda_codec_write(codec, nid, 0,
6631					    AC_VERB_SET_AMP_GAIN_MUTE,
6632					    AMP_OUT_MUTE);
6633	}
6634}
6635
6636static void alc882_auto_init_input_src(struct hda_codec *codec)
6637{
6638	struct alc_spec *spec = codec->spec;
6639	const struct hda_input_mux *imux = spec->input_mux;
6640	int c;
6641
6642	for (c = 0; c < spec->num_adc_nids; c++) {
6643		hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
6644		hda_nid_t nid = spec->capsrc_nids[c];
6645		int conns, mute, idx, item;
6646
6647		conns = snd_hda_get_connections(codec, nid, conn_list,
6648						ARRAY_SIZE(conn_list));
6649		if (conns < 0)
6650			continue;
6651		for (idx = 0; idx < conns; idx++) {
6652			/* if the current connection is the selected one,
6653			 * unmute it as default - otherwise mute it
6654			 */
6655			mute = AMP_IN_MUTE(idx);
6656			for (item = 0; item < imux->num_items; item++) {
6657				if (imux->items[item].index == idx) {
6658					if (spec->cur_mux[c] == item)
6659						mute = AMP_IN_UNMUTE(idx);
6660					break;
6661				}
6662			}
6663			snd_hda_codec_write(codec, nid, 0,
6664					    AC_VERB_SET_AMP_GAIN_MUTE, mute);
6665		}
6666	}
6667}
6668
6669/* add mic boosts if needed */
6670static int alc_auto_add_mic_boost(struct hda_codec *codec)
6671{
6672	struct alc_spec *spec = codec->spec;
6673	int err;
6674	hda_nid_t nid;
6675
6676	nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
6677	if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6678		err = add_control(spec, ALC_CTL_WIDGET_VOL,
6679				  "Mic Boost",
6680				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6681		if (err < 0)
6682			return err;
6683	}
6684	nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6685	if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6686		err = add_control(spec, ALC_CTL_WIDGET_VOL,
6687				  "Front Mic Boost",
6688				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6689		if (err < 0)
6690			return err;
6691	}
6692	return 0;
6693}
6694
6695/* almost identical with ALC880 parser... */
6696static int alc882_parse_auto_config(struct hda_codec *codec)
6697{
6698	struct alc_spec *spec = codec->spec;
6699	int err = alc880_parse_auto_config(codec);
6700
6701	if (err < 0)
6702		return err;
6703	else if (!err)
6704		return 0; /* no config found */
6705
6706	err = alc_auto_add_mic_boost(codec);
6707	if (err < 0)
6708		return err;
6709
6710	/* hack - override the init verbs */
6711	spec->init_verbs[0] = alc882_auto_init_verbs;
6712
6713	return 1; /* config found */
6714}
6715
6716/* additional initialization for auto-configuration model */
6717static void alc882_auto_init(struct hda_codec *codec)
6718{
6719	struct alc_spec *spec = codec->spec;
6720	alc882_auto_init_multi_out(codec);
6721	alc882_auto_init_hp_out(codec);
6722	alc882_auto_init_analog_input(codec);
6723	alc882_auto_init_input_src(codec);
6724	if (spec->unsol_event)
6725		alc_inithook(codec);
6726}
6727
6728static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
6729
6730static int patch_alc882(struct hda_codec *codec)
6731{
6732	struct alc_spec *spec;
6733	int err, board_config;
6734
6735	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6736	if (spec == NULL)
6737		return -ENOMEM;
6738
6739	codec->spec = spec;
6740
6741	board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6742						  alc882_models,
6743						  alc882_cfg_tbl);
6744
6745	if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
6746		/* Pick up systems that don't supply PCI SSID */
6747		switch (codec->subsystem_id) {
6748		case 0x106b0c00: /* Mac Pro */
6749			board_config = ALC885_MACPRO;
6750			break;
6751		case 0x106b1000: /* iMac 24 */
6752		case 0x106b2800: /* AppleTV */
6753			board_config = ALC885_IMAC24;
6754			break;
6755		case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
6756		case 0x106b00a4: /* MacbookPro4,1 */
6757		case 0x106b2c00: /* Macbook Pro rev3 */
6758		case 0x106b3600: /* Macbook 3.1 */
6759			board_config = ALC885_MBP3;
6760			break;
6761		default:
6762			/* ALC889A is handled better as ALC888-compatible */
6763			if (codec->revision_id == 0x100101 ||
6764			    codec->revision_id == 0x100103) {
6765				alc_free(codec);
6766				return patch_alc883(codec);
6767			}
6768			printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6769		       			 "trying auto-probe from BIOS...\n");
6770			board_config = ALC882_AUTO;
6771		}
6772	}
6773
6774	alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6775
6776	if (board_config == ALC882_AUTO) {
6777		/* automatic parse from the BIOS config */
6778		err = alc882_parse_auto_config(codec);
6779		if (err < 0) {
6780			alc_free(codec);
6781			return err;
6782		} else if (!err) {
6783			printk(KERN_INFO
6784			       "hda_codec: Cannot set up configuration "
6785			       "from BIOS.  Using base mode...\n");
6786			board_config = ALC882_3ST_DIG;
6787		}
6788	}
6789
6790	if (board_config != ALC882_AUTO)
6791		setup_preset(spec, &alc882_presets[board_config]);
6792
6793	if (codec->vendor_id == 0x10ec0885) {
6794		spec->stream_name_analog = "ALC885 Analog";
6795		spec->stream_name_digital = "ALC885 Digital";
6796	} else {
6797		spec->stream_name_analog = "ALC882 Analog";
6798		spec->stream_name_digital = "ALC882 Digital";
6799	}
6800
6801	spec->stream_analog_playback = &alc882_pcm_analog_playback;
6802	spec->stream_analog_capture = &alc882_pcm_analog_capture;
6803	/* FIXME: setup DAC5 */
6804	/*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
6805	spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
6806
6807	spec->stream_digital_playback = &alc882_pcm_digital_playback;
6808	spec->stream_digital_capture = &alc882_pcm_digital_capture;
6809
6810	spec->is_mix_capture = 1; /* matrix-style capture */
6811	if (!spec->adc_nids && spec->input_mux) {
6812		/* check whether NID 0x07 is valid */
6813		unsigned int wcap = get_wcaps(codec, 0x07);
6814		/* get type */
6815		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6816		if (wcap != AC_WID_AUD_IN) {
6817			spec->adc_nids = alc882_adc_nids_alt;
6818			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6819			spec->capsrc_nids = alc882_capsrc_nids_alt;
6820		} else {
6821			spec->adc_nids = alc882_adc_nids;
6822			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6823			spec->capsrc_nids = alc882_capsrc_nids;
6824		}
6825	}
6826	set_capture_mixer(spec);
6827
6828	spec->vmaster_nid = 0x0c;
6829
6830	codec->patch_ops = alc_patch_ops;
6831	if (board_config == ALC882_AUTO)
6832		spec->init_hook = alc882_auto_init;
6833#ifdef CONFIG_SND_HDA_POWER_SAVE
6834	if (!spec->loopback.amplist)
6835		spec->loopback.amplist = alc882_loopbacks;
6836#endif
6837
6838	return 0;
6839}
6840
6841/*
6842 * ALC883 support
6843 *
6844 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6845 * configuration.  Each pin widget can choose any input DACs and a mixer.
6846 * Each ADC is connected from a mixer of all inputs.  This makes possible
6847 * 6-channel independent captures.
6848 *
6849 * In addition, an independent DAC for the multi-playback (not used in this
6850 * driver yet).
6851 */
6852#define ALC883_DIGOUT_NID	0x06
6853#define ALC883_DIGIN_NID	0x0a
6854
6855static hda_nid_t alc883_dac_nids[4] = {
6856	/* front, rear, clfe, rear_surr */
6857	0x02, 0x03, 0x04, 0x05
6858};
6859
6860static hda_nid_t alc883_adc_nids[2] = {
6861	/* ADC1-2 */
6862	0x08, 0x09,
6863};
6864
6865static hda_nid_t alc883_adc_nids_alt[1] = {
6866	/* ADC1 */
6867	0x08,
6868};
6869
6870static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
6871
6872/* input MUX */
6873/* FIXME: should be a matrix-type input source selection */
6874
6875static struct hda_input_mux alc883_capture_source = {
6876	.num_items = 4,
6877	.items = {
6878		{ "Mic", 0x0 },
6879		{ "Front Mic", 0x1 },
6880		{ "Line", 0x2 },
6881		{ "CD", 0x4 },
6882	},
6883};
6884
6885static struct hda_input_mux alc883_3stack_6ch_intel = {
6886	.num_items = 4,
6887	.items = {
6888		{ "Mic", 0x1 },
6889		{ "Front Mic", 0x0 },
6890		{ "Line", 0x2 },
6891		{ "CD", 0x4 },
6892	},
6893};
6894
6895static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6896	.num_items = 2,
6897	.items = {
6898		{ "Mic", 0x1 },
6899		{ "Line", 0x2 },
6900	},
6901};
6902
6903static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6904	.num_items = 4,
6905	.items = {
6906		{ "Mic", 0x0 },
6907		{ "iMic", 0x1 },
6908		{ "Line", 0x2 },
6909		{ "CD", 0x4 },
6910	},
6911};
6912
6913static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6914	.num_items = 2,
6915	.items = {
6916		{ "Mic", 0x0 },
6917		{ "Int Mic", 0x1 },
6918	},
6919};
6920
6921static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6922	.num_items = 3,
6923	.items = {
6924		{ "Mic", 0x0 },
6925		{ "Front Mic", 0x1 },
6926		{ "Line", 0x4 },
6927	},
6928};
6929
6930static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6931	.num_items = 2,
6932	.items = {
6933		{ "Mic", 0x0 },
6934		{ "Line", 0x2 },
6935	},
6936};
6937
6938/*
6939 * 2ch mode
6940 */
6941static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6942	{ 2, NULL }
6943};
6944
6945/*
6946 * 2ch mode
6947 */
6948static struct hda_verb alc883_3ST_ch2_init[] = {
6949	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6950	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6951	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6952	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6953	{ } /* end */
6954};
6955
6956/*
6957 * 4ch mode
6958 */
6959static struct hda_verb alc883_3ST_ch4_init[] = {
6960	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6961	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6962	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6963	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6964	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6965	{ } /* end */
6966};
6967
6968/*
6969 * 6ch mode
6970 */
6971static struct hda_verb alc883_3ST_ch6_init[] = {
6972	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6973	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6974	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6975	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6976	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6977	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6978	{ } /* end */
6979};
6980
6981static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
6982	{ 2, alc883_3ST_ch2_init },
6983	{ 4, alc883_3ST_ch4_init },
6984	{ 6, alc883_3ST_ch6_init },
6985};
6986
6987/*
6988 * 2ch mode
6989 */
6990static struct hda_verb alc883_3ST_ch2_intel_init[] = {
6991	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6992	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6993	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6994	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6995	{ } /* end */
6996};
6997
6998/*
6999 * 4ch mode
7000 */
7001static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7002	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7003	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7004	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7005	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7006	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7007	{ } /* end */
7008};
7009
7010/*
7011 * 6ch mode
7012 */
7013static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7014	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7015	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7016	{ 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7017	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7018	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7019	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7020	{ } /* end */
7021};
7022
7023static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7024	{ 2, alc883_3ST_ch2_intel_init },
7025	{ 4, alc883_3ST_ch4_intel_init },
7026	{ 6, alc883_3ST_ch6_intel_init },
7027};
7028
7029/*
7030 * 6ch mode
7031 */
7032static struct hda_verb alc883_sixstack_ch6_init[] = {
7033	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7034	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7035	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7036	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7037	{ } /* end */
7038};
7039
7040/*
7041 * 8ch mode
7042 */
7043static struct hda_verb alc883_sixstack_ch8_init[] = {
7044	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7045	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7046	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7047	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7048	{ } /* end */
7049};
7050
7051static struct hda_channel_mode alc883_sixstack_modes[2] = {
7052	{ 6, alc883_sixstack_ch6_init },
7053	{ 8, alc883_sixstack_ch8_init },
7054};
7055
7056static struct hda_verb alc883_medion_eapd_verbs[] = {
7057        /* eanable EAPD on medion laptop */
7058	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7059	{0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7060	{ }
7061};
7062
7063/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7064 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7065 */
7066
7067static struct snd_kcontrol_new alc883_base_mixer[] = {
7068	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7069	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7070	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7071	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7072	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7073	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7074	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7075	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7076	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7077	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7078	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7079	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7080	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7081	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7082	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7083	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7084	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7085	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7086	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7087	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7088	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7089	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7090	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7091	{ } /* end */
7092};
7093
7094static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7095	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7096	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7097	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7098	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7099	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7100	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7101	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7102	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7103	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7104	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7105	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7106	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7107	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7108	{ } /* end */
7109};
7110
7111static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7112	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7113	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7114	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7115	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7116	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7117	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7118	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7119	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7120	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7121	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7122	{ } /* end */
7123};
7124
7125static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7126	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7127	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7128	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7129	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7130	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7131	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7132	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7133	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7134	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7135	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7136	{ } /* end */
7137};
7138
7139static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7140	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7141	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7142	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7143	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7144	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7145	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7146	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7147	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7148	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7149	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7150	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7151	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7152	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7153	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7154	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7155	{ } /* end */
7156};
7157
7158static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7159	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7160	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7161	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7162	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7163	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7164	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7165	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7166	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7167	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7168	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7169	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7170	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7171	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7172	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7173	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7174	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7175	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7176	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7177	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7178	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7179	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7180	{ } /* end */
7181};
7182
7183static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7184	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7185	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7186	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7187	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7188	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7189			      HDA_OUTPUT),
7190	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7191	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7192	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7193	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7194	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7195	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7196	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7197	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7198	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7199	HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7200	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7201	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7202	HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7203	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7204	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7205	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7206	{ } /* end */
7207};
7208
7209static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7210	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7211	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7212	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7213	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7214	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7215	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7216	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7217	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7218	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7219	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7220	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7221	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7222	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7223	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7224	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7225	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7226	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7227	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7228	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7229	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7230	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7231	{ } /* end */
7232};
7233
7234static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7235	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7236	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7237	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7238	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7239	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7240	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7241	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7242	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7243	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7244	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7245	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7246	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7247	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7248	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7249	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7250	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7251	{ } /* end */
7252};
7253
7254static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7255	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7256	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7257	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7258	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7259	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7260	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7261	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7262	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7263	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7264	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7265	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7266	{ } /* end */
7267};
7268
7269static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7270	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7271	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7272	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7273	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7274	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7275	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7276	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7277	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7278	{ } /* end */
7279};
7280
7281static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7282	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7283	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7284	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7285	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7286	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7287	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7288	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7289	HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7290	HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7291	{ } /* end */
7292};
7293
7294static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7295	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7296	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7297	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7298	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7299	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7300	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7301	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7302	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7303	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7304	{ } /* end */
7305};
7306
7307static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7308	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7309	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7310	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7311	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7312	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7313	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7314	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7315	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7316	{ } /* end */
7317};
7318
7319static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7320	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7321	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7322	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7323	HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7324	HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7325						0x0d, 1, 0x0, HDA_OUTPUT),
7326	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7327	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7328	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7329	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7330	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7331	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7332	HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
7333	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7334	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7335	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7336	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7337	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7338	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7339	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7340	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7341	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7342	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7343	{ } /* end */
7344};
7345
7346static struct hda_bind_ctls alc883_bind_cap_vol = {
7347	.ops = &snd_hda_bind_vol,
7348	.values = {
7349		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7350		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7351		0
7352	},
7353};
7354
7355static struct hda_bind_ctls alc883_bind_cap_switch = {
7356	.ops = &snd_hda_bind_sw,
7357	.values = {
7358		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7359		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7360		0
7361	},
7362};
7363
7364static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7365	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7366	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7367	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7368	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7369	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7370	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7371	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7372	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7373	{ } /* end */
7374};
7375
7376static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
7377	HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7378	HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7379	{
7380		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7381		/* .name = "Capture Source", */
7382		.name = "Input Source",
7383		.count = 1,
7384		.info = alc_mux_enum_info,
7385		.get = alc_mux_enum_get,
7386		.put = alc_mux_enum_put,
7387	},
7388	{ } /* end */
7389};
7390
7391static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7392	{
7393		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7394		.name = "Channel Mode",
7395		.info = alc_ch_mode_info,
7396		.get = alc_ch_mode_get,
7397		.put = alc_ch_mode_put,
7398	},
7399	{ } /* end */
7400};
7401
7402static struct hda_verb alc883_init_verbs[] = {
7403	/* ADC1: mute amp left and right */
7404	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7405	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7406	/* ADC2: mute amp left and right */
7407	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7408	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7409	/* Front mixer: unmute input/output amp left and right (volume = 0) */
7410	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7411	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7412	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7413	/* Rear mixer */
7414	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7415	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7416	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7417	/* CLFE mixer */
7418	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7419	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7420	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7421	/* Side mixer */
7422	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7423	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7424	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7425
7426	/* mute analog input loopbacks */
7427	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7428	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7429	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7430	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7431	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7432
7433	/* Front Pin: output 0 (0x0c) */
7434	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7435	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7436	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7437	/* Rear Pin: output 1 (0x0d) */
7438	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7439	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7440	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7441	/* CLFE Pin: output 2 (0x0e) */
7442	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7443	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7444	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7445	/* Side Pin: output 3 (0x0f) */
7446	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7447	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7448	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7449	/* Mic (rear) pin: input vref at 80% */
7450	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7451	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7452	/* Front Mic pin: input vref at 80% */
7453	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7454	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7455	/* Line In pin: input */
7456	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7457	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7458	/* Line-2 In: Headphone output (output 0 - 0x0c) */
7459	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7460	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7461	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7462	/* CD pin widget for input */
7463	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7464
7465	/* FIXME: use matrix-type input source selection */
7466	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7467	/* Input mixer2 */
7468	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7469	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7470	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7471	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7472	/* Input mixer3 */
7473	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7474	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7475	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7476	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7477	{ }
7478};
7479
7480/* toggle speaker-output according to the hp-jack state */
7481static void alc883_mitac_hp_automute(struct hda_codec *codec)
7482{
7483	unsigned int present;
7484
7485	present = snd_hda_codec_read(codec, 0x15, 0,
7486				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7487	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7488				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7489	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7490				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7491}
7492
7493/* auto-toggle front mic */
7494/*
7495static void alc883_mitac_mic_automute(struct hda_codec *codec)
7496{
7497	unsigned int present;
7498	unsigned char bits;
7499
7500	present = snd_hda_codec_read(codec, 0x18, 0,
7501				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7502	bits = present ? HDA_AMP_MUTE : 0;
7503	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7504}
7505*/
7506
7507static void alc883_mitac_automute(struct hda_codec *codec)
7508{
7509	alc883_mitac_hp_automute(codec);
7510	/* alc883_mitac_mic_automute(codec); */
7511}
7512
7513static void alc883_mitac_unsol_event(struct hda_codec *codec,
7514					   unsigned int res)
7515{
7516	switch (res >> 26) {
7517	case ALC880_HP_EVENT:
7518		alc883_mitac_hp_automute(codec);
7519		break;
7520	case ALC880_MIC_EVENT:
7521		/* alc883_mitac_mic_automute(codec); */
7522		break;
7523	}
7524}
7525
7526static struct hda_verb alc883_mitac_verbs[] = {
7527	/* HP */
7528	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7529	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7530	/* Subwoofer */
7531	{0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7532	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7533
7534	/* enable unsolicited event */
7535	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7536	/* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7537
7538	{ } /* end */
7539};
7540
7541static struct hda_verb alc883_clevo_m720_verbs[] = {
7542	/* HP */
7543	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7544	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7545	/* Int speaker */
7546	{0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
7547	{0x14, 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_2ch_fujitsu_pi2515_verbs[] = {
7557	/* HP */
7558	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7559	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7560	/* Subwoofer */
7561	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7562	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7563
7564	/* enable unsolicited event */
7565	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7566
7567	{ } /* end */
7568};
7569
7570static struct hda_verb alc883_tagra_verbs[] = {
7571	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7572	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7573
7574	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7575	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7576
7577	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7578	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7579	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7580
7581	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7582	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7583	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7584	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
7585
7586	{ } /* end */
7587};
7588
7589static struct hda_verb alc883_lenovo_101e_verbs[] = {
7590	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7591	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7592        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7593	{ } /* end */
7594};
7595
7596static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7597        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7598	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7599        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7600        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7601	{ } /* end */
7602};
7603
7604static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7605	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7606	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7607	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7608	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7609	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
7610	{ } /* end */
7611};
7612
7613static struct hda_verb alc883_haier_w66_verbs[] = {
7614	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7615	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7616
7617	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7618
7619	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7620	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7621	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7622	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7623	{ } /* end */
7624};
7625
7626static struct hda_verb alc888_lenovo_sky_verbs[] = {
7627	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7628	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7629	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7630	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7631	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7632	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7633	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7634	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7635	{ } /* end */
7636};
7637
7638static struct hda_verb alc888_3st_hp_verbs[] = {
7639	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Front: output 0 (0x0c) */
7640	{0x16, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Rear : output 1 (0x0d) */
7641	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02},	/* CLFE : output 2 (0x0e) */
7642	{ }
7643};
7644
7645static struct hda_verb alc888_6st_dell_verbs[] = {
7646	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7647	{ }
7648};
7649
7650static struct hda_verb alc888_3st_hp_2ch_init[] = {
7651	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7652	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7653	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7654	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7655	{ }
7656};
7657
7658static struct hda_verb alc888_3st_hp_6ch_init[] = {
7659	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7660	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7661	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7662	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7663	{ }
7664};
7665
7666static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7667	{ 2, alc888_3st_hp_2ch_init },
7668	{ 6, alc888_3st_hp_6ch_init },
7669};
7670
7671/* toggle front-jack and RCA according to the hp-jack state */
7672static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7673{
7674 	unsigned int present;
7675
7676 	present = snd_hda_codec_read(codec, 0x1b, 0,
7677				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7678	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7679				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7680	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7681				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7682}
7683
7684/* toggle RCA according to the front-jack state */
7685static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7686{
7687 	unsigned int present;
7688
7689 	present = snd_hda_codec_read(codec, 0x14, 0,
7690				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7691	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7692				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7693}
7694
7695static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7696					     unsigned int res)
7697{
7698	if ((res >> 26) == ALC880_HP_EVENT)
7699		alc888_lenovo_ms7195_front_automute(codec);
7700	if ((res >> 26) == ALC880_FRONT_EVENT)
7701		alc888_lenovo_ms7195_rca_automute(codec);
7702}
7703
7704static struct hda_verb alc883_medion_md2_verbs[] = {
7705	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7706	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7707
7708	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7709
7710	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7711	{ } /* end */
7712};
7713
7714/* toggle speaker-output according to the hp-jack state */
7715static void alc883_medion_md2_automute(struct hda_codec *codec)
7716{
7717 	unsigned int present;
7718
7719 	present = snd_hda_codec_read(codec, 0x14, 0,
7720				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7721	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7722				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7723}
7724
7725static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7726					  unsigned int res)
7727{
7728	if ((res >> 26) == ALC880_HP_EVENT)
7729		alc883_medion_md2_automute(codec);
7730}
7731
7732/* toggle speaker-output according to the hp-jack state */
7733static void alc883_tagra_automute(struct hda_codec *codec)
7734{
7735 	unsigned int present;
7736	unsigned char bits;
7737
7738 	present = snd_hda_codec_read(codec, 0x14, 0,
7739				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7740	bits = present ? HDA_AMP_MUTE : 0;
7741	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7742				 HDA_AMP_MUTE, bits);
7743	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7744				  present ? 1 : 3);
7745}
7746
7747static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7748{
7749	if ((res >> 26) == ALC880_HP_EVENT)
7750		alc883_tagra_automute(codec);
7751}
7752
7753/* toggle speaker-output according to the hp-jack state */
7754static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
7755{
7756	unsigned int present;
7757	unsigned char bits;
7758
7759	present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
7760		& AC_PINSENSE_PRESENCE;
7761	bits = present ? HDA_AMP_MUTE : 0;
7762	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7763				 HDA_AMP_MUTE, bits);
7764}
7765
7766static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
7767{
7768	unsigned int present;
7769
7770	present = snd_hda_codec_read(codec, 0x18, 0,
7771				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7772	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
7773				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7774}
7775
7776static void alc883_clevo_m720_automute(struct hda_codec *codec)
7777{
7778	alc883_clevo_m720_hp_automute(codec);
7779	alc883_clevo_m720_mic_automute(codec);
7780}
7781
7782static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
7783					   unsigned int res)
7784{
7785	switch (res >> 26) {
7786	case ALC880_HP_EVENT:
7787		alc883_clevo_m720_hp_automute(codec);
7788		break;
7789	case ALC880_MIC_EVENT:
7790		alc883_clevo_m720_mic_automute(codec);
7791		break;
7792	}
7793}
7794
7795/* toggle speaker-output according to the hp-jack state */
7796static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
7797{
7798 	unsigned int present;
7799	unsigned char bits;
7800
7801 	present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
7802		& AC_PINSENSE_PRESENCE;
7803	bits = present ? HDA_AMP_MUTE : 0;
7804	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7805				 HDA_AMP_MUTE, bits);
7806}
7807
7808static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
7809						  unsigned int res)
7810{
7811	if ((res >> 26) == ALC880_HP_EVENT)
7812		alc883_2ch_fujitsu_pi2515_automute(codec);
7813}
7814
7815static void alc883_haier_w66_automute(struct hda_codec *codec)
7816{
7817	unsigned int present;
7818	unsigned char bits;
7819
7820	present = snd_hda_codec_read(codec, 0x1b, 0,
7821				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7822	bits = present ? 0x80 : 0;
7823	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7824				 0x80, bits);
7825}
7826
7827static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7828					 unsigned int res)
7829{
7830	if ((res >> 26) == ALC880_HP_EVENT)
7831		alc883_haier_w66_automute(codec);
7832}
7833
7834static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7835{
7836 	unsigned int present;
7837	unsigned char bits;
7838
7839 	present = snd_hda_codec_read(codec, 0x14, 0,
7840				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7841	bits = present ? HDA_AMP_MUTE : 0;
7842	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7843				 HDA_AMP_MUTE, bits);
7844}
7845
7846static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7847{
7848 	unsigned int present;
7849	unsigned char bits;
7850
7851 	present = snd_hda_codec_read(codec, 0x1b, 0,
7852				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7853	bits = present ? HDA_AMP_MUTE : 0;
7854	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7855				 HDA_AMP_MUTE, bits);
7856	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7857				 HDA_AMP_MUTE, bits);
7858}
7859
7860static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7861					   unsigned int res)
7862{
7863	if ((res >> 26) == ALC880_HP_EVENT)
7864		alc883_lenovo_101e_all_automute(codec);
7865	if ((res >> 26) == ALC880_FRONT_EVENT)
7866		alc883_lenovo_101e_ispeaker_automute(codec);
7867}
7868
7869/* toggle speaker-output according to the hp-jack state */
7870static void alc883_acer_aspire_automute(struct hda_codec *codec)
7871{
7872 	unsigned int present;
7873
7874 	present = snd_hda_codec_read(codec, 0x14, 0,
7875				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7876	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7877				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7878	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7879				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7880}
7881
7882static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7883					   unsigned int res)
7884{
7885	if ((res >> 26) == ALC880_HP_EVENT)
7886		alc883_acer_aspire_automute(codec);
7887}
7888
7889static struct hda_verb alc883_acer_eapd_verbs[] = {
7890	/* HP Pin: output 0 (0x0c) */
7891	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7892	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7893	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7894	/* Front Pin: output 0 (0x0c) */
7895	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7896	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7897	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7898	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7899        /* eanable EAPD on medion laptop */
7900	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7901	{0x20, AC_VERB_SET_PROC_COEF, 0x3050},
7902	/* enable unsolicited event */
7903	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7904	{ }
7905};
7906
7907static void alc888_6st_dell_front_automute(struct hda_codec *codec)
7908{
7909 	unsigned int present;
7910
7911 	present = snd_hda_codec_read(codec, 0x1b, 0,
7912				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7913	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7914				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7915	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7916				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7917	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7918				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7919	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7920				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7921}
7922
7923static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
7924					     unsigned int res)
7925{
7926	switch (res >> 26) {
7927	case ALC880_HP_EVENT:
7928		printk("hp_event\n");
7929		alc888_6st_dell_front_automute(codec);
7930		break;
7931	}
7932}
7933
7934static void alc888_lenovo_sky_front_automute(struct hda_codec *codec)
7935{
7936	unsigned int mute;
7937	unsigned int present;
7938
7939	snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
7940	present = snd_hda_codec_read(codec, 0x1b, 0,
7941				     AC_VERB_GET_PIN_SENSE, 0);
7942	present = (present & 0x80000000) != 0;
7943	if (present) {
7944		/* mute internal speaker */
7945		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7946					 HDA_AMP_MUTE, HDA_AMP_MUTE);
7947		snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7948					 HDA_AMP_MUTE, HDA_AMP_MUTE);
7949		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7950					 HDA_AMP_MUTE, HDA_AMP_MUTE);
7951		snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7952					 HDA_AMP_MUTE, HDA_AMP_MUTE);
7953		snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
7954					 HDA_AMP_MUTE, HDA_AMP_MUTE);
7955	} else {
7956		/* unmute internal speaker if necessary */
7957		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
7958		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7959					 HDA_AMP_MUTE, mute);
7960		snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7961					 HDA_AMP_MUTE, mute);
7962		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7963					 HDA_AMP_MUTE, mute);
7964		snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7965					 HDA_AMP_MUTE, mute);
7966		snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
7967					 HDA_AMP_MUTE, mute);
7968	}
7969}
7970
7971static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec,
7972					     unsigned int res)
7973{
7974	if ((res >> 26) == ALC880_HP_EVENT)
7975		alc888_lenovo_sky_front_automute(codec);
7976}
7977
7978/*
7979 * generic initialization of ADC, input mixers and output mixers
7980 */
7981static struct hda_verb alc883_auto_init_verbs[] = {
7982	/*
7983	 * Unmute ADC0-2 and set the default input to mic-in
7984	 */
7985	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7986	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7987	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7988	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7989
7990	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7991	 * mixer widget
7992	 * Note: PASD motherboards uses the Line In 2 as the input for
7993	 * front panel mic (mic 2)
7994	 */
7995	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7996	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7997	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7998	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7999	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8000	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8001
8002	/*
8003	 * Set up output mixers (0x0c - 0x0f)
8004	 */
8005	/* set vol=0 to output mixers */
8006	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8007	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8008	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8009	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8010	/* set up input amps for analog loopback */
8011	/* Amp Indices: DAC = 0, mixer = 1 */
8012	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8013	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8014	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8015	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8016	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8017	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8018	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8019	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8020	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8021	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8022
8023	/* FIXME: use matrix-type input source selection */
8024	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8025	/* Input mixer1 */
8026	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8027	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8028	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8029	/* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8030	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8031	/* Input mixer2 */
8032	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8033	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8034	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8035	/* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8036	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8037
8038	{ }
8039};
8040
8041static struct hda_verb alc888_asus_m90v_verbs[] = {
8042	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8043	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8044	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8045	/* enable unsolicited event */
8046	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8047	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8048	{ } /* end */
8049};
8050
8051static void alc883_nb_mic_automute(struct hda_codec *codec)
8052{
8053	unsigned int present;
8054
8055	present = snd_hda_codec_read(codec, 0x18, 0,
8056				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8057	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8058			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8059	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8060			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8061}
8062
8063static void alc883_M90V_speaker_automute(struct hda_codec *codec)
8064{
8065	unsigned int present;
8066	unsigned char bits;
8067
8068	present = snd_hda_codec_read(codec, 0x1b, 0,
8069				     AC_VERB_GET_PIN_SENSE, 0)
8070		& AC_PINSENSE_PRESENCE;
8071	bits = present ? 0 : PIN_OUT;
8072	snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8073			    bits);
8074	snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8075			    bits);
8076	snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8077			    bits);
8078}
8079
8080static void alc883_mode2_unsol_event(struct hda_codec *codec,
8081					   unsigned int res)
8082{
8083	switch (res >> 26) {
8084	case ALC880_HP_EVENT:
8085		alc883_M90V_speaker_automute(codec);
8086		break;
8087	case ALC880_MIC_EVENT:
8088		alc883_nb_mic_automute(codec);
8089		break;
8090	}
8091}
8092
8093static void alc883_mode2_inithook(struct hda_codec *codec)
8094{
8095	alc883_M90V_speaker_automute(codec);
8096	alc883_nb_mic_automute(codec);
8097}
8098
8099static struct hda_verb alc888_asus_eee1601_verbs[] = {
8100	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8101	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8102	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8103	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8104	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8105	{0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8106	{0x20, AC_VERB_SET_PROC_COEF,  0x0838},
8107	/* enable unsolicited event */
8108	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8109	{ } /* end */
8110};
8111
8112static void alc883_eee1601_speaker_automute(struct hda_codec *codec)
8113{
8114	unsigned int present;
8115	unsigned char bits;
8116
8117	present = snd_hda_codec_read(codec, 0x14, 0,
8118				     AC_VERB_GET_PIN_SENSE, 0)
8119		& AC_PINSENSE_PRESENCE;
8120	bits = present ? 0 : PIN_OUT;
8121	snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8122			    bits);
8123}
8124
8125static void alc883_eee1601_unsol_event(struct hda_codec *codec,
8126					   unsigned int res)
8127{
8128	switch (res >> 26) {
8129	case ALC880_HP_EVENT:
8130		alc883_eee1601_speaker_automute(codec);
8131		break;
8132	}
8133}
8134
8135static void alc883_eee1601_inithook(struct hda_codec *codec)
8136{
8137	alc883_eee1601_speaker_automute(codec);
8138}
8139
8140#ifdef CONFIG_SND_HDA_POWER_SAVE
8141#define alc883_loopbacks	alc880_loopbacks
8142#endif
8143
8144/* pcm configuration: identiacal with ALC880 */
8145#define alc883_pcm_analog_playback	alc880_pcm_analog_playback
8146#define alc883_pcm_analog_capture	alc880_pcm_analog_capture
8147#define alc883_pcm_analog_alt_capture	alc880_pcm_analog_alt_capture
8148#define alc883_pcm_digital_playback	alc880_pcm_digital_playback
8149#define alc883_pcm_digital_capture	alc880_pcm_digital_capture
8150
8151/*
8152 * configuration and preset
8153 */
8154static const char *alc883_models[ALC883_MODEL_LAST] = {
8155	[ALC883_3ST_2ch_DIG]	= "3stack-dig",
8156	[ALC883_3ST_6ch_DIG]	= "3stack-6ch-dig",
8157	[ALC883_3ST_6ch]	= "3stack-6ch",
8158	[ALC883_6ST_DIG]	= "6stack-dig",
8159	[ALC883_TARGA_DIG]	= "targa-dig",
8160	[ALC883_TARGA_2ch_DIG]	= "targa-2ch-dig",
8161	[ALC883_ACER]		= "acer",
8162	[ALC883_ACER_ASPIRE]	= "acer-aspire",
8163	[ALC883_MEDION]		= "medion",
8164	[ALC883_MEDION_MD2]	= "medion-md2",
8165	[ALC883_LAPTOP_EAPD]	= "laptop-eapd",
8166	[ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8167	[ALC883_LENOVO_NB0763]	= "lenovo-nb0763",
8168	[ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8169	[ALC888_LENOVO_SKY] = "lenovo-sky",
8170	[ALC883_HAIER_W66] 	= "haier-w66",
8171	[ALC888_3ST_HP]		= "3stack-hp",
8172	[ALC888_6ST_DELL]	= "6stack-dell",
8173	[ALC883_MITAC]		= "mitac",
8174	[ALC883_CLEVO_M720]	= "clevo-m720",
8175	[ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8176	[ALC883_3ST_6ch_INTEL]	= "3stack-6ch-intel",
8177	[ALC883_AUTO]		= "auto",
8178};
8179
8180static struct snd_pci_quirk alc883_cfg_tbl[] = {
8181	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
8182	SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8183	SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8184	SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8185	SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8186	SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
8187	SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8188	SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8189	SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8190	SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8191	SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8192	SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8193	SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8194	SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8195	SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8196	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
8197	SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8198	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8199	SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8200	SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8201	SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
8202	SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8203	SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8204	SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8205	SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8206	SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8207	SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8208	SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8209	SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8210	SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8211	SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8212	SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8213	SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8214	SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8215	SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8216	SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8217	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8218	SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8219	SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8220	SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8221	SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8222	SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8223	SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8224	SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8225	SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8226	SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8227	SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
8228	SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8229	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8230	SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515),
8231	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8232	SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8233	SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8234	SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8235	SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8236	SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8237	SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8238	SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8239	SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8240	SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8241	SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8242	{}
8243};
8244
8245static struct alc_config_preset alc883_presets[] = {
8246	[ALC883_3ST_2ch_DIG] = {
8247		.mixers = { alc883_3ST_2ch_mixer },
8248		.init_verbs = { alc883_init_verbs },
8249		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8250		.dac_nids = alc883_dac_nids,
8251		.dig_out_nid = ALC883_DIGOUT_NID,
8252		.dig_in_nid = ALC883_DIGIN_NID,
8253		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8254		.channel_mode = alc883_3ST_2ch_modes,
8255		.input_mux = &alc883_capture_source,
8256	},
8257	[ALC883_3ST_6ch_DIG] = {
8258		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8259		.init_verbs = { alc883_init_verbs },
8260		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8261		.dac_nids = alc883_dac_nids,
8262		.dig_out_nid = ALC883_DIGOUT_NID,
8263		.dig_in_nid = ALC883_DIGIN_NID,
8264		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8265		.channel_mode = alc883_3ST_6ch_modes,
8266		.need_dac_fix = 1,
8267		.input_mux = &alc883_capture_source,
8268	},
8269	[ALC883_3ST_6ch] = {
8270		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8271		.init_verbs = { alc883_init_verbs },
8272		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8273		.dac_nids = alc883_dac_nids,
8274		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8275		.channel_mode = alc883_3ST_6ch_modes,
8276		.need_dac_fix = 1,
8277		.input_mux = &alc883_capture_source,
8278	},
8279	[ALC883_3ST_6ch_INTEL] = {
8280		.mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8281		.init_verbs = { alc883_init_verbs },
8282		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8283		.dac_nids = alc883_dac_nids,
8284		.dig_out_nid = ALC883_DIGOUT_NID,
8285		.dig_in_nid = ALC883_DIGIN_NID,
8286		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8287		.channel_mode = alc883_3ST_6ch_intel_modes,
8288		.need_dac_fix = 1,
8289		.input_mux = &alc883_3stack_6ch_intel,
8290	},
8291	[ALC883_6ST_DIG] = {
8292		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
8293		.init_verbs = { alc883_init_verbs },
8294		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8295		.dac_nids = alc883_dac_nids,
8296		.dig_out_nid = ALC883_DIGOUT_NID,
8297		.dig_in_nid = ALC883_DIGIN_NID,
8298		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8299		.channel_mode = alc883_sixstack_modes,
8300		.input_mux = &alc883_capture_source,
8301	},
8302	[ALC883_TARGA_DIG] = {
8303		.mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8304		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8305		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8306		.dac_nids = alc883_dac_nids,
8307		.dig_out_nid = ALC883_DIGOUT_NID,
8308		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8309		.channel_mode = alc883_3ST_6ch_modes,
8310		.need_dac_fix = 1,
8311		.input_mux = &alc883_capture_source,
8312		.unsol_event = alc883_tagra_unsol_event,
8313		.init_hook = alc883_tagra_automute,
8314	},
8315	[ALC883_TARGA_2ch_DIG] = {
8316		.mixers = { alc883_tagra_2ch_mixer},
8317		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8318		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8319		.dac_nids = alc883_dac_nids,
8320		.adc_nids = alc883_adc_nids_alt,
8321		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8322		.dig_out_nid = ALC883_DIGOUT_NID,
8323		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8324		.channel_mode = alc883_3ST_2ch_modes,
8325		.input_mux = &alc883_capture_source,
8326		.unsol_event = alc883_tagra_unsol_event,
8327		.init_hook = alc883_tagra_automute,
8328	},
8329	[ALC883_ACER] = {
8330		.mixers = { alc883_base_mixer },
8331		/* On TravelMate laptops, GPIO 0 enables the internal speaker
8332		 * and the headphone jack.  Turn this on and rely on the
8333		 * standard mute methods whenever the user wants to turn
8334		 * these outputs off.
8335		 */
8336		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8337		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8338		.dac_nids = alc883_dac_nids,
8339		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8340		.channel_mode = alc883_3ST_2ch_modes,
8341		.input_mux = &alc883_capture_source,
8342	},
8343	[ALC883_ACER_ASPIRE] = {
8344		.mixers = { alc883_acer_aspire_mixer },
8345		.init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
8346		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8347		.dac_nids = alc883_dac_nids,
8348		.dig_out_nid = ALC883_DIGOUT_NID,
8349		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8350		.channel_mode = alc883_3ST_2ch_modes,
8351		.input_mux = &alc883_capture_source,
8352		.unsol_event = alc883_acer_aspire_unsol_event,
8353		.init_hook = alc883_acer_aspire_automute,
8354	},
8355	[ALC883_MEDION] = {
8356		.mixers = { alc883_fivestack_mixer,
8357			    alc883_chmode_mixer },
8358		.init_verbs = { alc883_init_verbs,
8359				alc883_medion_eapd_verbs },
8360		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8361		.dac_nids = alc883_dac_nids,
8362		.adc_nids = alc883_adc_nids_alt,
8363		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8364		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8365		.channel_mode = alc883_sixstack_modes,
8366		.input_mux = &alc883_capture_source,
8367	},
8368	[ALC883_MEDION_MD2] = {
8369		.mixers = { alc883_medion_md2_mixer},
8370		.init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8371		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8372		.dac_nids = alc883_dac_nids,
8373		.dig_out_nid = ALC883_DIGOUT_NID,
8374		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8375		.channel_mode = alc883_3ST_2ch_modes,
8376		.input_mux = &alc883_capture_source,
8377		.unsol_event = alc883_medion_md2_unsol_event,
8378		.init_hook = alc883_medion_md2_automute,
8379	},
8380	[ALC883_LAPTOP_EAPD] = {
8381		.mixers = { alc883_base_mixer },
8382		.init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8383		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8384		.dac_nids = alc883_dac_nids,
8385		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8386		.channel_mode = alc883_3ST_2ch_modes,
8387		.input_mux = &alc883_capture_source,
8388	},
8389	[ALC883_CLEVO_M720] = {
8390		.mixers = { alc883_clevo_m720_mixer },
8391		.init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
8392		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8393		.dac_nids = alc883_dac_nids,
8394		.dig_out_nid = ALC883_DIGOUT_NID,
8395		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8396		.channel_mode = alc883_3ST_2ch_modes,
8397		.input_mux = &alc883_capture_source,
8398		.unsol_event = alc883_clevo_m720_unsol_event,
8399		.init_hook = alc883_clevo_m720_automute,
8400	},
8401	[ALC883_LENOVO_101E_2ch] = {
8402		.mixers = { alc883_lenovo_101e_2ch_mixer},
8403		.init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8404		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8405		.dac_nids = alc883_dac_nids,
8406		.adc_nids = alc883_adc_nids_alt,
8407		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8408		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8409		.channel_mode = alc883_3ST_2ch_modes,
8410		.input_mux = &alc883_lenovo_101e_capture_source,
8411		.unsol_event = alc883_lenovo_101e_unsol_event,
8412		.init_hook = alc883_lenovo_101e_all_automute,
8413	},
8414	[ALC883_LENOVO_NB0763] = {
8415		.mixers = { alc883_lenovo_nb0763_mixer },
8416		.init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8417		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8418		.dac_nids = alc883_dac_nids,
8419		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8420		.channel_mode = alc883_3ST_2ch_modes,
8421		.need_dac_fix = 1,
8422		.input_mux = &alc883_lenovo_nb0763_capture_source,
8423		.unsol_event = alc883_medion_md2_unsol_event,
8424		.init_hook = alc883_medion_md2_automute,
8425	},
8426	[ALC888_LENOVO_MS7195_DIG] = {
8427		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8428		.init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8429		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8430		.dac_nids = alc883_dac_nids,
8431		.dig_out_nid = ALC883_DIGOUT_NID,
8432		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8433		.channel_mode = alc883_3ST_6ch_modes,
8434		.need_dac_fix = 1,
8435		.input_mux = &alc883_capture_source,
8436		.unsol_event = alc883_lenovo_ms7195_unsol_event,
8437		.init_hook = alc888_lenovo_ms7195_front_automute,
8438	},
8439	[ALC883_HAIER_W66] = {
8440		.mixers = { alc883_tagra_2ch_mixer},
8441		.init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8442		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8443		.dac_nids = alc883_dac_nids,
8444		.dig_out_nid = ALC883_DIGOUT_NID,
8445		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8446		.channel_mode = alc883_3ST_2ch_modes,
8447		.input_mux = &alc883_capture_source,
8448		.unsol_event = alc883_haier_w66_unsol_event,
8449		.init_hook = alc883_haier_w66_automute,
8450	},
8451	[ALC888_3ST_HP] = {
8452		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8453		.init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8454		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8455		.dac_nids = alc883_dac_nids,
8456		.num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
8457		.channel_mode = alc888_3st_hp_modes,
8458		.need_dac_fix = 1,
8459		.input_mux = &alc883_capture_source,
8460	},
8461	[ALC888_6ST_DELL] = {
8462		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
8463		.init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
8464		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8465		.dac_nids = alc883_dac_nids,
8466		.dig_out_nid = ALC883_DIGOUT_NID,
8467		.dig_in_nid = ALC883_DIGIN_NID,
8468		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8469		.channel_mode = alc883_sixstack_modes,
8470		.input_mux = &alc883_capture_source,
8471		.unsol_event = alc888_6st_dell_unsol_event,
8472		.init_hook = alc888_6st_dell_front_automute,
8473	},
8474	[ALC883_MITAC] = {
8475		.mixers = { alc883_mitac_mixer },
8476		.init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8477		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8478		.dac_nids = alc883_dac_nids,
8479		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8480		.channel_mode = alc883_3ST_2ch_modes,
8481		.input_mux = &alc883_capture_source,
8482		.unsol_event = alc883_mitac_unsol_event,
8483		.init_hook = alc883_mitac_automute,
8484	},
8485	[ALC883_FUJITSU_PI2515] = {
8486		.mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8487		.init_verbs = { alc883_init_verbs,
8488				alc883_2ch_fujitsu_pi2515_verbs},
8489		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8490		.dac_nids = alc883_dac_nids,
8491		.dig_out_nid = ALC883_DIGOUT_NID,
8492		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8493		.channel_mode = alc883_3ST_2ch_modes,
8494		.input_mux = &alc883_fujitsu_pi2515_capture_source,
8495		.unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
8496		.init_hook = alc883_2ch_fujitsu_pi2515_automute,
8497	},
8498	[ALC888_LENOVO_SKY] = {
8499		.mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
8500		.init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
8501		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8502		.dac_nids = alc883_dac_nids,
8503		.dig_out_nid = ALC883_DIGOUT_NID,
8504		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8505		.channel_mode = alc883_sixstack_modes,
8506		.need_dac_fix = 1,
8507		.input_mux = &alc883_lenovo_sky_capture_source,
8508		.unsol_event = alc883_lenovo_sky_unsol_event,
8509		.init_hook = alc888_lenovo_sky_front_automute,
8510	},
8511	[ALC888_ASUS_M90V] = {
8512		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8513		.init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
8514		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8515		.dac_nids = alc883_dac_nids,
8516		.dig_out_nid = ALC883_DIGOUT_NID,
8517		.dig_in_nid = ALC883_DIGIN_NID,
8518		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8519		.channel_mode = alc883_3ST_6ch_modes,
8520		.need_dac_fix = 1,
8521		.input_mux = &alc883_fujitsu_pi2515_capture_source,
8522		.unsol_event = alc883_mode2_unsol_event,
8523		.init_hook = alc883_mode2_inithook,
8524	},
8525	[ALC888_ASUS_EEE1601] = {
8526		.mixers = { alc883_asus_eee1601_mixer },
8527		.cap_mixer = alc883_asus_eee1601_cap_mixer,
8528		.init_verbs = { alc883_init_verbs, alc888_asus_eee1601_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_2ch_modes),
8534		.channel_mode = alc883_3ST_2ch_modes,
8535		.need_dac_fix = 1,
8536		.input_mux = &alc883_asus_eee1601_capture_source,
8537		.unsol_event = alc883_eee1601_unsol_event,
8538		.init_hook = alc883_eee1601_inithook,
8539	},
8540};
8541
8542
8543/*
8544 * BIOS auto configuration
8545 */
8546static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
8547					      hda_nid_t nid, int pin_type,
8548					      int dac_idx)
8549{
8550	/* set as output */
8551	struct alc_spec *spec = codec->spec;
8552	int idx;
8553
8554	alc_set_pin_output(codec, nid, pin_type);
8555	if (spec->multiout.dac_nids[dac_idx] == 0x25)
8556		idx = 4;
8557	else
8558		idx = spec->multiout.dac_nids[dac_idx] - 2;
8559	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
8560
8561}
8562
8563static void alc883_auto_init_multi_out(struct hda_codec *codec)
8564{
8565	struct alc_spec *spec = codec->spec;
8566	int i;
8567
8568	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
8569	for (i = 0; i <= HDA_SIDE; i++) {
8570		hda_nid_t nid = spec->autocfg.line_out_pins[i];
8571		int pin_type = get_pin_type(spec->autocfg.line_out_type);
8572		if (nid)
8573			alc883_auto_set_output_and_unmute(codec, nid, pin_type,
8574							  i);
8575	}
8576}
8577
8578static void alc883_auto_init_hp_out(struct hda_codec *codec)
8579{
8580	struct alc_spec *spec = codec->spec;
8581	hda_nid_t pin;
8582
8583	pin = spec->autocfg.hp_pins[0];
8584	if (pin) /* connect to front */
8585		/* use dac 0 */
8586		alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
8587	pin = spec->autocfg.speaker_pins[0];
8588	if (pin)
8589		alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
8590}
8591
8592#define alc883_is_input_pin(nid)	alc880_is_input_pin(nid)
8593#define ALC883_PIN_CD_NID		ALC880_PIN_CD_NID
8594
8595static void alc883_auto_init_analog_input(struct hda_codec *codec)
8596{
8597	struct alc_spec *spec = codec->spec;
8598	int i;
8599
8600	for (i = 0; i < AUTO_PIN_LAST; i++) {
8601		hda_nid_t nid = spec->autocfg.input_pins[i];
8602		if (alc883_is_input_pin(nid)) {
8603			snd_hda_codec_write(codec, nid, 0,
8604					    AC_VERB_SET_PIN_WIDGET_CONTROL,
8605					    (i <= AUTO_PIN_FRONT_MIC ?
8606					     PIN_VREF80 : PIN_IN));
8607			if (nid != ALC883_PIN_CD_NID)
8608				snd_hda_codec_write(codec, nid, 0,
8609						    AC_VERB_SET_AMP_GAIN_MUTE,
8610						    AMP_OUT_MUTE);
8611		}
8612	}
8613}
8614
8615#define alc883_auto_init_input_src	alc882_auto_init_input_src
8616
8617/* almost identical with ALC880 parser... */
8618static int alc883_parse_auto_config(struct hda_codec *codec)
8619{
8620	struct alc_spec *spec = codec->spec;
8621	int err = alc880_parse_auto_config(codec);
8622
8623	if (err < 0)
8624		return err;
8625	else if (!err)
8626		return 0; /* no config found */
8627
8628	err = alc_auto_add_mic_boost(codec);
8629	if (err < 0)
8630		return err;
8631
8632	/* hack - override the init verbs */
8633	spec->init_verbs[0] = alc883_auto_init_verbs;
8634
8635	return 1; /* config found */
8636}
8637
8638/* additional initialization for auto-configuration model */
8639static void alc883_auto_init(struct hda_codec *codec)
8640{
8641	struct alc_spec *spec = codec->spec;
8642	alc883_auto_init_multi_out(codec);
8643	alc883_auto_init_hp_out(codec);
8644	alc883_auto_init_analog_input(codec);
8645	alc883_auto_init_input_src(codec);
8646	if (spec->unsol_event)
8647		alc_inithook(codec);
8648}
8649
8650static int patch_alc883(struct hda_codec *codec)
8651{
8652	struct alc_spec *spec;
8653	int err, board_config;
8654
8655	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8656	if (spec == NULL)
8657		return -ENOMEM;
8658
8659	codec->spec = spec;
8660
8661	alc_fix_pll_init(codec, 0x20, 0x0a, 10);
8662
8663	board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
8664						  alc883_models,
8665						  alc883_cfg_tbl);
8666	if (board_config < 0) {
8667		printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
8668		       "trying auto-probe from BIOS...\n");
8669		board_config = ALC883_AUTO;
8670	}
8671
8672	if (board_config == ALC883_AUTO) {
8673		/* automatic parse from the BIOS config */
8674		err = alc883_parse_auto_config(codec);
8675		if (err < 0) {
8676			alc_free(codec);
8677			return err;
8678		} else if (!err) {
8679			printk(KERN_INFO
8680			       "hda_codec: Cannot set up configuration "
8681			       "from BIOS.  Using base mode...\n");
8682			board_config = ALC883_3ST_2ch_DIG;
8683		}
8684	}
8685
8686	if (board_config != ALC883_AUTO)
8687		setup_preset(spec, &alc883_presets[board_config]);
8688
8689	switch (codec->vendor_id) {
8690	case 0x10ec0888:
8691		if (codec->revision_id == 0x100101) {
8692			spec->stream_name_analog = "ALC1200 Analog";
8693			spec->stream_name_digital = "ALC1200 Digital";
8694		} else {
8695			spec->stream_name_analog = "ALC888 Analog";
8696			spec->stream_name_digital = "ALC888 Digital";
8697		}
8698		break;
8699	case 0x10ec0889:
8700		spec->stream_name_analog = "ALC889 Analog";
8701		spec->stream_name_digital = "ALC889 Digital";
8702		break;
8703	default:
8704		spec->stream_name_analog = "ALC883 Analog";
8705		spec->stream_name_digital = "ALC883 Digital";
8706		break;
8707	}
8708
8709	spec->stream_analog_playback = &alc883_pcm_analog_playback;
8710	spec->stream_analog_capture = &alc883_pcm_analog_capture;
8711	spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
8712
8713	spec->stream_digital_playback = &alc883_pcm_digital_playback;
8714	spec->stream_digital_capture = &alc883_pcm_digital_capture;
8715
8716	if (!spec->num_adc_nids) {
8717		spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8718		spec->adc_nids = alc883_adc_nids;
8719	}
8720	if (!spec->capsrc_nids)
8721		spec->capsrc_nids = alc883_capsrc_nids;
8722	spec->is_mix_capture = 1; /* matrix-style capture */
8723	if (!spec->cap_mixer)
8724		set_capture_mixer(spec);
8725
8726	spec->vmaster_nid = 0x0c;
8727
8728	codec->patch_ops = alc_patch_ops;
8729	if (board_config == ALC883_AUTO)
8730		spec->init_hook = alc883_auto_init;
8731
8732#ifdef CONFIG_SND_HDA_POWER_SAVE
8733	if (!spec->loopback.amplist)
8734		spec->loopback.amplist = alc883_loopbacks;
8735#endif
8736
8737	return 0;
8738}
8739
8740/*
8741 * ALC262 support
8742 */
8743
8744#define ALC262_DIGOUT_NID	ALC880_DIGOUT_NID
8745#define ALC262_DIGIN_NID	ALC880_DIGIN_NID
8746
8747#define alc262_dac_nids		alc260_dac_nids
8748#define alc262_adc_nids		alc882_adc_nids
8749#define alc262_adc_nids_alt	alc882_adc_nids_alt
8750#define alc262_capsrc_nids	alc882_capsrc_nids
8751#define alc262_capsrc_nids_alt	alc882_capsrc_nids_alt
8752
8753#define alc262_modes		alc260_modes
8754#define alc262_capture_source	alc882_capture_source
8755
8756static hda_nid_t alc262_dmic_adc_nids[1] = {
8757	/* ADC0 */
8758	0x09
8759};
8760
8761static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
8762
8763static struct snd_kcontrol_new alc262_base_mixer[] = {
8764	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8765	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8766	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8767	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8768	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8769	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8770	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8771	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8772	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8773	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8774	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8775	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8776	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8777	   HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8778	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
8779	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8780	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8781	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
8782	{ } /* end */
8783};
8784
8785static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
8786	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8787	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8788	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8789	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8790	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8791	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8792	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8793	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8794	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8795	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8796	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8797	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8798	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8799	   HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8800	/*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
8801	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8802	{ } /* end */
8803};
8804
8805/* update HP, line and mono-out pins according to the master switch */
8806static void alc262_hp_master_update(struct hda_codec *codec)
8807{
8808	struct alc_spec *spec = codec->spec;
8809	int val = spec->master_sw;
8810
8811	/* HP & line-out */
8812	snd_hda_codec_write_cache(codec, 0x1b, 0,
8813				  AC_VERB_SET_PIN_WIDGET_CONTROL,
8814				  val ? PIN_HP : 0);
8815	snd_hda_codec_write_cache(codec, 0x15, 0,
8816				  AC_VERB_SET_PIN_WIDGET_CONTROL,
8817				  val ? PIN_HP : 0);
8818	/* mono (speaker) depending on the HP jack sense */
8819	val = val && !spec->jack_present;
8820	snd_hda_codec_write_cache(codec, 0x16, 0,
8821				  AC_VERB_SET_PIN_WIDGET_CONTROL,
8822				  val ? PIN_OUT : 0);
8823}
8824
8825static void alc262_hp_bpc_automute(struct hda_codec *codec)
8826{
8827	struct alc_spec *spec = codec->spec;
8828	unsigned int presence;
8829	presence = snd_hda_codec_read(codec, 0x1b, 0,
8830				      AC_VERB_GET_PIN_SENSE, 0);
8831	spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8832	alc262_hp_master_update(codec);
8833}
8834
8835static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
8836{
8837	if ((res >> 26) != ALC880_HP_EVENT)
8838		return;
8839	alc262_hp_bpc_automute(codec);
8840}
8841
8842static void alc262_hp_wildwest_automute(struct hda_codec *codec)
8843{
8844	struct alc_spec *spec = codec->spec;
8845	unsigned int presence;
8846	presence = snd_hda_codec_read(codec, 0x15, 0,
8847				      AC_VERB_GET_PIN_SENSE, 0);
8848	spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8849	alc262_hp_master_update(codec);
8850}
8851
8852static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
8853					   unsigned int res)
8854{
8855	if ((res >> 26) != ALC880_HP_EVENT)
8856		return;
8857	alc262_hp_wildwest_automute(codec);
8858}
8859
8860static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
8861				   struct snd_ctl_elem_value *ucontrol)
8862{
8863	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8864	struct alc_spec *spec = codec->spec;
8865	*ucontrol->value.integer.value = spec->master_sw;
8866	return 0;
8867}
8868
8869static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
8870				   struct snd_ctl_elem_value *ucontrol)
8871{
8872	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8873	struct alc_spec *spec = codec->spec;
8874	int val = !!*ucontrol->value.integer.value;
8875
8876	if (val == spec->master_sw)
8877		return 0;
8878	spec->master_sw = val;
8879	alc262_hp_master_update(codec);
8880	return 1;
8881}
8882
8883static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
8884	{
8885		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8886		.name = "Master Playback Switch",
8887		.info = snd_ctl_boolean_mono_info,
8888		.get = alc262_hp_master_sw_get,
8889		.put = alc262_hp_master_sw_put,
8890	},
8891	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8892	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8893	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8894	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8895			      HDA_OUTPUT),
8896	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8897			    HDA_OUTPUT),
8898	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8899	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8900	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8901	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8902	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8903	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8904	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8905	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8906	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8907	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8908	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8909	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8910	HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
8911	HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
8912	{ } /* end */
8913};
8914
8915static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
8916	{
8917		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8918		.name = "Master Playback Switch",
8919		.info = snd_ctl_boolean_mono_info,
8920		.get = alc262_hp_master_sw_get,
8921		.put = alc262_hp_master_sw_put,
8922	},
8923	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8924	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8925	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8926	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8927	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8928			      HDA_OUTPUT),
8929	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8930			    HDA_OUTPUT),
8931	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
8932	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
8933	HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
8934	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8935	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8936	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8937	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8938	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8939	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8940	{ } /* end */
8941};
8942
8943static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
8944	HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8945	HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8946	HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
8947	{ } /* end */
8948};
8949
8950/* mute/unmute internal speaker according to the hp jack and mute state */
8951static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
8952{
8953	struct alc_spec *spec = codec->spec;
8954
8955	if (force || !spec->sense_updated) {
8956		unsigned int present;
8957		present = snd_hda_codec_read(codec, 0x15, 0,
8958					     AC_VERB_GET_PIN_SENSE, 0);
8959		spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
8960		spec->sense_updated = 1;
8961	}
8962	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
8963				 spec->jack_present ? HDA_AMP_MUTE : 0);
8964}
8965
8966static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
8967					unsigned int res)
8968{
8969	if ((res >> 26) != ALC880_HP_EVENT)
8970		return;
8971	alc262_hp_t5735_automute(codec, 1);
8972}
8973
8974static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
8975{
8976	alc262_hp_t5735_automute(codec, 1);
8977}
8978
8979static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
8980	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8981	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8982	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8983	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8984	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8985	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8986	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8987	{ } /* end */
8988};
8989
8990static struct hda_verb alc262_hp_t5735_verbs[] = {
8991	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8992	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8993
8994	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8995	{ }
8996};
8997
8998static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
8999	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9000	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9001	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9002	HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
9003	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9004	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9005	{ } /* end */
9006};
9007
9008static struct hda_verb alc262_hp_rp5700_verbs[] = {
9009	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9010	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9011	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9012	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9013	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9014	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9015	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9016	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9017	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9018	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9019	{}
9020};
9021
9022static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9023	.num_items = 1,
9024	.items = {
9025		{ "Line", 0x1 },
9026	},
9027};
9028
9029/* bind hp and internal speaker mute (with plug check) */
9030static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
9031				     struct snd_ctl_elem_value *ucontrol)
9032{
9033	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9034	long *valp = ucontrol->value.integer.value;
9035	int change;
9036
9037	/* change hp mute */
9038	change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
9039					  HDA_AMP_MUTE,
9040					  valp[0] ? 0 : HDA_AMP_MUTE);
9041	change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
9042					   HDA_AMP_MUTE,
9043					   valp[1] ? 0 : HDA_AMP_MUTE);
9044	if (change) {
9045		/* change speaker according to HP jack state */
9046		struct alc_spec *spec = codec->spec;
9047		unsigned int mute;
9048		if (spec->jack_present)
9049			mute = HDA_AMP_MUTE;
9050		else
9051			mute = snd_hda_codec_amp_read(codec, 0x15, 0,
9052						      HDA_OUTPUT, 0);
9053		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9054					 HDA_AMP_MUTE, mute);
9055	}
9056	return change;
9057}
9058
9059static struct snd_kcontrol_new alc262_sony_mixer[] = {
9060	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9061	{
9062		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9063		.name = "Master Playback Switch",
9064		.info = snd_hda_mixer_amp_switch_info,
9065		.get = snd_hda_mixer_amp_switch_get,
9066		.put = alc262_sony_master_sw_put,
9067		.private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9068	},
9069	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9070	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9071	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9072	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9073	{ } /* end */
9074};
9075
9076static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9077	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9078	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9079	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9080	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9081	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9082	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9083	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9084	{ } /* end */
9085};
9086
9087#define alc262_capture_mixer		alc882_capture_mixer
9088#define alc262_capture_alt_mixer	alc882_capture_alt_mixer
9089
9090/*
9091 * generic initialization of ADC, input mixers and output mixers
9092 */
9093static struct hda_verb alc262_init_verbs[] = {
9094	/*
9095	 * Unmute ADC0-2 and set the default input to mic-in
9096	 */
9097	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9098	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9099	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9100	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9101	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9102	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9103
9104	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9105	 * mixer widget
9106	 * Note: PASD motherboards uses the Line In 2 as the input for
9107	 * front panel mic (mic 2)
9108	 */
9109	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9110	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9111	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9112	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9113	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9114	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9115
9116	/*
9117	 * Set up output mixers (0x0c - 0x0e)
9118	 */
9119	/* set vol=0 to output mixers */
9120	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9121	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9122	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9123	/* set up input amps for analog loopback */
9124	/* Amp Indices: DAC = 0, mixer = 1 */
9125	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9126	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9127	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9128	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9129	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9130	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9131
9132	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9133	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9134	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9135	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9136	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9137	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9138
9139	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9140	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9141	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9142	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9143	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9144
9145	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9146	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9147
9148	/* FIXME: use matrix-type input source selection */
9149	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9150	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9151	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9152	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9153	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9154	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9155	/* Input mixer2 */
9156	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9157	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9158	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9159	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9160	/* Input mixer3 */
9161	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9162	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9163	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9164	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9165
9166	{ }
9167};
9168
9169static struct hda_verb alc262_eapd_verbs[] = {
9170	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9171	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9172	{ }
9173};
9174
9175static struct hda_verb alc262_hippo_unsol_verbs[] = {
9176	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9177	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9178	{}
9179};
9180
9181static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9182	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9183	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9184	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9185
9186	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9187	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9188	{}
9189};
9190
9191static struct hda_verb alc262_sony_unsol_verbs[] = {
9192	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9193	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9194	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},	// Front Mic
9195
9196	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9197	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9198	{}
9199};
9200
9201static struct hda_input_mux alc262_dmic_capture_source = {
9202	.num_items = 2,
9203	.items = {
9204		{ "Int DMic", 0x9 },
9205		{ "Mic", 0x0 },
9206	},
9207};
9208
9209static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9210	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9211	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9212	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9213	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9214	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9215	{ } /* end */
9216};
9217
9218static struct hda_verb alc262_toshiba_s06_verbs[] = {
9219	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9220	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9221	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9222	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9223	{0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9224	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9225	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9226	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9227	{}
9228};
9229
9230static void alc262_dmic_automute(struct hda_codec *codec)
9231{
9232	unsigned int present;
9233
9234	present = snd_hda_codec_read(codec, 0x18, 0,
9235					AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9236	snd_hda_codec_write(codec, 0x22, 0,
9237				AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9238}
9239
9240/* toggle speaker-output according to the hp-jack state */
9241static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
9242{
9243	unsigned int present;
9244	unsigned char bits;
9245
9246	present = snd_hda_codec_read(codec, 0x15, 0,
9247					AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9248	bits = present ? 0 : PIN_OUT;
9249	snd_hda_codec_write(codec, 0x14, 0,
9250					AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
9251}
9252
9253
9254
9255/* unsolicited event for HP jack sensing */
9256static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9257				       unsigned int res)
9258{
9259	if ((res >> 26) == ALC880_HP_EVENT)
9260		alc262_toshiba_s06_speaker_automute(codec);
9261	if ((res >> 26) == ALC880_MIC_EVENT)
9262		alc262_dmic_automute(codec);
9263
9264}
9265
9266static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9267{
9268	alc262_toshiba_s06_speaker_automute(codec);
9269	alc262_dmic_automute(codec);
9270}
9271
9272/* mute/unmute internal speaker according to the hp jack and mute state */
9273static void alc262_hippo_automute(struct hda_codec *codec)
9274{
9275	struct alc_spec *spec = codec->spec;
9276	unsigned int mute;
9277	unsigned int present;
9278
9279	/* need to execute and sync at first */
9280	snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9281	present = snd_hda_codec_read(codec, 0x15, 0,
9282				     AC_VERB_GET_PIN_SENSE, 0);
9283	spec->jack_present = (present & 0x80000000) != 0;
9284	if (spec->jack_present) {
9285		/* mute internal speaker */
9286		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9287					 HDA_AMP_MUTE, HDA_AMP_MUTE);
9288	} else {
9289		/* unmute internal speaker if necessary */
9290		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
9291		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9292					 HDA_AMP_MUTE, mute);
9293	}
9294}
9295
9296/* unsolicited event for HP jack sensing */
9297static void alc262_hippo_unsol_event(struct hda_codec *codec,
9298				       unsigned int res)
9299{
9300	if ((res >> 26) != ALC880_HP_EVENT)
9301		return;
9302	alc262_hippo_automute(codec);
9303}
9304
9305static void alc262_hippo1_automute(struct hda_codec *codec)
9306{
9307	unsigned int mute;
9308	unsigned int present;
9309
9310	snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9311	present = snd_hda_codec_read(codec, 0x1b, 0,
9312				     AC_VERB_GET_PIN_SENSE, 0);
9313	present = (present & 0x80000000) != 0;
9314	if (present) {
9315		/* mute internal speaker */
9316		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9317					 HDA_AMP_MUTE, HDA_AMP_MUTE);
9318	} else {
9319		/* unmute internal speaker if necessary */
9320		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9321		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9322					 HDA_AMP_MUTE, mute);
9323	}
9324}
9325
9326/* unsolicited event for HP jack sensing */
9327static void alc262_hippo1_unsol_event(struct hda_codec *codec,
9328				       unsigned int res)
9329{
9330	if ((res >> 26) != ALC880_HP_EVENT)
9331		return;
9332	alc262_hippo1_automute(codec);
9333}
9334
9335/*
9336 * nec model
9337 *  0x15 = headphone
9338 *  0x16 = internal speaker
9339 *  0x18 = external mic
9340 */
9341
9342static struct snd_kcontrol_new alc262_nec_mixer[] = {
9343	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9344	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
9345
9346	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9347	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9348	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9349
9350	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9351	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9352	{ } /* end */
9353};
9354
9355static struct hda_verb alc262_nec_verbs[] = {
9356	/* Unmute Speaker */
9357	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9358
9359	/* Headphone */
9360	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9361	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9362
9363	/* External mic to headphone */
9364	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9365	/* External mic to speaker */
9366	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9367	{}
9368};
9369
9370/*
9371 * fujitsu model
9372 *  0x14 = headphone/spdif-out, 0x15 = internal speaker,
9373 *  0x1b = port replicator headphone out
9374 */
9375
9376#define ALC_HP_EVENT	0x37
9377
9378static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
9379	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9380	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9381	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9382	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9383	{}
9384};
9385
9386static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
9387	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9388	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9389	{}
9390};
9391
9392static struct hda_input_mux alc262_fujitsu_capture_source = {
9393	.num_items = 3,
9394	.items = {
9395		{ "Mic", 0x0 },
9396		{ "Int Mic", 0x1 },
9397		{ "CD", 0x4 },
9398	},
9399};
9400
9401static struct hda_input_mux alc262_HP_capture_source = {
9402	.num_items = 5,
9403	.items = {
9404		{ "Mic", 0x0 },
9405		{ "Front Mic", 0x1 },
9406		{ "Line", 0x2 },
9407		{ "CD", 0x4 },
9408		{ "AUX IN", 0x6 },
9409	},
9410};
9411
9412static struct hda_input_mux alc262_HP_D7000_capture_source = {
9413	.num_items = 4,
9414	.items = {
9415		{ "Mic", 0x0 },
9416		{ "Front Mic", 0x2 },
9417		{ "Line", 0x1 },
9418		{ "CD", 0x4 },
9419	},
9420};
9421
9422/* mute/unmute internal speaker according to the hp jacks and mute state */
9423static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
9424{
9425	struct alc_spec *spec = codec->spec;
9426	unsigned int mute;
9427
9428	if (force || !spec->sense_updated) {
9429		unsigned int present;
9430		/* need to execute and sync at first */
9431		snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
9432		/* check laptop HP jack */
9433		present = snd_hda_codec_read(codec, 0x14, 0,
9434					     AC_VERB_GET_PIN_SENSE, 0);
9435		/* need to execute and sync at first */
9436		snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9437		/* check docking HP jack */
9438		present |= snd_hda_codec_read(codec, 0x1b, 0,
9439					      AC_VERB_GET_PIN_SENSE, 0);
9440		if (present & AC_PINSENSE_PRESENCE)
9441			spec->jack_present = 1;
9442		else
9443			spec->jack_present = 0;
9444		spec->sense_updated = 1;
9445	}
9446	/* unmute internal speaker only if both HPs are unplugged and
9447	 * master switch is on
9448	 */
9449	if (spec->jack_present)
9450		mute = HDA_AMP_MUTE;
9451	else
9452		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9453	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9454				 HDA_AMP_MUTE, mute);
9455}
9456
9457/* unsolicited event for HP jack sensing */
9458static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
9459				       unsigned int res)
9460{
9461	if ((res >> 26) != ALC_HP_EVENT)
9462		return;
9463	alc262_fujitsu_automute(codec, 1);
9464}
9465
9466static void alc262_fujitsu_init_hook(struct hda_codec *codec)
9467{
9468	alc262_fujitsu_automute(codec, 1);
9469}
9470
9471/* bind volumes of both NID 0x0c and 0x0d */
9472static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
9473	.ops = &snd_hda_bind_vol,
9474	.values = {
9475		HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
9476		HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
9477		0
9478	},
9479};
9480
9481/* mute/unmute internal speaker according to the hp jack and mute state */
9482static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
9483{
9484	struct alc_spec *spec = codec->spec;
9485	unsigned int mute;
9486
9487	if (force || !spec->sense_updated) {
9488		unsigned int present_int_hp;
9489		/* need to execute and sync at first */
9490		snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9491		present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
9492					AC_VERB_GET_PIN_SENSE, 0);
9493		spec->jack_present = (present_int_hp & 0x80000000) != 0;
9494		spec->sense_updated = 1;
9495	}
9496	if (spec->jack_present) {
9497		/* mute internal speaker */
9498		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9499					 HDA_AMP_MUTE, HDA_AMP_MUTE);
9500		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9501					 HDA_AMP_MUTE, HDA_AMP_MUTE);
9502	} else {
9503		/* unmute internal speaker if necessary */
9504		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9505		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9506					 HDA_AMP_MUTE, mute);
9507		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9508					 HDA_AMP_MUTE, mute);
9509	}
9510}
9511
9512/* unsolicited event for HP jack sensing */
9513static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
9514				       unsigned int res)
9515{
9516	if ((res >> 26) != ALC_HP_EVENT)
9517		return;
9518	alc262_lenovo_3000_automute(codec, 1);
9519}
9520
9521/* bind hp and internal speaker mute (with plug check) */
9522static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
9523					 struct snd_ctl_elem_value *ucontrol)
9524{
9525	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9526	long *valp = ucontrol->value.integer.value;
9527	int change;
9528
9529	change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9530						 HDA_AMP_MUTE,
9531						 valp ? 0 : HDA_AMP_MUTE);
9532	change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9533						 HDA_AMP_MUTE,
9534						 valp ? 0 : HDA_AMP_MUTE);
9535
9536	if (change)
9537		alc262_fujitsu_automute(codec, 0);
9538	return change;
9539}
9540
9541static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
9542	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9543	{
9544		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9545		.name = "Master Playback Switch",
9546		.info = snd_hda_mixer_amp_switch_info,
9547		.get = snd_hda_mixer_amp_switch_get,
9548		.put = alc262_fujitsu_master_sw_put,
9549		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9550	},
9551	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9552	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9553	HDA_CODEC_VOLUME("PC Speaker Volume", 0x0b, 0x05, HDA_INPUT),
9554	HDA_CODEC_MUTE("PC Speaker Switch", 0x0b, 0x05, HDA_INPUT),
9555	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9556	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9557	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9558	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9559	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9560	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9561	{ } /* end */
9562};
9563
9564/* bind hp and internal speaker mute (with plug check) */
9565static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
9566					 struct snd_ctl_elem_value *ucontrol)
9567{
9568	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9569	long *valp = ucontrol->value.integer.value;
9570	int change;
9571
9572	change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9573						 HDA_AMP_MUTE,
9574						 valp ? 0 : HDA_AMP_MUTE);
9575
9576	if (change)
9577		alc262_lenovo_3000_automute(codec, 0);
9578	return change;
9579}
9580
9581static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
9582	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9583	{
9584		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9585		.name = "Master Playback Switch",
9586		.info = snd_hda_mixer_amp_switch_info,
9587		.get = snd_hda_mixer_amp_switch_get,
9588		.put = alc262_lenovo_3000_master_sw_put,
9589		.private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
9590	},
9591	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9592	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9593	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9594	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9595	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9596	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9597	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9598	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9599	{ } /* end */
9600};
9601
9602static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
9603	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9604	{
9605		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9606		.name = "Master Playback Switch",
9607		.info = snd_hda_mixer_amp_switch_info,
9608		.get = snd_hda_mixer_amp_switch_get,
9609		.put = alc262_sony_master_sw_put,
9610		.private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9611	},
9612	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9613	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9614	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9615	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9616	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9617	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9618	{ } /* end */
9619};
9620
9621/* additional init verbs for Benq laptops */
9622static struct hda_verb alc262_EAPD_verbs[] = {
9623	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9624	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
9625	{}
9626};
9627
9628static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
9629	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9630	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9631
9632	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9633	{0x20, AC_VERB_SET_PROC_COEF,  0x3050},
9634	{}
9635};
9636
9637/* Samsung Q1 Ultra Vista model setup */
9638static struct snd_kcontrol_new alc262_ultra_mixer[] = {
9639	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9640	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9641	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9642	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9643	HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
9644	HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
9645	{ } /* end */
9646};
9647
9648static struct hda_verb alc262_ultra_verbs[] = {
9649	/* output mixer */
9650	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9651	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9652	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9653	/* speaker */
9654	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9655	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9656	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9657	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9658	/* HP */
9659	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9660	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9661	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9662	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9663	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9664	/* internal mic */
9665	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9666	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9667	/* ADC, choose mic */
9668	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9669	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9670	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9671	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9672	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9673	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9674	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9675	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9676	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
9677	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
9678	{}
9679};
9680
9681/* mute/unmute internal speaker according to the hp jack and mute state */
9682static void alc262_ultra_automute(struct hda_codec *codec)
9683{
9684	struct alc_spec *spec = codec->spec;
9685	unsigned int mute;
9686
9687	mute = 0;
9688	/* auto-mute only when HP is used as HP */
9689	if (!spec->cur_mux[0]) {
9690		unsigned int present;
9691		/* need to execute and sync at first */
9692		snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9693		present = snd_hda_codec_read(codec, 0x15, 0,
9694					     AC_VERB_GET_PIN_SENSE, 0);
9695		spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9696		if (spec->jack_present)
9697			mute = HDA_AMP_MUTE;
9698	}
9699	/* mute/unmute internal speaker */
9700	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9701				 HDA_AMP_MUTE, mute);
9702	/* mute/unmute HP */
9703	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9704				 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
9705}
9706
9707/* unsolicited event for HP jack sensing */
9708static void alc262_ultra_unsol_event(struct hda_codec *codec,
9709				       unsigned int res)
9710{
9711	if ((res >> 26) != ALC880_HP_EVENT)
9712		return;
9713	alc262_ultra_automute(codec);
9714}
9715
9716static struct hda_input_mux alc262_ultra_capture_source = {
9717	.num_items = 2,
9718	.items = {
9719		{ "Mic", 0x1 },
9720		{ "Headphone", 0x7 },
9721	},
9722};
9723
9724static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
9725				     struct snd_ctl_elem_value *ucontrol)
9726{
9727	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9728	struct alc_spec *spec = codec->spec;
9729	int ret;
9730
9731	ret = alc_mux_enum_put(kcontrol, ucontrol);
9732	if (!ret)
9733		return 0;
9734	/* reprogram the HP pin as mic or HP according to the input source */
9735	snd_hda_codec_write_cache(codec, 0x15, 0,
9736				  AC_VERB_SET_PIN_WIDGET_CONTROL,
9737				  spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
9738	alc262_ultra_automute(codec); /* mute/unmute HP */
9739	return ret;
9740}
9741
9742static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
9743	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
9744	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
9745	{
9746		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9747		.name = "Capture Source",
9748		.info = alc_mux_enum_info,
9749		.get = alc_mux_enum_get,
9750		.put = alc262_ultra_mux_enum_put,
9751	},
9752	{ } /* end */
9753};
9754
9755/* add playback controls from the parsed DAC table */
9756static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
9757					     const struct auto_pin_cfg *cfg)
9758{
9759	hda_nid_t nid;
9760	int err;
9761
9762	spec->multiout.num_dacs = 1;	/* only use one dac */
9763	spec->multiout.dac_nids = spec->private_dac_nids;
9764	spec->multiout.dac_nids[0] = 2;
9765
9766	nid = cfg->line_out_pins[0];
9767	if (nid) {
9768		err = add_control(spec, ALC_CTL_WIDGET_VOL,
9769				  "Front Playback Volume",
9770				  HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
9771		if (err < 0)
9772			return err;
9773		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9774				  "Front Playback Switch",
9775				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9776		if (err < 0)
9777			return err;
9778	}
9779
9780	nid = cfg->speaker_pins[0];
9781	if (nid) {
9782		if (nid == 0x16) {
9783			err = add_control(spec, ALC_CTL_WIDGET_VOL,
9784					  "Speaker Playback Volume",
9785					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9786							      HDA_OUTPUT));
9787			if (err < 0)
9788				return err;
9789			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9790					  "Speaker Playback Switch",
9791					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9792							      HDA_OUTPUT));
9793			if (err < 0)
9794				return err;
9795		} else {
9796			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9797					  "Speaker Playback Switch",
9798					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9799							      HDA_OUTPUT));
9800			if (err < 0)
9801				return err;
9802		}
9803	}
9804	nid = cfg->hp_pins[0];
9805	if (nid) {
9806		/* spec->multiout.hp_nid = 2; */
9807		if (nid == 0x16) {
9808			err = add_control(spec, ALC_CTL_WIDGET_VOL,
9809					  "Headphone Playback Volume",
9810					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9811							      HDA_OUTPUT));
9812			if (err < 0)
9813				return err;
9814			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9815					  "Headphone Playback Switch",
9816					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9817							      HDA_OUTPUT));
9818			if (err < 0)
9819				return err;
9820		} else {
9821			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9822					  "Headphone Playback Switch",
9823					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9824							      HDA_OUTPUT));
9825			if (err < 0)
9826				return err;
9827		}
9828	}
9829	return 0;
9830}
9831
9832/* identical with ALC880 */
9833#define alc262_auto_create_analog_input_ctls \
9834	alc880_auto_create_analog_input_ctls
9835
9836/*
9837 * generic initialization of ADC, input mixers and output mixers
9838 */
9839static struct hda_verb alc262_volume_init_verbs[] = {
9840	/*
9841	 * Unmute ADC0-2 and set the default input to mic-in
9842	 */
9843	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9844	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9845	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9846	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9847	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9848	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9849
9850	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9851	 * mixer widget
9852	 * Note: PASD motherboards uses the Line In 2 as the input for
9853	 * front panel mic (mic 2)
9854	 */
9855	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9856	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9857	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9858	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9859	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9860	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9861
9862	/*
9863	 * Set up output mixers (0x0c - 0x0f)
9864	 */
9865	/* set vol=0 to output mixers */
9866	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9867	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9868	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9869
9870	/* set up input amps for analog loopback */
9871	/* Amp Indices: DAC = 0, mixer = 1 */
9872	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9873	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9874	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9875	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9876	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9877	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9878
9879	/* FIXME: use matrix-type input source selection */
9880	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9881	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9882	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9883	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9884	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9885	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9886	/* Input mixer2 */
9887	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9888	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9889	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9890	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9891	/* Input mixer3 */
9892	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9893	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9894	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9895	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9896
9897	{ }
9898};
9899
9900static struct hda_verb alc262_HP_BPC_init_verbs[] = {
9901	/*
9902	 * Unmute ADC0-2 and set the default input to mic-in
9903	 */
9904	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9905	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9906	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9907	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9908	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9909	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9910
9911	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9912	 * mixer widget
9913	 * Note: PASD motherboards uses the Line In 2 as the input for
9914	 * front panel mic (mic 2)
9915	 */
9916	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9917	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9918	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9919	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9920	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9921	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9922	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9923        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9924
9925	/*
9926	 * Set up output mixers (0x0c - 0x0e)
9927	 */
9928	/* set vol=0 to output mixers */
9929	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9930	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9931	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9932
9933	/* set up input amps for analog loopback */
9934	/* Amp Indices: DAC = 0, mixer = 1 */
9935	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9936	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9937	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9938	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9939	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9940	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9941
9942	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9943	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9944	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9945
9946	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9947	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9948
9949	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9950	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9951
9952	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9953	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9954        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9955	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9956	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9957
9958	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9959	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9960        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9961	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9962	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9963	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9964
9965
9966	/* FIXME: use matrix-type input source selection */
9967	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9968	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9969	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9970	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9971	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9972	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9973	/* Input mixer2 */
9974	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9975	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9976	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9977	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9978	/* Input mixer3 */
9979	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9980	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9981	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9982	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9983
9984	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9985
9986	{ }
9987};
9988
9989static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
9990	/*
9991	 * Unmute ADC0-2 and set the default input to mic-in
9992	 */
9993	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9994	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9995	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9996	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9997	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9998	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9999
10000	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10001	 * mixer widget
10002	 * Note: PASD motherboards uses the Line In 2 as the input for front
10003	 * panel mic (mic 2)
10004	 */
10005	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10006	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10007	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10008	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10009	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10010	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10011	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10012	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10013	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10014	/*
10015	 * Set up output mixers (0x0c - 0x0e)
10016	 */
10017	/* set vol=0 to output mixers */
10018	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10019	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10020	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10021
10022	/* set up input amps for analog loopback */
10023	/* Amp Indices: DAC = 0, mixer = 1 */
10024	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10025	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10026	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10027	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10028	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10029	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10030
10031
10032	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },	/* HP */
10033	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Mono */
10034	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* rear MIC */
10035	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* Line in */
10036	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* Front MIC */
10037	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Line out */
10038	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* CD in */
10039
10040	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10041	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10042
10043	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10044	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10045
10046	/* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10047	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10048	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10049	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10050	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10051	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10052
10053	/* FIXME: use matrix-type input source selection */
10054	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10055	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10056	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10057	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10058	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10059	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10060	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10061        /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
10062	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10063	/* Input mixer2 */
10064	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10065	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10066	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10067	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10068	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10069        /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10070	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10071	/* Input mixer3 */
10072	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10073	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10074	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10075	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10076	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10077        /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10078	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10079
10080	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10081
10082	{ }
10083};
10084
10085static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10086
10087	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Front Speaker */
10088	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10089	{0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10090
10091	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* MIC jack */
10092	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* Front MIC */
10093	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10094	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10095
10096	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },	/* HP  jack */
10097	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10098	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10099	{}
10100};
10101
10102
10103#ifdef CONFIG_SND_HDA_POWER_SAVE
10104#define alc262_loopbacks	alc880_loopbacks
10105#endif
10106
10107/* pcm configuration: identiacal with ALC880 */
10108#define alc262_pcm_analog_playback	alc880_pcm_analog_playback
10109#define alc262_pcm_analog_capture	alc880_pcm_analog_capture
10110#define alc262_pcm_digital_playback	alc880_pcm_digital_playback
10111#define alc262_pcm_digital_capture	alc880_pcm_digital_capture
10112
10113/*
10114 * BIOS auto configuration
10115 */
10116static int alc262_parse_auto_config(struct hda_codec *codec)
10117{
10118	struct alc_spec *spec = codec->spec;
10119	int err;
10120	static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10121
10122	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10123					   alc262_ignore);
10124	if (err < 0)
10125		return err;
10126	if (!spec->autocfg.line_outs)
10127		return 0; /* can't find valid BIOS pin config */
10128	err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10129	if (err < 0)
10130		return err;
10131	err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10132	if (err < 0)
10133		return err;
10134
10135	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10136
10137	if (spec->autocfg.dig_out_pin)
10138		spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10139	if (spec->autocfg.dig_in_pin)
10140		spec->dig_in_nid = ALC262_DIGIN_NID;
10141
10142	if (spec->kctls.list)
10143		add_mixer(spec, spec->kctls.list);
10144
10145	add_verb(spec, alc262_volume_init_verbs);
10146	spec->num_mux_defs = 1;
10147	spec->input_mux = &spec->private_imux;
10148
10149	err = alc_auto_add_mic_boost(codec);
10150	if (err < 0)
10151		return err;
10152
10153	store_pin_configs(codec);
10154	return 1;
10155}
10156
10157#define alc262_auto_init_multi_out	alc882_auto_init_multi_out
10158#define alc262_auto_init_hp_out		alc882_auto_init_hp_out
10159#define alc262_auto_init_analog_input	alc882_auto_init_analog_input
10160#define alc262_auto_init_input_src	alc882_auto_init_input_src
10161
10162
10163/* init callback for auto-configuration model -- overriding the default init */
10164static void alc262_auto_init(struct hda_codec *codec)
10165{
10166	struct alc_spec *spec = codec->spec;
10167	alc262_auto_init_multi_out(codec);
10168	alc262_auto_init_hp_out(codec);
10169	alc262_auto_init_analog_input(codec);
10170	alc262_auto_init_input_src(codec);
10171	if (spec->unsol_event)
10172		alc_inithook(codec);
10173}
10174
10175/*
10176 * configuration and preset
10177 */
10178static const char *alc262_models[ALC262_MODEL_LAST] = {
10179	[ALC262_BASIC]		= "basic",
10180	[ALC262_HIPPO]		= "hippo",
10181	[ALC262_HIPPO_1]	= "hippo_1",
10182	[ALC262_FUJITSU]	= "fujitsu",
10183	[ALC262_HP_BPC]		= "hp-bpc",
10184	[ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
10185	[ALC262_HP_TC_T5735]	= "hp-tc-t5735",
10186	[ALC262_HP_RP5700]	= "hp-rp5700",
10187	[ALC262_BENQ_ED8]	= "benq",
10188	[ALC262_BENQ_T31]	= "benq-t31",
10189	[ALC262_SONY_ASSAMD]	= "sony-assamd",
10190	[ALC262_TOSHIBA_S06]	= "toshiba-s06",
10191	[ALC262_TOSHIBA_RX1]	= "toshiba-rx1",
10192	[ALC262_ULTRA]		= "ultra",
10193	[ALC262_LENOVO_3000]	= "lenovo-3000",
10194	[ALC262_NEC]		= "nec",
10195	[ALC262_AUTO]		= "auto",
10196};
10197
10198static struct snd_pci_quirk alc262_cfg_tbl[] = {
10199	SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10200	SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
10201	SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
10202	SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
10203	SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
10204	SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
10205	SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
10206	SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
10207	SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
10208	SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
10209	SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
10210	SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
10211	SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
10212	SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
10213	SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
10214	SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
10215	SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
10216	SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
10217	SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10218	SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10219	SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
10220	SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10221		      ALC262_HP_TC_T5735),
10222	SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
10223	SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10224	SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
10225	SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10226	SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10227	SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
10228	SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10229		      ALC262_TOSHIBA_RX1),
10230	SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
10231	SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
10232	SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
10233	SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
10234	SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA),
10235	SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
10236	SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10237	SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10238	SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
10239	{}
10240};
10241
10242static struct alc_config_preset alc262_presets[] = {
10243	[ALC262_BASIC] = {
10244		.mixers = { alc262_base_mixer },
10245		.init_verbs = { alc262_init_verbs },
10246		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10247		.dac_nids = alc262_dac_nids,
10248		.hp_nid = 0x03,
10249		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10250		.channel_mode = alc262_modes,
10251		.input_mux = &alc262_capture_source,
10252	},
10253	[ALC262_HIPPO] = {
10254		.mixers = { alc262_base_mixer },
10255		.init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10256		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10257		.dac_nids = alc262_dac_nids,
10258		.hp_nid = 0x03,
10259		.dig_out_nid = ALC262_DIGOUT_NID,
10260		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10261		.channel_mode = alc262_modes,
10262		.input_mux = &alc262_capture_source,
10263		.unsol_event = alc262_hippo_unsol_event,
10264		.init_hook = alc262_hippo_automute,
10265	},
10266	[ALC262_HIPPO_1] = {
10267		.mixers = { alc262_hippo1_mixer },
10268		.init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10269		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10270		.dac_nids = alc262_dac_nids,
10271		.hp_nid = 0x02,
10272		.dig_out_nid = ALC262_DIGOUT_NID,
10273		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10274		.channel_mode = alc262_modes,
10275		.input_mux = &alc262_capture_source,
10276		.unsol_event = alc262_hippo1_unsol_event,
10277		.init_hook = alc262_hippo1_automute,
10278	},
10279	[ALC262_FUJITSU] = {
10280		.mixers = { alc262_fujitsu_mixer },
10281		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10282				alc262_fujitsu_unsol_verbs },
10283		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10284		.dac_nids = alc262_dac_nids,
10285		.hp_nid = 0x03,
10286		.dig_out_nid = ALC262_DIGOUT_NID,
10287		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10288		.channel_mode = alc262_modes,
10289		.input_mux = &alc262_fujitsu_capture_source,
10290		.unsol_event = alc262_fujitsu_unsol_event,
10291		.init_hook = alc262_fujitsu_init_hook,
10292	},
10293	[ALC262_HP_BPC] = {
10294		.mixers = { alc262_HP_BPC_mixer },
10295		.init_verbs = { alc262_HP_BPC_init_verbs },
10296		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10297		.dac_nids = alc262_dac_nids,
10298		.hp_nid = 0x03,
10299		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10300		.channel_mode = alc262_modes,
10301		.input_mux = &alc262_HP_capture_source,
10302		.unsol_event = alc262_hp_bpc_unsol_event,
10303		.init_hook = alc262_hp_bpc_automute,
10304	},
10305	[ALC262_HP_BPC_D7000_WF] = {
10306		.mixers = { alc262_HP_BPC_WildWest_mixer },
10307		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10308		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10309		.dac_nids = alc262_dac_nids,
10310		.hp_nid = 0x03,
10311		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10312		.channel_mode = alc262_modes,
10313		.input_mux = &alc262_HP_D7000_capture_source,
10314		.unsol_event = alc262_hp_wildwest_unsol_event,
10315		.init_hook = alc262_hp_wildwest_automute,
10316	},
10317	[ALC262_HP_BPC_D7000_WL] = {
10318		.mixers = { alc262_HP_BPC_WildWest_mixer,
10319			    alc262_HP_BPC_WildWest_option_mixer },
10320		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10321		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10322		.dac_nids = alc262_dac_nids,
10323		.hp_nid = 0x03,
10324		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10325		.channel_mode = alc262_modes,
10326		.input_mux = &alc262_HP_D7000_capture_source,
10327		.unsol_event = alc262_hp_wildwest_unsol_event,
10328		.init_hook = alc262_hp_wildwest_automute,
10329	},
10330	[ALC262_HP_TC_T5735] = {
10331		.mixers = { alc262_hp_t5735_mixer },
10332		.init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
10333		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10334		.dac_nids = alc262_dac_nids,
10335		.hp_nid = 0x03,
10336		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10337		.channel_mode = alc262_modes,
10338		.input_mux = &alc262_capture_source,
10339		.unsol_event = alc262_hp_t5735_unsol_event,
10340		.init_hook = alc262_hp_t5735_init_hook,
10341	},
10342	[ALC262_HP_RP5700] = {
10343		.mixers = { alc262_hp_rp5700_mixer },
10344		.init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
10345		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10346		.dac_nids = alc262_dac_nids,
10347		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10348		.channel_mode = alc262_modes,
10349		.input_mux = &alc262_hp_rp5700_capture_source,
10350        },
10351	[ALC262_BENQ_ED8] = {
10352		.mixers = { alc262_base_mixer },
10353		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
10354		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10355		.dac_nids = alc262_dac_nids,
10356		.hp_nid = 0x03,
10357		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10358		.channel_mode = alc262_modes,
10359		.input_mux = &alc262_capture_source,
10360	},
10361	[ALC262_SONY_ASSAMD] = {
10362		.mixers = { alc262_sony_mixer },
10363		.init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
10364		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10365		.dac_nids = alc262_dac_nids,
10366		.hp_nid = 0x02,
10367		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10368		.channel_mode = alc262_modes,
10369		.input_mux = &alc262_capture_source,
10370		.unsol_event = alc262_hippo_unsol_event,
10371		.init_hook = alc262_hippo_automute,
10372	},
10373	[ALC262_BENQ_T31] = {
10374		.mixers = { alc262_benq_t31_mixer },
10375		.init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
10376		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10377		.dac_nids = alc262_dac_nids,
10378		.hp_nid = 0x03,
10379		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10380		.channel_mode = alc262_modes,
10381		.input_mux = &alc262_capture_source,
10382		.unsol_event = alc262_hippo_unsol_event,
10383		.init_hook = alc262_hippo_automute,
10384	},
10385	[ALC262_ULTRA] = {
10386		.mixers = { alc262_ultra_mixer },
10387		.cap_mixer = alc262_ultra_capture_mixer,
10388		.init_verbs = { alc262_ultra_verbs },
10389		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10390		.dac_nids = alc262_dac_nids,
10391		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10392		.channel_mode = alc262_modes,
10393		.input_mux = &alc262_ultra_capture_source,
10394		.adc_nids = alc262_adc_nids, /* ADC0 */
10395		.capsrc_nids = alc262_capsrc_nids,
10396		.num_adc_nids = 1, /* single ADC */
10397		.unsol_event = alc262_ultra_unsol_event,
10398		.init_hook = alc262_ultra_automute,
10399	},
10400	[ALC262_LENOVO_3000] = {
10401		.mixers = { alc262_lenovo_3000_mixer },
10402		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10403				alc262_lenovo_3000_unsol_verbs },
10404		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10405		.dac_nids = alc262_dac_nids,
10406		.hp_nid = 0x03,
10407		.dig_out_nid = ALC262_DIGOUT_NID,
10408		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10409		.channel_mode = alc262_modes,
10410		.input_mux = &alc262_fujitsu_capture_source,
10411		.unsol_event = alc262_lenovo_3000_unsol_event,
10412	},
10413	[ALC262_NEC] = {
10414		.mixers = { alc262_nec_mixer },
10415		.init_verbs = { alc262_nec_verbs },
10416		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10417		.dac_nids = alc262_dac_nids,
10418		.hp_nid = 0x03,
10419		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10420		.channel_mode = alc262_modes,
10421		.input_mux = &alc262_capture_source,
10422	},
10423	[ALC262_TOSHIBA_S06] = {
10424		.mixers = { alc262_toshiba_s06_mixer },
10425		.init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
10426							alc262_eapd_verbs },
10427		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10428		.capsrc_nids = alc262_dmic_capsrc_nids,
10429		.dac_nids = alc262_dac_nids,
10430		.adc_nids = alc262_dmic_adc_nids, /* ADC0 */
10431		.dig_out_nid = ALC262_DIGOUT_NID,
10432		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10433		.channel_mode = alc262_modes,
10434		.input_mux = &alc262_dmic_capture_source,
10435		.unsol_event = alc262_toshiba_s06_unsol_event,
10436		.init_hook = alc262_toshiba_s06_init_hook,
10437	},
10438	[ALC262_TOSHIBA_RX1] = {
10439		.mixers = { alc262_toshiba_rx1_mixer },
10440		.init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
10441		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10442		.dac_nids = alc262_dac_nids,
10443		.hp_nid = 0x03,
10444		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10445		.channel_mode = alc262_modes,
10446		.input_mux = &alc262_capture_source,
10447		.unsol_event = alc262_hippo_unsol_event,
10448		.init_hook = alc262_hippo_automute,
10449	},
10450};
10451
10452static int patch_alc262(struct hda_codec *codec)
10453{
10454	struct alc_spec *spec;
10455	int board_config;
10456	int err;
10457
10458	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10459	if (spec == NULL)
10460		return -ENOMEM;
10461
10462	codec->spec = spec;
10463#if 0
10464	/* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
10465	 * under-run
10466	 */
10467	{
10468	int tmp;
10469	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10470	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
10471	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10472	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
10473	}
10474#endif
10475
10476	alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10477
10478	board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
10479						  alc262_models,
10480						  alc262_cfg_tbl);
10481
10482	if (board_config < 0) {
10483		printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
10484		       "trying auto-probe from BIOS...\n");
10485		board_config = ALC262_AUTO;
10486	}
10487
10488	if (board_config == ALC262_AUTO) {
10489		/* automatic parse from the BIOS config */
10490		err = alc262_parse_auto_config(codec);
10491		if (err < 0) {
10492			alc_free(codec);
10493			return err;
10494		} else if (!err) {
10495			printk(KERN_INFO
10496			       "hda_codec: Cannot set up configuration "
10497			       "from BIOS.  Using base mode...\n");
10498			board_config = ALC262_BASIC;
10499		}
10500	}
10501
10502	if (board_config != ALC262_AUTO)
10503		setup_preset(spec, &alc262_presets[board_config]);
10504
10505	spec->stream_name_analog = "ALC262 Analog";
10506	spec->stream_analog_playback = &alc262_pcm_analog_playback;
10507	spec->stream_analog_capture = &alc262_pcm_analog_capture;
10508
10509	spec->stream_name_digital = "ALC262 Digital";
10510	spec->stream_digital_playback = &alc262_pcm_digital_playback;
10511	spec->stream_digital_capture = &alc262_pcm_digital_capture;
10512
10513	spec->is_mix_capture = 1;
10514	if (!spec->adc_nids && spec->input_mux) {
10515		/* check whether NID 0x07 is valid */
10516		unsigned int wcap = get_wcaps(codec, 0x07);
10517
10518		/* get type */
10519		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
10520		if (wcap != AC_WID_AUD_IN) {
10521			spec->adc_nids = alc262_adc_nids_alt;
10522			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
10523			spec->capsrc_nids = alc262_capsrc_nids_alt;
10524		} else {
10525			spec->adc_nids = alc262_adc_nids;
10526			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
10527			spec->capsrc_nids = alc262_capsrc_nids;
10528		}
10529	}
10530	if (!spec->cap_mixer)
10531		set_capture_mixer(spec);
10532
10533	spec->vmaster_nid = 0x0c;
10534
10535	codec->patch_ops = alc_patch_ops;
10536	if (board_config == ALC262_AUTO)
10537		spec->init_hook = alc262_auto_init;
10538#ifdef CONFIG_SND_HDA_POWER_SAVE
10539	if (!spec->loopback.amplist)
10540		spec->loopback.amplist = alc262_loopbacks;
10541#endif
10542
10543	return 0;
10544}
10545
10546/*
10547 *  ALC268 channel source setting (2 channel)
10548 */
10549#define ALC268_DIGOUT_NID	ALC880_DIGOUT_NID
10550#define alc268_modes		alc260_modes
10551
10552static hda_nid_t alc268_dac_nids[2] = {
10553	/* front, hp */
10554	0x02, 0x03
10555};
10556
10557static hda_nid_t alc268_adc_nids[2] = {
10558	/* ADC0-1 */
10559	0x08, 0x07
10560};
10561
10562static hda_nid_t alc268_adc_nids_alt[1] = {
10563	/* ADC0 */
10564	0x08
10565};
10566
10567static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
10568
10569static struct snd_kcontrol_new alc268_base_mixer[] = {
10570	/* output mixer control */
10571	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10572	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10573	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10574	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10575	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10576	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10577	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10578	{ }
10579};
10580
10581/* bind Beep switches of both NID 0x0f and 0x10 */
10582static struct hda_bind_ctls alc268_bind_beep_sw = {
10583	.ops = &snd_hda_bind_sw,
10584	.values = {
10585		HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
10586		HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
10587		0
10588	},
10589};
10590
10591static struct snd_kcontrol_new alc268_beep_mixer[] = {
10592	HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
10593	HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
10594	{ }
10595};
10596
10597static struct hda_verb alc268_eapd_verbs[] = {
10598	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10599	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10600	{ }
10601};
10602
10603/* Toshiba specific */
10604#define alc268_toshiba_automute	alc262_hippo_automute
10605
10606static struct hda_verb alc268_toshiba_verbs[] = {
10607	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10608	{ } /* end */
10609};
10610
10611static struct hda_input_mux alc268_acer_lc_capture_source = {
10612	.num_items = 2,
10613	.items = {
10614		{ "i-Mic", 0x6 },
10615		{ "E-Mic", 0x0 },
10616	},
10617};
10618
10619/* Acer specific */
10620/* bind volumes of both NID 0x02 and 0x03 */
10621static struct hda_bind_ctls alc268_acer_bind_master_vol = {
10622	.ops = &snd_hda_bind_vol,
10623	.values = {
10624		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
10625		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
10626		0
10627	},
10628};
10629
10630/* mute/unmute internal speaker according to the hp jack and mute state */
10631static void alc268_acer_automute(struct hda_codec *codec, int force)
10632{
10633	struct alc_spec *spec = codec->spec;
10634	unsigned int mute;
10635
10636	if (force || !spec->sense_updated) {
10637		unsigned int present;
10638		present = snd_hda_codec_read(codec, 0x14, 0,
10639				    	 AC_VERB_GET_PIN_SENSE, 0);
10640		spec->jack_present = (present & 0x80000000) != 0;
10641		spec->sense_updated = 1;
10642	}
10643	if (spec->jack_present)
10644		mute = HDA_AMP_MUTE; /* mute internal speaker */
10645	else /* unmute internal speaker if necessary */
10646		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10647	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10648				 HDA_AMP_MUTE, mute);
10649}
10650
10651
10652/* bind hp and internal speaker mute (with plug check) */
10653static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
10654				     struct snd_ctl_elem_value *ucontrol)
10655{
10656	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10657	long *valp = ucontrol->value.integer.value;
10658	int change;
10659
10660	change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10661					  HDA_AMP_MUTE,
10662					  valp[0] ? 0 : HDA_AMP_MUTE);
10663	change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10664					   HDA_AMP_MUTE,
10665					   valp[1] ? 0 : HDA_AMP_MUTE);
10666	if (change)
10667		alc268_acer_automute(codec, 0);
10668	return change;
10669}
10670
10671static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
10672	/* output mixer control */
10673	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10674	{
10675		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10676		.name = "Master Playback Switch",
10677		.info = snd_hda_mixer_amp_switch_info,
10678		.get = snd_hda_mixer_amp_switch_get,
10679		.put = alc268_acer_master_sw_put,
10680		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10681	},
10682	HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
10683	{ }
10684};
10685
10686static struct snd_kcontrol_new alc268_acer_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", 0x18, 0, HDA_INPUT),
10698	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10699	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10700	{ }
10701};
10702
10703static struct hda_verb alc268_acer_aspire_one_verbs[] = {
10704	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10705	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10706	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10707	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10708	{0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
10709	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
10710	{ }
10711};
10712
10713static struct hda_verb alc268_acer_verbs[] = {
10714	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
10715	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10716	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10717	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10718	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10719	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10720	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10721	{ }
10722};
10723
10724/* unsolicited event for HP jack sensing */
10725static void alc268_toshiba_unsol_event(struct hda_codec *codec,
10726				       unsigned int res)
10727{
10728	if ((res >> 26) != ALC880_HP_EVENT)
10729		return;
10730	alc268_toshiba_automute(codec);
10731}
10732
10733static void alc268_acer_unsol_event(struct hda_codec *codec,
10734				       unsigned int res)
10735{
10736	if ((res >> 26) != ALC880_HP_EVENT)
10737		return;
10738	alc268_acer_automute(codec, 1);
10739}
10740
10741static void alc268_acer_init_hook(struct hda_codec *codec)
10742{
10743	alc268_acer_automute(codec, 1);
10744}
10745
10746/* toggle speaker-output according to the hp-jack state */
10747static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
10748{
10749	unsigned int present;
10750	unsigned char bits;
10751
10752	present = snd_hda_codec_read(codec, 0x15, 0,
10753				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10754	bits = present ? AMP_IN_MUTE(0) : 0;
10755	snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
10756				AMP_IN_MUTE(0), bits);
10757	snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
10758				AMP_IN_MUTE(0), bits);
10759}
10760
10761
10762static void alc268_acer_mic_automute(struct hda_codec *codec)
10763{
10764	unsigned int present;
10765
10766	present = snd_hda_codec_read(codec, 0x18, 0,
10767				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10768	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
10769			    present ? 0x0 : 0x6);
10770}
10771
10772static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
10773				    unsigned int res)
10774{
10775	if ((res >> 26) == ALC880_HP_EVENT)
10776		alc268_aspire_one_speaker_automute(codec);
10777	if ((res >> 26) == ALC880_MIC_EVENT)
10778		alc268_acer_mic_automute(codec);
10779}
10780
10781static void alc268_acer_lc_init_hook(struct hda_codec *codec)
10782{
10783	alc268_aspire_one_speaker_automute(codec);
10784	alc268_acer_mic_automute(codec);
10785}
10786
10787static struct snd_kcontrol_new alc268_dell_mixer[] = {
10788	/* output mixer control */
10789	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10790	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10791	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10792	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10793	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10794	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10795	{ }
10796};
10797
10798static struct hda_verb alc268_dell_verbs[] = {
10799	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10800	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10801	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10802	{ }
10803};
10804
10805/* mute/unmute internal speaker according to the hp jack and mute state */
10806static void alc268_dell_automute(struct hda_codec *codec)
10807{
10808	unsigned int present;
10809	unsigned int mute;
10810
10811	present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
10812	if (present & 0x80000000)
10813		mute = HDA_AMP_MUTE;
10814	else
10815		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
10816	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10817				 HDA_AMP_MUTE, mute);
10818}
10819
10820static void alc268_dell_unsol_event(struct hda_codec *codec,
10821				    unsigned int res)
10822{
10823	if ((res >> 26) != ALC880_HP_EVENT)
10824		return;
10825	alc268_dell_automute(codec);
10826}
10827
10828#define alc268_dell_init_hook	alc268_dell_automute
10829
10830static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
10831	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10832	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10833	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10834	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10835	HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10836	HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
10837	HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
10838	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10839	{ }
10840};
10841
10842static struct hda_verb alc267_quanta_il1_verbs[] = {
10843	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10844	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
10845	{ }
10846};
10847
10848static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
10849{
10850	unsigned int present;
10851
10852	present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
10853		& AC_PINSENSE_PRESENCE;
10854	snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
10855			    present ? 0 : PIN_OUT);
10856}
10857
10858static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
10859{
10860	unsigned int present;
10861
10862	present = snd_hda_codec_read(codec, 0x18, 0,
10863				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10864	snd_hda_codec_write(codec, 0x23, 0,
10865			    AC_VERB_SET_CONNECT_SEL,
10866			    present ? 0x00 : 0x01);
10867}
10868
10869static void alc267_quanta_il1_automute(struct hda_codec *codec)
10870{
10871	alc267_quanta_il1_hp_automute(codec);
10872	alc267_quanta_il1_mic_automute(codec);
10873}
10874
10875static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
10876					   unsigned int res)
10877{
10878	switch (res >> 26) {
10879	case ALC880_HP_EVENT:
10880		alc267_quanta_il1_hp_automute(codec);
10881		break;
10882	case ALC880_MIC_EVENT:
10883		alc267_quanta_il1_mic_automute(codec);
10884		break;
10885	}
10886}
10887
10888/*
10889 * generic initialization of ADC, input mixers and output mixers
10890 */
10891static struct hda_verb alc268_base_init_verbs[] = {
10892	/* Unmute DAC0-1 and set vol = 0 */
10893	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10894	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10895	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10896	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10897	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10898	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10899
10900	/*
10901	 * Set up output mixers (0x0c - 0x0e)
10902	 */
10903	/* set vol=0 to output mixers */
10904	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10905	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10906	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10907        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
10908
10909	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10910	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10911
10912	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10913	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10914	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10915	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10916	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10917	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10918	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10919	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10920
10921	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10922	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10923	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10924	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10925	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10926	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10927	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10928
10929	/* set PCBEEP vol = 0, mute connections */
10930	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10931	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10932	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10933
10934	/* Unmute Selector 23h,24h and set the default input to mic-in */
10935
10936	{0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
10937	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10938	{0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
10939	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10940
10941	{ }
10942};
10943
10944/*
10945 * generic initialization of ADC, input mixers and output mixers
10946 */
10947static struct hda_verb alc268_volume_init_verbs[] = {
10948	/* set output DAC */
10949	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10950	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10951	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10952	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10953
10954	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10955	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10956	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10957	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10958	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10959
10960	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10961	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10962	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10963	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10964	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10965
10966	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10967	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10968	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10969	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10970
10971	/* set PCBEEP vol = 0, mute connections */
10972	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10973	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10974	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10975
10976	{ }
10977};
10978
10979static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
10980	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10981	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
10982	{
10983		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10984		/* The multiple "Capture Source" controls confuse alsamixer
10985		 * So call somewhat different..
10986		 */
10987		/* .name = "Capture Source", */
10988		.name = "Input Source",
10989		.count = 1,
10990		.info = alc_mux_enum_info,
10991		.get = alc_mux_enum_get,
10992		.put = alc_mux_enum_put,
10993	},
10994	{ } /* end */
10995};
10996
10997static struct snd_kcontrol_new alc268_capture_mixer[] = {
10998	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10999	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11000	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11001	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11002	{
11003		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11004		/* The multiple "Capture Source" controls confuse alsamixer
11005		 * So call somewhat different..
11006		 */
11007		/* .name = "Capture Source", */
11008		.name = "Input Source",
11009		.count = 2,
11010		.info = alc_mux_enum_info,
11011		.get = alc_mux_enum_get,
11012		.put = alc_mux_enum_put,
11013	},
11014	{ } /* end */
11015};
11016
11017static struct hda_input_mux alc268_capture_source = {
11018	.num_items = 4,
11019	.items = {
11020		{ "Mic", 0x0 },
11021		{ "Front Mic", 0x1 },
11022		{ "Line", 0x2 },
11023		{ "CD", 0x3 },
11024	},
11025};
11026
11027static struct hda_input_mux alc268_acer_capture_source = {
11028	.num_items = 3,
11029	.items = {
11030		{ "Mic", 0x0 },
11031		{ "Internal Mic", 0x6 },
11032		{ "Line", 0x2 },
11033	},
11034};
11035
11036#ifdef CONFIG_SND_DEBUG
11037static struct snd_kcontrol_new alc268_test_mixer[] = {
11038	/* Volume widgets */
11039	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11040	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11041	HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11042	HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11043	HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11044	HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11045	HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11046	HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11047	HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11048	HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11049	HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11050	HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11051	HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11052	/* The below appears problematic on some hardwares */
11053	/*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11054	HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11055	HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11056	HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11057	HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11058
11059	/* Modes for retasking pin widgets */
11060	ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11061	ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11062	ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11063	ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11064
11065	/* Controls for GPIO pins, assuming they are configured as outputs */
11066	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11067	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11068	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11069	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11070
11071	/* Switches to allow the digital SPDIF output pin to be enabled.
11072	 * The ALC268 does not have an SPDIF input.
11073	 */
11074	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11075
11076	/* A switch allowing EAPD to be enabled.  Some laptops seem to use
11077	 * this output to turn on an external amplifier.
11078	 */
11079	ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11080	ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11081
11082	{ } /* end */
11083};
11084#endif
11085
11086/* create input playback/capture controls for the given pin */
11087static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11088				    const char *ctlname, int idx)
11089{
11090	char name[32];
11091	int err;
11092
11093	sprintf(name, "%s Playback Volume", ctlname);
11094	if (nid == 0x14) {
11095		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11096				  HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11097						      HDA_OUTPUT));
11098		if (err < 0)
11099			return err;
11100	} else if (nid == 0x15) {
11101		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11102				  HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11103						      HDA_OUTPUT));
11104		if (err < 0)
11105			return err;
11106	} else
11107		return -1;
11108	sprintf(name, "%s Playback Switch", ctlname);
11109	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11110			  HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11111	if (err < 0)
11112		return err;
11113	return 0;
11114}
11115
11116/* add playback controls from the parsed DAC table */
11117static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11118					     const struct auto_pin_cfg *cfg)
11119{
11120	hda_nid_t nid;
11121	int err;
11122
11123	spec->multiout.num_dacs = 2;	/* only use one dac */
11124	spec->multiout.dac_nids = spec->private_dac_nids;
11125	spec->multiout.dac_nids[0] = 2;
11126	spec->multiout.dac_nids[1] = 3;
11127
11128	nid = cfg->line_out_pins[0];
11129	if (nid)
11130		alc268_new_analog_output(spec, nid, "Front", 0);
11131
11132	nid = cfg->speaker_pins[0];
11133	if (nid == 0x1d) {
11134		err = add_control(spec, ALC_CTL_WIDGET_VOL,
11135				  "Speaker Playback Volume",
11136				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11137		if (err < 0)
11138			return err;
11139	}
11140	nid = cfg->hp_pins[0];
11141	if (nid)
11142		alc268_new_analog_output(spec, nid, "Headphone", 0);
11143
11144	nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11145	if (nid == 0x16) {
11146		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11147				  "Mono Playback Switch",
11148				  HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11149		if (err < 0)
11150			return err;
11151	}
11152	return 0;
11153}
11154
11155/* create playback/capture controls for input pins */
11156static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11157						const struct auto_pin_cfg *cfg)
11158{
11159	struct hda_input_mux *imux = &spec->private_imux;
11160	int i, idx1;
11161
11162	for (i = 0; i < AUTO_PIN_LAST; i++) {
11163		switch(cfg->input_pins[i]) {
11164		case 0x18:
11165			idx1 = 0;	/* Mic 1 */
11166			break;
11167		case 0x19:
11168			idx1 = 1;	/* Mic 2 */
11169			break;
11170		case 0x1a:
11171			idx1 = 2;	/* Line In */
11172			break;
11173		case 0x1c:
11174			idx1 = 3;	/* CD */
11175			break;
11176		case 0x12:
11177		case 0x13:
11178			idx1 = 6;	/* digital mics */
11179			break;
11180		default:
11181			continue;
11182		}
11183		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11184		imux->items[imux->num_items].index = idx1;
11185		imux->num_items++;
11186	}
11187	return 0;
11188}
11189
11190static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11191{
11192	struct alc_spec *spec = codec->spec;
11193	hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11194	hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11195	hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11196	unsigned int	dac_vol1, dac_vol2;
11197
11198	if (speaker_nid) {
11199		snd_hda_codec_write(codec, speaker_nid, 0,
11200				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11201		snd_hda_codec_write(codec, 0x0f, 0,
11202				    AC_VERB_SET_AMP_GAIN_MUTE,
11203				    AMP_IN_UNMUTE(1));
11204		snd_hda_codec_write(codec, 0x10, 0,
11205				    AC_VERB_SET_AMP_GAIN_MUTE,
11206				    AMP_IN_UNMUTE(1));
11207	} else {
11208		snd_hda_codec_write(codec, 0x0f, 0,
11209				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11210		snd_hda_codec_write(codec, 0x10, 0,
11211				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11212	}
11213
11214	dac_vol1 = dac_vol2 = 0xb000 | 0x40;	/* set max volume  */
11215	if (line_nid == 0x14)
11216		dac_vol2 = AMP_OUT_ZERO;
11217	else if (line_nid == 0x15)
11218		dac_vol1 = AMP_OUT_ZERO;
11219	if (hp_nid == 0x14)
11220		dac_vol2 = AMP_OUT_ZERO;
11221	else if (hp_nid == 0x15)
11222		dac_vol1 = AMP_OUT_ZERO;
11223	if (line_nid != 0x16 || hp_nid != 0x16 ||
11224	    spec->autocfg.line_out_pins[1] != 0x16 ||
11225	    spec->autocfg.line_out_pins[2] != 0x16)
11226		dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11227
11228	snd_hda_codec_write(codec, 0x02, 0,
11229			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11230	snd_hda_codec_write(codec, 0x03, 0,
11231			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11232}
11233
11234/* pcm configuration: identiacal with ALC880 */
11235#define alc268_pcm_analog_playback	alc880_pcm_analog_playback
11236#define alc268_pcm_analog_capture	alc880_pcm_analog_capture
11237#define alc268_pcm_analog_alt_capture	alc880_pcm_analog_alt_capture
11238#define alc268_pcm_digital_playback	alc880_pcm_digital_playback
11239
11240/*
11241 * BIOS auto configuration
11242 */
11243static int alc268_parse_auto_config(struct hda_codec *codec)
11244{
11245	struct alc_spec *spec = codec->spec;
11246	int err;
11247	static hda_nid_t alc268_ignore[] = { 0 };
11248
11249	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11250					   alc268_ignore);
11251	if (err < 0)
11252		return err;
11253	if (!spec->autocfg.line_outs)
11254		return 0; /* can't find valid BIOS pin config */
11255
11256	err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11257	if (err < 0)
11258		return err;
11259	err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11260	if (err < 0)
11261		return err;
11262
11263	spec->multiout.max_channels = 2;
11264
11265	/* digital only support output */
11266	if (spec->autocfg.dig_out_pin)
11267		spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
11268
11269	if (spec->kctls.list)
11270		add_mixer(spec, spec->kctls.list);
11271
11272	if (spec->autocfg.speaker_pins[0] != 0x1d)
11273		add_mixer(spec, alc268_beep_mixer);
11274
11275	add_verb(spec, alc268_volume_init_verbs);
11276	spec->num_mux_defs = 1;
11277	spec->input_mux = &spec->private_imux;
11278
11279	err = alc_auto_add_mic_boost(codec);
11280	if (err < 0)
11281		return err;
11282
11283	store_pin_configs(codec);
11284	return 1;
11285}
11286
11287#define alc268_auto_init_multi_out	alc882_auto_init_multi_out
11288#define alc268_auto_init_hp_out		alc882_auto_init_hp_out
11289#define alc268_auto_init_analog_input	alc882_auto_init_analog_input
11290
11291/* init callback for auto-configuration model -- overriding the default init */
11292static void alc268_auto_init(struct hda_codec *codec)
11293{
11294	struct alc_spec *spec = codec->spec;
11295	alc268_auto_init_multi_out(codec);
11296	alc268_auto_init_hp_out(codec);
11297	alc268_auto_init_mono_speaker_out(codec);
11298	alc268_auto_init_analog_input(codec);
11299	if (spec->unsol_event)
11300		alc_inithook(codec);
11301}
11302
11303/*
11304 * configuration and preset
11305 */
11306static const char *alc268_models[ALC268_MODEL_LAST] = {
11307	[ALC267_QUANTA_IL1]	= "quanta-il1",
11308	[ALC268_3ST]		= "3stack",
11309	[ALC268_TOSHIBA]	= "toshiba",
11310	[ALC268_ACER]		= "acer",
11311	[ALC268_ACER_ASPIRE_ONE]	= "acer-aspire",
11312	[ALC268_DELL]		= "dell",
11313	[ALC268_ZEPTO]		= "zepto",
11314#ifdef CONFIG_SND_DEBUG
11315	[ALC268_TEST]		= "test",
11316#endif
11317	[ALC268_AUTO]		= "auto",
11318};
11319
11320static struct snd_pci_quirk alc268_cfg_tbl[] = {
11321	SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
11322	SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
11323	SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
11324	SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
11325	SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
11326	SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
11327						ALC268_ACER_ASPIRE_ONE),
11328	SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
11329	SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
11330	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
11331	SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
11332	SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
11333	SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
11334	SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
11335	SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
11336	SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
11337	SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
11338	{}
11339};
11340
11341static struct alc_config_preset alc268_presets[] = {
11342	[ALC267_QUANTA_IL1] = {
11343		.mixers = { alc267_quanta_il1_mixer },
11344		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11345				alc267_quanta_il1_verbs },
11346		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11347		.dac_nids = alc268_dac_nids,
11348		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11349		.adc_nids = alc268_adc_nids_alt,
11350		.hp_nid = 0x03,
11351		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11352		.channel_mode = alc268_modes,
11353		.input_mux = &alc268_capture_source,
11354		.unsol_event = alc267_quanta_il1_unsol_event,
11355		.init_hook = alc267_quanta_il1_automute,
11356	},
11357	[ALC268_3ST] = {
11358		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11359			    alc268_beep_mixer },
11360		.init_verbs = { alc268_base_init_verbs },
11361		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11362		.dac_nids = alc268_dac_nids,
11363                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11364                .adc_nids = alc268_adc_nids_alt,
11365		.capsrc_nids = alc268_capsrc_nids,
11366		.hp_nid = 0x03,
11367		.dig_out_nid = ALC268_DIGOUT_NID,
11368		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11369		.channel_mode = alc268_modes,
11370		.input_mux = &alc268_capture_source,
11371	},
11372	[ALC268_TOSHIBA] = {
11373		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11374			    alc268_beep_mixer },
11375		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11376				alc268_toshiba_verbs },
11377		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11378		.dac_nids = alc268_dac_nids,
11379		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11380		.adc_nids = alc268_adc_nids_alt,
11381		.capsrc_nids = alc268_capsrc_nids,
11382		.hp_nid = 0x03,
11383		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11384		.channel_mode = alc268_modes,
11385		.input_mux = &alc268_capture_source,
11386		.unsol_event = alc268_toshiba_unsol_event,
11387		.init_hook = alc268_toshiba_automute,
11388	},
11389	[ALC268_ACER] = {
11390		.mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
11391			    alc268_beep_mixer },
11392		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11393				alc268_acer_verbs },
11394		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11395		.dac_nids = alc268_dac_nids,
11396		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11397		.adc_nids = alc268_adc_nids_alt,
11398		.capsrc_nids = alc268_capsrc_nids,
11399		.hp_nid = 0x02,
11400		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11401		.channel_mode = alc268_modes,
11402		.input_mux = &alc268_acer_capture_source,
11403		.unsol_event = alc268_acer_unsol_event,
11404		.init_hook = alc268_acer_init_hook,
11405	},
11406	[ALC268_ACER_ASPIRE_ONE] = {
11407		.mixers = { alc268_acer_aspire_one_mixer,
11408				alc268_capture_alt_mixer },
11409		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11410				alc268_acer_aspire_one_verbs },
11411		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11412		.dac_nids = alc268_dac_nids,
11413		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11414		.adc_nids = alc268_adc_nids_alt,
11415		.capsrc_nids = alc268_capsrc_nids,
11416		.hp_nid = 0x03,
11417		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11418		.channel_mode = alc268_modes,
11419		.input_mux = &alc268_acer_lc_capture_source,
11420		.unsol_event = alc268_acer_lc_unsol_event,
11421		.init_hook = alc268_acer_lc_init_hook,
11422	},
11423	[ALC268_DELL] = {
11424		.mixers = { alc268_dell_mixer, alc268_beep_mixer },
11425		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11426				alc268_dell_verbs },
11427		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11428		.dac_nids = alc268_dac_nids,
11429		.hp_nid = 0x02,
11430		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11431		.channel_mode = alc268_modes,
11432		.unsol_event = alc268_dell_unsol_event,
11433		.init_hook = alc268_dell_init_hook,
11434		.input_mux = &alc268_capture_source,
11435	},
11436	[ALC268_ZEPTO] = {
11437		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11438			    alc268_beep_mixer },
11439		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11440				alc268_toshiba_verbs },
11441		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11442		.dac_nids = alc268_dac_nids,
11443		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11444		.adc_nids = alc268_adc_nids_alt,
11445		.capsrc_nids = alc268_capsrc_nids,
11446		.hp_nid = 0x03,
11447		.dig_out_nid = ALC268_DIGOUT_NID,
11448		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11449		.channel_mode = alc268_modes,
11450		.input_mux = &alc268_capture_source,
11451		.unsol_event = alc268_toshiba_unsol_event,
11452		.init_hook = alc268_toshiba_automute
11453	},
11454#ifdef CONFIG_SND_DEBUG
11455	[ALC268_TEST] = {
11456		.mixers = { alc268_test_mixer, alc268_capture_mixer },
11457		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11458				alc268_volume_init_verbs },
11459		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11460		.dac_nids = alc268_dac_nids,
11461		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11462		.adc_nids = alc268_adc_nids_alt,
11463		.capsrc_nids = alc268_capsrc_nids,
11464		.hp_nid = 0x03,
11465		.dig_out_nid = ALC268_DIGOUT_NID,
11466		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11467		.channel_mode = alc268_modes,
11468		.input_mux = &alc268_capture_source,
11469	},
11470#endif
11471};
11472
11473static int patch_alc268(struct hda_codec *codec)
11474{
11475	struct alc_spec *spec;
11476	int board_config;
11477	int err;
11478
11479	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
11480	if (spec == NULL)
11481		return -ENOMEM;
11482
11483	codec->spec = spec;
11484
11485	board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
11486						  alc268_models,
11487						  alc268_cfg_tbl);
11488
11489	if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
11490		printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
11491		       "trying auto-probe from BIOS...\n");
11492		board_config = ALC268_AUTO;
11493	}
11494
11495	if (board_config == ALC268_AUTO) {
11496		/* automatic parse from the BIOS config */
11497		err = alc268_parse_auto_config(codec);
11498		if (err < 0) {
11499			alc_free(codec);
11500			return err;
11501		} else if (!err) {
11502			printk(KERN_INFO
11503			       "hda_codec: Cannot set up configuration "
11504			       "from BIOS.  Using base mode...\n");
11505			board_config = ALC268_3ST;
11506		}
11507	}
11508
11509	if (board_config != ALC268_AUTO)
11510		setup_preset(spec, &alc268_presets[board_config]);
11511
11512	if (codec->vendor_id == 0x10ec0267) {
11513		spec->stream_name_analog = "ALC267 Analog";
11514		spec->stream_name_digital = "ALC267 Digital";
11515	} else {
11516		spec->stream_name_analog = "ALC268 Analog";
11517		spec->stream_name_digital = "ALC268 Digital";
11518	}
11519
11520	spec->stream_analog_playback = &alc268_pcm_analog_playback;
11521	spec->stream_analog_capture = &alc268_pcm_analog_capture;
11522	spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
11523
11524	spec->stream_digital_playback = &alc268_pcm_digital_playback;
11525
11526	if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
11527		/* override the amp caps for beep generator */
11528		snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
11529					  (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
11530					  (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
11531					  (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
11532					  (0 << AC_AMPCAP_MUTE_SHIFT));
11533
11534	if (!spec->adc_nids && spec->input_mux) {
11535		/* check whether NID 0x07 is valid */
11536		unsigned int wcap = get_wcaps(codec, 0x07);
11537		int i;
11538
11539		/* get type */
11540		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11541		if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
11542			spec->adc_nids = alc268_adc_nids_alt;
11543			spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
11544			add_mixer(spec, alc268_capture_alt_mixer);
11545		} else {
11546			spec->adc_nids = alc268_adc_nids;
11547			spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
11548			add_mixer(spec, alc268_capture_mixer);
11549		}
11550		spec->capsrc_nids = alc268_capsrc_nids;
11551		/* set default input source */
11552		for (i = 0; i < spec->num_adc_nids; i++)
11553			snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
11554				0, AC_VERB_SET_CONNECT_SEL,
11555				spec->input_mux->items[0].index);
11556	}
11557
11558	spec->vmaster_nid = 0x02;
11559
11560	codec->patch_ops = alc_patch_ops;
11561	if (board_config == ALC268_AUTO)
11562		spec->init_hook = alc268_auto_init;
11563
11564	return 0;
11565}
11566
11567/*
11568 *  ALC269 channel source setting (2 channel)
11569 */
11570#define ALC269_DIGOUT_NID	ALC880_DIGOUT_NID
11571
11572#define alc269_dac_nids		alc260_dac_nids
11573
11574static hda_nid_t alc269_adc_nids[1] = {
11575	/* ADC1 */
11576	0x08,
11577};
11578
11579static hda_nid_t alc269_capsrc_nids[1] = {
11580	0x23,
11581};
11582
11583/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
11584 *       not a mux!
11585 */
11586
11587static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
11588	.num_items = 2,
11589	.items = {
11590		{ "i-Mic", 0x5 },
11591		{ "e-Mic", 0x0 },
11592	},
11593};
11594
11595static struct hda_input_mux alc269_eeepc_amic_capture_source = {
11596	.num_items = 2,
11597	.items = {
11598		{ "i-Mic", 0x1 },
11599		{ "e-Mic", 0x0 },
11600	},
11601};
11602
11603#define alc269_modes		alc260_modes
11604#define alc269_capture_source	alc880_lg_lw_capture_source
11605
11606static struct snd_kcontrol_new alc269_base_mixer[] = {
11607	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11608	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11609	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11610	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11611	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11612	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11613	HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11614	HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11615	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11616	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11617	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11618	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11619	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11620	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11621	{ } /* end */
11622};
11623
11624static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
11625	/* output mixer control */
11626	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11627	{
11628		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11629		.name = "Master Playback Switch",
11630		.info = snd_hda_mixer_amp_switch_info,
11631		.get = snd_hda_mixer_amp_switch_get,
11632		.put = alc268_acer_master_sw_put,
11633		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11634	},
11635	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11636	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11637	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11638	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11639	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11640	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11641	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
11642	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
11643	{ }
11644};
11645
11646/* bind volumes of both NID 0x0c and 0x0d */
11647static struct hda_bind_ctls alc269_epc_bind_vol = {
11648	.ops = &snd_hda_bind_vol,
11649	.values = {
11650		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11651		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11652		0
11653	},
11654};
11655
11656static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
11657	HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11658	HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
11659	HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11660	{ } /* end */
11661};
11662
11663/* capture mixer elements */
11664static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
11665	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11666	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11667	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11668	{ } /* end */
11669};
11670
11671/* FSC amilo */
11672static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
11673	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11674	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11675	HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol),
11676	{ } /* end */
11677};
11678
11679/* beep control */
11680static struct snd_kcontrol_new alc269_beep_mixer[] = {
11681	HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11682	HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11683	{ } /* end */
11684};
11685
11686static struct hda_verb alc269_quanta_fl1_verbs[] = {
11687	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11688	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11689	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11690	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11691	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11692	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11693	{ }
11694};
11695
11696/* toggle speaker-output according to the hp-jack state */
11697static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
11698{
11699	unsigned int present;
11700	unsigned char bits;
11701
11702	present = snd_hda_codec_read(codec, 0x15, 0,
11703			AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11704	bits = present ? AMP_IN_MUTE(0) : 0;
11705	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11706			AMP_IN_MUTE(0), bits);
11707	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11708			AMP_IN_MUTE(0), bits);
11709
11710	snd_hda_codec_write(codec, 0x20, 0,
11711			AC_VERB_SET_COEF_INDEX, 0x0c);
11712	snd_hda_codec_write(codec, 0x20, 0,
11713			AC_VERB_SET_PROC_COEF, 0x680);
11714
11715	snd_hda_codec_write(codec, 0x20, 0,
11716			AC_VERB_SET_COEF_INDEX, 0x0c);
11717	snd_hda_codec_write(codec, 0x20, 0,
11718			AC_VERB_SET_PROC_COEF, 0x480);
11719}
11720
11721static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
11722{
11723	unsigned int present;
11724
11725	present = snd_hda_codec_read(codec, 0x18, 0,
11726				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11727	snd_hda_codec_write(codec, 0x23, 0,
11728			    AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
11729}
11730
11731static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
11732				    unsigned int res)
11733{
11734	if ((res >> 26) == ALC880_HP_EVENT)
11735		alc269_quanta_fl1_speaker_automute(codec);
11736	if ((res >> 26) == ALC880_MIC_EVENT)
11737		alc269_quanta_fl1_mic_automute(codec);
11738}
11739
11740static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
11741{
11742	alc269_quanta_fl1_speaker_automute(codec);
11743	alc269_quanta_fl1_mic_automute(codec);
11744}
11745
11746static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
11747	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11748	{0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
11749	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11750	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
11751	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11752	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11753	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11754	{}
11755};
11756
11757static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
11758	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11759	{0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
11760	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11761	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
11762	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11763	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11764	{}
11765};
11766
11767/* toggle speaker-output according to the hp-jack state */
11768static void alc269_speaker_automute(struct hda_codec *codec)
11769{
11770	unsigned int present;
11771	unsigned char bits;
11772
11773	present = snd_hda_codec_read(codec, 0x15, 0,
11774				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11775	bits = present ? AMP_IN_MUTE(0) : 0;
11776	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11777				AMP_IN_MUTE(0), bits);
11778	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11779				AMP_IN_MUTE(0), bits);
11780}
11781
11782static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
11783{
11784	unsigned int present;
11785
11786	present = snd_hda_codec_read(codec, 0x18, 0,
11787				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11788	snd_hda_codec_write(codec, 0x23, 0,
11789				AC_VERB_SET_CONNECT_SEL,  (present ? 0 : 5));
11790}
11791
11792static void alc269_eeepc_amic_automute(struct hda_codec *codec)
11793{
11794	unsigned int present;
11795
11796	present = snd_hda_codec_read(codec, 0x18, 0,
11797				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11798	snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11799				0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
11800	snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11801				0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
11802}
11803
11804/* unsolicited event for HP jack sensing */
11805static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
11806				     unsigned int res)
11807{
11808	if ((res >> 26) == ALC880_HP_EVENT)
11809		alc269_speaker_automute(codec);
11810
11811	if ((res >> 26) == ALC880_MIC_EVENT)
11812		alc269_eeepc_dmic_automute(codec);
11813}
11814
11815static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
11816{
11817	alc269_speaker_automute(codec);
11818	alc269_eeepc_dmic_automute(codec);
11819}
11820
11821/* unsolicited event for HP jack sensing */
11822static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
11823				     unsigned int res)
11824{
11825	if ((res >> 26) == ALC880_HP_EVENT)
11826		alc269_speaker_automute(codec);
11827
11828	if ((res >> 26) == ALC880_MIC_EVENT)
11829		alc269_eeepc_amic_automute(codec);
11830}
11831
11832static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
11833{
11834	alc269_speaker_automute(codec);
11835	alc269_eeepc_amic_automute(codec);
11836}
11837
11838/*
11839 * generic initialization of ADC, input mixers and output mixers
11840 */
11841static struct hda_verb alc269_init_verbs[] = {
11842	/*
11843	 * Unmute ADC0 and set the default input to mic-in
11844	 */
11845	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11846
11847	/* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
11848	 * analog-loopback mixer widget
11849	 * Note: PASD motherboards uses the Line In 2 as the input for
11850	 * front panel mic (mic 2)
11851	 */
11852	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11853	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11854	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11855	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11856	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11857	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11858
11859	/*
11860	 * Set up output mixers (0x0c - 0x0e)
11861	 */
11862	/* set vol=0 to output mixers */
11863	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11864	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11865
11866	/* set up input amps for analog loopback */
11867	/* Amp Indices: DAC = 0, mixer = 1 */
11868	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11869	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11870	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11871	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11872	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11873	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11874
11875	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11876	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11877	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11878	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11879	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11880	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11881	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11882
11883	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11884	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11885	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11886	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11887	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11888	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11889	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11890
11891	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11892	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11893
11894	/* FIXME: use matrix-type input source selection */
11895	/* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
11896	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11897	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11898	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11899	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11900	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11901
11902	/* set EAPD */
11903	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11904	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11905	{ }
11906};
11907
11908/* add playback controls from the parsed DAC table */
11909static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
11910					     const struct auto_pin_cfg *cfg)
11911{
11912	hda_nid_t nid;
11913	int err;
11914
11915	spec->multiout.num_dacs = 1;	/* only use one dac */
11916	spec->multiout.dac_nids = spec->private_dac_nids;
11917	spec->multiout.dac_nids[0] = 2;
11918
11919	nid = cfg->line_out_pins[0];
11920	if (nid) {
11921		err = add_control(spec, ALC_CTL_WIDGET_VOL,
11922				  "Front Playback Volume",
11923				  HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
11924		if (err < 0)
11925			return err;
11926		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11927				  "Front Playback Switch",
11928				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
11929		if (err < 0)
11930			return err;
11931	}
11932
11933	nid = cfg->speaker_pins[0];
11934	if (nid) {
11935		if (!cfg->line_out_pins[0]) {
11936			err = add_control(spec, ALC_CTL_WIDGET_VOL,
11937					  "Speaker Playback Volume",
11938					  HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
11939							      HDA_OUTPUT));
11940			if (err < 0)
11941				return err;
11942		}
11943		if (nid == 0x16) {
11944			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11945					  "Speaker Playback Switch",
11946					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11947							      HDA_OUTPUT));
11948			if (err < 0)
11949				return err;
11950		} else {
11951			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11952					  "Speaker Playback Switch",
11953					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11954							      HDA_OUTPUT));
11955			if (err < 0)
11956				return err;
11957		}
11958	}
11959	nid = cfg->hp_pins[0];
11960	if (nid) {
11961		/* spec->multiout.hp_nid = 2; */
11962		if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
11963			err = add_control(spec, ALC_CTL_WIDGET_VOL,
11964					  "Headphone Playback Volume",
11965					  HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
11966							      HDA_OUTPUT));
11967			if (err < 0)
11968				return err;
11969		}
11970		if (nid == 0x16) {
11971			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11972					  "Headphone Playback Switch",
11973					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11974							      HDA_OUTPUT));
11975			if (err < 0)
11976				return err;
11977		} else {
11978			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11979					  "Headphone Playback Switch",
11980					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11981							      HDA_OUTPUT));
11982			if (err < 0)
11983				return err;
11984		}
11985	}
11986	return 0;
11987}
11988
11989static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
11990						const struct auto_pin_cfg *cfg)
11991{
11992	int err;
11993
11994	err = alc880_auto_create_analog_input_ctls(spec, cfg);
11995	if (err < 0)
11996		return err;
11997	/* digital-mic input pin is excluded in alc880_auto_create..()
11998	 * because it's under 0x18
11999	 */
12000	if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
12001	    cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
12002		struct hda_input_mux *imux = &spec->private_imux;
12003		imux->items[imux->num_items].label = "Int Mic";
12004		imux->items[imux->num_items].index = 0x05;
12005		imux->num_items++;
12006	}
12007	return 0;
12008}
12009
12010#ifdef CONFIG_SND_HDA_POWER_SAVE
12011#define alc269_loopbacks	alc880_loopbacks
12012#endif
12013
12014/* pcm configuration: identiacal with ALC880 */
12015#define alc269_pcm_analog_playback	alc880_pcm_analog_playback
12016#define alc269_pcm_analog_capture	alc880_pcm_analog_capture
12017#define alc269_pcm_digital_playback	alc880_pcm_digital_playback
12018#define alc269_pcm_digital_capture	alc880_pcm_digital_capture
12019
12020/*
12021 * BIOS auto configuration
12022 */
12023static int alc269_parse_auto_config(struct hda_codec *codec)
12024{
12025	struct alc_spec *spec = codec->spec;
12026	int i, err;
12027	static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12028
12029	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12030					   alc269_ignore);
12031	if (err < 0)
12032		return err;
12033
12034	err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12035	if (err < 0)
12036		return err;
12037	err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12038	if (err < 0)
12039		return err;
12040
12041	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12042
12043	if (spec->autocfg.dig_out_pin)
12044		spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12045
12046	if (spec->kctls.list)
12047		add_mixer(spec, spec->kctls.list);
12048
12049	/* create a beep mixer control if the pin 0x1d isn't assigned */
12050	for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++)
12051		if (spec->autocfg.input_pins[i] == 0x1d)
12052			break;
12053	if (i >= ARRAY_SIZE(spec->autocfg.input_pins))
12054		add_mixer(spec, alc269_beep_mixer);
12055
12056	add_verb(spec, alc269_init_verbs);
12057	spec->num_mux_defs = 1;
12058	spec->input_mux = &spec->private_imux;
12059	/* set default input source */
12060	snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12061				  0, AC_VERB_SET_CONNECT_SEL,
12062				  spec->input_mux->items[0].index);
12063
12064	err = alc_auto_add_mic_boost(codec);
12065	if (err < 0)
12066		return err;
12067
12068	if (!spec->cap_mixer)
12069		set_capture_mixer(spec);
12070
12071	store_pin_configs(codec);
12072	return 1;
12073}
12074
12075#define alc269_auto_init_multi_out	alc882_auto_init_multi_out
12076#define alc269_auto_init_hp_out		alc882_auto_init_hp_out
12077#define alc269_auto_init_analog_input	alc882_auto_init_analog_input
12078
12079
12080/* init callback for auto-configuration model -- overriding the default init */
12081static void alc269_auto_init(struct hda_codec *codec)
12082{
12083	struct alc_spec *spec = codec->spec;
12084	alc269_auto_init_multi_out(codec);
12085	alc269_auto_init_hp_out(codec);
12086	alc269_auto_init_analog_input(codec);
12087	if (spec->unsol_event)
12088		alc_inithook(codec);
12089}
12090
12091/*
12092 * configuration and preset
12093 */
12094static const char *alc269_models[ALC269_MODEL_LAST] = {
12095	[ALC269_BASIC]			= "basic",
12096	[ALC269_QUANTA_FL1]		= "quanta",
12097	[ALC269_ASUS_EEEPC_P703]	= "eeepc-p703",
12098	[ALC269_ASUS_EEEPC_P901]	= "eeepc-p901",
12099	[ALC269_FUJITSU]		= "fujitsu"
12100};
12101
12102static struct snd_pci_quirk alc269_cfg_tbl[] = {
12103	SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
12104	SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12105		      ALC269_ASUS_EEEPC_P703),
12106	SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12107		      ALC269_ASUS_EEEPC_P901),
12108	SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12109		      ALC269_ASUS_EEEPC_P901),
12110	SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
12111	{}
12112};
12113
12114static struct alc_config_preset alc269_presets[] = {
12115	[ALC269_BASIC] = {
12116		.mixers = { alc269_base_mixer },
12117		.init_verbs = { alc269_init_verbs },
12118		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
12119		.dac_nids = alc269_dac_nids,
12120		.hp_nid = 0x03,
12121		.num_channel_mode = ARRAY_SIZE(alc269_modes),
12122		.channel_mode = alc269_modes,
12123		.input_mux = &alc269_capture_source,
12124	},
12125	[ALC269_QUANTA_FL1] = {
12126		.mixers = { alc269_quanta_fl1_mixer },
12127		.init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
12128		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
12129		.dac_nids = alc269_dac_nids,
12130		.hp_nid = 0x03,
12131		.num_channel_mode = ARRAY_SIZE(alc269_modes),
12132		.channel_mode = alc269_modes,
12133		.input_mux = &alc269_capture_source,
12134		.unsol_event = alc269_quanta_fl1_unsol_event,
12135		.init_hook = alc269_quanta_fl1_init_hook,
12136	},
12137	[ALC269_ASUS_EEEPC_P703] = {
12138		.mixers = { alc269_eeepc_mixer },
12139		.cap_mixer = alc269_epc_capture_mixer,
12140		.init_verbs = { alc269_init_verbs,
12141				alc269_eeepc_amic_init_verbs },
12142		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
12143		.dac_nids = alc269_dac_nids,
12144		.hp_nid = 0x03,
12145		.num_channel_mode = ARRAY_SIZE(alc269_modes),
12146		.channel_mode = alc269_modes,
12147		.input_mux = &alc269_eeepc_amic_capture_source,
12148		.unsol_event = alc269_eeepc_amic_unsol_event,
12149		.init_hook = alc269_eeepc_amic_inithook,
12150	},
12151	[ALC269_ASUS_EEEPC_P901] = {
12152		.mixers = { alc269_eeepc_mixer },
12153		.cap_mixer = alc269_epc_capture_mixer,
12154		.init_verbs = { alc269_init_verbs,
12155				alc269_eeepc_dmic_init_verbs },
12156		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
12157		.dac_nids = alc269_dac_nids,
12158		.hp_nid = 0x03,
12159		.num_channel_mode = ARRAY_SIZE(alc269_modes),
12160		.channel_mode = alc269_modes,
12161		.input_mux = &alc269_eeepc_dmic_capture_source,
12162		.unsol_event = alc269_eeepc_dmic_unsol_event,
12163		.init_hook = alc269_eeepc_dmic_inithook,
12164	},
12165	[ALC269_FUJITSU] = {
12166		.mixers = { alc269_fujitsu_mixer, alc269_beep_mixer },
12167		.cap_mixer = alc269_epc_capture_mixer,
12168		.init_verbs = { alc269_init_verbs,
12169				alc269_eeepc_dmic_init_verbs },
12170		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
12171		.dac_nids = alc269_dac_nids,
12172		.hp_nid = 0x03,
12173		.num_channel_mode = ARRAY_SIZE(alc269_modes),
12174		.channel_mode = alc269_modes,
12175		.input_mux = &alc269_eeepc_dmic_capture_source,
12176		.unsol_event = alc269_eeepc_dmic_unsol_event,
12177		.init_hook = alc269_eeepc_dmic_inithook,
12178	},
12179};
12180
12181static int patch_alc269(struct hda_codec *codec)
12182{
12183	struct alc_spec *spec;
12184	int board_config;
12185	int err;
12186
12187	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12188	if (spec == NULL)
12189		return -ENOMEM;
12190
12191	codec->spec = spec;
12192
12193	alc_fix_pll_init(codec, 0x20, 0x04, 15);
12194
12195	board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
12196						  alc269_models,
12197						  alc269_cfg_tbl);
12198
12199	if (board_config < 0) {
12200		printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
12201		       "trying auto-probe from BIOS...\n");
12202		board_config = ALC269_AUTO;
12203	}
12204
12205	if (board_config == ALC269_AUTO) {
12206		/* automatic parse from the BIOS config */
12207		err = alc269_parse_auto_config(codec);
12208		if (err < 0) {
12209			alc_free(codec);
12210			return err;
12211		} else if (!err) {
12212			printk(KERN_INFO
12213			       "hda_codec: Cannot set up configuration "
12214			       "from BIOS.  Using base mode...\n");
12215			board_config = ALC269_BASIC;
12216		}
12217	}
12218
12219	if (board_config != ALC269_AUTO)
12220		setup_preset(spec, &alc269_presets[board_config]);
12221
12222	spec->stream_name_analog = "ALC269 Analog";
12223	spec->stream_analog_playback = &alc269_pcm_analog_playback;
12224	spec->stream_analog_capture = &alc269_pcm_analog_capture;
12225
12226	spec->stream_name_digital = "ALC269 Digital";
12227	spec->stream_digital_playback = &alc269_pcm_digital_playback;
12228	spec->stream_digital_capture = &alc269_pcm_digital_capture;
12229
12230	spec->adc_nids = alc269_adc_nids;
12231	spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
12232	spec->capsrc_nids = alc269_capsrc_nids;
12233	if (!spec->cap_mixer)
12234		set_capture_mixer(spec);
12235
12236	codec->patch_ops = alc_patch_ops;
12237	if (board_config == ALC269_AUTO)
12238		spec->init_hook = alc269_auto_init;
12239#ifdef CONFIG_SND_HDA_POWER_SAVE
12240	if (!spec->loopback.amplist)
12241		spec->loopback.amplist = alc269_loopbacks;
12242#endif
12243
12244	return 0;
12245}
12246
12247/*
12248 *  ALC861 channel source setting (2/6 channel selection for 3-stack)
12249 */
12250
12251/*
12252 * set the path ways for 2 channel output
12253 * need to set the codec line out and mic 1 pin widgets to inputs
12254 */
12255static struct hda_verb alc861_threestack_ch2_init[] = {
12256	/* set pin widget 1Ah (line in) for input */
12257	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12258	/* set pin widget 18h (mic1/2) for input, for mic also enable
12259	 * the vref
12260	 */
12261	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12262
12263	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12264#if 0
12265	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12266	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12267#endif
12268	{ } /* end */
12269};
12270/*
12271 * 6ch mode
12272 * need to set the codec line out and mic 1 pin widgets to outputs
12273 */
12274static struct hda_verb alc861_threestack_ch6_init[] = {
12275	/* set pin widget 1Ah (line in) for output (Back Surround)*/
12276	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12277	/* set pin widget 18h (mic1) for output (CLFE)*/
12278	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12279
12280	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12281	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12282
12283	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12284#if 0
12285	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12286	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12287#endif
12288	{ } /* end */
12289};
12290
12291static struct hda_channel_mode alc861_threestack_modes[2] = {
12292	{ 2, alc861_threestack_ch2_init },
12293	{ 6, alc861_threestack_ch6_init },
12294};
12295/* Set mic1 as input and unmute the mixer */
12296static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
12297	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12298	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12299	{ } /* end */
12300};
12301/* Set mic1 as output and mute mixer */
12302static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
12303	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12304	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12305	{ } /* end */
12306};
12307
12308static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
12309	{ 2, alc861_uniwill_m31_ch2_init },
12310	{ 4, alc861_uniwill_m31_ch4_init },
12311};
12312
12313/* Set mic1 and line-in as input and unmute the mixer */
12314static struct hda_verb alc861_asus_ch2_init[] = {
12315	/* set pin widget 1Ah (line in) for input */
12316	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12317	/* set pin widget 18h (mic1/2) for input, for mic also enable
12318	 * the vref
12319	 */
12320	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12321
12322	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12323#if 0
12324	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12325	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12326#endif
12327	{ } /* end */
12328};
12329/* Set mic1 nad line-in as output and mute mixer */
12330static struct hda_verb alc861_asus_ch6_init[] = {
12331	/* set pin widget 1Ah (line in) for output (Back Surround)*/
12332	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12333	/* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12334	/* set pin widget 18h (mic1) for output (CLFE)*/
12335	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12336	/* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12337	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12338	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12339
12340	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12341#if 0
12342	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12343	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12344#endif
12345	{ } /* end */
12346};
12347
12348static struct hda_channel_mode alc861_asus_modes[2] = {
12349	{ 2, alc861_asus_ch2_init },
12350	{ 6, alc861_asus_ch6_init },
12351};
12352
12353/* patch-ALC861 */
12354
12355static struct snd_kcontrol_new alc861_base_mixer[] = {
12356        /* output mixer control */
12357	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12358	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12359	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12360	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12361	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12362
12363        /*Input mixer control */
12364	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12365	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12366	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12367	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12368	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12369	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12370	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12371	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12372	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12373	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12374
12375	{ } /* end */
12376};
12377
12378static struct snd_kcontrol_new alc861_3ST_mixer[] = {
12379        /* output mixer control */
12380	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12381	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12382	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12383	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12384	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12385
12386	/* Input mixer control */
12387	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12388	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12389	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12390	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12391	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12392	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12393	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12394	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12395	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12396	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12397
12398	{
12399		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12400		.name = "Channel Mode",
12401		.info = alc_ch_mode_info,
12402		.get = alc_ch_mode_get,
12403		.put = alc_ch_mode_put,
12404                .private_value = ARRAY_SIZE(alc861_threestack_modes),
12405	},
12406	{ } /* end */
12407};
12408
12409static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
12410        /* output mixer control */
12411	HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12412	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12413	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12414
12415	{ } /* end */
12416};
12417
12418static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
12419        /* output mixer control */
12420	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12421	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12422	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12423	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12424	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12425
12426	/* Input mixer control */
12427	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12428	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12429	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12430	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12431	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12432	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12433	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12434	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12435	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12436	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12437
12438	{
12439		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12440		.name = "Channel Mode",
12441		.info = alc_ch_mode_info,
12442		.get = alc_ch_mode_get,
12443		.put = alc_ch_mode_put,
12444                .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
12445	},
12446	{ } /* end */
12447};
12448
12449static struct snd_kcontrol_new alc861_asus_mixer[] = {
12450        /* output mixer control */
12451	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12452	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12453	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12454	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12455	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12456
12457	/* Input mixer control */
12458	HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12459	HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12460	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12461	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12462	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12463	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12464	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12465	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12466	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12467	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
12468
12469	{
12470		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12471		.name = "Channel Mode",
12472		.info = alc_ch_mode_info,
12473		.get = alc_ch_mode_get,
12474		.put = alc_ch_mode_put,
12475                .private_value = ARRAY_SIZE(alc861_asus_modes),
12476	},
12477	{ }
12478};
12479
12480/* additional mixer */
12481static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
12482	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12483	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12484	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
12485	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
12486	{ }
12487};
12488
12489/*
12490 * generic initialization of ADC, input mixers and output mixers
12491 */
12492static struct hda_verb alc861_base_init_verbs[] = {
12493	/*
12494	 * Unmute ADC0 and set the default input to mic-in
12495	 */
12496	/* port-A for surround (rear panel) */
12497	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12498	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
12499	/* port-B for mic-in (rear panel) with vref */
12500	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12501	/* port-C for line-in (rear panel) */
12502	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12503	/* port-D for Front */
12504	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12505	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12506	/* port-E for HP out (front panel) */
12507	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12508	/* route front PCM to HP */
12509	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12510	/* port-F for mic-in (front panel) with vref */
12511	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12512	/* port-G for CLFE (rear panel) */
12513	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12514	{ 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12515	/* port-H for side (rear panel) */
12516	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12517	{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
12518	/* CD-in */
12519	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12520	/* route front mic to ADC1*/
12521	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12522	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12523
12524	/* Unmute DAC0~3 & spdif out*/
12525	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12526	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12527	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12528	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12529	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12530
12531	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12532	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12533        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12534	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12535        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12536
12537	/* Unmute Stereo Mixer 15 */
12538	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12539	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12540	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12541	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12542
12543	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12544	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12545	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12546	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12547	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12548	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12549	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12550	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12551	/* hp used DAC 3 (Front) */
12552	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12553        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12554
12555	{ }
12556};
12557
12558static struct hda_verb alc861_threestack_init_verbs[] = {
12559	/*
12560	 * Unmute ADC0 and set the default input to mic-in
12561	 */
12562	/* port-A for surround (rear panel) */
12563	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12564	/* port-B for mic-in (rear panel) with vref */
12565	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12566	/* port-C for line-in (rear panel) */
12567	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12568	/* port-D for Front */
12569	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12570	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12571	/* port-E for HP out (front panel) */
12572	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12573	/* route front PCM to HP */
12574	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12575	/* port-F for mic-in (front panel) with vref */
12576	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12577	/* port-G for CLFE (rear panel) */
12578	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12579	/* port-H for side (rear panel) */
12580	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12581	/* CD-in */
12582	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12583	/* route front mic to ADC1*/
12584	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12585	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12586	/* Unmute DAC0~3 & spdif out*/
12587	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12588	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12589	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12590	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12591	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12592
12593	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12594	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12595        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12596	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12597        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12598
12599	/* Unmute Stereo Mixer 15 */
12600	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12601	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12602	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12603	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12604
12605	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12606	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12607	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12608	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12609	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12610	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12611	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12612	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12613	/* hp used DAC 3 (Front) */
12614	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12615        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12616	{ }
12617};
12618
12619static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
12620	/*
12621	 * Unmute ADC0 and set the default input to mic-in
12622	 */
12623	/* port-A for surround (rear panel) */
12624	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12625	/* port-B for mic-in (rear panel) with vref */
12626	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12627	/* port-C for line-in (rear panel) */
12628	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12629	/* port-D for Front */
12630	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12631	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12632	/* port-E for HP out (front panel) */
12633	/* this has to be set to VREF80 */
12634	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12635	/* route front PCM to HP */
12636	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12637	/* port-F for mic-in (front panel) with vref */
12638	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12639	/* port-G for CLFE (rear panel) */
12640	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12641	/* port-H for side (rear panel) */
12642	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12643	/* CD-in */
12644	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12645	/* route front mic to ADC1*/
12646	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12647	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12648	/* Unmute DAC0~3 & spdif out*/
12649	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12650	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12651	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12652	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12653	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12654
12655	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12656	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12657        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12658	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12659        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12660
12661	/* Unmute Stereo Mixer 15 */
12662	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12663	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12664	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12665	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12666
12667	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12668	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12669	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12670	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12671	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12672	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12673	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12674	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12675	/* hp used DAC 3 (Front) */
12676	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12677        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12678	{ }
12679};
12680
12681static struct hda_verb alc861_asus_init_verbs[] = {
12682	/*
12683	 * Unmute ADC0 and set the default input to mic-in
12684	 */
12685	/* port-A for surround (rear panel)
12686	 * according to codec#0 this is the HP jack
12687	 */
12688	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
12689	/* route front PCM to HP */
12690	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
12691	/* port-B for mic-in (rear panel) with vref */
12692	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12693	/* port-C for line-in (rear panel) */
12694	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12695	/* port-D for Front */
12696	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12697	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12698	/* port-E for HP out (front panel) */
12699	/* this has to be set to VREF80 */
12700	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12701	/* route front PCM to HP */
12702	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12703	/* port-F for mic-in (front panel) with vref */
12704	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12705	/* port-G for CLFE (rear panel) */
12706	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12707	/* port-H for side (rear panel) */
12708	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12709	/* CD-in */
12710	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12711	/* route front mic to ADC1*/
12712	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12713	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12714	/* Unmute DAC0~3 & spdif out*/
12715	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12716	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12717	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12718	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12719	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12720	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12721	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12722        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12723	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12724        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12725
12726	/* Unmute Stereo Mixer 15 */
12727	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12728	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12729	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12730	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12731
12732	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12733	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12734	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12735	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12736	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12737	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12738	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12739	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12740	/* hp used DAC 3 (Front) */
12741	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12742	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12743	{ }
12744};
12745
12746/* additional init verbs for ASUS laptops */
12747static struct hda_verb alc861_asus_laptop_init_verbs[] = {
12748	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
12749	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
12750	{ }
12751};
12752
12753/*
12754 * generic initialization of ADC, input mixers and output mixers
12755 */
12756static struct hda_verb alc861_auto_init_verbs[] = {
12757	/*
12758	 * Unmute ADC0 and set the default input to mic-in
12759	 */
12760	/* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
12761	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12762
12763	/* Unmute DAC0~3 & spdif out*/
12764	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12765	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12766	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12767	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12768	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12769
12770	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12771	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12772	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12773	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12774	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12775
12776	/* Unmute Stereo Mixer 15 */
12777	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12778	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12779	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12780	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
12781
12782	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12783	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12784	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12785	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12786	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12787	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12788	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12789	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12790
12791	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12792	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12793	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12794	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12795	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12796	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12797	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12798	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12799
12800	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},	/* set Mic 1 */
12801
12802	{ }
12803};
12804
12805static struct hda_verb alc861_toshiba_init_verbs[] = {
12806	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12807
12808	{ }
12809};
12810
12811/* toggle speaker-output according to the hp-jack state */
12812static void alc861_toshiba_automute(struct hda_codec *codec)
12813{
12814	unsigned int present;
12815
12816	present = snd_hda_codec_read(codec, 0x0f, 0,
12817				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12818	snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
12819				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
12820	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
12821				 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
12822}
12823
12824static void alc861_toshiba_unsol_event(struct hda_codec *codec,
12825				       unsigned int res)
12826{
12827	if ((res >> 26) == ALC880_HP_EVENT)
12828		alc861_toshiba_automute(codec);
12829}
12830
12831/* pcm configuration: identiacal with ALC880 */
12832#define alc861_pcm_analog_playback	alc880_pcm_analog_playback
12833#define alc861_pcm_analog_capture	alc880_pcm_analog_capture
12834#define alc861_pcm_digital_playback	alc880_pcm_digital_playback
12835#define alc861_pcm_digital_capture	alc880_pcm_digital_capture
12836
12837
12838#define ALC861_DIGOUT_NID	0x07
12839
12840static struct hda_channel_mode alc861_8ch_modes[1] = {
12841	{ 8, NULL }
12842};
12843
12844static hda_nid_t alc861_dac_nids[4] = {
12845	/* front, surround, clfe, side */
12846	0x03, 0x06, 0x05, 0x04
12847};
12848
12849static hda_nid_t alc660_dac_nids[3] = {
12850	/* front, clfe, surround */
12851	0x03, 0x05, 0x06
12852};
12853
12854static hda_nid_t alc861_adc_nids[1] = {
12855	/* ADC0-2 */
12856	0x08,
12857};
12858
12859static struct hda_input_mux alc861_capture_source = {
12860	.num_items = 5,
12861	.items = {
12862		{ "Mic", 0x0 },
12863		{ "Front Mic", 0x3 },
12864		{ "Line", 0x1 },
12865		{ "CD", 0x4 },
12866		{ "Mixer", 0x5 },
12867	},
12868};
12869
12870/* fill in the dac_nids table from the parsed pin configuration */
12871static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
12872				     const struct auto_pin_cfg *cfg)
12873{
12874	int i;
12875	hda_nid_t nid;
12876
12877	spec->multiout.dac_nids = spec->private_dac_nids;
12878	for (i = 0; i < cfg->line_outs; i++) {
12879		nid = cfg->line_out_pins[i];
12880		if (nid) {
12881			if (i >= ARRAY_SIZE(alc861_dac_nids))
12882				continue;
12883			spec->multiout.dac_nids[i] = alc861_dac_nids[i];
12884		}
12885	}
12886	spec->multiout.num_dacs = cfg->line_outs;
12887	return 0;
12888}
12889
12890/* add playback controls from the parsed DAC table */
12891static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
12892					     const struct auto_pin_cfg *cfg)
12893{
12894	char name[32];
12895	static const char *chname[4] = {
12896		"Front", "Surround", NULL /*CLFE*/, "Side"
12897	};
12898	hda_nid_t nid;
12899	int i, idx, err;
12900
12901	for (i = 0; i < cfg->line_outs; i++) {
12902		nid = spec->multiout.dac_nids[i];
12903		if (!nid)
12904			continue;
12905		if (nid == 0x05) {
12906			/* Center/LFE */
12907			err = add_control(spec, ALC_CTL_BIND_MUTE,
12908					  "Center Playback Switch",
12909					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
12910							      HDA_OUTPUT));
12911			if (err < 0)
12912				return err;
12913			err = add_control(spec, ALC_CTL_BIND_MUTE,
12914					  "LFE Playback Switch",
12915					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12916							      HDA_OUTPUT));
12917			if (err < 0)
12918				return err;
12919		} else {
12920			for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
12921			     idx++)
12922				if (nid == alc861_dac_nids[idx])
12923					break;
12924			sprintf(name, "%s Playback Switch", chname[idx]);
12925			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12926					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12927							      HDA_OUTPUT));
12928			if (err < 0)
12929				return err;
12930		}
12931	}
12932	return 0;
12933}
12934
12935static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
12936{
12937	int err;
12938	hda_nid_t nid;
12939
12940	if (!pin)
12941		return 0;
12942
12943	if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
12944		nid = 0x03;
12945		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12946				  "Headphone Playback Switch",
12947				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12948		if (err < 0)
12949			return err;
12950		spec->multiout.hp_nid = nid;
12951	}
12952	return 0;
12953}
12954
12955/* create playback/capture controls for input pins */
12956static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
12957						const struct auto_pin_cfg *cfg)
12958{
12959	struct hda_input_mux *imux = &spec->private_imux;
12960	int i, err, idx, idx1;
12961
12962	for (i = 0; i < AUTO_PIN_LAST; i++) {
12963		switch (cfg->input_pins[i]) {
12964		case 0x0c:
12965			idx1 = 1;
12966			idx = 2;	/* Line In */
12967			break;
12968		case 0x0f:
12969			idx1 = 2;
12970			idx = 2;	/* Line In */
12971			break;
12972		case 0x0d:
12973			idx1 = 0;
12974			idx = 1;	/* Mic In */
12975			break;
12976		case 0x10:
12977			idx1 = 3;
12978			idx = 1;	/* Mic In */
12979			break;
12980		case 0x11:
12981			idx1 = 4;
12982			idx = 0;	/* CD */
12983			break;
12984		default:
12985			continue;
12986		}
12987
12988		err = new_analog_input(spec, cfg->input_pins[i],
12989				       auto_pin_cfg_labels[i], idx, 0x15);
12990		if (err < 0)
12991			return err;
12992
12993		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
12994		imux->items[imux->num_items].index = idx1;
12995		imux->num_items++;
12996	}
12997	return 0;
12998}
12999
13000static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13001					      hda_nid_t nid,
13002					      int pin_type, int dac_idx)
13003{
13004	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13005			    pin_type);
13006	snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13007			    AMP_OUT_UNMUTE);
13008}
13009
13010static void alc861_auto_init_multi_out(struct hda_codec *codec)
13011{
13012	struct alc_spec *spec = codec->spec;
13013	int i;
13014
13015	alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
13016	for (i = 0; i < spec->autocfg.line_outs; i++) {
13017		hda_nid_t nid = spec->autocfg.line_out_pins[i];
13018		int pin_type = get_pin_type(spec->autocfg.line_out_type);
13019		if (nid)
13020			alc861_auto_set_output_and_unmute(codec, nid, pin_type,
13021							  spec->multiout.dac_nids[i]);
13022	}
13023}
13024
13025static void alc861_auto_init_hp_out(struct hda_codec *codec)
13026{
13027	struct alc_spec *spec = codec->spec;
13028	hda_nid_t pin;
13029
13030	pin = spec->autocfg.hp_pins[0];
13031	if (pin) /* connect to front */
13032		alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13033						  spec->multiout.dac_nids[0]);
13034	pin = spec->autocfg.speaker_pins[0];
13035	if (pin)
13036		alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13037}
13038
13039static void alc861_auto_init_analog_input(struct hda_codec *codec)
13040{
13041	struct alc_spec *spec = codec->spec;
13042	int i;
13043
13044	for (i = 0; i < AUTO_PIN_LAST; i++) {
13045		hda_nid_t nid = spec->autocfg.input_pins[i];
13046		if (nid >= 0x0c && nid <= 0x11) {
13047			snd_hda_codec_write(codec, nid, 0,
13048					    AC_VERB_SET_PIN_WIDGET_CONTROL,
13049					    i <= AUTO_PIN_FRONT_MIC ?
13050					    PIN_VREF80 : PIN_IN);
13051		}
13052	}
13053}
13054
13055/* parse the BIOS configuration and set up the alc_spec */
13056/* return 1 if successful, 0 if the proper config is not found,
13057 * or a negative error code
13058 */
13059static int alc861_parse_auto_config(struct hda_codec *codec)
13060{
13061	struct alc_spec *spec = codec->spec;
13062	int err;
13063	static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13064
13065	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13066					   alc861_ignore);
13067	if (err < 0)
13068		return err;
13069	if (!spec->autocfg.line_outs)
13070		return 0; /* can't find valid BIOS pin config */
13071
13072	err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13073	if (err < 0)
13074		return err;
13075	err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13076	if (err < 0)
13077		return err;
13078	err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13079	if (err < 0)
13080		return err;
13081	err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13082	if (err < 0)
13083		return err;
13084
13085	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13086
13087	if (spec->autocfg.dig_out_pin)
13088		spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13089
13090	if (spec->kctls.list)
13091		add_mixer(spec, spec->kctls.list);
13092
13093	add_verb(spec, alc861_auto_init_verbs);
13094
13095	spec->num_mux_defs = 1;
13096	spec->input_mux = &spec->private_imux;
13097
13098	spec->adc_nids = alc861_adc_nids;
13099	spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
13100	set_capture_mixer(spec);
13101
13102	store_pin_configs(codec);
13103	return 1;
13104}
13105
13106/* additional initialization for auto-configuration model */
13107static void alc861_auto_init(struct hda_codec *codec)
13108{
13109	struct alc_spec *spec = codec->spec;
13110	alc861_auto_init_multi_out(codec);
13111	alc861_auto_init_hp_out(codec);
13112	alc861_auto_init_analog_input(codec);
13113	if (spec->unsol_event)
13114		alc_inithook(codec);
13115}
13116
13117#ifdef CONFIG_SND_HDA_POWER_SAVE
13118static struct hda_amp_list alc861_loopbacks[] = {
13119	{ 0x15, HDA_INPUT, 0 },
13120	{ 0x15, HDA_INPUT, 1 },
13121	{ 0x15, HDA_INPUT, 2 },
13122	{ 0x15, HDA_INPUT, 3 },
13123	{ } /* end */
13124};
13125#endif
13126
13127
13128/*
13129 * configuration and preset
13130 */
13131static const char *alc861_models[ALC861_MODEL_LAST] = {
13132	[ALC861_3ST]		= "3stack",
13133	[ALC660_3ST]		= "3stack-660",
13134	[ALC861_3ST_DIG]	= "3stack-dig",
13135	[ALC861_6ST_DIG]	= "6stack-dig",
13136	[ALC861_UNIWILL_M31]	= "uniwill-m31",
13137	[ALC861_TOSHIBA]	= "toshiba",
13138	[ALC861_ASUS]		= "asus",
13139	[ALC861_ASUS_LAPTOP]	= "asus-laptop",
13140	[ALC861_AUTO]		= "auto",
13141};
13142
13143static struct snd_pci_quirk alc861_cfg_tbl[] = {
13144	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
13145	SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13146	SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13147	SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
13148	SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
13149	SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
13150	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
13151	/* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
13152	 *        Any other models that need this preset?
13153	 */
13154	/* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
13155	SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
13156	SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
13157	SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
13158	SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
13159	SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
13160	/* FIXME: the below seems conflict */
13161	/* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
13162	SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
13163	SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
13164	{}
13165};
13166
13167static struct alc_config_preset alc861_presets[] = {
13168	[ALC861_3ST] = {
13169		.mixers = { alc861_3ST_mixer },
13170		.init_verbs = { alc861_threestack_init_verbs },
13171		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13172		.dac_nids = alc861_dac_nids,
13173		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13174		.channel_mode = alc861_threestack_modes,
13175		.need_dac_fix = 1,
13176		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13177		.adc_nids = alc861_adc_nids,
13178		.input_mux = &alc861_capture_source,
13179	},
13180	[ALC861_3ST_DIG] = {
13181		.mixers = { alc861_base_mixer },
13182		.init_verbs = { alc861_threestack_init_verbs },
13183		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13184		.dac_nids = alc861_dac_nids,
13185		.dig_out_nid = ALC861_DIGOUT_NID,
13186		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13187		.channel_mode = alc861_threestack_modes,
13188		.need_dac_fix = 1,
13189		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13190		.adc_nids = alc861_adc_nids,
13191		.input_mux = &alc861_capture_source,
13192	},
13193	[ALC861_6ST_DIG] = {
13194		.mixers = { alc861_base_mixer },
13195		.init_verbs = { alc861_base_init_verbs },
13196		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13197		.dac_nids = alc861_dac_nids,
13198		.dig_out_nid = ALC861_DIGOUT_NID,
13199		.num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
13200		.channel_mode = alc861_8ch_modes,
13201		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13202		.adc_nids = alc861_adc_nids,
13203		.input_mux = &alc861_capture_source,
13204	},
13205	[ALC660_3ST] = {
13206		.mixers = { alc861_3ST_mixer },
13207		.init_verbs = { alc861_threestack_init_verbs },
13208		.num_dacs = ARRAY_SIZE(alc660_dac_nids),
13209		.dac_nids = alc660_dac_nids,
13210		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13211		.channel_mode = alc861_threestack_modes,
13212		.need_dac_fix = 1,
13213		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13214		.adc_nids = alc861_adc_nids,
13215		.input_mux = &alc861_capture_source,
13216	},
13217	[ALC861_UNIWILL_M31] = {
13218		.mixers = { alc861_uniwill_m31_mixer },
13219		.init_verbs = { alc861_uniwill_m31_init_verbs },
13220		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13221		.dac_nids = alc861_dac_nids,
13222		.dig_out_nid = ALC861_DIGOUT_NID,
13223		.num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
13224		.channel_mode = alc861_uniwill_m31_modes,
13225		.need_dac_fix = 1,
13226		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13227		.adc_nids = alc861_adc_nids,
13228		.input_mux = &alc861_capture_source,
13229	},
13230	[ALC861_TOSHIBA] = {
13231		.mixers = { alc861_toshiba_mixer },
13232		.init_verbs = { alc861_base_init_verbs,
13233				alc861_toshiba_init_verbs },
13234		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13235		.dac_nids = alc861_dac_nids,
13236		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13237		.channel_mode = alc883_3ST_2ch_modes,
13238		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13239		.adc_nids = alc861_adc_nids,
13240		.input_mux = &alc861_capture_source,
13241		.unsol_event = alc861_toshiba_unsol_event,
13242		.init_hook = alc861_toshiba_automute,
13243	},
13244	[ALC861_ASUS] = {
13245		.mixers = { alc861_asus_mixer },
13246		.init_verbs = { alc861_asus_init_verbs },
13247		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13248		.dac_nids = alc861_dac_nids,
13249		.dig_out_nid = ALC861_DIGOUT_NID,
13250		.num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
13251		.channel_mode = alc861_asus_modes,
13252		.need_dac_fix = 1,
13253		.hp_nid = 0x06,
13254		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13255		.adc_nids = alc861_adc_nids,
13256		.input_mux = &alc861_capture_source,
13257	},
13258	[ALC861_ASUS_LAPTOP] = {
13259		.mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
13260		.init_verbs = { alc861_asus_init_verbs,
13261				alc861_asus_laptop_init_verbs },
13262		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13263		.dac_nids = alc861_dac_nids,
13264		.dig_out_nid = ALC861_DIGOUT_NID,
13265		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13266		.channel_mode = alc883_3ST_2ch_modes,
13267		.need_dac_fix = 1,
13268		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13269		.adc_nids = alc861_adc_nids,
13270		.input_mux = &alc861_capture_source,
13271	},
13272};
13273
13274
13275static int patch_alc861(struct hda_codec *codec)
13276{
13277	struct alc_spec *spec;
13278	int board_config;
13279	int err;
13280
13281	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13282	if (spec == NULL)
13283		return -ENOMEM;
13284
13285	codec->spec = spec;
13286
13287        board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
13288						  alc861_models,
13289						  alc861_cfg_tbl);
13290
13291	if (board_config < 0) {
13292		printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
13293		       "trying auto-probe from BIOS...\n");
13294		board_config = ALC861_AUTO;
13295	}
13296
13297	if (board_config == ALC861_AUTO) {
13298		/* automatic parse from the BIOS config */
13299		err = alc861_parse_auto_config(codec);
13300		if (err < 0) {
13301			alc_free(codec);
13302			return err;
13303		} else if (!err) {
13304			printk(KERN_INFO
13305			       "hda_codec: Cannot set up configuration "
13306			       "from BIOS.  Using base mode...\n");
13307		   board_config = ALC861_3ST_DIG;
13308		}
13309	}
13310
13311	if (board_config != ALC861_AUTO)
13312		setup_preset(spec, &alc861_presets[board_config]);
13313
13314	spec->stream_name_analog = "ALC861 Analog";
13315	spec->stream_analog_playback = &alc861_pcm_analog_playback;
13316	spec->stream_analog_capture = &alc861_pcm_analog_capture;
13317
13318	spec->stream_name_digital = "ALC861 Digital";
13319	spec->stream_digital_playback = &alc861_pcm_digital_playback;
13320	spec->stream_digital_capture = &alc861_pcm_digital_capture;
13321
13322	spec->vmaster_nid = 0x03;
13323
13324	codec->patch_ops = alc_patch_ops;
13325	if (board_config == ALC861_AUTO)
13326		spec->init_hook = alc861_auto_init;
13327#ifdef CONFIG_SND_HDA_POWER_SAVE
13328	if (!spec->loopback.amplist)
13329		spec->loopback.amplist = alc861_loopbacks;
13330#endif
13331
13332	return 0;
13333}
13334
13335/*
13336 * ALC861-VD support
13337 *
13338 * Based on ALC882
13339 *
13340 * In addition, an independent DAC
13341 */
13342#define ALC861VD_DIGOUT_NID	0x06
13343
13344static hda_nid_t alc861vd_dac_nids[4] = {
13345	/* front, surr, clfe, side surr */
13346	0x02, 0x03, 0x04, 0x05
13347};
13348
13349/* dac_nids for ALC660vd are in a different order - according to
13350 * Realtek's driver.
13351 * This should probably tesult in a different mixer for 6stack models
13352 * of ALC660vd codecs, but for now there is only 3stack mixer
13353 * - and it is the same as in 861vd.
13354 * adc_nids in ALC660vd are (is) the same as in 861vd
13355 */
13356static hda_nid_t alc660vd_dac_nids[3] = {
13357	/* front, rear, clfe, rear_surr */
13358	0x02, 0x04, 0x03
13359};
13360
13361static hda_nid_t alc861vd_adc_nids[1] = {
13362	/* ADC0 */
13363	0x09,
13364};
13365
13366static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
13367
13368/* input MUX */
13369/* FIXME: should be a matrix-type input source selection */
13370static struct hda_input_mux alc861vd_capture_source = {
13371	.num_items = 4,
13372	.items = {
13373		{ "Mic", 0x0 },
13374		{ "Front Mic", 0x1 },
13375		{ "Line", 0x2 },
13376		{ "CD", 0x4 },
13377	},
13378};
13379
13380static struct hda_input_mux alc861vd_dallas_capture_source = {
13381	.num_items = 2,
13382	.items = {
13383		{ "Ext Mic", 0x0 },
13384		{ "Int Mic", 0x1 },
13385	},
13386};
13387
13388static struct hda_input_mux alc861vd_hp_capture_source = {
13389	.num_items = 2,
13390	.items = {
13391		{ "Front Mic", 0x0 },
13392		{ "ATAPI Mic", 0x1 },
13393	},
13394};
13395
13396/*
13397 * 2ch mode
13398 */
13399static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
13400	{ 2, NULL }
13401};
13402
13403/*
13404 * 6ch mode
13405 */
13406static struct hda_verb alc861vd_6stack_ch6_init[] = {
13407	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13408	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13409	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13410	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13411	{ } /* end */
13412};
13413
13414/*
13415 * 8ch mode
13416 */
13417static struct hda_verb alc861vd_6stack_ch8_init[] = {
13418	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13419	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13420	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13421	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13422	{ } /* end */
13423};
13424
13425static struct hda_channel_mode alc861vd_6stack_modes[2] = {
13426	{ 6, alc861vd_6stack_ch6_init },
13427	{ 8, alc861vd_6stack_ch8_init },
13428};
13429
13430static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
13431	{
13432		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13433		.name = "Channel Mode",
13434		.info = alc_ch_mode_info,
13435		.get = alc_ch_mode_get,
13436		.put = alc_ch_mode_put,
13437	},
13438	{ } /* end */
13439};
13440
13441/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
13442 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
13443 */
13444static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
13445	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13446	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13447
13448	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13449	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
13450
13451	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
13452				HDA_OUTPUT),
13453	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
13454				HDA_OUTPUT),
13455	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13456	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
13457
13458	HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
13459	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
13460
13461	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13462
13463	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13464	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13465	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13466
13467	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13468	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13469	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13470
13471	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13472	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13473
13474	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13475	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13476
13477	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13478	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13479
13480	{ } /* end */
13481};
13482
13483static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
13484	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13485	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13486
13487	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13488
13489	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13490	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13491	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13492
13493	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13494	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13495	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13496
13497	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13498	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13499
13500	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13501	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13502
13503	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13504	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13505
13506	{ } /* end */
13507};
13508
13509static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
13510	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13511	/*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
13512	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13513
13514	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13515
13516	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13517	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13518	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13519
13520	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13521	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13522	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13523
13524	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13525	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13526
13527	{ } /* end */
13528};
13529
13530/* Pin assignment: Speaker=0x14, HP = 0x15,
13531 *                 Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
13532 */
13533static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
13534	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13535	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
13536	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13537	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13538	HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
13539	HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13540	HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13541	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
13542	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13543	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13544	HDA_CODEC_VOLUME("PC Beep Volume", 0x0b, 0x05, HDA_INPUT),
13545	HDA_CODEC_MUTE("PC Beep Switch", 0x0b, 0x05, HDA_INPUT),
13546	{ } /* end */
13547};
13548
13549/* Pin assignment: Speaker=0x14, Line-out = 0x15,
13550 *                 Front Mic=0x18, ATAPI Mic = 0x19,
13551 */
13552static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
13553	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13554	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13555	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13556	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13557	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13558	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13559	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13560	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13561
13562	{ } /* end */
13563};
13564
13565/*
13566 * generic initialization of ADC, input mixers and output mixers
13567 */
13568static struct hda_verb alc861vd_volume_init_verbs[] = {
13569	/*
13570	 * Unmute ADC0 and set the default input to mic-in
13571	 */
13572	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13573	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13574
13575	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
13576	 * the analog-loopback mixer widget
13577	 */
13578	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13579	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13580	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13581	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13582	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13583	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13584
13585	/* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
13586	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13587	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13588	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13589	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
13590
13591	/*
13592	 * Set up output mixers (0x02 - 0x05)
13593	 */
13594	/* set vol=0 to output mixers */
13595	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13596	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13597	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13598	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13599
13600	/* set up input amps for analog loopback */
13601	/* Amp Indices: DAC = 0, mixer = 1 */
13602	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13603	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13604	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13605	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13606	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13607	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13608	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13609	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13610
13611	{ }
13612};
13613
13614/*
13615 * 3-stack pin configuration:
13616 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
13617 */
13618static struct hda_verb alc861vd_3stack_init_verbs[] = {
13619	/*
13620	 * Set pin mode and muting
13621	 */
13622	/* set front pin widgets 0x14 for output */
13623	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13624	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13625	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13626
13627	/* Mic (rear) pin: input vref at 80% */
13628	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13629	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13630	/* Front Mic pin: input vref at 80% */
13631	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13632	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13633	/* Line In pin: input */
13634	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13635	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13636	/* Line-2 In: Headphone output (output 0 - 0x0c) */
13637	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13638	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13639	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13640	/* CD pin widget for input */
13641	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13642
13643	{ }
13644};
13645
13646/*
13647 * 6-stack pin configuration:
13648 */
13649static struct hda_verb alc861vd_6stack_init_verbs[] = {
13650	/*
13651	 * Set pin mode and muting
13652	 */
13653	/* set front pin widgets 0x14 for output */
13654	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13655	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13656	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13657
13658	/* Rear Pin: output 1 (0x0d) */
13659	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13660	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13661	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13662	/* CLFE Pin: output 2 (0x0e) */
13663	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13664	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13665	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
13666	/* Side Pin: output 3 (0x0f) */
13667	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13668	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13669	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
13670
13671	/* Mic (rear) pin: input vref at 80% */
13672	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13673	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13674	/* Front Mic pin: input vref at 80% */
13675	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13676	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13677	/* Line In pin: input */
13678	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13679	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13680	/* Line-2 In: Headphone output (output 0 - 0x0c) */
13681	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13682	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13683	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13684	/* CD pin widget for input */
13685	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13686
13687	{ }
13688};
13689
13690static struct hda_verb alc861vd_eapd_verbs[] = {
13691	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13692	{ }
13693};
13694
13695static struct hda_verb alc660vd_eapd_verbs[] = {
13696	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13697	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13698	{ }
13699};
13700
13701static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
13702	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13703	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13704	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
13705	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13706	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13707	{}
13708};
13709
13710/* toggle speaker-output according to the hp-jack state */
13711static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
13712{
13713	unsigned int present;
13714	unsigned char bits;
13715
13716	present = snd_hda_codec_read(codec, 0x1b, 0,
13717				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13718	bits = present ? HDA_AMP_MUTE : 0;
13719	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13720				 HDA_AMP_MUTE, bits);
13721}
13722
13723static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
13724{
13725	unsigned int present;
13726	unsigned char bits;
13727
13728	present = snd_hda_codec_read(codec, 0x18, 0,
13729				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13730	bits = present ? HDA_AMP_MUTE : 0;
13731	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
13732				 HDA_AMP_MUTE, bits);
13733}
13734
13735static void alc861vd_lenovo_automute(struct hda_codec *codec)
13736{
13737	alc861vd_lenovo_hp_automute(codec);
13738	alc861vd_lenovo_mic_automute(codec);
13739}
13740
13741static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
13742					unsigned int res)
13743{
13744	switch (res >> 26) {
13745	case ALC880_HP_EVENT:
13746		alc861vd_lenovo_hp_automute(codec);
13747		break;
13748	case ALC880_MIC_EVENT:
13749		alc861vd_lenovo_mic_automute(codec);
13750		break;
13751	}
13752}
13753
13754static struct hda_verb alc861vd_dallas_verbs[] = {
13755	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13756	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13757	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13758	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13759
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	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13763	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13764	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13765	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13766	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13767	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13768
13769	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13770	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13771	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13772	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13773	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13774	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13775	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13776	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13777
13778	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
13779	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13780	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
13781	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13782	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13783	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13784	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13785	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13786
13787	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13788	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13789	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13790	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13791
13792	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13793	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13794	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13795
13796	{ } /* end */
13797};
13798
13799/* toggle speaker-output according to the hp-jack state */
13800static void alc861vd_dallas_automute(struct hda_codec *codec)
13801{
13802	unsigned int present;
13803
13804	present = snd_hda_codec_read(codec, 0x15, 0,
13805				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13806	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13807				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13808}
13809
13810static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
13811{
13812	if ((res >> 26) == ALC880_HP_EVENT)
13813		alc861vd_dallas_automute(codec);
13814}
13815
13816#ifdef CONFIG_SND_HDA_POWER_SAVE
13817#define alc861vd_loopbacks	alc880_loopbacks
13818#endif
13819
13820/* pcm configuration: identiacal with ALC880 */
13821#define alc861vd_pcm_analog_playback	alc880_pcm_analog_playback
13822#define alc861vd_pcm_analog_capture	alc880_pcm_analog_capture
13823#define alc861vd_pcm_digital_playback	alc880_pcm_digital_playback
13824#define alc861vd_pcm_digital_capture	alc880_pcm_digital_capture
13825
13826/*
13827 * configuration and preset
13828 */
13829static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
13830	[ALC660VD_3ST]		= "3stack-660",
13831	[ALC660VD_3ST_DIG]	= "3stack-660-digout",
13832	[ALC861VD_3ST]		= "3stack",
13833	[ALC861VD_3ST_DIG]	= "3stack-digout",
13834	[ALC861VD_6ST_DIG]	= "6stack-digout",
13835	[ALC861VD_LENOVO]	= "lenovo",
13836	[ALC861VD_DALLAS]	= "dallas",
13837	[ALC861VD_HP]		= "hp",
13838	[ALC861VD_AUTO]		= "auto",
13839};
13840
13841static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
13842	SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
13843	SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
13844	SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
13845	SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
13846	SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC861VD_LENOVO),
13847	SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
13848	SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
13849	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
13850	/*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
13851	SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
13852	SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
13853	SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
13854	SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
13855	SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
13856	SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
13857	SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO),
13858	SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
13859	{}
13860};
13861
13862static struct alc_config_preset alc861vd_presets[] = {
13863	[ALC660VD_3ST] = {
13864		.mixers = { alc861vd_3st_mixer },
13865		.init_verbs = { alc861vd_volume_init_verbs,
13866				 alc861vd_3stack_init_verbs },
13867		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
13868		.dac_nids = alc660vd_dac_nids,
13869		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13870		.channel_mode = alc861vd_3stack_2ch_modes,
13871		.input_mux = &alc861vd_capture_source,
13872	},
13873	[ALC660VD_3ST_DIG] = {
13874		.mixers = { alc861vd_3st_mixer },
13875		.init_verbs = { alc861vd_volume_init_verbs,
13876				 alc861vd_3stack_init_verbs },
13877		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
13878		.dac_nids = alc660vd_dac_nids,
13879		.dig_out_nid = ALC861VD_DIGOUT_NID,
13880		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13881		.channel_mode = alc861vd_3stack_2ch_modes,
13882		.input_mux = &alc861vd_capture_source,
13883	},
13884	[ALC861VD_3ST] = {
13885		.mixers = { alc861vd_3st_mixer },
13886		.init_verbs = { alc861vd_volume_init_verbs,
13887				 alc861vd_3stack_init_verbs },
13888		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
13889		.dac_nids = alc861vd_dac_nids,
13890		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13891		.channel_mode = alc861vd_3stack_2ch_modes,
13892		.input_mux = &alc861vd_capture_source,
13893	},
13894	[ALC861VD_3ST_DIG] = {
13895		.mixers = { alc861vd_3st_mixer },
13896		.init_verbs = { alc861vd_volume_init_verbs,
13897		 		 alc861vd_3stack_init_verbs },
13898		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
13899		.dac_nids = alc861vd_dac_nids,
13900		.dig_out_nid = ALC861VD_DIGOUT_NID,
13901		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13902		.channel_mode = alc861vd_3stack_2ch_modes,
13903		.input_mux = &alc861vd_capture_source,
13904	},
13905	[ALC861VD_6ST_DIG] = {
13906		.mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
13907		.init_verbs = { alc861vd_volume_init_verbs,
13908				alc861vd_6stack_init_verbs },
13909		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
13910		.dac_nids = alc861vd_dac_nids,
13911		.dig_out_nid = ALC861VD_DIGOUT_NID,
13912		.num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
13913		.channel_mode = alc861vd_6stack_modes,
13914		.input_mux = &alc861vd_capture_source,
13915	},
13916	[ALC861VD_LENOVO] = {
13917		.mixers = { alc861vd_lenovo_mixer },
13918		.init_verbs = { alc861vd_volume_init_verbs,
13919				alc861vd_3stack_init_verbs,
13920				alc861vd_eapd_verbs,
13921				alc861vd_lenovo_unsol_verbs },
13922		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
13923		.dac_nids = alc660vd_dac_nids,
13924		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13925		.channel_mode = alc861vd_3stack_2ch_modes,
13926		.input_mux = &alc861vd_capture_source,
13927		.unsol_event = alc861vd_lenovo_unsol_event,
13928		.init_hook = alc861vd_lenovo_automute,
13929	},
13930	[ALC861VD_DALLAS] = {
13931		.mixers = { alc861vd_dallas_mixer },
13932		.init_verbs = { alc861vd_dallas_verbs },
13933		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
13934		.dac_nids = alc861vd_dac_nids,
13935		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13936		.channel_mode = alc861vd_3stack_2ch_modes,
13937		.input_mux = &alc861vd_dallas_capture_source,
13938		.unsol_event = alc861vd_dallas_unsol_event,
13939		.init_hook = alc861vd_dallas_automute,
13940	},
13941	[ALC861VD_HP] = {
13942		.mixers = { alc861vd_hp_mixer },
13943		.init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
13944		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
13945		.dac_nids = alc861vd_dac_nids,
13946		.dig_out_nid = ALC861VD_DIGOUT_NID,
13947		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13948		.channel_mode = alc861vd_3stack_2ch_modes,
13949		.input_mux = &alc861vd_hp_capture_source,
13950		.unsol_event = alc861vd_dallas_unsol_event,
13951		.init_hook = alc861vd_dallas_automute,
13952	},
13953};
13954
13955/*
13956 * BIOS auto configuration
13957 */
13958static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
13959				hda_nid_t nid, int pin_type, int dac_idx)
13960{
13961	alc_set_pin_output(codec, nid, pin_type);
13962}
13963
13964static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
13965{
13966	struct alc_spec *spec = codec->spec;
13967	int i;
13968
13969	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
13970	for (i = 0; i <= HDA_SIDE; i++) {
13971		hda_nid_t nid = spec->autocfg.line_out_pins[i];
13972		int pin_type = get_pin_type(spec->autocfg.line_out_type);
13973		if (nid)
13974			alc861vd_auto_set_output_and_unmute(codec, nid,
13975							    pin_type, i);
13976	}
13977}
13978
13979
13980static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
13981{
13982	struct alc_spec *spec = codec->spec;
13983	hda_nid_t pin;
13984
13985	pin = spec->autocfg.hp_pins[0];
13986	if (pin) /* connect to front and  use dac 0 */
13987		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
13988	pin = spec->autocfg.speaker_pins[0];
13989	if (pin)
13990		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13991}
13992
13993#define alc861vd_is_input_pin(nid)	alc880_is_input_pin(nid)
13994#define ALC861VD_PIN_CD_NID		ALC880_PIN_CD_NID
13995
13996static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
13997{
13998	struct alc_spec *spec = codec->spec;
13999	int i;
14000
14001	for (i = 0; i < AUTO_PIN_LAST; i++) {
14002		hda_nid_t nid = spec->autocfg.input_pins[i];
14003		if (alc861vd_is_input_pin(nid)) {
14004			snd_hda_codec_write(codec, nid, 0,
14005					AC_VERB_SET_PIN_WIDGET_CONTROL,
14006					i <= AUTO_PIN_FRONT_MIC ?
14007							PIN_VREF80 : PIN_IN);
14008			if (nid != ALC861VD_PIN_CD_NID)
14009				snd_hda_codec_write(codec, nid, 0,
14010						AC_VERB_SET_AMP_GAIN_MUTE,
14011						AMP_OUT_MUTE);
14012		}
14013	}
14014}
14015
14016#define alc861vd_auto_init_input_src	alc882_auto_init_input_src
14017
14018#define alc861vd_idx_to_mixer_vol(nid)		((nid) + 0x02)
14019#define alc861vd_idx_to_mixer_switch(nid)	((nid) + 0x0c)
14020
14021/* add playback controls from the parsed DAC table */
14022/* Based on ALC880 version. But ALC861VD has separate,
14023 * different NIDs for mute/unmute switch and volume control */
14024static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14025					     const struct auto_pin_cfg *cfg)
14026{
14027	char name[32];
14028	static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14029	hda_nid_t nid_v, nid_s;
14030	int i, err;
14031
14032	for (i = 0; i < cfg->line_outs; i++) {
14033		if (!spec->multiout.dac_nids[i])
14034			continue;
14035		nid_v = alc861vd_idx_to_mixer_vol(
14036				alc880_dac_to_idx(
14037					spec->multiout.dac_nids[i]));
14038		nid_s = alc861vd_idx_to_mixer_switch(
14039				alc880_dac_to_idx(
14040					spec->multiout.dac_nids[i]));
14041
14042		if (i == 2) {
14043			/* Center/LFE */
14044			err = add_control(spec, ALC_CTL_WIDGET_VOL,
14045					  "Center Playback Volume",
14046					  HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14047							      HDA_OUTPUT));
14048			if (err < 0)
14049				return err;
14050			err = add_control(spec, ALC_CTL_WIDGET_VOL,
14051					  "LFE Playback Volume",
14052					  HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14053							      HDA_OUTPUT));
14054			if (err < 0)
14055				return err;
14056			err = add_control(spec, ALC_CTL_BIND_MUTE,
14057					  "Center Playback Switch",
14058					  HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14059							      HDA_INPUT));
14060			if (err < 0)
14061				return err;
14062			err = add_control(spec, ALC_CTL_BIND_MUTE,
14063					  "LFE Playback Switch",
14064					  HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14065							      HDA_INPUT));
14066			if (err < 0)
14067				return err;
14068		} else {
14069			sprintf(name, "%s Playback Volume", chname[i]);
14070			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14071					  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14072							      HDA_OUTPUT));
14073			if (err < 0)
14074				return err;
14075			sprintf(name, "%s Playback Switch", chname[i]);
14076			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14077					  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
14078							      HDA_INPUT));
14079			if (err < 0)
14080				return err;
14081		}
14082	}
14083	return 0;
14084}
14085
14086/* add playback controls for speaker and HP outputs */
14087/* Based on ALC880 version. But ALC861VD has separate,
14088 * different NIDs for mute/unmute switch and volume control */
14089static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
14090					hda_nid_t pin, const char *pfx)
14091{
14092	hda_nid_t nid_v, nid_s;
14093	int err;
14094	char name[32];
14095
14096	if (!pin)
14097		return 0;
14098
14099	if (alc880_is_fixed_pin(pin)) {
14100		nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14101		/* specify the DAC as the extra output */
14102		if (!spec->multiout.hp_nid)
14103			spec->multiout.hp_nid = nid_v;
14104		else
14105			spec->multiout.extra_out_nid[0] = nid_v;
14106		/* control HP volume/switch on the output mixer amp */
14107		nid_v = alc861vd_idx_to_mixer_vol(
14108				alc880_fixed_pin_idx(pin));
14109		nid_s = alc861vd_idx_to_mixer_switch(
14110				alc880_fixed_pin_idx(pin));
14111
14112		sprintf(name, "%s Playback Volume", pfx);
14113		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14114				  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
14115		if (err < 0)
14116			return err;
14117		sprintf(name, "%s Playback Switch", pfx);
14118		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14119				  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
14120		if (err < 0)
14121			return err;
14122	} else if (alc880_is_multi_pin(pin)) {
14123		/* set manual connection */
14124		/* we have only a switch on HP-out PIN */
14125		sprintf(name, "%s Playback Switch", pfx);
14126		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14127				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
14128		if (err < 0)
14129			return err;
14130	}
14131	return 0;
14132}
14133
14134/* parse the BIOS configuration and set up the alc_spec
14135 * return 1 if successful, 0 if the proper config is not found,
14136 * or a negative error code
14137 * Based on ALC880 version - had to change it to override
14138 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
14139static int alc861vd_parse_auto_config(struct hda_codec *codec)
14140{
14141	struct alc_spec *spec = codec->spec;
14142	int err;
14143	static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
14144
14145	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14146					   alc861vd_ignore);
14147	if (err < 0)
14148		return err;
14149	if (!spec->autocfg.line_outs)
14150		return 0; /* can't find valid BIOS pin config */
14151
14152	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
14153	if (err < 0)
14154		return err;
14155	err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
14156	if (err < 0)
14157		return err;
14158	err = alc861vd_auto_create_extra_out(spec,
14159					     spec->autocfg.speaker_pins[0],
14160					     "Speaker");
14161	if (err < 0)
14162		return err;
14163	err = alc861vd_auto_create_extra_out(spec,
14164					     spec->autocfg.hp_pins[0],
14165					     "Headphone");
14166	if (err < 0)
14167		return err;
14168	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
14169	if (err < 0)
14170		return err;
14171
14172	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14173
14174	if (spec->autocfg.dig_out_pin)
14175		spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
14176
14177	if (spec->kctls.list)
14178		add_mixer(spec, spec->kctls.list);
14179
14180	add_verb(spec, alc861vd_volume_init_verbs);
14181
14182	spec->num_mux_defs = 1;
14183	spec->input_mux = &spec->private_imux;
14184
14185	err = alc_auto_add_mic_boost(codec);
14186	if (err < 0)
14187		return err;
14188
14189	store_pin_configs(codec);
14190	return 1;
14191}
14192
14193/* additional initialization for auto-configuration model */
14194static void alc861vd_auto_init(struct hda_codec *codec)
14195{
14196	struct alc_spec *spec = codec->spec;
14197	alc861vd_auto_init_multi_out(codec);
14198	alc861vd_auto_init_hp_out(codec);
14199	alc861vd_auto_init_analog_input(codec);
14200	alc861vd_auto_init_input_src(codec);
14201	if (spec->unsol_event)
14202		alc_inithook(codec);
14203}
14204
14205static int patch_alc861vd(struct hda_codec *codec)
14206{
14207	struct alc_spec *spec;
14208	int err, board_config;
14209
14210	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14211	if (spec == NULL)
14212		return -ENOMEM;
14213
14214	codec->spec = spec;
14215
14216	board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
14217						  alc861vd_models,
14218						  alc861vd_cfg_tbl);
14219
14220	if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
14221		printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
14222			"ALC861VD, trying auto-probe from BIOS...\n");
14223		board_config = ALC861VD_AUTO;
14224	}
14225
14226	if (board_config == ALC861VD_AUTO) {
14227		/* automatic parse from the BIOS config */
14228		err = alc861vd_parse_auto_config(codec);
14229		if (err < 0) {
14230			alc_free(codec);
14231			return err;
14232		} else if (!err) {
14233			printk(KERN_INFO
14234			       "hda_codec: Cannot set up configuration "
14235			       "from BIOS.  Using base mode...\n");
14236			board_config = ALC861VD_3ST;
14237		}
14238	}
14239
14240	if (board_config != ALC861VD_AUTO)
14241		setup_preset(spec, &alc861vd_presets[board_config]);
14242
14243	if (codec->vendor_id == 0x10ec0660) {
14244		spec->stream_name_analog = "ALC660-VD Analog";
14245		spec->stream_name_digital = "ALC660-VD Digital";
14246		/* always turn on EAPD */
14247		add_verb(spec, alc660vd_eapd_verbs);
14248	} else {
14249		spec->stream_name_analog = "ALC861VD Analog";
14250		spec->stream_name_digital = "ALC861VD Digital";
14251	}
14252
14253	spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
14254	spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
14255
14256	spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
14257	spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
14258
14259	spec->adc_nids = alc861vd_adc_nids;
14260	spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
14261	spec->capsrc_nids = alc861vd_capsrc_nids;
14262	spec->is_mix_capture = 1;
14263
14264	set_capture_mixer(spec);
14265
14266	spec->vmaster_nid = 0x02;
14267
14268	codec->patch_ops = alc_patch_ops;
14269
14270	if (board_config == ALC861VD_AUTO)
14271		spec->init_hook = alc861vd_auto_init;
14272#ifdef CONFIG_SND_HDA_POWER_SAVE
14273	if (!spec->loopback.amplist)
14274		spec->loopback.amplist = alc861vd_loopbacks;
14275#endif
14276
14277	return 0;
14278}
14279
14280/*
14281 * ALC662 support
14282 *
14283 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
14284 * configuration.  Each pin widget can choose any input DACs and a mixer.
14285 * Each ADC is connected from a mixer of all inputs.  This makes possible
14286 * 6-channel independent captures.
14287 *
14288 * In addition, an independent DAC for the multi-playback (not used in this
14289 * driver yet).
14290 */
14291#define ALC662_DIGOUT_NID	0x06
14292#define ALC662_DIGIN_NID	0x0a
14293
14294static hda_nid_t alc662_dac_nids[4] = {
14295	/* front, rear, clfe, rear_surr */
14296	0x02, 0x03, 0x04
14297};
14298
14299static hda_nid_t alc662_adc_nids[1] = {
14300	/* ADC1-2 */
14301	0x09,
14302};
14303
14304static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
14305
14306/* input MUX */
14307/* FIXME: should be a matrix-type input source selection */
14308static struct hda_input_mux alc662_capture_source = {
14309	.num_items = 4,
14310	.items = {
14311		{ "Mic", 0x0 },
14312		{ "Front Mic", 0x1 },
14313		{ "Line", 0x2 },
14314		{ "CD", 0x4 },
14315	},
14316};
14317
14318static struct hda_input_mux alc662_lenovo_101e_capture_source = {
14319	.num_items = 2,
14320	.items = {
14321		{ "Mic", 0x1 },
14322		{ "Line", 0x2 },
14323	},
14324};
14325
14326static struct hda_input_mux alc662_eeepc_capture_source = {
14327	.num_items = 2,
14328	.items = {
14329		{ "i-Mic", 0x1 },
14330		{ "e-Mic", 0x0 },
14331	},
14332};
14333
14334static struct hda_input_mux alc663_capture_source = {
14335	.num_items = 3,
14336	.items = {
14337		{ "Mic", 0x0 },
14338		{ "Front Mic", 0x1 },
14339		{ "Line", 0x2 },
14340	},
14341};
14342
14343static struct hda_input_mux alc663_m51va_capture_source = {
14344	.num_items = 2,
14345	.items = {
14346		{ "Ext-Mic", 0x0 },
14347		{ "D-Mic", 0x9 },
14348	},
14349};
14350
14351/*
14352 * 2ch mode
14353 */
14354static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
14355	{ 2, NULL }
14356};
14357
14358/*
14359 * 2ch mode
14360 */
14361static struct hda_verb alc662_3ST_ch2_init[] = {
14362	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
14363	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14364	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
14365	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14366	{ } /* end */
14367};
14368
14369/*
14370 * 6ch mode
14371 */
14372static struct hda_verb alc662_3ST_ch6_init[] = {
14373	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14374	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14375	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
14376	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14377	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14378	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
14379	{ } /* end */
14380};
14381
14382static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
14383	{ 2, alc662_3ST_ch2_init },
14384	{ 6, alc662_3ST_ch6_init },
14385};
14386
14387/*
14388 * 2ch mode
14389 */
14390static struct hda_verb alc662_sixstack_ch6_init[] = {
14391	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14392	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14393	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14394	{ } /* end */
14395};
14396
14397/*
14398 * 6ch mode
14399 */
14400static struct hda_verb alc662_sixstack_ch8_init[] = {
14401	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14402	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14403	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14404	{ } /* end */
14405};
14406
14407static struct hda_channel_mode alc662_5stack_modes[2] = {
14408	{ 2, alc662_sixstack_ch6_init },
14409	{ 6, alc662_sixstack_ch8_init },
14410};
14411
14412/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14413 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14414 */
14415
14416static struct snd_kcontrol_new alc662_base_mixer[] = {
14417	/* output mixer control */
14418	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
14419	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14420	HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
14421	HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14422	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14423	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14424	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14425	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14426	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14427
14428	/*Input mixer control */
14429	HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
14430	HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
14431	HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
14432	HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
14433	HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
14434	HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
14435	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
14436	HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
14437	{ } /* end */
14438};
14439
14440static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
14441	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14442	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14443	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14444	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14445	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14446	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14447	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14448	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14449	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14450	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14451	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14452	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14453	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14454	{ } /* end */
14455};
14456
14457static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
14458	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14459	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14460	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14461	HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14462	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14463	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14464	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14465	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14466	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14467	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14468	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14469	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14470	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14471	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14472	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14473	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14474	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14475	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14476	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14477	{ } /* end */
14478};
14479
14480static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
14481	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14482	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
14483	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14484	HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
14485	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14486	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14487	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14488	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14489	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14490	{ } /* end */
14491};
14492
14493static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
14494	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14495
14496	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14497	HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14498
14499	HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
14500	HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14501	HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14502
14503	HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
14504	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14505	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14506	{ } /* end */
14507};
14508
14509static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
14510	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14511	HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14512	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14513	HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
14514	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14515	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14516	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
14517	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
14518	HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14519	HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, 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	{ } /* end */
14525};
14526
14527static struct hda_bind_ctls alc663_asus_bind_master_vol = {
14528	.ops = &snd_hda_bind_vol,
14529	.values = {
14530		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14531		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
14532		0
14533	},
14534};
14535
14536static struct hda_bind_ctls alc663_asus_one_bind_switch = {
14537	.ops = &snd_hda_bind_sw,
14538	.values = {
14539		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14540		HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14541		0
14542	},
14543};
14544
14545static struct snd_kcontrol_new alc663_m51va_mixer[] = {
14546	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14547	HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
14548	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14549	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14550	{ } /* end */
14551};
14552
14553static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
14554	.ops = &snd_hda_bind_sw,
14555	.values = {
14556		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14557		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14558		HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14559		0
14560	},
14561};
14562
14563static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
14564	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14565	HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
14566	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14567	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14568	HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14569	HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14570
14571	{ } /* end */
14572};
14573
14574static struct hda_bind_ctls alc663_asus_four_bind_switch = {
14575	.ops = &snd_hda_bind_sw,
14576	.values = {
14577		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14578		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14579		HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
14580		0
14581	},
14582};
14583
14584static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
14585	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14586	HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
14587	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14588	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14589	HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14590	HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14591	{ } /* end */
14592};
14593
14594static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
14595	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14596	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14597	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14598	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14599	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14600	HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14601	HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14602	{ } /* end */
14603};
14604
14605static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
14606	.ops = &snd_hda_bind_vol,
14607	.values = {
14608		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14609		HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
14610		0
14611	},
14612};
14613
14614static struct hda_bind_ctls alc663_asus_two_bind_switch = {
14615	.ops = &snd_hda_bind_sw,
14616	.values = {
14617		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14618		HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
14619		0
14620	},
14621};
14622
14623static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
14624	HDA_BIND_VOL("Master Playback Volume",
14625				&alc663_asus_two_bind_master_vol),
14626	HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14627	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14628	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14629	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14630	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14631	{ } /* end */
14632};
14633
14634static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
14635	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14636	HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14637	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14638	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14639	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14640	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14641	{ } /* end */
14642};
14643
14644static struct snd_kcontrol_new alc663_g71v_mixer[] = {
14645	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14646	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14647	HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14648	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14649	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14650
14651	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14652	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14653	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14654	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14655	{ } /* end */
14656};
14657
14658static struct snd_kcontrol_new alc663_g50v_mixer[] = {
14659	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14660	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14661	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14662
14663	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14664	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14665	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14666	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14667	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14668	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14669	{ } /* end */
14670};
14671
14672static struct snd_kcontrol_new alc662_chmode_mixer[] = {
14673	{
14674		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14675		.name = "Channel Mode",
14676		.info = alc_ch_mode_info,
14677		.get = alc_ch_mode_get,
14678		.put = alc_ch_mode_put,
14679	},
14680	{ } /* end */
14681};
14682
14683static struct hda_verb alc662_init_verbs[] = {
14684	/* ADC: mute amp left and right */
14685	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14686	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14687	/* Front mixer: unmute input/output amp left and right (volume = 0) */
14688
14689	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14690	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14691	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14692	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14693	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14694
14695	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14696	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14697	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14698	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14699	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14700	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14701
14702	/* Front Pin: output 0 (0x0c) */
14703	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14704	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14705
14706	/* Rear Pin: output 1 (0x0d) */
14707	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14708	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14709
14710	/* CLFE Pin: output 2 (0x0e) */
14711	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14712	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14713
14714	/* Mic (rear) pin: input vref at 80% */
14715	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14716	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14717	/* Front Mic pin: input vref at 80% */
14718	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14719	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14720	/* Line In pin: input */
14721	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14722	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14723	/* Line-2 In: Headphone output (output 0 - 0x0c) */
14724	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14725	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14726	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14727	/* CD pin widget for input */
14728	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14729
14730	/* FIXME: use matrix-type input source selection */
14731	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
14732	/* Input mixer */
14733	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14734	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14735	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14736	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14737
14738	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14739	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14740	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14741	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14742
14743	/* always trun on EAPD */
14744	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14745	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14746
14747	{ }
14748};
14749
14750static struct hda_verb alc662_sue_init_verbs[] = {
14751	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
14752	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
14753	{}
14754};
14755
14756static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
14757	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14758	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14759	{}
14760};
14761
14762/* Set Unsolicited Event*/
14763static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
14764	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14765	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14766	{}
14767};
14768
14769/*
14770 * generic initialization of ADC, input mixers and output mixers
14771 */
14772static struct hda_verb alc662_auto_init_verbs[] = {
14773	/*
14774	 * Unmute ADC and set the default input to mic-in
14775	 */
14776	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14777	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14778
14779	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
14780	 * mixer widget
14781	 * Note: PASD motherboards uses the Line In 2 as the input for front
14782	 * panel mic (mic 2)
14783	 */
14784	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14785	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14786	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14787	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14788	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14789	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14790
14791	/*
14792	 * Set up output mixers (0x0c - 0x0f)
14793	 */
14794	/* set vol=0 to output mixers */
14795	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14796	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14797	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14798
14799	/* set up input amps for analog loopback */
14800	/* Amp Indices: DAC = 0, mixer = 1 */
14801	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14802	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14803	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14804	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14805	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14806	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14807
14808
14809	/* FIXME: use matrix-type input source selection */
14810	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
14811	/* Input mixer */
14812	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14813	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14814	{ }
14815};
14816
14817/* additional verbs for ALC663 */
14818static struct hda_verb alc663_auto_init_verbs[] = {
14819	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14820	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14821	{ }
14822};
14823
14824static struct hda_verb alc663_m51va_init_verbs[] = {
14825	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14826	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14827	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14828	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14829	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
14830	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14831	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
14832	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14833	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14834	{}
14835};
14836
14837static struct hda_verb alc663_21jd_amic_init_verbs[] = {
14838	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14839	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14840	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
14841	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14842	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14843	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14844	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14845	{}
14846};
14847
14848static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
14849	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14850	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14851	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14852	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
14853	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14854	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14855	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14856	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14857	{}
14858};
14859
14860static struct hda_verb alc663_15jd_amic_init_verbs[] = {
14861	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14862	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14863	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
14864	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14865	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14866	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14867	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14868	{}
14869};
14870
14871static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
14872	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14873	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14874	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14875	{0x21, AC_VERB_SET_CONNECT_SEL, 0x0},	/* Headphone */
14876	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14877	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14878	{0x15, AC_VERB_SET_CONNECT_SEL, 0x0},	/* Headphone */
14879	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14880	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14881	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14882	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14883	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14884	{}
14885};
14886
14887static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
14888	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14889	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14890	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14891	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
14892	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14893	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14894	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
14895	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14896	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14897	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14898	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14899	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14900	{}
14901};
14902
14903static struct hda_verb alc663_g71v_init_verbs[] = {
14904	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14905	/* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
14906	/* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
14907
14908	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14909	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14910	{0x21, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
14911
14912	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
14913	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
14914	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
14915	{}
14916};
14917
14918static struct hda_verb alc663_g50v_init_verbs[] = {
14919	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14920	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14921	{0x21, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
14922
14923	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14924	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14925	{}
14926};
14927
14928static struct hda_verb alc662_ecs_init_verbs[] = {
14929	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
14930	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14931	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14932	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14933	{}
14934};
14935
14936static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
14937	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14938	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14939	{ } /* end */
14940};
14941
14942static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
14943{
14944	unsigned int present;
14945	unsigned char bits;
14946
14947	present = snd_hda_codec_read(codec, 0x14, 0,
14948				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14949	bits = present ? HDA_AMP_MUTE : 0;
14950	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
14951				 HDA_AMP_MUTE, bits);
14952}
14953
14954static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
14955{
14956	unsigned int present;
14957	unsigned char bits;
14958
14959 	present = snd_hda_codec_read(codec, 0x1b, 0,
14960				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14961	bits = present ? HDA_AMP_MUTE : 0;
14962	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
14963				 HDA_AMP_MUTE, bits);
14964	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14965				 HDA_AMP_MUTE, bits);
14966}
14967
14968static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
14969					   unsigned int res)
14970{
14971	if ((res >> 26) == ALC880_HP_EVENT)
14972		alc662_lenovo_101e_all_automute(codec);
14973	if ((res >> 26) == ALC880_FRONT_EVENT)
14974		alc662_lenovo_101e_ispeaker_automute(codec);
14975}
14976
14977static void alc662_eeepc_mic_automute(struct hda_codec *codec)
14978{
14979	unsigned int present;
14980
14981	present = snd_hda_codec_read(codec, 0x18, 0,
14982				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14983	snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14984			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
14985	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14986			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
14987	snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14988			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
14989	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14990			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
14991}
14992
14993/* unsolicited event for HP jack sensing */
14994static void alc662_eeepc_unsol_event(struct hda_codec *codec,
14995				     unsigned int res)
14996{
14997	if ((res >> 26) == ALC880_HP_EVENT)
14998		alc262_hippo1_automute( codec );
14999
15000	if ((res >> 26) == ALC880_MIC_EVENT)
15001		alc662_eeepc_mic_automute(codec);
15002}
15003
15004static void alc662_eeepc_inithook(struct hda_codec *codec)
15005{
15006	alc262_hippo1_automute( codec );
15007	alc662_eeepc_mic_automute(codec);
15008}
15009
15010static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
15011{
15012	unsigned int mute;
15013	unsigned int present;
15014
15015	snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
15016	present = snd_hda_codec_read(codec, 0x14, 0,
15017				     AC_VERB_GET_PIN_SENSE, 0);
15018	present = (present & 0x80000000) != 0;
15019	if (present) {
15020		/* mute internal speaker */
15021		snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15022					HDA_AMP_MUTE, HDA_AMP_MUTE);
15023	} else {
15024		/* unmute internal speaker if necessary */
15025		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
15026		snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15027					HDA_AMP_MUTE, mute);
15028	}
15029}
15030
15031/* unsolicited event for HP jack sensing */
15032static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
15033					  unsigned int res)
15034{
15035	if ((res >> 26) == ALC880_HP_EVENT)
15036		alc662_eeepc_ep20_automute(codec);
15037}
15038
15039static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
15040{
15041	alc662_eeepc_ep20_automute(codec);
15042}
15043
15044static void alc663_m51va_speaker_automute(struct hda_codec *codec)
15045{
15046	unsigned int present;
15047	unsigned char bits;
15048
15049	present = snd_hda_codec_read(codec, 0x21, 0,
15050			AC_VERB_GET_PIN_SENSE, 0)
15051			& AC_PINSENSE_PRESENCE;
15052	bits = present ? HDA_AMP_MUTE : 0;
15053	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15054				AMP_IN_MUTE(0), bits);
15055	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15056				AMP_IN_MUTE(0), bits);
15057}
15058
15059static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
15060{
15061	unsigned int present;
15062	unsigned char bits;
15063
15064	present = snd_hda_codec_read(codec, 0x21, 0,
15065			AC_VERB_GET_PIN_SENSE, 0)
15066			& AC_PINSENSE_PRESENCE;
15067	bits = present ? HDA_AMP_MUTE : 0;
15068	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15069				AMP_IN_MUTE(0), bits);
15070	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15071				AMP_IN_MUTE(0), bits);
15072	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15073				AMP_IN_MUTE(0), bits);
15074	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15075				AMP_IN_MUTE(0), bits);
15076}
15077
15078static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
15079{
15080	unsigned int present;
15081	unsigned char bits;
15082
15083	present = snd_hda_codec_read(codec, 0x15, 0,
15084			AC_VERB_GET_PIN_SENSE, 0)
15085			& AC_PINSENSE_PRESENCE;
15086	bits = present ? HDA_AMP_MUTE : 0;
15087	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15088				AMP_IN_MUTE(0), bits);
15089	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15090				AMP_IN_MUTE(0), bits);
15091	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15092				AMP_IN_MUTE(0), bits);
15093	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15094				AMP_IN_MUTE(0), bits);
15095}
15096
15097static void alc662_f5z_speaker_automute(struct hda_codec *codec)
15098{
15099	unsigned int present;
15100	unsigned char bits;
15101
15102	present = snd_hda_codec_read(codec, 0x1b, 0,
15103			AC_VERB_GET_PIN_SENSE, 0)
15104			& AC_PINSENSE_PRESENCE;
15105	bits = present ? 0 : PIN_OUT;
15106	snd_hda_codec_write(codec, 0x14, 0,
15107			 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
15108}
15109
15110static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
15111{
15112	unsigned int present1, present2;
15113
15114	present1 = snd_hda_codec_read(codec, 0x21, 0,
15115			AC_VERB_GET_PIN_SENSE, 0)
15116			& AC_PINSENSE_PRESENCE;
15117	present2 = snd_hda_codec_read(codec, 0x15, 0,
15118			AC_VERB_GET_PIN_SENSE, 0)
15119			& AC_PINSENSE_PRESENCE;
15120
15121	if (present1 || present2) {
15122		snd_hda_codec_write_cache(codec, 0x14, 0,
15123			AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
15124	} else {
15125		snd_hda_codec_write_cache(codec, 0x14, 0,
15126			AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
15127	}
15128}
15129
15130static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
15131{
15132	unsigned int present1, present2;
15133
15134	present1 = snd_hda_codec_read(codec, 0x1b, 0,
15135				AC_VERB_GET_PIN_SENSE, 0)
15136				& AC_PINSENSE_PRESENCE;
15137	present2 = snd_hda_codec_read(codec, 0x15, 0,
15138				AC_VERB_GET_PIN_SENSE, 0)
15139				& AC_PINSENSE_PRESENCE;
15140
15141	if (present1 || present2) {
15142		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15143				AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15144		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15145				AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15146	} else {
15147		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15148				AMP_IN_MUTE(0), 0);
15149		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15150				AMP_IN_MUTE(0), 0);
15151	}
15152}
15153
15154static void alc663_m51va_mic_automute(struct hda_codec *codec)
15155{
15156	unsigned int present;
15157
15158	present = snd_hda_codec_read(codec, 0x18, 0,
15159			AC_VERB_GET_PIN_SENSE, 0)
15160			& AC_PINSENSE_PRESENCE;
15161	snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15162			0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15163	snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15164			0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15165	snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15166			0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15167	snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15168			0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15169}
15170
15171static void alc663_m51va_unsol_event(struct hda_codec *codec,
15172					   unsigned int res)
15173{
15174	switch (res >> 26) {
15175	case ALC880_HP_EVENT:
15176		alc663_m51va_speaker_automute(codec);
15177		break;
15178	case ALC880_MIC_EVENT:
15179		alc663_m51va_mic_automute(codec);
15180		break;
15181	}
15182}
15183
15184static void alc663_m51va_inithook(struct hda_codec *codec)
15185{
15186	alc663_m51va_speaker_automute(codec);
15187	alc663_m51va_mic_automute(codec);
15188}
15189
15190/* ***************** Mode1 ******************************/
15191static void alc663_mode1_unsol_event(struct hda_codec *codec,
15192					   unsigned int res)
15193{
15194	switch (res >> 26) {
15195	case ALC880_HP_EVENT:
15196		alc663_m51va_speaker_automute(codec);
15197		break;
15198	case ALC880_MIC_EVENT:
15199		alc662_eeepc_mic_automute(codec);
15200		break;
15201	}
15202}
15203
15204static void alc663_mode1_inithook(struct hda_codec *codec)
15205{
15206	alc663_m51va_speaker_automute(codec);
15207	alc662_eeepc_mic_automute(codec);
15208}
15209/* ***************** Mode2 ******************************/
15210static void alc662_mode2_unsol_event(struct hda_codec *codec,
15211					   unsigned int res)
15212{
15213	switch (res >> 26) {
15214	case ALC880_HP_EVENT:
15215		alc662_f5z_speaker_automute(codec);
15216		break;
15217	case ALC880_MIC_EVENT:
15218		alc662_eeepc_mic_automute(codec);
15219		break;
15220	}
15221}
15222
15223static void alc662_mode2_inithook(struct hda_codec *codec)
15224{
15225	alc662_f5z_speaker_automute(codec);
15226	alc662_eeepc_mic_automute(codec);
15227}
15228/* ***************** Mode3 ******************************/
15229static void alc663_mode3_unsol_event(struct hda_codec *codec,
15230					   unsigned int res)
15231{
15232	switch (res >> 26) {
15233	case ALC880_HP_EVENT:
15234		alc663_two_hp_m1_speaker_automute(codec);
15235		break;
15236	case ALC880_MIC_EVENT:
15237		alc662_eeepc_mic_automute(codec);
15238		break;
15239	}
15240}
15241
15242static void alc663_mode3_inithook(struct hda_codec *codec)
15243{
15244	alc663_two_hp_m1_speaker_automute(codec);
15245	alc662_eeepc_mic_automute(codec);
15246}
15247/* ***************** Mode4 ******************************/
15248static void alc663_mode4_unsol_event(struct hda_codec *codec,
15249					   unsigned int res)
15250{
15251	switch (res >> 26) {
15252	case ALC880_HP_EVENT:
15253		alc663_21jd_two_speaker_automute(codec);
15254		break;
15255	case ALC880_MIC_EVENT:
15256		alc662_eeepc_mic_automute(codec);
15257		break;
15258	}
15259}
15260
15261static void alc663_mode4_inithook(struct hda_codec *codec)
15262{
15263	alc663_21jd_two_speaker_automute(codec);
15264	alc662_eeepc_mic_automute(codec);
15265}
15266/* ***************** Mode5 ******************************/
15267static void alc663_mode5_unsol_event(struct hda_codec *codec,
15268					   unsigned int res)
15269{
15270	switch (res >> 26) {
15271	case ALC880_HP_EVENT:
15272		alc663_15jd_two_speaker_automute(codec);
15273		break;
15274	case ALC880_MIC_EVENT:
15275		alc662_eeepc_mic_automute(codec);
15276		break;
15277	}
15278}
15279
15280static void alc663_mode5_inithook(struct hda_codec *codec)
15281{
15282	alc663_15jd_two_speaker_automute(codec);
15283	alc662_eeepc_mic_automute(codec);
15284}
15285/* ***************** Mode6 ******************************/
15286static void alc663_mode6_unsol_event(struct hda_codec *codec,
15287					   unsigned int res)
15288{
15289	switch (res >> 26) {
15290	case ALC880_HP_EVENT:
15291		alc663_two_hp_m2_speaker_automute(codec);
15292		break;
15293	case ALC880_MIC_EVENT:
15294		alc662_eeepc_mic_automute(codec);
15295		break;
15296	}
15297}
15298
15299static void alc663_mode6_inithook(struct hda_codec *codec)
15300{
15301	alc663_two_hp_m2_speaker_automute(codec);
15302	alc662_eeepc_mic_automute(codec);
15303}
15304
15305static void alc663_g71v_hp_automute(struct hda_codec *codec)
15306{
15307	unsigned int present;
15308	unsigned char bits;
15309
15310	present = snd_hda_codec_read(codec, 0x21, 0,
15311				     AC_VERB_GET_PIN_SENSE, 0)
15312		& AC_PINSENSE_PRESENCE;
15313	bits = present ? HDA_AMP_MUTE : 0;
15314	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15315				 HDA_AMP_MUTE, bits);
15316	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15317				 HDA_AMP_MUTE, bits);
15318}
15319
15320static void alc663_g71v_front_automute(struct hda_codec *codec)
15321{
15322	unsigned int present;
15323	unsigned char bits;
15324
15325	present = snd_hda_codec_read(codec, 0x15, 0,
15326				     AC_VERB_GET_PIN_SENSE, 0)
15327		& AC_PINSENSE_PRESENCE;
15328	bits = present ? HDA_AMP_MUTE : 0;
15329	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15330				 HDA_AMP_MUTE, bits);
15331}
15332
15333static void alc663_g71v_unsol_event(struct hda_codec *codec,
15334					   unsigned int res)
15335{
15336	switch (res >> 26) {
15337	case ALC880_HP_EVENT:
15338		alc663_g71v_hp_automute(codec);
15339		break;
15340	case ALC880_FRONT_EVENT:
15341		alc663_g71v_front_automute(codec);
15342		break;
15343	case ALC880_MIC_EVENT:
15344		alc662_eeepc_mic_automute(codec);
15345		break;
15346	}
15347}
15348
15349static void alc663_g71v_inithook(struct hda_codec *codec)
15350{
15351	alc663_g71v_front_automute(codec);
15352	alc663_g71v_hp_automute(codec);
15353	alc662_eeepc_mic_automute(codec);
15354}
15355
15356static void alc663_g50v_unsol_event(struct hda_codec *codec,
15357					   unsigned int res)
15358{
15359	switch (res >> 26) {
15360	case ALC880_HP_EVENT:
15361		alc663_m51va_speaker_automute(codec);
15362		break;
15363	case ALC880_MIC_EVENT:
15364		alc662_eeepc_mic_automute(codec);
15365		break;
15366	}
15367}
15368
15369static void alc663_g50v_inithook(struct hda_codec *codec)
15370{
15371	alc663_m51va_speaker_automute(codec);
15372	alc662_eeepc_mic_automute(codec);
15373}
15374
15375/* bind hp and internal speaker mute (with plug check) */
15376static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol,
15377				     struct snd_ctl_elem_value *ucontrol)
15378{
15379	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
15380	long *valp = ucontrol->value.integer.value;
15381	int change;
15382
15383	change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
15384					  HDA_AMP_MUTE,
15385					  valp[0] ? 0 : HDA_AMP_MUTE);
15386	change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
15387					   HDA_AMP_MUTE,
15388					   valp[1] ? 0 : HDA_AMP_MUTE);
15389	if (change)
15390		alc262_hippo1_automute(codec);
15391	return change;
15392}
15393
15394static struct snd_kcontrol_new alc662_ecs_mixer[] = {
15395	HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15396	{
15397		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15398		.name = "Master Playback Switch",
15399		.info = snd_hda_mixer_amp_switch_info,
15400		.get = snd_hda_mixer_amp_switch_get,
15401		.put = alc662_ecs_master_sw_put,
15402		.private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15403	},
15404
15405	HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
15406	HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
15407	HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
15408
15409	HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15410	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15411	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15412	{ } /* end */
15413};
15414
15415#ifdef CONFIG_SND_HDA_POWER_SAVE
15416#define alc662_loopbacks	alc880_loopbacks
15417#endif
15418
15419
15420/* pcm configuration: identiacal with ALC880 */
15421#define alc662_pcm_analog_playback	alc880_pcm_analog_playback
15422#define alc662_pcm_analog_capture	alc880_pcm_analog_capture
15423#define alc662_pcm_digital_playback	alc880_pcm_digital_playback
15424#define alc662_pcm_digital_capture	alc880_pcm_digital_capture
15425
15426/*
15427 * configuration and preset
15428 */
15429static const char *alc662_models[ALC662_MODEL_LAST] = {
15430	[ALC662_3ST_2ch_DIG]	= "3stack-dig",
15431	[ALC662_3ST_6ch_DIG]	= "3stack-6ch-dig",
15432	[ALC662_3ST_6ch]	= "3stack-6ch",
15433	[ALC662_5ST_DIG]	= "6stack-dig",
15434	[ALC662_LENOVO_101E]	= "lenovo-101e",
15435	[ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
15436	[ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
15437	[ALC662_ECS] = "ecs",
15438	[ALC663_ASUS_M51VA] = "m51va",
15439	[ALC663_ASUS_G71V] = "g71v",
15440	[ALC663_ASUS_H13] = "h13",
15441	[ALC663_ASUS_G50V] = "g50v",
15442	[ALC663_ASUS_MODE1] = "asus-mode1",
15443	[ALC662_ASUS_MODE2] = "asus-mode2",
15444	[ALC663_ASUS_MODE3] = "asus-mode3",
15445	[ALC663_ASUS_MODE4] = "asus-mode4",
15446	[ALC663_ASUS_MODE5] = "asus-mode5",
15447	[ALC663_ASUS_MODE6] = "asus-mode6",
15448	[ALC662_AUTO]		= "auto",
15449};
15450
15451static struct snd_pci_quirk alc662_cfg_tbl[] = {
15452	SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
15453	SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
15454	SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
15455	SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
15456	SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
15457	SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
15458	SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),
15459	SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
15460	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
15461	SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
15462	SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),
15463	SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
15464	SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
15465	SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
15466	SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
15467	SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
15468	SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
15469	SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
15470	SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
15471	SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
15472	SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
15473	SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
15474	SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
15475	SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
15476	SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
15477	SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
15478	SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
15479	SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
15480	SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
15481	SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
15482	SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
15483	SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
15484	SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
15485	SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
15486	SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
15487	SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
15488	SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
15489	SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
15490		      ALC662_3ST_6ch_DIG),
15491	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
15492	SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
15493	SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
15494	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
15495		      ALC662_3ST_6ch_DIG),
15496	SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
15497	SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
15498					ALC662_3ST_6ch_DIG),
15499	SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13),
15500	SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13),
15501	SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13),
15502	{}
15503};
15504
15505static struct alc_config_preset alc662_presets[] = {
15506	[ALC662_3ST_2ch_DIG] = {
15507		.mixers = { alc662_3ST_2ch_mixer },
15508		.init_verbs = { alc662_init_verbs },
15509		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15510		.dac_nids = alc662_dac_nids,
15511		.dig_out_nid = ALC662_DIGOUT_NID,
15512		.dig_in_nid = ALC662_DIGIN_NID,
15513		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15514		.channel_mode = alc662_3ST_2ch_modes,
15515		.input_mux = &alc662_capture_source,
15516	},
15517	[ALC662_3ST_6ch_DIG] = {
15518		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
15519		.init_verbs = { alc662_init_verbs },
15520		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15521		.dac_nids = alc662_dac_nids,
15522		.dig_out_nid = ALC662_DIGOUT_NID,
15523		.dig_in_nid = ALC662_DIGIN_NID,
15524		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15525		.channel_mode = alc662_3ST_6ch_modes,
15526		.need_dac_fix = 1,
15527		.input_mux = &alc662_capture_source,
15528	},
15529	[ALC662_3ST_6ch] = {
15530		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
15531		.init_verbs = { alc662_init_verbs },
15532		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15533		.dac_nids = alc662_dac_nids,
15534		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15535		.channel_mode = alc662_3ST_6ch_modes,
15536		.need_dac_fix = 1,
15537		.input_mux = &alc662_capture_source,
15538	},
15539	[ALC662_5ST_DIG] = {
15540		.mixers = { alc662_base_mixer, alc662_chmode_mixer },
15541		.init_verbs = { alc662_init_verbs },
15542		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15543		.dac_nids = alc662_dac_nids,
15544		.dig_out_nid = ALC662_DIGOUT_NID,
15545		.dig_in_nid = ALC662_DIGIN_NID,
15546		.num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
15547		.channel_mode = alc662_5stack_modes,
15548		.input_mux = &alc662_capture_source,
15549	},
15550	[ALC662_LENOVO_101E] = {
15551		.mixers = { alc662_lenovo_101e_mixer },
15552		.init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
15553		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15554		.dac_nids = alc662_dac_nids,
15555		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15556		.channel_mode = alc662_3ST_2ch_modes,
15557		.input_mux = &alc662_lenovo_101e_capture_source,
15558		.unsol_event = alc662_lenovo_101e_unsol_event,
15559		.init_hook = alc662_lenovo_101e_all_automute,
15560	},
15561	[ALC662_ASUS_EEEPC_P701] = {
15562		.mixers = { alc662_eeepc_p701_mixer },
15563		.init_verbs = { alc662_init_verbs,
15564				alc662_eeepc_sue_init_verbs },
15565		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15566		.dac_nids = alc662_dac_nids,
15567		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15568		.channel_mode = alc662_3ST_2ch_modes,
15569		.input_mux = &alc662_eeepc_capture_source,
15570		.unsol_event = alc662_eeepc_unsol_event,
15571		.init_hook = alc662_eeepc_inithook,
15572	},
15573	[ALC662_ASUS_EEEPC_EP20] = {
15574		.mixers = { alc662_eeepc_ep20_mixer,
15575			    alc662_chmode_mixer },
15576		.init_verbs = { alc662_init_verbs,
15577				alc662_eeepc_ep20_sue_init_verbs },
15578		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15579		.dac_nids = alc662_dac_nids,
15580		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15581		.channel_mode = alc662_3ST_6ch_modes,
15582		.input_mux = &alc662_lenovo_101e_capture_source,
15583		.unsol_event = alc662_eeepc_ep20_unsol_event,
15584		.init_hook = alc662_eeepc_ep20_inithook,
15585	},
15586	[ALC662_ECS] = {
15587		.mixers = { alc662_ecs_mixer },
15588		.init_verbs = { alc662_init_verbs,
15589				alc662_ecs_init_verbs },
15590		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15591		.dac_nids = alc662_dac_nids,
15592		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15593		.channel_mode = alc662_3ST_2ch_modes,
15594		.input_mux = &alc662_eeepc_capture_source,
15595		.unsol_event = alc662_eeepc_unsol_event,
15596		.init_hook = alc662_eeepc_inithook,
15597	},
15598	[ALC663_ASUS_M51VA] = {
15599		.mixers = { alc663_m51va_mixer },
15600		.init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15601		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15602		.dac_nids = alc662_dac_nids,
15603		.dig_out_nid = ALC662_DIGOUT_NID,
15604		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15605		.channel_mode = alc662_3ST_2ch_modes,
15606		.input_mux = &alc663_m51va_capture_source,
15607		.unsol_event = alc663_m51va_unsol_event,
15608		.init_hook = alc663_m51va_inithook,
15609	},
15610	[ALC663_ASUS_G71V] = {
15611		.mixers = { alc663_g71v_mixer },
15612		.init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
15613		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15614		.dac_nids = alc662_dac_nids,
15615		.dig_out_nid = ALC662_DIGOUT_NID,
15616		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15617		.channel_mode = alc662_3ST_2ch_modes,
15618		.input_mux = &alc662_eeepc_capture_source,
15619		.unsol_event = alc663_g71v_unsol_event,
15620		.init_hook = alc663_g71v_inithook,
15621	},
15622	[ALC663_ASUS_H13] = {
15623		.mixers = { alc663_m51va_mixer },
15624		.init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15625		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15626		.dac_nids = alc662_dac_nids,
15627		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15628		.channel_mode = alc662_3ST_2ch_modes,
15629		.input_mux = &alc663_m51va_capture_source,
15630		.unsol_event = alc663_m51va_unsol_event,
15631		.init_hook = alc663_m51va_inithook,
15632	},
15633	[ALC663_ASUS_G50V] = {
15634		.mixers = { alc663_g50v_mixer },
15635		.init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
15636		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15637		.dac_nids = alc662_dac_nids,
15638		.dig_out_nid = ALC662_DIGOUT_NID,
15639		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15640		.channel_mode = alc662_3ST_6ch_modes,
15641		.input_mux = &alc663_capture_source,
15642		.unsol_event = alc663_g50v_unsol_event,
15643		.init_hook = alc663_g50v_inithook,
15644	},
15645	[ALC663_ASUS_MODE1] = {
15646		.mixers = { alc663_m51va_mixer },
15647		.cap_mixer = alc662_auto_capture_mixer,
15648		.init_verbs = { alc662_init_verbs,
15649				alc663_21jd_amic_init_verbs },
15650		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15651		.hp_nid = 0x03,
15652		.dac_nids = alc662_dac_nids,
15653		.dig_out_nid = ALC662_DIGOUT_NID,
15654		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15655		.channel_mode = alc662_3ST_2ch_modes,
15656		.input_mux = &alc662_eeepc_capture_source,
15657		.unsol_event = alc663_mode1_unsol_event,
15658		.init_hook = alc663_mode1_inithook,
15659	},
15660	[ALC662_ASUS_MODE2] = {
15661		.mixers = { alc662_1bjd_mixer },
15662		.cap_mixer = alc662_auto_capture_mixer,
15663		.init_verbs = { alc662_init_verbs,
15664				alc662_1bjd_amic_init_verbs },
15665		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15666		.dac_nids = alc662_dac_nids,
15667		.dig_out_nid = ALC662_DIGOUT_NID,
15668		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15669		.channel_mode = alc662_3ST_2ch_modes,
15670		.input_mux = &alc662_eeepc_capture_source,
15671		.unsol_event = alc662_mode2_unsol_event,
15672		.init_hook = alc662_mode2_inithook,
15673	},
15674	[ALC663_ASUS_MODE3] = {
15675		.mixers = { alc663_two_hp_m1_mixer },
15676		.cap_mixer = alc662_auto_capture_mixer,
15677		.init_verbs = { alc662_init_verbs,
15678				alc663_two_hp_amic_m1_init_verbs },
15679		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15680		.hp_nid = 0x03,
15681		.dac_nids = alc662_dac_nids,
15682		.dig_out_nid = ALC662_DIGOUT_NID,
15683		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15684		.channel_mode = alc662_3ST_2ch_modes,
15685		.input_mux = &alc662_eeepc_capture_source,
15686		.unsol_event = alc663_mode3_unsol_event,
15687		.init_hook = alc663_mode3_inithook,
15688	},
15689	[ALC663_ASUS_MODE4] = {
15690		.mixers = { alc663_asus_21jd_clfe_mixer },
15691		.cap_mixer = alc662_auto_capture_mixer,
15692		.init_verbs = { alc662_init_verbs,
15693				alc663_21jd_amic_init_verbs},
15694		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15695		.hp_nid = 0x03,
15696		.dac_nids = alc662_dac_nids,
15697		.dig_out_nid = ALC662_DIGOUT_NID,
15698		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15699		.channel_mode = alc662_3ST_2ch_modes,
15700		.input_mux = &alc662_eeepc_capture_source,
15701		.unsol_event = alc663_mode4_unsol_event,
15702		.init_hook = alc663_mode4_inithook,
15703	},
15704	[ALC663_ASUS_MODE5] = {
15705		.mixers = { alc663_asus_15jd_clfe_mixer },
15706		.cap_mixer = alc662_auto_capture_mixer,
15707		.init_verbs = { alc662_init_verbs,
15708				alc663_15jd_amic_init_verbs },
15709		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15710		.hp_nid = 0x03,
15711		.dac_nids = alc662_dac_nids,
15712		.dig_out_nid = ALC662_DIGOUT_NID,
15713		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15714		.channel_mode = alc662_3ST_2ch_modes,
15715		.input_mux = &alc662_eeepc_capture_source,
15716		.unsol_event = alc663_mode5_unsol_event,
15717		.init_hook = alc663_mode5_inithook,
15718	},
15719	[ALC663_ASUS_MODE6] = {
15720		.mixers = { alc663_two_hp_m2_mixer },
15721		.cap_mixer = alc662_auto_capture_mixer,
15722		.init_verbs = { alc662_init_verbs,
15723				alc663_two_hp_amic_m2_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_mode6_unsol_event,
15732		.init_hook = alc663_mode6_inithook,
15733	},
15734};
15735
15736
15737/*
15738 * BIOS auto configuration
15739 */
15740
15741/* add playback controls from the parsed DAC table */
15742static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
15743					     const struct auto_pin_cfg *cfg)
15744{
15745	char name[32];
15746	static const char *chname[4] = {
15747		"Front", "Surround", NULL /*CLFE*/, "Side"
15748	};
15749	hda_nid_t nid;
15750	int i, err;
15751
15752	for (i = 0; i < cfg->line_outs; i++) {
15753		if (!spec->multiout.dac_nids[i])
15754			continue;
15755		nid = alc880_idx_to_dac(i);
15756		if (i == 2) {
15757			/* Center/LFE */
15758			err = add_control(spec, ALC_CTL_WIDGET_VOL,
15759					  "Center Playback Volume",
15760					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
15761							      HDA_OUTPUT));
15762			if (err < 0)
15763				return err;
15764			err = add_control(spec, ALC_CTL_WIDGET_VOL,
15765					  "LFE Playback Volume",
15766					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
15767							      HDA_OUTPUT));
15768			if (err < 0)
15769				return err;
15770			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
15771					  "Center Playback Switch",
15772					  HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
15773							      HDA_INPUT));
15774			if (err < 0)
15775				return err;
15776			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
15777					  "LFE Playback Switch",
15778					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
15779							      HDA_INPUT));
15780			if (err < 0)
15781				return err;
15782		} else {
15783			sprintf(name, "%s Playback Volume", chname[i]);
15784			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15785					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
15786							      HDA_OUTPUT));
15787			if (err < 0)
15788				return err;
15789			sprintf(name, "%s Playback Switch", chname[i]);
15790			err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15791				HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
15792						    3, 0, HDA_INPUT));
15793			if (err < 0)
15794				return err;
15795		}
15796	}
15797	return 0;
15798}
15799
15800/* add playback controls for speaker and HP outputs */
15801static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
15802					const char *pfx)
15803{
15804	hda_nid_t nid;
15805	int err;
15806	char name[32];
15807
15808	if (!pin)
15809		return 0;
15810
15811	if (pin == 0x17) {
15812		/* ALC663 has a mono output pin on 0x17 */
15813		sprintf(name, "%s Playback Switch", pfx);
15814		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15815				  HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
15816		return err;
15817	}
15818
15819	if (alc880_is_fixed_pin(pin)) {
15820		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15821                /* printk("DAC nid=%x\n",nid); */
15822		/* specify the DAC as the extra output */
15823		if (!spec->multiout.hp_nid)
15824			spec->multiout.hp_nid = nid;
15825		else
15826			spec->multiout.extra_out_nid[0] = nid;
15827		/* control HP volume/switch on the output mixer amp */
15828		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15829		sprintf(name, "%s Playback Volume", pfx);
15830		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15831				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
15832		if (err < 0)
15833			return err;
15834		sprintf(name, "%s Playback Switch", pfx);
15835		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15836				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
15837		if (err < 0)
15838			return err;
15839	} else if (alc880_is_multi_pin(pin)) {
15840		/* set manual connection */
15841		/* we have only a switch on HP-out PIN */
15842		sprintf(name, "%s Playback Switch", pfx);
15843		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15844				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
15845		if (err < 0)
15846			return err;
15847	}
15848	return 0;
15849}
15850
15851/* create playback/capture controls for input pins */
15852static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
15853						const struct auto_pin_cfg *cfg)
15854{
15855	struct hda_input_mux *imux = &spec->private_imux;
15856	int i, err, idx;
15857
15858	for (i = 0; i < AUTO_PIN_LAST; i++) {
15859		if (alc880_is_input_pin(cfg->input_pins[i])) {
15860			idx = alc880_input_pin_idx(cfg->input_pins[i]);
15861			err = new_analog_input(spec, cfg->input_pins[i],
15862					       auto_pin_cfg_labels[i],
15863					       idx, 0x0b);
15864			if (err < 0)
15865				return err;
15866			imux->items[imux->num_items].label =
15867				auto_pin_cfg_labels[i];
15868			imux->items[imux->num_items].index =
15869				alc880_input_pin_idx(cfg->input_pins[i]);
15870			imux->num_items++;
15871		}
15872	}
15873	return 0;
15874}
15875
15876static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
15877					      hda_nid_t nid, int pin_type,
15878					      int dac_idx)
15879{
15880	alc_set_pin_output(codec, nid, pin_type);
15881	/* need the manual connection? */
15882	if (alc880_is_multi_pin(nid)) {
15883		struct alc_spec *spec = codec->spec;
15884		int idx = alc880_multi_pin_idx(nid);
15885		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
15886				    AC_VERB_SET_CONNECT_SEL,
15887				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
15888	}
15889}
15890
15891static void alc662_auto_init_multi_out(struct hda_codec *codec)
15892{
15893	struct alc_spec *spec = codec->spec;
15894	int i;
15895
15896	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
15897	for (i = 0; i <= HDA_SIDE; i++) {
15898		hda_nid_t nid = spec->autocfg.line_out_pins[i];
15899		int pin_type = get_pin_type(spec->autocfg.line_out_type);
15900		if (nid)
15901			alc662_auto_set_output_and_unmute(codec, nid, pin_type,
15902							  i);
15903	}
15904}
15905
15906static void alc662_auto_init_hp_out(struct hda_codec *codec)
15907{
15908	struct alc_spec *spec = codec->spec;
15909	hda_nid_t pin;
15910
15911	pin = spec->autocfg.hp_pins[0];
15912	if (pin) /* connect to front */
15913		/* use dac 0 */
15914		alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
15915	pin = spec->autocfg.speaker_pins[0];
15916	if (pin)
15917		alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
15918}
15919
15920#define alc662_is_input_pin(nid)	alc880_is_input_pin(nid)
15921#define ALC662_PIN_CD_NID		ALC880_PIN_CD_NID
15922
15923static void alc662_auto_init_analog_input(struct hda_codec *codec)
15924{
15925	struct alc_spec *spec = codec->spec;
15926	int i;
15927
15928	for (i = 0; i < AUTO_PIN_LAST; i++) {
15929		hda_nid_t nid = spec->autocfg.input_pins[i];
15930		if (alc662_is_input_pin(nid)) {
15931			snd_hda_codec_write(codec, nid, 0,
15932					    AC_VERB_SET_PIN_WIDGET_CONTROL,
15933					    (i <= AUTO_PIN_FRONT_MIC ?
15934					     PIN_VREF80 : PIN_IN));
15935			if (nid != ALC662_PIN_CD_NID)
15936				snd_hda_codec_write(codec, nid, 0,
15937						    AC_VERB_SET_AMP_GAIN_MUTE,
15938						    AMP_OUT_MUTE);
15939		}
15940	}
15941}
15942
15943#define alc662_auto_init_input_src	alc882_auto_init_input_src
15944
15945static int alc662_parse_auto_config(struct hda_codec *codec)
15946{
15947	struct alc_spec *spec = codec->spec;
15948	int err;
15949	static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
15950
15951	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15952					   alc662_ignore);
15953	if (err < 0)
15954		return err;
15955	if (!spec->autocfg.line_outs)
15956		return 0; /* can't find valid BIOS pin config */
15957
15958	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
15959	if (err < 0)
15960		return err;
15961	err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
15962	if (err < 0)
15963		return err;
15964	err = alc662_auto_create_extra_out(spec,
15965					   spec->autocfg.speaker_pins[0],
15966					   "Speaker");
15967	if (err < 0)
15968		return err;
15969	err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
15970					   "Headphone");
15971	if (err < 0)
15972		return err;
15973	err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
15974	if (err < 0)
15975		return err;
15976
15977	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15978
15979	if (spec->autocfg.dig_out_pin)
15980		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
15981
15982	if (spec->kctls.list)
15983		add_mixer(spec, spec->kctls.list);
15984
15985	spec->num_mux_defs = 1;
15986	spec->input_mux = &spec->private_imux;
15987
15988	add_verb(spec, alc662_auto_init_verbs);
15989	if (codec->vendor_id == 0x10ec0663)
15990		add_verb(spec, alc663_auto_init_verbs);
15991
15992	err = alc_auto_add_mic_boost(codec);
15993	if (err < 0)
15994		return err;
15995
15996	store_pin_configs(codec);
15997	return 1;
15998}
15999
16000/* additional initialization for auto-configuration model */
16001static void alc662_auto_init(struct hda_codec *codec)
16002{
16003	struct alc_spec *spec = codec->spec;
16004	alc662_auto_init_multi_out(codec);
16005	alc662_auto_init_hp_out(codec);
16006	alc662_auto_init_analog_input(codec);
16007	alc662_auto_init_input_src(codec);
16008	if (spec->unsol_event)
16009		alc_inithook(codec);
16010}
16011
16012static int patch_alc662(struct hda_codec *codec)
16013{
16014	struct alc_spec *spec;
16015	int err, board_config;
16016
16017	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16018	if (!spec)
16019		return -ENOMEM;
16020
16021	codec->spec = spec;
16022
16023	alc_fix_pll_init(codec, 0x20, 0x04, 15);
16024
16025	board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
16026						  alc662_models,
16027			  	                  alc662_cfg_tbl);
16028	if (board_config < 0) {
16029		printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
16030		       "trying auto-probe from BIOS...\n");
16031		board_config = ALC662_AUTO;
16032	}
16033
16034	if (board_config == ALC662_AUTO) {
16035		/* automatic parse from the BIOS config */
16036		err = alc662_parse_auto_config(codec);
16037		if (err < 0) {
16038			alc_free(codec);
16039			return err;
16040		} else if (!err) {
16041			printk(KERN_INFO
16042			       "hda_codec: Cannot set up configuration "
16043			       "from BIOS.  Using base mode...\n");
16044			board_config = ALC662_3ST_2ch_DIG;
16045		}
16046	}
16047
16048	if (board_config != ALC662_AUTO)
16049		setup_preset(spec, &alc662_presets[board_config]);
16050
16051	if (codec->vendor_id == 0x10ec0663) {
16052		spec->stream_name_analog = "ALC663 Analog";
16053		spec->stream_name_digital = "ALC663 Digital";
16054	} else if (codec->vendor_id == 0x10ec0272) {
16055		spec->stream_name_analog = "ALC272 Analog";
16056		spec->stream_name_digital = "ALC272 Digital";
16057	} else {
16058		spec->stream_name_analog = "ALC662 Analog";
16059		spec->stream_name_digital = "ALC662 Digital";
16060	}
16061
16062	spec->stream_analog_playback = &alc662_pcm_analog_playback;
16063	spec->stream_analog_capture = &alc662_pcm_analog_capture;
16064
16065	spec->stream_digital_playback = &alc662_pcm_digital_playback;
16066	spec->stream_digital_capture = &alc662_pcm_digital_capture;
16067
16068	spec->adc_nids = alc662_adc_nids;
16069	spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
16070	spec->capsrc_nids = alc662_capsrc_nids;
16071	spec->is_mix_capture = 1;
16072
16073	if (!spec->cap_mixer)
16074		set_capture_mixer(spec);
16075
16076	spec->vmaster_nid = 0x02;
16077
16078	codec->patch_ops = alc_patch_ops;
16079	if (board_config == ALC662_AUTO)
16080		spec->init_hook = alc662_auto_init;
16081#ifdef CONFIG_SND_HDA_POWER_SAVE
16082	if (!spec->loopback.amplist)
16083		spec->loopback.amplist = alc662_loopbacks;
16084#endif
16085
16086	return 0;
16087}
16088
16089/*
16090 * patch entries
16091 */
16092struct hda_codec_preset snd_hda_preset_realtek[] = {
16093	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
16094	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
16095	{ .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
16096	{ .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
16097	{ .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
16098	{ .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
16099	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
16100	  .patch = patch_alc861 },
16101	{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
16102	{ .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
16103	{ .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
16104	{ .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
16105	  .patch = patch_alc883 },
16106	{ .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
16107	  .patch = patch_alc662 },
16108	{ .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
16109	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
16110	{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
16111	{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
16112	{ .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
16113	  .patch = patch_alc882 }, /* should be patch_alc883() in future */
16114	{ .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
16115	  .patch = patch_alc882 }, /* should be patch_alc883() in future */
16116	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
16117	{ .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
16118	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
16119	{ .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
16120	  .patch = patch_alc883 },
16121	{ .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
16122	{} /* terminator */
16123};
16124