patch_realtek.c revision 7fb0d78fb155845812e98ed10605d8f01963ce05
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_AUTO,
134	ALC269_MODEL_LAST /* last tag */
135};
136
137/* ALC861 models */
138enum {
139	ALC861_3ST,
140	ALC660_3ST,
141	ALC861_3ST_DIG,
142	ALC861_6ST_DIG,
143	ALC861_UNIWILL_M31,
144	ALC861_TOSHIBA,
145	ALC861_ASUS,
146	ALC861_ASUS_LAPTOP,
147	ALC861_AUTO,
148	ALC861_MODEL_LAST,
149};
150
151/* ALC861-VD models */
152enum {
153	ALC660VD_3ST,
154	ALC660VD_3ST_DIG,
155	ALC861VD_3ST,
156	ALC861VD_3ST_DIG,
157	ALC861VD_6ST_DIG,
158	ALC861VD_LENOVO,
159	ALC861VD_DALLAS,
160	ALC861VD_HP,
161	ALC861VD_AUTO,
162	ALC861VD_MODEL_LAST,
163};
164
165/* ALC662 models */
166enum {
167	ALC662_3ST_2ch_DIG,
168	ALC662_3ST_6ch_DIG,
169	ALC662_3ST_6ch,
170	ALC662_5ST_DIG,
171	ALC662_LENOVO_101E,
172	ALC662_ASUS_EEEPC_P701,
173	ALC662_ASUS_EEEPC_EP20,
174	ALC663_ASUS_M51VA,
175	ALC663_ASUS_G71V,
176	ALC663_ASUS_H13,
177	ALC663_ASUS_G50V,
178	ALC662_ECS,
179	ALC663_ASUS_MODE1,
180	ALC662_ASUS_MODE2,
181	ALC663_ASUS_MODE3,
182	ALC663_ASUS_MODE4,
183	ALC663_ASUS_MODE5,
184	ALC663_ASUS_MODE6,
185	ALC662_AUTO,
186	ALC662_MODEL_LAST,
187};
188
189/* ALC882 models */
190enum {
191	ALC882_3ST_DIG,
192	ALC882_6ST_DIG,
193	ALC882_ARIMA,
194	ALC882_W2JC,
195	ALC882_TARGA,
196	ALC882_ASUS_A7J,
197	ALC882_ASUS_A7M,
198	ALC885_MACPRO,
199	ALC885_MBP3,
200	ALC885_IMAC24,
201	ALC882_AUTO,
202	ALC882_MODEL_LAST,
203};
204
205/* ALC883 models */
206enum {
207	ALC883_3ST_2ch_DIG,
208	ALC883_3ST_6ch_DIG,
209	ALC883_3ST_6ch,
210	ALC883_6ST_DIG,
211	ALC883_TARGA_DIG,
212	ALC883_TARGA_2ch_DIG,
213	ALC883_ACER,
214	ALC883_ACER_ASPIRE,
215	ALC883_MEDION,
216	ALC883_MEDION_MD2,
217	ALC883_LAPTOP_EAPD,
218	ALC883_LENOVO_101E_2ch,
219	ALC883_LENOVO_NB0763,
220	ALC888_LENOVO_MS7195_DIG,
221	ALC888_LENOVO_SKY,
222	ALC883_HAIER_W66,
223	ALC888_3ST_HP,
224	ALC888_6ST_DELL,
225	ALC883_MITAC,
226	ALC883_CLEVO_M720,
227	ALC883_FUJITSU_PI2515,
228	ALC883_3ST_6ch_INTEL,
229	ALC888_ASUS_M90V,
230	ALC888_ASUS_EEE1601,
231	ALC883_AUTO,
232	ALC883_MODEL_LAST,
233};
234
235/* for GPIO Poll */
236#define GPIO_MASK	0x03
237
238struct alc_spec {
239	/* codec parameterization */
240	struct snd_kcontrol_new *mixers[5];	/* mixer arrays */
241	unsigned int num_mixers;
242
243	const struct hda_verb *init_verbs[5];	/* initialization verbs
244						 * don't forget NULL
245						 * termination!
246						 */
247	unsigned int num_init_verbs;
248
249	char *stream_name_analog;	/* analog PCM stream */
250	struct hda_pcm_stream *stream_analog_playback;
251	struct hda_pcm_stream *stream_analog_capture;
252	struct hda_pcm_stream *stream_analog_alt_playback;
253	struct hda_pcm_stream *stream_analog_alt_capture;
254
255	char *stream_name_digital;	/* digital PCM stream */
256	struct hda_pcm_stream *stream_digital_playback;
257	struct hda_pcm_stream *stream_digital_capture;
258
259	/* playback */
260	struct hda_multi_out multiout;	/* playback set-up
261					 * max_channels, dacs must be set
262					 * dig_out_nid and hp_nid are optional
263					 */
264	hda_nid_t alt_dac_nid;
265
266	/* capture */
267	unsigned int num_adc_nids;
268	hda_nid_t *adc_nids;
269	hda_nid_t *capsrc_nids;
270	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
271
272	/* capture source */
273	unsigned int num_mux_defs;
274	const struct hda_input_mux *input_mux;
275	unsigned int cur_mux[3];
276
277	/* channel model */
278	const struct hda_channel_mode *channel_mode;
279	int num_channel_mode;
280	int need_dac_fix;
281
282	/* PCM information */
283	struct hda_pcm pcm_rec[3];	/* used in alc_build_pcms() */
284
285	/* dynamic controls, init_verbs and input_mux */
286	struct auto_pin_cfg autocfg;
287	unsigned int num_kctl_alloc, num_kctl_used;
288	struct snd_kcontrol_new *kctl_alloc;
289	struct hda_input_mux private_imux;
290	hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
291
292	/* hooks */
293	void (*init_hook)(struct hda_codec *codec);
294	void (*unsol_event)(struct hda_codec *codec, unsigned int res);
295
296	/* for pin sensing */
297	unsigned int sense_updated: 1;
298	unsigned int jack_present: 1;
299	unsigned int master_sw: 1;
300
301	/* for virtual master */
302	hda_nid_t vmaster_nid;
303#ifdef CONFIG_SND_HDA_POWER_SAVE
304	struct hda_loopback_check loopback;
305#endif
306
307	/* for PLL fix */
308	hda_nid_t pll_nid;
309	unsigned int pll_coef_idx, pll_coef_bit;
310};
311
312/*
313 * configuration template - to be copied to the spec instance
314 */
315struct alc_config_preset {
316	struct snd_kcontrol_new *mixers[5]; /* should be identical size
317					     * with spec
318					     */
319	const struct hda_verb *init_verbs[5];
320	unsigned int num_dacs;
321	hda_nid_t *dac_nids;
322	hda_nid_t dig_out_nid;		/* optional */
323	hda_nid_t hp_nid;		/* optional */
324	unsigned int num_adc_nids;
325	hda_nid_t *adc_nids;
326	hda_nid_t *capsrc_nids;
327	hda_nid_t dig_in_nid;
328	unsigned int num_channel_mode;
329	const struct hda_channel_mode *channel_mode;
330	int need_dac_fix;
331	unsigned int num_mux_defs;
332	const struct hda_input_mux *input_mux;
333	void (*unsol_event)(struct hda_codec *, unsigned int);
334	void (*init_hook)(struct hda_codec *);
335#ifdef CONFIG_SND_HDA_POWER_SAVE
336	struct hda_amp_list *loopbacks;
337#endif
338};
339
340
341/*
342 * input MUX handling
343 */
344static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
345			     struct snd_ctl_elem_info *uinfo)
346{
347	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
348	struct alc_spec *spec = codec->spec;
349	unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
350	if (mux_idx >= spec->num_mux_defs)
351		mux_idx = 0;
352	return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
353}
354
355static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
356			    struct snd_ctl_elem_value *ucontrol)
357{
358	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
359	struct alc_spec *spec = codec->spec;
360	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
361
362	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
363	return 0;
364}
365
366static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
367			    struct snd_ctl_elem_value *ucontrol)
368{
369	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
370	struct alc_spec *spec = codec->spec;
371	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
372	unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
373	hda_nid_t nid = spec->capsrc_nids ?
374		spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
375	return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
376				     nid, &spec->cur_mux[adc_idx]);
377}
378
379
380/*
381 * channel mode setting
382 */
383static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
384			    struct snd_ctl_elem_info *uinfo)
385{
386	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
387	struct alc_spec *spec = codec->spec;
388	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
389				    spec->num_channel_mode);
390}
391
392static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
393			   struct snd_ctl_elem_value *ucontrol)
394{
395	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
396	struct alc_spec *spec = codec->spec;
397	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
398				   spec->num_channel_mode,
399				   spec->multiout.max_channels);
400}
401
402static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
403			   struct snd_ctl_elem_value *ucontrol)
404{
405	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
406	struct alc_spec *spec = codec->spec;
407	int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
408				      spec->num_channel_mode,
409				      &spec->multiout.max_channels);
410	if (err >= 0 && spec->need_dac_fix)
411		spec->multiout.num_dacs = spec->multiout.max_channels / 2;
412	return err;
413}
414
415/*
416 * Control the mode of pin widget settings via the mixer.  "pc" is used
417 * instead of "%" to avoid consequences of accidently treating the % as
418 * being part of a format specifier.  Maximum allowed length of a value is
419 * 63 characters plus NULL terminator.
420 *
421 * Note: some retasking pin complexes seem to ignore requests for input
422 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
423 * are requested.  Therefore order this list so that this behaviour will not
424 * cause problems when mixer clients move through the enum sequentially.
425 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
426 * March 2006.
427 */
428static char *alc_pin_mode_names[] = {
429	"Mic 50pc bias", "Mic 80pc bias",
430	"Line in", "Line out", "Headphone out",
431};
432static unsigned char alc_pin_mode_values[] = {
433	PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
434};
435/* The control can present all 5 options, or it can limit the options based
436 * in the pin being assumed to be exclusively an input or an output pin.  In
437 * addition, "input" pins may or may not process the mic bias option
438 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
439 * accept requests for bias as of chip versions up to March 2006) and/or
440 * wiring in the computer.
441 */
442#define ALC_PIN_DIR_IN              0x00
443#define ALC_PIN_DIR_OUT             0x01
444#define ALC_PIN_DIR_INOUT           0x02
445#define ALC_PIN_DIR_IN_NOMICBIAS    0x03
446#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
447
448/* Info about the pin modes supported by the different pin direction modes.
449 * For each direction the minimum and maximum values are given.
450 */
451static signed char alc_pin_mode_dir_info[5][2] = {
452	{ 0, 2 },    /* ALC_PIN_DIR_IN */
453	{ 3, 4 },    /* ALC_PIN_DIR_OUT */
454	{ 0, 4 },    /* ALC_PIN_DIR_INOUT */
455	{ 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
456	{ 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
457};
458#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
459#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
460#define alc_pin_mode_n_items(_dir) \
461	(alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
462
463static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
464			     struct snd_ctl_elem_info *uinfo)
465{
466	unsigned int item_num = uinfo->value.enumerated.item;
467	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
468
469	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
470	uinfo->count = 1;
471	uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
472
473	if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
474		item_num = alc_pin_mode_min(dir);
475	strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
476	return 0;
477}
478
479static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
480			    struct snd_ctl_elem_value *ucontrol)
481{
482	unsigned int i;
483	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
484	hda_nid_t nid = kcontrol->private_value & 0xffff;
485	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
486	long *valp = ucontrol->value.integer.value;
487	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
488						 AC_VERB_GET_PIN_WIDGET_CONTROL,
489						 0x00);
490
491	/* Find enumerated value for current pinctl setting */
492	i = alc_pin_mode_min(dir);
493	while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
494		i++;
495	*valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
496	return 0;
497}
498
499static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
500			    struct snd_ctl_elem_value *ucontrol)
501{
502	signed int change;
503	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
504	hda_nid_t nid = kcontrol->private_value & 0xffff;
505	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
506	long val = *ucontrol->value.integer.value;
507	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
508						 AC_VERB_GET_PIN_WIDGET_CONTROL,
509						 0x00);
510
511	if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
512		val = alc_pin_mode_min(dir);
513
514	change = pinctl != alc_pin_mode_values[val];
515	if (change) {
516		/* Set pin mode to that requested */
517		snd_hda_codec_write_cache(codec, nid, 0,
518					  AC_VERB_SET_PIN_WIDGET_CONTROL,
519					  alc_pin_mode_values[val]);
520
521		/* Also enable the retasking pin's input/output as required
522		 * for the requested pin mode.  Enum values of 2 or less are
523		 * input modes.
524		 *
525		 * Dynamically switching the input/output buffers probably
526		 * reduces noise slightly (particularly on input) so we'll
527		 * do it.  However, having both input and output buffers
528		 * enabled simultaneously doesn't seem to be problematic if
529		 * this turns out to be necessary in the future.
530		 */
531		if (val <= 2) {
532			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
533						 HDA_AMP_MUTE, HDA_AMP_MUTE);
534			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
535						 HDA_AMP_MUTE, 0);
536		} else {
537			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
538						 HDA_AMP_MUTE, HDA_AMP_MUTE);
539			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
540						 HDA_AMP_MUTE, 0);
541		}
542	}
543	return change;
544}
545
546#define ALC_PIN_MODE(xname, nid, dir) \
547	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
548	  .info = alc_pin_mode_info, \
549	  .get = alc_pin_mode_get, \
550	  .put = alc_pin_mode_put, \
551	  .private_value = nid | (dir<<16) }
552
553/* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
554 * together using a mask with more than one bit set.  This control is
555 * currently used only by the ALC260 test model.  At this stage they are not
556 * needed for any "production" models.
557 */
558#ifdef CONFIG_SND_DEBUG
559#define alc_gpio_data_info	snd_ctl_boolean_mono_info
560
561static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
562			     struct snd_ctl_elem_value *ucontrol)
563{
564	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
565	hda_nid_t nid = kcontrol->private_value & 0xffff;
566	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
567	long *valp = ucontrol->value.integer.value;
568	unsigned int val = snd_hda_codec_read(codec, nid, 0,
569					      AC_VERB_GET_GPIO_DATA, 0x00);
570
571	*valp = (val & mask) != 0;
572	return 0;
573}
574static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
575			     struct snd_ctl_elem_value *ucontrol)
576{
577	signed int change;
578	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
579	hda_nid_t nid = kcontrol->private_value & 0xffff;
580	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
581	long val = *ucontrol->value.integer.value;
582	unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
583						    AC_VERB_GET_GPIO_DATA,
584						    0x00);
585
586	/* Set/unset the masked GPIO bit(s) as needed */
587	change = (val == 0 ? 0 : mask) != (gpio_data & mask);
588	if (val == 0)
589		gpio_data &= ~mask;
590	else
591		gpio_data |= mask;
592	snd_hda_codec_write_cache(codec, nid, 0,
593				  AC_VERB_SET_GPIO_DATA, gpio_data);
594
595	return change;
596}
597#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
598	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
599	  .info = alc_gpio_data_info, \
600	  .get = alc_gpio_data_get, \
601	  .put = alc_gpio_data_put, \
602	  .private_value = nid | (mask<<16) }
603#endif   /* CONFIG_SND_DEBUG */
604
605/* A switch control to allow the enabling of the digital IO pins on the
606 * ALC260.  This is incredibly simplistic; the intention of this control is
607 * to provide something in the test model allowing digital outputs to be
608 * identified if present.  If models are found which can utilise these
609 * outputs a more complete mixer control can be devised for those models if
610 * necessary.
611 */
612#ifdef CONFIG_SND_DEBUG
613#define alc_spdif_ctrl_info	snd_ctl_boolean_mono_info
614
615static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
616			      struct snd_ctl_elem_value *ucontrol)
617{
618	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
619	hda_nid_t nid = kcontrol->private_value & 0xffff;
620	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
621	long *valp = ucontrol->value.integer.value;
622	unsigned int val = snd_hda_codec_read(codec, nid, 0,
623					      AC_VERB_GET_DIGI_CONVERT_1, 0x00);
624
625	*valp = (val & mask) != 0;
626	return 0;
627}
628static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
629			      struct snd_ctl_elem_value *ucontrol)
630{
631	signed int change;
632	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
633	hda_nid_t nid = kcontrol->private_value & 0xffff;
634	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
635	long val = *ucontrol->value.integer.value;
636	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
637						    AC_VERB_GET_DIGI_CONVERT_1,
638						    0x00);
639
640	/* Set/unset the masked control bit(s) as needed */
641	change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
642	if (val==0)
643		ctrl_data &= ~mask;
644	else
645		ctrl_data |= mask;
646	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
647				  ctrl_data);
648
649	return change;
650}
651#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
652	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
653	  .info = alc_spdif_ctrl_info, \
654	  .get = alc_spdif_ctrl_get, \
655	  .put = alc_spdif_ctrl_put, \
656	  .private_value = nid | (mask<<16) }
657#endif   /* CONFIG_SND_DEBUG */
658
659/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
660 * Again, this is only used in the ALC26x test models to help identify when
661 * the EAPD line must be asserted for features to work.
662 */
663#ifdef CONFIG_SND_DEBUG
664#define alc_eapd_ctrl_info	snd_ctl_boolean_mono_info
665
666static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
667			      struct snd_ctl_elem_value *ucontrol)
668{
669	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
670	hda_nid_t nid = kcontrol->private_value & 0xffff;
671	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
672	long *valp = ucontrol->value.integer.value;
673	unsigned int val = snd_hda_codec_read(codec, nid, 0,
674					      AC_VERB_GET_EAPD_BTLENABLE, 0x00);
675
676	*valp = (val & mask) != 0;
677	return 0;
678}
679
680static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
681			      struct snd_ctl_elem_value *ucontrol)
682{
683	int change;
684	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
685	hda_nid_t nid = kcontrol->private_value & 0xffff;
686	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
687	long val = *ucontrol->value.integer.value;
688	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
689						    AC_VERB_GET_EAPD_BTLENABLE,
690						    0x00);
691
692	/* Set/unset the masked control bit(s) as needed */
693	change = (!val ? 0 : mask) != (ctrl_data & mask);
694	if (!val)
695		ctrl_data &= ~mask;
696	else
697		ctrl_data |= mask;
698	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
699				  ctrl_data);
700
701	return change;
702}
703
704#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
705	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
706	  .info = alc_eapd_ctrl_info, \
707	  .get = alc_eapd_ctrl_get, \
708	  .put = alc_eapd_ctrl_put, \
709	  .private_value = nid | (mask<<16) }
710#endif   /* CONFIG_SND_DEBUG */
711
712/*
713 * set up from the preset table
714 */
715static void setup_preset(struct alc_spec *spec,
716			 const struct alc_config_preset *preset)
717{
718	int i;
719
720	for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
721		spec->mixers[spec->num_mixers++] = preset->mixers[i];
722	for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
723	     i++)
724		spec->init_verbs[spec->num_init_verbs++] =
725			preset->init_verbs[i];
726
727	spec->channel_mode = preset->channel_mode;
728	spec->num_channel_mode = preset->num_channel_mode;
729	spec->need_dac_fix = preset->need_dac_fix;
730
731	spec->multiout.max_channels = spec->channel_mode[0].channels;
732
733	spec->multiout.num_dacs = preset->num_dacs;
734	spec->multiout.dac_nids = preset->dac_nids;
735	spec->multiout.dig_out_nid = preset->dig_out_nid;
736	spec->multiout.hp_nid = preset->hp_nid;
737
738	spec->num_mux_defs = preset->num_mux_defs;
739	if (!spec->num_mux_defs)
740		spec->num_mux_defs = 1;
741	spec->input_mux = preset->input_mux;
742
743	spec->num_adc_nids = preset->num_adc_nids;
744	spec->adc_nids = preset->adc_nids;
745	spec->capsrc_nids = preset->capsrc_nids;
746	spec->dig_in_nid = preset->dig_in_nid;
747
748	spec->unsol_event = preset->unsol_event;
749	spec->init_hook = preset->init_hook;
750#ifdef CONFIG_SND_HDA_POWER_SAVE
751	spec->loopback.amplist = preset->loopbacks;
752#endif
753}
754
755/* Enable GPIO mask and set output */
756static struct hda_verb alc_gpio1_init_verbs[] = {
757	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
758	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
759	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
760	{ }
761};
762
763static struct hda_verb alc_gpio2_init_verbs[] = {
764	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
765	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
766	{0x01, AC_VERB_SET_GPIO_DATA, 0x02},
767	{ }
768};
769
770static struct hda_verb alc_gpio3_init_verbs[] = {
771	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
772	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
773	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
774	{ }
775};
776
777/*
778 * Fix hardware PLL issue
779 * On some codecs, the analog PLL gating control must be off while
780 * the default value is 1.
781 */
782static void alc_fix_pll(struct hda_codec *codec)
783{
784	struct alc_spec *spec = codec->spec;
785	unsigned int val;
786
787	if (!spec->pll_nid)
788		return;
789	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
790			    spec->pll_coef_idx);
791	val = snd_hda_codec_read(codec, spec->pll_nid, 0,
792				 AC_VERB_GET_PROC_COEF, 0);
793	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
794			    spec->pll_coef_idx);
795	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
796			    val & ~(1 << spec->pll_coef_bit));
797}
798
799static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
800			     unsigned int coef_idx, unsigned int coef_bit)
801{
802	struct alc_spec *spec = codec->spec;
803	spec->pll_nid = nid;
804	spec->pll_coef_idx = coef_idx;
805	spec->pll_coef_bit = coef_bit;
806	alc_fix_pll(codec);
807}
808
809static void alc_sku_automute(struct hda_codec *codec)
810{
811	struct alc_spec *spec = codec->spec;
812	unsigned int present;
813	unsigned int hp_nid = spec->autocfg.hp_pins[0];
814	unsigned int sp_nid = spec->autocfg.speaker_pins[0];
815
816	/* need to execute and sync at first */
817	snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
818	present = snd_hda_codec_read(codec, hp_nid, 0,
819				     AC_VERB_GET_PIN_SENSE, 0);
820	spec->jack_present = (present & 0x80000000) != 0;
821	snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
822			    spec->jack_present ? 0 : PIN_OUT);
823}
824
825static void alc_mic_automute(struct hda_codec *codec)
826{
827	struct alc_spec *spec = codec->spec;
828	unsigned int present;
829	unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
830	unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
831	unsigned int mix_nid = spec->capsrc_nids[0];
832	unsigned int capsrc_idx_mic, capsrc_idx_fmic;
833
834	capsrc_idx_mic = mic_nid - 0x18;
835	capsrc_idx_fmic = fmic_nid - 0x18;
836	present = snd_hda_codec_read(codec, mic_nid, 0,
837				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
838	snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
839		    0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
840	snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
841		    0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
842	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
843			 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
844}
845
846/* unsolicited event for HP jack sensing */
847static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
848{
849	if (codec->vendor_id == 0x10ec0880)
850		res >>= 28;
851	else
852		res >>= 26;
853	if (res == ALC880_HP_EVENT)
854		alc_sku_automute(codec);
855
856	if (res == ALC880_MIC_EVENT)
857		alc_mic_automute(codec);
858}
859
860static void alc_inithook(struct hda_codec *codec)
861{
862	alc_sku_automute(codec);
863	alc_mic_automute(codec);
864}
865
866/* additional initialization for ALC888 variants */
867static void alc888_coef_init(struct hda_codec *codec)
868{
869	unsigned int tmp;
870
871	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
872	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
873	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
874	if ((tmp & 0xf0) == 2)
875		/* alc888S-VC */
876		snd_hda_codec_read(codec, 0x20, 0,
877				   AC_VERB_SET_PROC_COEF, 0x830);
878	 else
879		 /* alc888-VB */
880		 snd_hda_codec_read(codec, 0x20, 0,
881				    AC_VERB_SET_PROC_COEF, 0x3030);
882}
883
884/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
885 *	31 ~ 16 :	Manufacture ID
886 *	15 ~ 8	:	SKU ID
887 *	7  ~ 0	:	Assembly ID
888 *	port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
889 */
890static void alc_subsystem_id(struct hda_codec *codec,
891			     unsigned int porta, unsigned int porte,
892			     unsigned int portd)
893{
894	unsigned int ass, tmp, i;
895	unsigned nid;
896	struct alc_spec *spec = codec->spec;
897
898	ass = codec->subsystem_id & 0xffff;
899	if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
900		goto do_sku;
901
902	/*
903	 * 31~30	: port conetcivity
904	 * 29~21	: reserve
905	 * 20		: PCBEEP input
906	 * 19~16	: Check sum (15:1)
907	 * 15~1		: Custom
908	 * 0		: override
909	*/
910	nid = 0x1d;
911	if (codec->vendor_id == 0x10ec0260)
912		nid = 0x17;
913	ass = snd_hda_codec_read(codec, nid, 0,
914				 AC_VERB_GET_CONFIG_DEFAULT, 0);
915	if (!(ass & 1) && !(ass & 0x100000))
916		return;
917	if ((ass >> 30) != 1)	/* no physical connection */
918		return;
919
920	/* check sum */
921	tmp = 0;
922	for (i = 1; i < 16; i++) {
923		if ((ass >> i) & 1)
924			tmp++;
925	}
926	if (((ass >> 16) & 0xf) != tmp)
927		return;
928do_sku:
929	/*
930	 * 0 : override
931	 * 1 :	Swap Jack
932	 * 2 : 0 --> Desktop, 1 --> Laptop
933	 * 3~5 : External Amplifier control
934	 * 7~6 : Reserved
935	*/
936	tmp = (ass & 0x38) >> 3;	/* external Amp control */
937	switch (tmp) {
938	case 1:
939		snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
940		break;
941	case 3:
942		snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
943		break;
944	case 7:
945		snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
946		break;
947	case 5:	/* set EAPD output high */
948		switch (codec->vendor_id) {
949		case 0x10ec0260:
950			snd_hda_codec_write(codec, 0x0f, 0,
951					    AC_VERB_SET_EAPD_BTLENABLE, 2);
952			snd_hda_codec_write(codec, 0x10, 0,
953					    AC_VERB_SET_EAPD_BTLENABLE, 2);
954			break;
955		case 0x10ec0262:
956		case 0x10ec0267:
957		case 0x10ec0268:
958		case 0x10ec0269:
959		case 0x10ec0660:
960		case 0x10ec0662:
961		case 0x10ec0663:
962		case 0x10ec0862:
963		case 0x10ec0889:
964			snd_hda_codec_write(codec, 0x14, 0,
965					    AC_VERB_SET_EAPD_BTLENABLE, 2);
966			snd_hda_codec_write(codec, 0x15, 0,
967					    AC_VERB_SET_EAPD_BTLENABLE, 2);
968			break;
969		}
970		switch (codec->vendor_id) {
971		case 0x10ec0260:
972			snd_hda_codec_write(codec, 0x1a, 0,
973					    AC_VERB_SET_COEF_INDEX, 7);
974			tmp = snd_hda_codec_read(codec, 0x1a, 0,
975						 AC_VERB_GET_PROC_COEF, 0);
976			snd_hda_codec_write(codec, 0x1a, 0,
977					    AC_VERB_SET_COEF_INDEX, 7);
978			snd_hda_codec_write(codec, 0x1a, 0,
979					    AC_VERB_SET_PROC_COEF,
980					    tmp | 0x2010);
981			break;
982		case 0x10ec0262:
983		case 0x10ec0880:
984		case 0x10ec0882:
985		case 0x10ec0883:
986		case 0x10ec0885:
987		case 0x10ec0889:
988			snd_hda_codec_write(codec, 0x20, 0,
989					    AC_VERB_SET_COEF_INDEX, 7);
990			tmp = snd_hda_codec_read(codec, 0x20, 0,
991						 AC_VERB_GET_PROC_COEF, 0);
992			snd_hda_codec_write(codec, 0x20, 0,
993					    AC_VERB_SET_COEF_INDEX, 7);
994			snd_hda_codec_write(codec, 0x20, 0,
995					    AC_VERB_SET_PROC_COEF,
996					    tmp | 0x2010);
997			break;
998		case 0x10ec0888:
999			/*alc888_coef_init(codec);*/ /* called in alc_init() */
1000			break;
1001		case 0x10ec0267:
1002		case 0x10ec0268:
1003			snd_hda_codec_write(codec, 0x20, 0,
1004					    AC_VERB_SET_COEF_INDEX, 7);
1005			tmp = snd_hda_codec_read(codec, 0x20, 0,
1006						 AC_VERB_GET_PROC_COEF, 0);
1007			snd_hda_codec_write(codec, 0x20, 0,
1008					    AC_VERB_SET_COEF_INDEX, 7);
1009			snd_hda_codec_write(codec, 0x20, 0,
1010					    AC_VERB_SET_PROC_COEF,
1011					    tmp | 0x3000);
1012			break;
1013		}
1014	default:
1015		break;
1016	}
1017
1018	/* is laptop or Desktop and enable the function "Mute internal speaker
1019	 * when the external headphone out jack is plugged"
1020	 */
1021	if (!(ass & 0x8000))
1022		return;
1023	/*
1024	 * 10~8 : Jack location
1025	 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1026	 * 14~13: Resvered
1027	 * 15   : 1 --> enable the function "Mute internal speaker
1028	 *	        when the external headphone out jack is plugged"
1029	 */
1030	if (!spec->autocfg.speaker_pins[0]) {
1031		if (spec->autocfg.line_out_pins[0])
1032			spec->autocfg.speaker_pins[0] =
1033				spec->autocfg.line_out_pins[0];
1034		else
1035			return;
1036	}
1037
1038	if (!spec->autocfg.hp_pins[0]) {
1039		tmp = (ass >> 11) & 0x3;	/* HP to chassis */
1040		if (tmp == 0)
1041			spec->autocfg.hp_pins[0] = porta;
1042		else if (tmp == 1)
1043			spec->autocfg.hp_pins[0] = porte;
1044		else if (tmp == 2)
1045			spec->autocfg.hp_pins[0] = portd;
1046		else
1047			return;
1048	}
1049	if (spec->autocfg.hp_pins[0])
1050		snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
1051			AC_VERB_SET_UNSOLICITED_ENABLE,
1052			AC_USRSP_EN | ALC880_HP_EVENT);
1053
1054	if (spec->autocfg.input_pins[AUTO_PIN_MIC] &&
1055		spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC])
1056		snd_hda_codec_write(codec,
1057			spec->autocfg.input_pins[AUTO_PIN_MIC], 0,
1058			AC_VERB_SET_UNSOLICITED_ENABLE,
1059			AC_USRSP_EN | ALC880_MIC_EVENT);
1060
1061	spec->unsol_event = alc_sku_unsol_event;
1062}
1063
1064/*
1065 * Fix-up pin default configurations
1066 */
1067
1068struct alc_pincfg {
1069	hda_nid_t nid;
1070	u32 val;
1071};
1072
1073static void alc_fix_pincfg(struct hda_codec *codec,
1074			   const struct snd_pci_quirk *quirk,
1075			   const struct alc_pincfg **pinfix)
1076{
1077	const struct alc_pincfg *cfg;
1078
1079	quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1080	if (!quirk)
1081		return;
1082
1083	cfg = pinfix[quirk->value];
1084	for (; cfg->nid; cfg++) {
1085		int i;
1086		u32 val = cfg->val;
1087		for (i = 0; i < 4; i++) {
1088			snd_hda_codec_write(codec, cfg->nid, 0,
1089				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
1090				    val & 0xff);
1091			val >>= 8;
1092		}
1093	}
1094}
1095
1096/*
1097 * ALC880 3-stack model
1098 *
1099 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1100 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1101 *                 F-Mic = 0x1b, HP = 0x19
1102 */
1103
1104static hda_nid_t alc880_dac_nids[4] = {
1105	/* front, rear, clfe, rear_surr */
1106	0x02, 0x05, 0x04, 0x03
1107};
1108
1109static hda_nid_t alc880_adc_nids[3] = {
1110	/* ADC0-2 */
1111	0x07, 0x08, 0x09,
1112};
1113
1114/* The datasheet says the node 0x07 is connected from inputs,
1115 * but it shows zero connection in the real implementation on some devices.
1116 * Note: this is a 915GAV bug, fixed on 915GLV
1117 */
1118static hda_nid_t alc880_adc_nids_alt[2] = {
1119	/* ADC1-2 */
1120	0x08, 0x09,
1121};
1122
1123#define ALC880_DIGOUT_NID	0x06
1124#define ALC880_DIGIN_NID	0x0a
1125
1126static struct hda_input_mux alc880_capture_source = {
1127	.num_items = 4,
1128	.items = {
1129		{ "Mic", 0x0 },
1130		{ "Front Mic", 0x3 },
1131		{ "Line", 0x2 },
1132		{ "CD", 0x4 },
1133	},
1134};
1135
1136/* channel source setting (2/6 channel selection for 3-stack) */
1137/* 2ch mode */
1138static struct hda_verb alc880_threestack_ch2_init[] = {
1139	/* set line-in to input, mute it */
1140	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1141	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1142	/* set mic-in to input vref 80%, mute it */
1143	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1144	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1145	{ } /* end */
1146};
1147
1148/* 6ch mode */
1149static struct hda_verb alc880_threestack_ch6_init[] = {
1150	/* set line-in to output, unmute it */
1151	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1152	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1153	/* set mic-in to output, unmute it */
1154	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1155	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1156	{ } /* end */
1157};
1158
1159static struct hda_channel_mode alc880_threestack_modes[2] = {
1160	{ 2, alc880_threestack_ch2_init },
1161	{ 6, alc880_threestack_ch6_init },
1162};
1163
1164static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1165	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1166	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1167	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1168	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1169	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1170	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1171	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1172	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1173	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1174	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1175	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1176	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1177	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1178	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1179	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1180	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1181	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1182	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1183	HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1184	{
1185		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1186		.name = "Channel Mode",
1187		.info = alc_ch_mode_info,
1188		.get = alc_ch_mode_get,
1189		.put = alc_ch_mode_put,
1190	},
1191	{ } /* end */
1192};
1193
1194/* capture mixer elements */
1195static struct snd_kcontrol_new alc880_capture_mixer[] = {
1196	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1197	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1198	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1199	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1200	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1201	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1202	{
1203		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1204		/* The multiple "Capture Source" controls confuse alsamixer
1205		 * So call somewhat different..
1206		 */
1207		/* .name = "Capture Source", */
1208		.name = "Input Source",
1209		.count = 3,
1210		.info = alc_mux_enum_info,
1211		.get = alc_mux_enum_get,
1212		.put = alc_mux_enum_put,
1213	},
1214	{ } /* end */
1215};
1216
1217/* capture mixer elements (in case NID 0x07 not available) */
1218static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
1219	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1220	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1221	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1222	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1223	{
1224		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1225		/* The multiple "Capture Source" controls confuse alsamixer
1226		 * So call somewhat different..
1227		 */
1228		/* .name = "Capture Source", */
1229		.name = "Input Source",
1230		.count = 2,
1231		.info = alc_mux_enum_info,
1232		.get = alc_mux_enum_get,
1233		.put = alc_mux_enum_put,
1234	},
1235	{ } /* end */
1236};
1237
1238
1239
1240/*
1241 * ALC880 5-stack model
1242 *
1243 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1244 *      Side = 0x02 (0xd)
1245 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1246 *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1247 */
1248
1249/* additional mixers to alc880_three_stack_mixer */
1250static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1251	HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1252	HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1253	{ } /* end */
1254};
1255
1256/* channel source setting (6/8 channel selection for 5-stack) */
1257/* 6ch mode */
1258static struct hda_verb alc880_fivestack_ch6_init[] = {
1259	/* set line-in to input, mute it */
1260	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1261	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1262	{ } /* end */
1263};
1264
1265/* 8ch mode */
1266static struct hda_verb alc880_fivestack_ch8_init[] = {
1267	/* set line-in to output, unmute it */
1268	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1269	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1270	{ } /* end */
1271};
1272
1273static struct hda_channel_mode alc880_fivestack_modes[2] = {
1274	{ 6, alc880_fivestack_ch6_init },
1275	{ 8, alc880_fivestack_ch8_init },
1276};
1277
1278
1279/*
1280 * ALC880 6-stack model
1281 *
1282 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1283 *      Side = 0x05 (0x0f)
1284 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1285 *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1286 */
1287
1288static hda_nid_t alc880_6st_dac_nids[4] = {
1289	/* front, rear, clfe, rear_surr */
1290	0x02, 0x03, 0x04, 0x05
1291};
1292
1293static struct hda_input_mux alc880_6stack_capture_source = {
1294	.num_items = 4,
1295	.items = {
1296		{ "Mic", 0x0 },
1297		{ "Front Mic", 0x1 },
1298		{ "Line", 0x2 },
1299		{ "CD", 0x4 },
1300	},
1301};
1302
1303/* fixed 8-channels */
1304static struct hda_channel_mode alc880_sixstack_modes[1] = {
1305	{ 8, NULL },
1306};
1307
1308static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1309	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1310	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1311	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1312	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1313	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1314	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1315	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1316	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1317	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1318	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1319	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1320	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1321	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1322	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1323	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1324	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1325	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1326	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1327	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1328	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1329	{
1330		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1331		.name = "Channel Mode",
1332		.info = alc_ch_mode_info,
1333		.get = alc_ch_mode_get,
1334		.put = alc_ch_mode_put,
1335	},
1336	{ } /* end */
1337};
1338
1339
1340/*
1341 * ALC880 W810 model
1342 *
1343 * W810 has rear IO for:
1344 * Front (DAC 02)
1345 * Surround (DAC 03)
1346 * Center/LFE (DAC 04)
1347 * Digital out (06)
1348 *
1349 * The system also has a pair of internal speakers, and a headphone jack.
1350 * These are both connected to Line2 on the codec, hence to DAC 02.
1351 *
1352 * There is a variable resistor to control the speaker or headphone
1353 * volume. This is a hardware-only device without a software API.
1354 *
1355 * Plugging headphones in will disable the internal speakers. This is
1356 * implemented in hardware, not via the driver using jack sense. In
1357 * a similar fashion, plugging into the rear socket marked "front" will
1358 * disable both the speakers and headphones.
1359 *
1360 * For input, there's a microphone jack, and an "audio in" jack.
1361 * These may not do anything useful with this driver yet, because I
1362 * haven't setup any initialization verbs for these yet...
1363 */
1364
1365static hda_nid_t alc880_w810_dac_nids[3] = {
1366	/* front, rear/surround, clfe */
1367	0x02, 0x03, 0x04
1368};
1369
1370/* fixed 6 channels */
1371static struct hda_channel_mode alc880_w810_modes[1] = {
1372	{ 6, NULL }
1373};
1374
1375/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1376static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1377	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1378	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1379	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1380	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1381	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1382	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1383	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1384	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1385	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1386	{ } /* end */
1387};
1388
1389
1390/*
1391 * Z710V model
1392 *
1393 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1394 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1395 *                 Line = 0x1a
1396 */
1397
1398static hda_nid_t alc880_z71v_dac_nids[1] = {
1399	0x02
1400};
1401#define ALC880_Z71V_HP_DAC	0x03
1402
1403/* fixed 2 channels */
1404static struct hda_channel_mode alc880_2_jack_modes[1] = {
1405	{ 2, NULL }
1406};
1407
1408static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1409	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1410	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1411	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1412	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1413	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1414	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1415	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1416	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1417	{ } /* end */
1418};
1419
1420
1421/*
1422 * ALC880 F1734 model
1423 *
1424 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1425 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1426 */
1427
1428static hda_nid_t alc880_f1734_dac_nids[1] = {
1429	0x03
1430};
1431#define ALC880_F1734_HP_DAC	0x02
1432
1433static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1434	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1435	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1436	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1437	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1438	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1439	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1440	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1441	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1442	{ } /* end */
1443};
1444
1445static struct hda_input_mux alc880_f1734_capture_source = {
1446	.num_items = 2,
1447	.items = {
1448		{ "Mic", 0x1 },
1449		{ "CD", 0x4 },
1450	},
1451};
1452
1453
1454/*
1455 * ALC880 ASUS model
1456 *
1457 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1458 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1459 *  Mic = 0x18, Line = 0x1a
1460 */
1461
1462#define alc880_asus_dac_nids	alc880_w810_dac_nids	/* identical with w810 */
1463#define alc880_asus_modes	alc880_threestack_modes	/* 2/6 channel mode */
1464
1465static struct snd_kcontrol_new alc880_asus_mixer[] = {
1466	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1467	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1468	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1469	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1470	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1471	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1472	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1473	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1474	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1475	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1476	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1477	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1478	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1479	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1480	{
1481		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1482		.name = "Channel Mode",
1483		.info = alc_ch_mode_info,
1484		.get = alc_ch_mode_get,
1485		.put = alc_ch_mode_put,
1486	},
1487	{ } /* end */
1488};
1489
1490/*
1491 * ALC880 ASUS W1V model
1492 *
1493 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1494 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1495 *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1496 */
1497
1498/* additional mixers to alc880_asus_mixer */
1499static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1500	HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1501	HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1502	{ } /* end */
1503};
1504
1505/* additional mixers to alc880_asus_mixer */
1506static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1507	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1508	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1509	{ } /* end */
1510};
1511
1512/* TCL S700 */
1513static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1514	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1515	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1516	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1517	HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1518	HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1519	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1520	HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1521	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1522	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1523	{
1524		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1525		/* The multiple "Capture Source" controls confuse alsamixer
1526		 * So call somewhat different..
1527		 */
1528		/* .name = "Capture Source", */
1529		.name = "Input Source",
1530		.count = 1,
1531		.info = alc_mux_enum_info,
1532		.get = alc_mux_enum_get,
1533		.put = alc_mux_enum_put,
1534	},
1535	{ } /* end */
1536};
1537
1538/* Uniwill */
1539static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1540	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1541	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1542	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1543	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1544	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1545	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1546	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1547	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1548	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1549	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1550	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1551	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1552	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1553	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1554	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1555	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1556	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1557	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1558	{
1559		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1560		.name = "Channel Mode",
1561		.info = alc_ch_mode_info,
1562		.get = alc_ch_mode_get,
1563		.put = alc_ch_mode_put,
1564	},
1565	{ } /* end */
1566};
1567
1568static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1569	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1570	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1571	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1572	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1573	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1574	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1575	HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1576	HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1577	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1578	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1579	{ } /* end */
1580};
1581
1582static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1583	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1584	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1585	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1586	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1587	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1588	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1589	{ } /* end */
1590};
1591
1592/*
1593 * virtual master controls
1594 */
1595
1596/*
1597 * slave controls for virtual master
1598 */
1599static const char *alc_slave_vols[] = {
1600	"Front Playback Volume",
1601	"Surround Playback Volume",
1602	"Center Playback Volume",
1603	"LFE Playback Volume",
1604	"Side Playback Volume",
1605	"Headphone Playback Volume",
1606	"Speaker Playback Volume",
1607	"Mono Playback Volume",
1608	"Line-Out Playback Volume",
1609	NULL,
1610};
1611
1612static const char *alc_slave_sws[] = {
1613	"Front Playback Switch",
1614	"Surround Playback Switch",
1615	"Center Playback Switch",
1616	"LFE Playback Switch",
1617	"Side Playback Switch",
1618	"Headphone Playback Switch",
1619	"Speaker Playback Switch",
1620	"Mono Playback Switch",
1621	"IEC958 Playback Switch",
1622	NULL,
1623};
1624
1625/*
1626 * build control elements
1627 */
1628static int alc_build_controls(struct hda_codec *codec)
1629{
1630	struct alc_spec *spec = codec->spec;
1631	int err;
1632	int i;
1633
1634	for (i = 0; i < spec->num_mixers; i++) {
1635		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1636		if (err < 0)
1637			return err;
1638	}
1639
1640	if (spec->multiout.dig_out_nid) {
1641		err = snd_hda_create_spdif_out_ctls(codec,
1642						    spec->multiout.dig_out_nid);
1643		if (err < 0)
1644			return err;
1645		err = snd_hda_create_spdif_share_sw(codec,
1646						    &spec->multiout);
1647		if (err < 0)
1648			return err;
1649		spec->multiout.share_spdif = 1;
1650	}
1651	if (spec->dig_in_nid) {
1652		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1653		if (err < 0)
1654			return err;
1655	}
1656
1657	/* if we have no master control, let's create it */
1658	if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1659		unsigned int vmaster_tlv[4];
1660		snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1661					HDA_OUTPUT, vmaster_tlv);
1662		err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1663					  vmaster_tlv, alc_slave_vols);
1664		if (err < 0)
1665			return err;
1666	}
1667	if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1668		err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1669					  NULL, alc_slave_sws);
1670		if (err < 0)
1671			return err;
1672	}
1673
1674	return 0;
1675}
1676
1677
1678/*
1679 * initialize the codec volumes, etc
1680 */
1681
1682/*
1683 * generic initialization of ADC, input mixers and output mixers
1684 */
1685static struct hda_verb alc880_volume_init_verbs[] = {
1686	/*
1687	 * Unmute ADC0-2 and set the default input to mic-in
1688	 */
1689	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1690	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1691	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1692	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1693	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1694	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1695
1696	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1697	 * mixer widget
1698	 * Note: PASD motherboards uses the Line In 2 as the input for front
1699	 * panel mic (mic 2)
1700	 */
1701	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1702	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1703	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1704	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1705	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1706	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1707	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1708	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1709
1710	/*
1711	 * Set up output mixers (0x0c - 0x0f)
1712	 */
1713	/* set vol=0 to output mixers */
1714	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1715	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1716	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1717	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1718	/* set up input amps for analog loopback */
1719	/* Amp Indices: DAC = 0, mixer = 1 */
1720	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1721	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1722	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1723	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1724	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1725	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1726	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1727	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1728
1729	{ }
1730};
1731
1732/*
1733 * 3-stack pin configuration:
1734 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1735 */
1736static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1737	/*
1738	 * preset connection lists of input pins
1739	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1740	 */
1741	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1742	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1743	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1744
1745	/*
1746	 * Set pin mode and muting
1747	 */
1748	/* set front pin widgets 0x14 for output */
1749	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1750	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1751	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1752	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1753	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1754	/* Mic2 (as headphone out) for HP output */
1755	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1756	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1757	/* Line In pin widget for input */
1758	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1759	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1760	/* Line2 (as front mic) pin widget for input and vref at 80% */
1761	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1762	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1763	/* CD pin widget for input */
1764	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1765
1766	{ }
1767};
1768
1769/*
1770 * 5-stack pin configuration:
1771 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1772 * line-in/side = 0x1a, f-mic = 0x1b
1773 */
1774static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1775	/*
1776	 * preset connection lists of input pins
1777	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1778	 */
1779	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1780	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1781
1782	/*
1783	 * Set pin mode and muting
1784	 */
1785	/* set pin widgets 0x14-0x17 for output */
1786	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1787	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1788	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1789	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1790	/* unmute pins for output (no gain on this amp) */
1791	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1792	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1793	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1794	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1795
1796	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1797	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1798	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1799	/* Mic2 (as headphone out) for HP output */
1800	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1801	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1802	/* Line In pin widget for input */
1803	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1804	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1805	/* Line2 (as front mic) pin widget for input and vref at 80% */
1806	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1807	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1808	/* CD pin widget for input */
1809	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1810
1811	{ }
1812};
1813
1814/*
1815 * W810 pin configuration:
1816 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1817 */
1818static struct hda_verb alc880_pin_w810_init_verbs[] = {
1819	/* hphone/speaker input selector: front DAC */
1820	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1821
1822	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1823	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1824	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1825	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1826	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1827	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1828
1829	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1830	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1831
1832	{ }
1833};
1834
1835/*
1836 * Z71V pin configuration:
1837 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1838 */
1839static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1840	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1841	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1842	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1843	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1844
1845	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1846	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1847	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1848	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1849
1850	{ }
1851};
1852
1853/*
1854 * 6-stack pin configuration:
1855 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1856 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1857 */
1858static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1859	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1860
1861	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1862	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1863	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1864	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1865	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1866	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1867	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1868	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1869
1870	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1871	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1872	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1873	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1874	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1875	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1876	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1877	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1878	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1879
1880	{ }
1881};
1882
1883/*
1884 * Uniwill pin configuration:
1885 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1886 * line = 0x1a
1887 */
1888static struct hda_verb alc880_uniwill_init_verbs[] = {
1889	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1890
1891	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1892	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1893	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1894	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1895	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1896	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1897	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1898	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1899	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1900	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1901	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1902	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1903	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1904	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1905
1906	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1907	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1908	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1909	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1910	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1911	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1912	/* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1913	/* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1914	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1915
1916	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1917	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1918
1919	{ }
1920};
1921
1922/*
1923* Uniwill P53
1924* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1925 */
1926static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1927	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1928
1929	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1930	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1931	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1932	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1933	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1934	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1935	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1936	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1937	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1938	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1939	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1940	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1941
1942	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1943	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1944	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1945	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1946	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1947	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1948
1949	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1950	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1951
1952	{ }
1953};
1954
1955static struct hda_verb alc880_beep_init_verbs[] = {
1956	{ 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1957	{ }
1958};
1959
1960/* toggle speaker-output according to the hp-jack state */
1961static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1962{
1963 	unsigned int present;
1964	unsigned char bits;
1965
1966 	present = snd_hda_codec_read(codec, 0x14, 0,
1967				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1968	bits = present ? HDA_AMP_MUTE : 0;
1969	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1970				 HDA_AMP_MUTE, bits);
1971	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1972				 HDA_AMP_MUTE, bits);
1973}
1974
1975/* auto-toggle front mic */
1976static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1977{
1978 	unsigned int present;
1979	unsigned char bits;
1980
1981	present = snd_hda_codec_read(codec, 0x18, 0,
1982				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1983	bits = present ? HDA_AMP_MUTE : 0;
1984	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
1985}
1986
1987static void alc880_uniwill_automute(struct hda_codec *codec)
1988{
1989	alc880_uniwill_hp_automute(codec);
1990	alc880_uniwill_mic_automute(codec);
1991}
1992
1993static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1994				       unsigned int res)
1995{
1996	/* Looks like the unsol event is incompatible with the standard
1997	 * definition.  4bit tag is placed at 28 bit!
1998	 */
1999	switch (res >> 28) {
2000	case ALC880_HP_EVENT:
2001		alc880_uniwill_hp_automute(codec);
2002		break;
2003	case ALC880_MIC_EVENT:
2004		alc880_uniwill_mic_automute(codec);
2005		break;
2006	}
2007}
2008
2009static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
2010{
2011 	unsigned int present;
2012	unsigned char bits;
2013
2014 	present = snd_hda_codec_read(codec, 0x14, 0,
2015				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2016	bits = present ? HDA_AMP_MUTE : 0;
2017	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
2018}
2019
2020static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2021{
2022	unsigned int present;
2023
2024	present = snd_hda_codec_read(codec, 0x21, 0,
2025				     AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2026	present &= HDA_AMP_VOLMASK;
2027	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2028				 HDA_AMP_VOLMASK, present);
2029	snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2030				 HDA_AMP_VOLMASK, present);
2031}
2032
2033static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2034					   unsigned int res)
2035{
2036	/* Looks like the unsol event is incompatible with the standard
2037	 * definition.  4bit tag is placed at 28 bit!
2038	 */
2039	if ((res >> 28) == ALC880_HP_EVENT)
2040		alc880_uniwill_p53_hp_automute(codec);
2041	if ((res >> 28) == ALC880_DCVOL_EVENT)
2042		alc880_uniwill_p53_dcvol_automute(codec);
2043}
2044
2045/*
2046 * F1734 pin configuration:
2047 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2048 */
2049static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2050	{0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2051	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2052	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2053	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2054	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2055
2056	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2057	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2058	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2059	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2060
2061	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2062	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2063	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2064	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2065	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2066	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2067	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2068	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2069	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2070
2071	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2072	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2073
2074	{ }
2075};
2076
2077/*
2078 * ASUS pin configuration:
2079 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2080 */
2081static struct hda_verb alc880_pin_asus_init_verbs[] = {
2082	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2083	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2084	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2085	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2086
2087	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2088	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2089	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2090	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2091	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2092	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2093	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2094	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2095
2096	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2097	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2098	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2099	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2100	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2101	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2102	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2103	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2104	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2105
2106	{ }
2107};
2108
2109/* Enable GPIO mask and set output */
2110#define alc880_gpio1_init_verbs	alc_gpio1_init_verbs
2111#define alc880_gpio2_init_verbs	alc_gpio2_init_verbs
2112
2113/* Clevo m520g init */
2114static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2115	/* headphone output */
2116	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2117	/* line-out */
2118	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2119	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2120	/* Line-in */
2121	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2122	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2123	/* CD */
2124	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2125	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2126	/* Mic1 (rear panel) */
2127	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2128	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2129	/* Mic2 (front panel) */
2130	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2131	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2132	/* headphone */
2133	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2134	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2135        /* change to EAPD mode */
2136	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2137	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2138
2139	{ }
2140};
2141
2142static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2143	/* change to EAPD mode */
2144	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2145	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2146
2147	/* Headphone output */
2148	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2149	/* Front output*/
2150	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2151	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2152
2153	/* Line In pin widget for input */
2154	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2155	/* CD pin widget for input */
2156	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2157	/* Mic1 (rear panel) pin widget for input and vref at 80% */
2158	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2159
2160	/* change to EAPD mode */
2161	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2162	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
2163
2164	{ }
2165};
2166
2167/*
2168 * LG m1 express dual
2169 *
2170 * Pin assignment:
2171 *   Rear Line-In/Out (blue): 0x14
2172 *   Build-in Mic-In: 0x15
2173 *   Speaker-out: 0x17
2174 *   HP-Out (green): 0x1b
2175 *   Mic-In/Out (red): 0x19
2176 *   SPDIF-Out: 0x1e
2177 */
2178
2179/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2180static hda_nid_t alc880_lg_dac_nids[3] = {
2181	0x05, 0x02, 0x03
2182};
2183
2184/* seems analog CD is not working */
2185static struct hda_input_mux alc880_lg_capture_source = {
2186	.num_items = 3,
2187	.items = {
2188		{ "Mic", 0x1 },
2189		{ "Line", 0x5 },
2190		{ "Internal Mic", 0x6 },
2191	},
2192};
2193
2194/* 2,4,6 channel modes */
2195static struct hda_verb alc880_lg_ch2_init[] = {
2196	/* set line-in and mic-in to input */
2197	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2198	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2199	{ }
2200};
2201
2202static struct hda_verb alc880_lg_ch4_init[] = {
2203	/* set line-in to out and mic-in to input */
2204	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2205	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2206	{ }
2207};
2208
2209static struct hda_verb alc880_lg_ch6_init[] = {
2210	/* set line-in and mic-in to output */
2211	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2212	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2213	{ }
2214};
2215
2216static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2217	{ 2, alc880_lg_ch2_init },
2218	{ 4, alc880_lg_ch4_init },
2219	{ 6, alc880_lg_ch6_init },
2220};
2221
2222static struct snd_kcontrol_new alc880_lg_mixer[] = {
2223	HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2224	HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2225	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2226	HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2227	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2228	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2229	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2230	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2231	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2232	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2233	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2234	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2235	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2236	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2237	{
2238		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2239		.name = "Channel Mode",
2240		.info = alc_ch_mode_info,
2241		.get = alc_ch_mode_get,
2242		.put = alc_ch_mode_put,
2243	},
2244	{ } /* end */
2245};
2246
2247static struct hda_verb alc880_lg_init_verbs[] = {
2248	/* set capture source to mic-in */
2249	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2250	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2251	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2252	/* mute all amp mixer inputs */
2253	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2254	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2255	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2256	/* line-in to input */
2257	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2258	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2259	/* built-in mic */
2260	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2261	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2262	/* speaker-out */
2263	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2264	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2265	/* mic-in to input */
2266	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2267	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2268	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2269	/* HP-out */
2270	{0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2271	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2272	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2273	/* jack sense */
2274	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2275	{ }
2276};
2277
2278/* toggle speaker-output according to the hp-jack state */
2279static void alc880_lg_automute(struct hda_codec *codec)
2280{
2281	unsigned int present;
2282	unsigned char bits;
2283
2284	present = snd_hda_codec_read(codec, 0x1b, 0,
2285				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2286	bits = present ? HDA_AMP_MUTE : 0;
2287	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2288				 HDA_AMP_MUTE, bits);
2289}
2290
2291static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2292{
2293	/* Looks like the unsol event is incompatible with the standard
2294	 * definition.  4bit tag is placed at 28 bit!
2295	 */
2296	if ((res >> 28) == 0x01)
2297		alc880_lg_automute(codec);
2298}
2299
2300/*
2301 * LG LW20
2302 *
2303 * Pin assignment:
2304 *   Speaker-out: 0x14
2305 *   Mic-In: 0x18
2306 *   Built-in Mic-In: 0x19
2307 *   Line-In: 0x1b
2308 *   HP-Out: 0x1a
2309 *   SPDIF-Out: 0x1e
2310 */
2311
2312static struct hda_input_mux alc880_lg_lw_capture_source = {
2313	.num_items = 3,
2314	.items = {
2315		{ "Mic", 0x0 },
2316		{ "Internal Mic", 0x1 },
2317		{ "Line In", 0x2 },
2318	},
2319};
2320
2321#define alc880_lg_lw_modes alc880_threestack_modes
2322
2323static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2324	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2325	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2326	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2327	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2328	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2329	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2330	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2331	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2332	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2333	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2334	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2335	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2336	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2337	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2338	{
2339		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2340		.name = "Channel Mode",
2341		.info = alc_ch_mode_info,
2342		.get = alc_ch_mode_get,
2343		.put = alc_ch_mode_put,
2344	},
2345	{ } /* end */
2346};
2347
2348static struct hda_verb alc880_lg_lw_init_verbs[] = {
2349	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2350	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2351	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2352
2353	/* set capture source to mic-in */
2354	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2355	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2356	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2357	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2358	/* speaker-out */
2359	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2360	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2361	/* HP-out */
2362	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2363	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2364	/* mic-in to input */
2365	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2366	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2367	/* built-in mic */
2368	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2369	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2370	/* jack sense */
2371	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2372	{ }
2373};
2374
2375/* toggle speaker-output according to the hp-jack state */
2376static void alc880_lg_lw_automute(struct hda_codec *codec)
2377{
2378	unsigned int present;
2379	unsigned char bits;
2380
2381	present = snd_hda_codec_read(codec, 0x1b, 0,
2382				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2383	bits = present ? HDA_AMP_MUTE : 0;
2384	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2385				 HDA_AMP_MUTE, bits);
2386}
2387
2388static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2389{
2390	/* Looks like the unsol event is incompatible with the standard
2391	 * definition.  4bit tag is placed at 28 bit!
2392	 */
2393	if ((res >> 28) == 0x01)
2394		alc880_lg_lw_automute(codec);
2395}
2396
2397static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2398	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2399	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2400	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2401	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2402	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2403	HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2404	{ } /* end */
2405};
2406
2407static struct hda_input_mux alc880_medion_rim_capture_source = {
2408	.num_items = 2,
2409	.items = {
2410		{ "Mic", 0x0 },
2411		{ "Internal Mic", 0x1 },
2412	},
2413};
2414
2415static struct hda_verb alc880_medion_rim_init_verbs[] = {
2416	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2417
2418	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2419	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2420
2421	/* Mic1 (rear panel) pin widget for input and vref at 80% */
2422	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2423	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2424	/* Mic2 (as headphone out) for HP output */
2425	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2426	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2427	/* Internal Speaker */
2428	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2429	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2430
2431	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2432	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2433
2434	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2435	{ }
2436};
2437
2438/* toggle speaker-output according to the hp-jack state */
2439static void alc880_medion_rim_automute(struct hda_codec *codec)
2440{
2441	unsigned int present;
2442	unsigned char bits;
2443
2444	present = snd_hda_codec_read(codec, 0x14, 0,
2445				     AC_VERB_GET_PIN_SENSE, 0)
2446		& AC_PINSENSE_PRESENCE;
2447	bits = present ? HDA_AMP_MUTE : 0;
2448	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
2449				 HDA_AMP_MUTE, bits);
2450	if (present)
2451		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2452	else
2453		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2454}
2455
2456static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2457					  unsigned int res)
2458{
2459	/* Looks like the unsol event is incompatible with the standard
2460	 * definition.  4bit tag is placed at 28 bit!
2461	 */
2462	if ((res >> 28) == ALC880_HP_EVENT)
2463		alc880_medion_rim_automute(codec);
2464}
2465
2466#ifdef CONFIG_SND_HDA_POWER_SAVE
2467static struct hda_amp_list alc880_loopbacks[] = {
2468	{ 0x0b, HDA_INPUT, 0 },
2469	{ 0x0b, HDA_INPUT, 1 },
2470	{ 0x0b, HDA_INPUT, 2 },
2471	{ 0x0b, HDA_INPUT, 3 },
2472	{ 0x0b, HDA_INPUT, 4 },
2473	{ } /* end */
2474};
2475
2476static struct hda_amp_list alc880_lg_loopbacks[] = {
2477	{ 0x0b, HDA_INPUT, 1 },
2478	{ 0x0b, HDA_INPUT, 6 },
2479	{ 0x0b, HDA_INPUT, 7 },
2480	{ } /* end */
2481};
2482#endif
2483
2484/*
2485 * Common callbacks
2486 */
2487
2488static int alc_init(struct hda_codec *codec)
2489{
2490	struct alc_spec *spec = codec->spec;
2491	unsigned int i;
2492
2493	alc_fix_pll(codec);
2494	if (codec->vendor_id == 0x10ec0888)
2495		alc888_coef_init(codec);
2496
2497	for (i = 0; i < spec->num_init_verbs; i++)
2498		snd_hda_sequence_write(codec, spec->init_verbs[i]);
2499
2500	if (spec->init_hook)
2501		spec->init_hook(codec);
2502
2503	return 0;
2504}
2505
2506static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2507{
2508	struct alc_spec *spec = codec->spec;
2509
2510	if (spec->unsol_event)
2511		spec->unsol_event(codec, res);
2512}
2513
2514#ifdef CONFIG_SND_HDA_POWER_SAVE
2515static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2516{
2517	struct alc_spec *spec = codec->spec;
2518	return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2519}
2520#endif
2521
2522/*
2523 * Analog playback callbacks
2524 */
2525static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2526				    struct hda_codec *codec,
2527				    struct snd_pcm_substream *substream)
2528{
2529	struct alc_spec *spec = codec->spec;
2530	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2531					     hinfo);
2532}
2533
2534static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2535				       struct hda_codec *codec,
2536				       unsigned int stream_tag,
2537				       unsigned int format,
2538				       struct snd_pcm_substream *substream)
2539{
2540	struct alc_spec *spec = codec->spec;
2541	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2542						stream_tag, format, substream);
2543}
2544
2545static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2546				       struct hda_codec *codec,
2547				       struct snd_pcm_substream *substream)
2548{
2549	struct alc_spec *spec = codec->spec;
2550	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2551}
2552
2553/*
2554 * Digital out
2555 */
2556static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2557					struct hda_codec *codec,
2558					struct snd_pcm_substream *substream)
2559{
2560	struct alc_spec *spec = codec->spec;
2561	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2562}
2563
2564static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2565					   struct hda_codec *codec,
2566					   unsigned int stream_tag,
2567					   unsigned int format,
2568					   struct snd_pcm_substream *substream)
2569{
2570	struct alc_spec *spec = codec->spec;
2571	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2572					     stream_tag, format, substream);
2573}
2574
2575static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2576					 struct hda_codec *codec,
2577					 struct snd_pcm_substream *substream)
2578{
2579	struct alc_spec *spec = codec->spec;
2580	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2581}
2582
2583/*
2584 * Analog capture
2585 */
2586static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2587				      struct hda_codec *codec,
2588				      unsigned int stream_tag,
2589				      unsigned int format,
2590				      struct snd_pcm_substream *substream)
2591{
2592	struct alc_spec *spec = codec->spec;
2593
2594	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
2595				   stream_tag, 0, format);
2596	return 0;
2597}
2598
2599static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2600				      struct hda_codec *codec,
2601				      struct snd_pcm_substream *substream)
2602{
2603	struct alc_spec *spec = codec->spec;
2604
2605	snd_hda_codec_cleanup_stream(codec,
2606				     spec->adc_nids[substream->number + 1]);
2607	return 0;
2608}
2609
2610
2611/*
2612 */
2613static struct hda_pcm_stream alc880_pcm_analog_playback = {
2614	.substreams = 1,
2615	.channels_min = 2,
2616	.channels_max = 8,
2617	/* NID is set in alc_build_pcms */
2618	.ops = {
2619		.open = alc880_playback_pcm_open,
2620		.prepare = alc880_playback_pcm_prepare,
2621		.cleanup = alc880_playback_pcm_cleanup
2622	},
2623};
2624
2625static struct hda_pcm_stream alc880_pcm_analog_capture = {
2626	.substreams = 1,
2627	.channels_min = 2,
2628	.channels_max = 2,
2629	/* NID is set in alc_build_pcms */
2630};
2631
2632static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
2633	.substreams = 1,
2634	.channels_min = 2,
2635	.channels_max = 2,
2636	/* NID is set in alc_build_pcms */
2637};
2638
2639static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
2640	.substreams = 2, /* can be overridden */
2641	.channels_min = 2,
2642	.channels_max = 2,
2643	/* NID is set in alc_build_pcms */
2644	.ops = {
2645		.prepare = alc880_alt_capture_pcm_prepare,
2646		.cleanup = alc880_alt_capture_pcm_cleanup
2647	},
2648};
2649
2650static struct hda_pcm_stream alc880_pcm_digital_playback = {
2651	.substreams = 1,
2652	.channels_min = 2,
2653	.channels_max = 2,
2654	/* NID is set in alc_build_pcms */
2655	.ops = {
2656		.open = alc880_dig_playback_pcm_open,
2657		.close = alc880_dig_playback_pcm_close,
2658		.prepare = alc880_dig_playback_pcm_prepare
2659	},
2660};
2661
2662static struct hda_pcm_stream alc880_pcm_digital_capture = {
2663	.substreams = 1,
2664	.channels_min = 2,
2665	.channels_max = 2,
2666	/* NID is set in alc_build_pcms */
2667};
2668
2669/* Used by alc_build_pcms to flag that a PCM has no playback stream */
2670static struct hda_pcm_stream alc_pcm_null_stream = {
2671	.substreams = 0,
2672	.channels_min = 0,
2673	.channels_max = 0,
2674};
2675
2676static int alc_build_pcms(struct hda_codec *codec)
2677{
2678	struct alc_spec *spec = codec->spec;
2679	struct hda_pcm *info = spec->pcm_rec;
2680	int i;
2681
2682	codec->num_pcms = 1;
2683	codec->pcm_info = info;
2684
2685	info->name = spec->stream_name_analog;
2686	if (spec->stream_analog_playback) {
2687		if (snd_BUG_ON(!spec->multiout.dac_nids))
2688			return -EINVAL;
2689		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2690		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2691	}
2692	if (spec->stream_analog_capture) {
2693		if (snd_BUG_ON(!spec->adc_nids))
2694			return -EINVAL;
2695		info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2696		info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2697	}
2698
2699	if (spec->channel_mode) {
2700		info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2701		for (i = 0; i < spec->num_channel_mode; i++) {
2702			if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2703				info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2704			}
2705		}
2706	}
2707
2708	/* SPDIF for stream index #1 */
2709	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2710		codec->num_pcms = 2;
2711		info = spec->pcm_rec + 1;
2712		info->name = spec->stream_name_digital;
2713		info->pcm_type = HDA_PCM_TYPE_SPDIF;
2714		if (spec->multiout.dig_out_nid &&
2715		    spec->stream_digital_playback) {
2716			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2717			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2718		}
2719		if (spec->dig_in_nid &&
2720		    spec->stream_digital_capture) {
2721			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2722			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2723		}
2724		/* FIXME: do we need this for all Realtek codec models? */
2725		codec->spdif_status_reset = 1;
2726	}
2727
2728	/* If the use of more than one ADC is requested for the current
2729	 * model, configure a second analog capture-only PCM.
2730	 */
2731	/* Additional Analaog capture for index #2 */
2732	if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
2733	    (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
2734		codec->num_pcms = 3;
2735		info = spec->pcm_rec + 2;
2736		info->name = spec->stream_name_analog;
2737		if (spec->alt_dac_nid) {
2738			info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2739				*spec->stream_analog_alt_playback;
2740			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2741				spec->alt_dac_nid;
2742		} else {
2743			info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2744				alc_pcm_null_stream;
2745			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2746		}
2747		if (spec->num_adc_nids > 1) {
2748			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2749				*spec->stream_analog_alt_capture;
2750			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
2751				spec->adc_nids[1];
2752			info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
2753				spec->num_adc_nids - 1;
2754		} else {
2755			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2756				alc_pcm_null_stream;
2757			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
2758		}
2759	}
2760
2761	return 0;
2762}
2763
2764static void alc_free(struct hda_codec *codec)
2765{
2766	struct alc_spec *spec = codec->spec;
2767	unsigned int i;
2768
2769	if (!spec)
2770		return;
2771
2772	if (spec->kctl_alloc) {
2773		for (i = 0; i < spec->num_kctl_used; i++)
2774			kfree(spec->kctl_alloc[i].name);
2775		kfree(spec->kctl_alloc);
2776	}
2777	kfree(spec);
2778	codec->spec = NULL; /* to be sure */
2779}
2780
2781/*
2782 */
2783static struct hda_codec_ops alc_patch_ops = {
2784	.build_controls = alc_build_controls,
2785	.build_pcms = alc_build_pcms,
2786	.init = alc_init,
2787	.free = alc_free,
2788	.unsol_event = alc_unsol_event,
2789#ifdef CONFIG_SND_HDA_POWER_SAVE
2790	.check_power_status = alc_check_power_status,
2791#endif
2792};
2793
2794
2795/*
2796 * Test configuration for debugging
2797 *
2798 * Almost all inputs/outputs are enabled.  I/O pins can be configured via
2799 * enum controls.
2800 */
2801#ifdef CONFIG_SND_DEBUG
2802static hda_nid_t alc880_test_dac_nids[4] = {
2803	0x02, 0x03, 0x04, 0x05
2804};
2805
2806static struct hda_input_mux alc880_test_capture_source = {
2807	.num_items = 7,
2808	.items = {
2809		{ "In-1", 0x0 },
2810		{ "In-2", 0x1 },
2811		{ "In-3", 0x2 },
2812		{ "In-4", 0x3 },
2813		{ "CD", 0x4 },
2814		{ "Front", 0x5 },
2815		{ "Surround", 0x6 },
2816	},
2817};
2818
2819static struct hda_channel_mode alc880_test_modes[4] = {
2820	{ 2, NULL },
2821	{ 4, NULL },
2822	{ 6, NULL },
2823	{ 8, NULL },
2824};
2825
2826static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2827				 struct snd_ctl_elem_info *uinfo)
2828{
2829	static char *texts[] = {
2830		"N/A", "Line Out", "HP Out",
2831		"In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2832	};
2833	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2834	uinfo->count = 1;
2835	uinfo->value.enumerated.items = 8;
2836	if (uinfo->value.enumerated.item >= 8)
2837		uinfo->value.enumerated.item = 7;
2838	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2839	return 0;
2840}
2841
2842static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2843				struct snd_ctl_elem_value *ucontrol)
2844{
2845	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2846	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2847	unsigned int pin_ctl, item = 0;
2848
2849	pin_ctl = snd_hda_codec_read(codec, nid, 0,
2850				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2851	if (pin_ctl & AC_PINCTL_OUT_EN) {
2852		if (pin_ctl & AC_PINCTL_HP_EN)
2853			item = 2;
2854		else
2855			item = 1;
2856	} else if (pin_ctl & AC_PINCTL_IN_EN) {
2857		switch (pin_ctl & AC_PINCTL_VREFEN) {
2858		case AC_PINCTL_VREF_HIZ: item = 3; break;
2859		case AC_PINCTL_VREF_50:  item = 4; break;
2860		case AC_PINCTL_VREF_GRD: item = 5; break;
2861		case AC_PINCTL_VREF_80:  item = 6; break;
2862		case AC_PINCTL_VREF_100: item = 7; break;
2863		}
2864	}
2865	ucontrol->value.enumerated.item[0] = item;
2866	return 0;
2867}
2868
2869static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2870				struct snd_ctl_elem_value *ucontrol)
2871{
2872	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2873	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2874	static unsigned int ctls[] = {
2875		0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2876		AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2877		AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2878		AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2879		AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2880		AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2881	};
2882	unsigned int old_ctl, new_ctl;
2883
2884	old_ctl = snd_hda_codec_read(codec, nid, 0,
2885				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2886	new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2887	if (old_ctl != new_ctl) {
2888		int val;
2889		snd_hda_codec_write_cache(codec, nid, 0,
2890					  AC_VERB_SET_PIN_WIDGET_CONTROL,
2891					  new_ctl);
2892		val = ucontrol->value.enumerated.item[0] >= 3 ?
2893			HDA_AMP_MUTE : 0;
2894		snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2895					 HDA_AMP_MUTE, val);
2896		return 1;
2897	}
2898	return 0;
2899}
2900
2901static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2902				 struct snd_ctl_elem_info *uinfo)
2903{
2904	static char *texts[] = {
2905		"Front", "Surround", "CLFE", "Side"
2906	};
2907	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2908	uinfo->count = 1;
2909	uinfo->value.enumerated.items = 4;
2910	if (uinfo->value.enumerated.item >= 4)
2911		uinfo->value.enumerated.item = 3;
2912	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2913	return 0;
2914}
2915
2916static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2917				struct snd_ctl_elem_value *ucontrol)
2918{
2919	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2920	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2921	unsigned int sel;
2922
2923	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2924	ucontrol->value.enumerated.item[0] = sel & 3;
2925	return 0;
2926}
2927
2928static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2929				struct snd_ctl_elem_value *ucontrol)
2930{
2931	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2932	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2933	unsigned int sel;
2934
2935	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2936	if (ucontrol->value.enumerated.item[0] != sel) {
2937		sel = ucontrol->value.enumerated.item[0] & 3;
2938		snd_hda_codec_write_cache(codec, nid, 0,
2939					  AC_VERB_SET_CONNECT_SEL, sel);
2940		return 1;
2941	}
2942	return 0;
2943}
2944
2945#define PIN_CTL_TEST(xname,nid) {			\
2946		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
2947			.name = xname,		       \
2948			.info = alc_test_pin_ctl_info, \
2949			.get = alc_test_pin_ctl_get,   \
2950			.put = alc_test_pin_ctl_put,   \
2951			.private_value = nid	       \
2952			}
2953
2954#define PIN_SRC_TEST(xname,nid) {			\
2955		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
2956			.name = xname,		       \
2957			.info = alc_test_pin_src_info, \
2958			.get = alc_test_pin_src_get,   \
2959			.put = alc_test_pin_src_put,   \
2960			.private_value = nid	       \
2961			}
2962
2963static struct snd_kcontrol_new alc880_test_mixer[] = {
2964	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2965	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2966	HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2967	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2968	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2969	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2970	HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2971	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2972	PIN_CTL_TEST("Front Pin Mode", 0x14),
2973	PIN_CTL_TEST("Surround Pin Mode", 0x15),
2974	PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2975	PIN_CTL_TEST("Side Pin Mode", 0x17),
2976	PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2977	PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2978	PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2979	PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2980	PIN_SRC_TEST("In-1 Pin Source", 0x18),
2981	PIN_SRC_TEST("In-2 Pin Source", 0x19),
2982	PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2983	PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2984	HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2985	HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2986	HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2987	HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2988	HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2989	HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2990	HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2991	HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2992	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2993	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2994	{
2995		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2996		.name = "Channel Mode",
2997		.info = alc_ch_mode_info,
2998		.get = alc_ch_mode_get,
2999		.put = alc_ch_mode_put,
3000	},
3001	{ } /* end */
3002};
3003
3004static struct hda_verb alc880_test_init_verbs[] = {
3005	/* Unmute inputs of 0x0c - 0x0f */
3006	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3007	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3008	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3009	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3010	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3011	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3012	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3013	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3014	/* Vol output for 0x0c-0x0f */
3015	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3016	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3017	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3018	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3019	/* Set output pins 0x14-0x17 */
3020	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3021	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3022	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3023	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3024	/* Unmute output pins 0x14-0x17 */
3025	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3026	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3027	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3028	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3029	/* Set input pins 0x18-0x1c */
3030	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3031	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3032	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3033	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3034	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3035	/* Mute input pins 0x18-0x1b */
3036	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3037	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3038	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3039	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3040	/* ADC set up */
3041	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3042	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3043	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3044	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3045	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3046	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3047	/* Analog input/passthru */
3048	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3049	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3050	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3051	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3052	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3053	{ }
3054};
3055#endif
3056
3057/*
3058 */
3059
3060static const char *alc880_models[ALC880_MODEL_LAST] = {
3061	[ALC880_3ST]		= "3stack",
3062	[ALC880_TCL_S700]	= "tcl",
3063	[ALC880_3ST_DIG]	= "3stack-digout",
3064	[ALC880_CLEVO]		= "clevo",
3065	[ALC880_5ST]		= "5stack",
3066	[ALC880_5ST_DIG]	= "5stack-digout",
3067	[ALC880_W810]		= "w810",
3068	[ALC880_Z71V]		= "z71v",
3069	[ALC880_6ST]		= "6stack",
3070	[ALC880_6ST_DIG]	= "6stack-digout",
3071	[ALC880_ASUS]		= "asus",
3072	[ALC880_ASUS_W1V]	= "asus-w1v",
3073	[ALC880_ASUS_DIG]	= "asus-dig",
3074	[ALC880_ASUS_DIG2]	= "asus-dig2",
3075	[ALC880_UNIWILL_DIG]	= "uniwill",
3076	[ALC880_UNIWILL_P53]	= "uniwill-p53",
3077	[ALC880_FUJITSU]	= "fujitsu",
3078	[ALC880_F1734]		= "F1734",
3079	[ALC880_LG]		= "lg",
3080	[ALC880_LG_LW]		= "lg-lw",
3081	[ALC880_MEDION_RIM]	= "medion",
3082#ifdef CONFIG_SND_DEBUG
3083	[ALC880_TEST]		= "test",
3084#endif
3085	[ALC880_AUTO]		= "auto",
3086};
3087
3088static struct snd_pci_quirk alc880_cfg_tbl[] = {
3089	SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3090	SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3091	SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3092	SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3093	SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3094	SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3095	SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3096	SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3097	SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3098	SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3099	SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3100	SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3101	SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3102	SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3103	SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3104	SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3105	SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3106	SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3107	/* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3108	SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3109	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3110	SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3111	SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3112	SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3113	SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3114	SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
3115	SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3116	SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3117	SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3118	SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3119	SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3120	SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3121	SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3122	SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3123	SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3124	SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3125	SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3126	SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3127	SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3128	SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3129	SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3130	SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3131	SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3132	SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3133	SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3134	SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3135	SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3136	SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3137	SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3138	SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3139	SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3140	SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3141	SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3142	SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3143	SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3144	SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3145	SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3146	SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3147	SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3148	SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3149	SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3150	SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3151	SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3152	SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3153	SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3154	SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3155	SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3156	SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3157	SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
3158	SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3159	SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3160	{}
3161};
3162
3163/*
3164 * ALC880 codec presets
3165 */
3166static struct alc_config_preset alc880_presets[] = {
3167	[ALC880_3ST] = {
3168		.mixers = { alc880_three_stack_mixer },
3169		.init_verbs = { alc880_volume_init_verbs,
3170				alc880_pin_3stack_init_verbs },
3171		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3172		.dac_nids = alc880_dac_nids,
3173		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3174		.channel_mode = alc880_threestack_modes,
3175		.need_dac_fix = 1,
3176		.input_mux = &alc880_capture_source,
3177	},
3178	[ALC880_3ST_DIG] = {
3179		.mixers = { alc880_three_stack_mixer },
3180		.init_verbs = { alc880_volume_init_verbs,
3181				alc880_pin_3stack_init_verbs },
3182		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3183		.dac_nids = alc880_dac_nids,
3184		.dig_out_nid = ALC880_DIGOUT_NID,
3185		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3186		.channel_mode = alc880_threestack_modes,
3187		.need_dac_fix = 1,
3188		.input_mux = &alc880_capture_source,
3189	},
3190	[ALC880_TCL_S700] = {
3191		.mixers = { alc880_tcl_s700_mixer },
3192		.init_verbs = { alc880_volume_init_verbs,
3193				alc880_pin_tcl_S700_init_verbs,
3194				alc880_gpio2_init_verbs },
3195		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3196		.dac_nids = alc880_dac_nids,
3197		.hp_nid = 0x03,
3198		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3199		.channel_mode = alc880_2_jack_modes,
3200		.input_mux = &alc880_capture_source,
3201	},
3202	[ALC880_5ST] = {
3203		.mixers = { alc880_three_stack_mixer,
3204			    alc880_five_stack_mixer},
3205		.init_verbs = { alc880_volume_init_verbs,
3206				alc880_pin_5stack_init_verbs },
3207		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3208		.dac_nids = alc880_dac_nids,
3209		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3210		.channel_mode = alc880_fivestack_modes,
3211		.input_mux = &alc880_capture_source,
3212	},
3213	[ALC880_5ST_DIG] = {
3214		.mixers = { alc880_three_stack_mixer,
3215			    alc880_five_stack_mixer },
3216		.init_verbs = { alc880_volume_init_verbs,
3217				alc880_pin_5stack_init_verbs },
3218		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3219		.dac_nids = alc880_dac_nids,
3220		.dig_out_nid = ALC880_DIGOUT_NID,
3221		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3222		.channel_mode = alc880_fivestack_modes,
3223		.input_mux = &alc880_capture_source,
3224	},
3225	[ALC880_6ST] = {
3226		.mixers = { alc880_six_stack_mixer },
3227		.init_verbs = { alc880_volume_init_verbs,
3228				alc880_pin_6stack_init_verbs },
3229		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3230		.dac_nids = alc880_6st_dac_nids,
3231		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3232		.channel_mode = alc880_sixstack_modes,
3233		.input_mux = &alc880_6stack_capture_source,
3234	},
3235	[ALC880_6ST_DIG] = {
3236		.mixers = { alc880_six_stack_mixer },
3237		.init_verbs = { alc880_volume_init_verbs,
3238				alc880_pin_6stack_init_verbs },
3239		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3240		.dac_nids = alc880_6st_dac_nids,
3241		.dig_out_nid = ALC880_DIGOUT_NID,
3242		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3243		.channel_mode = alc880_sixstack_modes,
3244		.input_mux = &alc880_6stack_capture_source,
3245	},
3246	[ALC880_W810] = {
3247		.mixers = { alc880_w810_base_mixer },
3248		.init_verbs = { alc880_volume_init_verbs,
3249				alc880_pin_w810_init_verbs,
3250				alc880_gpio2_init_verbs },
3251		.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3252		.dac_nids = alc880_w810_dac_nids,
3253		.dig_out_nid = ALC880_DIGOUT_NID,
3254		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3255		.channel_mode = alc880_w810_modes,
3256		.input_mux = &alc880_capture_source,
3257	},
3258	[ALC880_Z71V] = {
3259		.mixers = { alc880_z71v_mixer },
3260		.init_verbs = { alc880_volume_init_verbs,
3261				alc880_pin_z71v_init_verbs },
3262		.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3263		.dac_nids = alc880_z71v_dac_nids,
3264		.dig_out_nid = ALC880_DIGOUT_NID,
3265		.hp_nid = 0x03,
3266		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3267		.channel_mode = alc880_2_jack_modes,
3268		.input_mux = &alc880_capture_source,
3269	},
3270	[ALC880_F1734] = {
3271		.mixers = { alc880_f1734_mixer },
3272		.init_verbs = { alc880_volume_init_verbs,
3273				alc880_pin_f1734_init_verbs },
3274		.num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3275		.dac_nids = alc880_f1734_dac_nids,
3276		.hp_nid = 0x02,
3277		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3278		.channel_mode = alc880_2_jack_modes,
3279		.input_mux = &alc880_f1734_capture_source,
3280		.unsol_event = alc880_uniwill_p53_unsol_event,
3281		.init_hook = alc880_uniwill_p53_hp_automute,
3282	},
3283	[ALC880_ASUS] = {
3284		.mixers = { alc880_asus_mixer },
3285		.init_verbs = { alc880_volume_init_verbs,
3286				alc880_pin_asus_init_verbs,
3287				alc880_gpio1_init_verbs },
3288		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3289		.dac_nids = alc880_asus_dac_nids,
3290		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3291		.channel_mode = alc880_asus_modes,
3292		.need_dac_fix = 1,
3293		.input_mux = &alc880_capture_source,
3294	},
3295	[ALC880_ASUS_DIG] = {
3296		.mixers = { alc880_asus_mixer },
3297		.init_verbs = { alc880_volume_init_verbs,
3298				alc880_pin_asus_init_verbs,
3299				alc880_gpio1_init_verbs },
3300		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3301		.dac_nids = alc880_asus_dac_nids,
3302		.dig_out_nid = ALC880_DIGOUT_NID,
3303		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3304		.channel_mode = alc880_asus_modes,
3305		.need_dac_fix = 1,
3306		.input_mux = &alc880_capture_source,
3307	},
3308	[ALC880_ASUS_DIG2] = {
3309		.mixers = { alc880_asus_mixer },
3310		.init_verbs = { alc880_volume_init_verbs,
3311				alc880_pin_asus_init_verbs,
3312				alc880_gpio2_init_verbs }, /* use GPIO2 */
3313		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3314		.dac_nids = alc880_asus_dac_nids,
3315		.dig_out_nid = ALC880_DIGOUT_NID,
3316		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3317		.channel_mode = alc880_asus_modes,
3318		.need_dac_fix = 1,
3319		.input_mux = &alc880_capture_source,
3320	},
3321	[ALC880_ASUS_W1V] = {
3322		.mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3323		.init_verbs = { alc880_volume_init_verbs,
3324				alc880_pin_asus_init_verbs,
3325				alc880_gpio1_init_verbs },
3326		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3327		.dac_nids = alc880_asus_dac_nids,
3328		.dig_out_nid = ALC880_DIGOUT_NID,
3329		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3330		.channel_mode = alc880_asus_modes,
3331		.need_dac_fix = 1,
3332		.input_mux = &alc880_capture_source,
3333	},
3334	[ALC880_UNIWILL_DIG] = {
3335		.mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
3336		.init_verbs = { alc880_volume_init_verbs,
3337				alc880_pin_asus_init_verbs },
3338		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3339		.dac_nids = alc880_asus_dac_nids,
3340		.dig_out_nid = ALC880_DIGOUT_NID,
3341		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3342		.channel_mode = alc880_asus_modes,
3343		.need_dac_fix = 1,
3344		.input_mux = &alc880_capture_source,
3345	},
3346	[ALC880_UNIWILL] = {
3347		.mixers = { alc880_uniwill_mixer },
3348		.init_verbs = { alc880_volume_init_verbs,
3349				alc880_uniwill_init_verbs },
3350		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3351		.dac_nids = alc880_asus_dac_nids,
3352		.dig_out_nid = ALC880_DIGOUT_NID,
3353		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3354		.channel_mode = alc880_threestack_modes,
3355		.need_dac_fix = 1,
3356		.input_mux = &alc880_capture_source,
3357		.unsol_event = alc880_uniwill_unsol_event,
3358		.init_hook = alc880_uniwill_automute,
3359	},
3360	[ALC880_UNIWILL_P53] = {
3361		.mixers = { alc880_uniwill_p53_mixer },
3362		.init_verbs = { alc880_volume_init_verbs,
3363				alc880_uniwill_p53_init_verbs },
3364		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3365		.dac_nids = alc880_asus_dac_nids,
3366		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3367		.channel_mode = alc880_threestack_modes,
3368		.input_mux = &alc880_capture_source,
3369		.unsol_event = alc880_uniwill_p53_unsol_event,
3370		.init_hook = alc880_uniwill_p53_hp_automute,
3371	},
3372	[ALC880_FUJITSU] = {
3373		.mixers = { alc880_fujitsu_mixer,
3374			    alc880_pcbeep_mixer, },
3375		.init_verbs = { alc880_volume_init_verbs,
3376				alc880_uniwill_p53_init_verbs,
3377	       			alc880_beep_init_verbs },
3378		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3379		.dac_nids = alc880_dac_nids,
3380		.dig_out_nid = ALC880_DIGOUT_NID,
3381		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3382		.channel_mode = alc880_2_jack_modes,
3383		.input_mux = &alc880_capture_source,
3384		.unsol_event = alc880_uniwill_p53_unsol_event,
3385		.init_hook = alc880_uniwill_p53_hp_automute,
3386	},
3387	[ALC880_CLEVO] = {
3388		.mixers = { alc880_three_stack_mixer },
3389		.init_verbs = { alc880_volume_init_verbs,
3390				alc880_pin_clevo_init_verbs },
3391		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3392		.dac_nids = alc880_dac_nids,
3393		.hp_nid = 0x03,
3394		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3395		.channel_mode = alc880_threestack_modes,
3396		.need_dac_fix = 1,
3397		.input_mux = &alc880_capture_source,
3398	},
3399	[ALC880_LG] = {
3400		.mixers = { alc880_lg_mixer },
3401		.init_verbs = { alc880_volume_init_verbs,
3402				alc880_lg_init_verbs },
3403		.num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3404		.dac_nids = alc880_lg_dac_nids,
3405		.dig_out_nid = ALC880_DIGOUT_NID,
3406		.num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3407		.channel_mode = alc880_lg_ch_modes,
3408		.need_dac_fix = 1,
3409		.input_mux = &alc880_lg_capture_source,
3410		.unsol_event = alc880_lg_unsol_event,
3411		.init_hook = alc880_lg_automute,
3412#ifdef CONFIG_SND_HDA_POWER_SAVE
3413		.loopbacks = alc880_lg_loopbacks,
3414#endif
3415	},
3416	[ALC880_LG_LW] = {
3417		.mixers = { alc880_lg_lw_mixer },
3418		.init_verbs = { alc880_volume_init_verbs,
3419				alc880_lg_lw_init_verbs },
3420		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3421		.dac_nids = alc880_dac_nids,
3422		.dig_out_nid = ALC880_DIGOUT_NID,
3423		.num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3424		.channel_mode = alc880_lg_lw_modes,
3425		.input_mux = &alc880_lg_lw_capture_source,
3426		.unsol_event = alc880_lg_lw_unsol_event,
3427		.init_hook = alc880_lg_lw_automute,
3428	},
3429	[ALC880_MEDION_RIM] = {
3430		.mixers = { alc880_medion_rim_mixer },
3431		.init_verbs = { alc880_volume_init_verbs,
3432				alc880_medion_rim_init_verbs,
3433				alc_gpio2_init_verbs },
3434		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3435		.dac_nids = alc880_dac_nids,
3436		.dig_out_nid = ALC880_DIGOUT_NID,
3437		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3438		.channel_mode = alc880_2_jack_modes,
3439		.input_mux = &alc880_medion_rim_capture_source,
3440		.unsol_event = alc880_medion_rim_unsol_event,
3441		.init_hook = alc880_medion_rim_automute,
3442	},
3443#ifdef CONFIG_SND_DEBUG
3444	[ALC880_TEST] = {
3445		.mixers = { alc880_test_mixer },
3446		.init_verbs = { alc880_test_init_verbs },
3447		.num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3448		.dac_nids = alc880_test_dac_nids,
3449		.dig_out_nid = ALC880_DIGOUT_NID,
3450		.num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3451		.channel_mode = alc880_test_modes,
3452		.input_mux = &alc880_test_capture_source,
3453	},
3454#endif
3455};
3456
3457/*
3458 * Automatic parse of I/O pins from the BIOS configuration
3459 */
3460
3461#define NUM_CONTROL_ALLOC	32
3462#define NUM_VERB_ALLOC		32
3463
3464enum {
3465	ALC_CTL_WIDGET_VOL,
3466	ALC_CTL_WIDGET_MUTE,
3467	ALC_CTL_BIND_MUTE,
3468};
3469static struct snd_kcontrol_new alc880_control_templates[] = {
3470	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3471	HDA_CODEC_MUTE(NULL, 0, 0, 0),
3472	HDA_BIND_MUTE(NULL, 0, 0, 0),
3473};
3474
3475/* add dynamic controls */
3476static int add_control(struct alc_spec *spec, int type, const char *name,
3477		       unsigned long val)
3478{
3479	struct snd_kcontrol_new *knew;
3480
3481	if (spec->num_kctl_used >= spec->num_kctl_alloc) {
3482		int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
3483
3484		/* array + terminator */
3485		knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
3486		if (!knew)
3487			return -ENOMEM;
3488		if (spec->kctl_alloc) {
3489			memcpy(knew, spec->kctl_alloc,
3490			       sizeof(*knew) * spec->num_kctl_alloc);
3491			kfree(spec->kctl_alloc);
3492		}
3493		spec->kctl_alloc = knew;
3494		spec->num_kctl_alloc = num;
3495	}
3496
3497	knew = &spec->kctl_alloc[spec->num_kctl_used];
3498	*knew = alc880_control_templates[type];
3499	knew->name = kstrdup(name, GFP_KERNEL);
3500	if (!knew->name)
3501		return -ENOMEM;
3502	knew->private_value = val;
3503	spec->num_kctl_used++;
3504	return 0;
3505}
3506
3507#define alc880_is_fixed_pin(nid)	((nid) >= 0x14 && (nid) <= 0x17)
3508#define alc880_fixed_pin_idx(nid)	((nid) - 0x14)
3509#define alc880_is_multi_pin(nid)	((nid) >= 0x18)
3510#define alc880_multi_pin_idx(nid)	((nid) - 0x18)
3511#define alc880_is_input_pin(nid)	((nid) >= 0x18)
3512#define alc880_input_pin_idx(nid)	((nid) - 0x18)
3513#define alc880_idx_to_dac(nid)		((nid) + 0x02)
3514#define alc880_dac_to_idx(nid)		((nid) - 0x02)
3515#define alc880_idx_to_mixer(nid)	((nid) + 0x0c)
3516#define alc880_idx_to_selector(nid)	((nid) + 0x10)
3517#define ALC880_PIN_CD_NID		0x1c
3518
3519/* fill in the dac_nids table from the parsed pin configuration */
3520static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3521				     const struct auto_pin_cfg *cfg)
3522{
3523	hda_nid_t nid;
3524	int assigned[4];
3525	int i, j;
3526
3527	memset(assigned, 0, sizeof(assigned));
3528	spec->multiout.dac_nids = spec->private_dac_nids;
3529
3530	/* check the pins hardwired to audio widget */
3531	for (i = 0; i < cfg->line_outs; i++) {
3532		nid = cfg->line_out_pins[i];
3533		if (alc880_is_fixed_pin(nid)) {
3534			int idx = alc880_fixed_pin_idx(nid);
3535			spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3536			assigned[idx] = 1;
3537		}
3538	}
3539	/* left pins can be connect to any audio widget */
3540	for (i = 0; i < cfg->line_outs; i++) {
3541		nid = cfg->line_out_pins[i];
3542		if (alc880_is_fixed_pin(nid))
3543			continue;
3544		/* search for an empty channel */
3545		for (j = 0; j < cfg->line_outs; j++) {
3546			if (!assigned[j]) {
3547				spec->multiout.dac_nids[i] =
3548					alc880_idx_to_dac(j);
3549				assigned[j] = 1;
3550				break;
3551			}
3552		}
3553	}
3554	spec->multiout.num_dacs = cfg->line_outs;
3555	return 0;
3556}
3557
3558/* add playback controls from the parsed DAC table */
3559static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3560					     const struct auto_pin_cfg *cfg)
3561{
3562	char name[32];
3563	static const char *chname[4] = {
3564		"Front", "Surround", NULL /*CLFE*/, "Side"
3565	};
3566	hda_nid_t nid;
3567	int i, err;
3568
3569	for (i = 0; i < cfg->line_outs; i++) {
3570		if (!spec->multiout.dac_nids[i])
3571			continue;
3572		nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3573		if (i == 2) {
3574			/* Center/LFE */
3575			err = add_control(spec, ALC_CTL_WIDGET_VOL,
3576					  "Center Playback Volume",
3577					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3578							      HDA_OUTPUT));
3579			if (err < 0)
3580				return err;
3581			err = add_control(spec, ALC_CTL_WIDGET_VOL,
3582					  "LFE Playback Volume",
3583					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3584							      HDA_OUTPUT));
3585			if (err < 0)
3586				return err;
3587			err = add_control(spec, ALC_CTL_BIND_MUTE,
3588					  "Center Playback Switch",
3589					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3590							      HDA_INPUT));
3591			if (err < 0)
3592				return err;
3593			err = add_control(spec, ALC_CTL_BIND_MUTE,
3594					  "LFE Playback Switch",
3595					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3596							      HDA_INPUT));
3597			if (err < 0)
3598				return err;
3599		} else {
3600			sprintf(name, "%s Playback Volume", chname[i]);
3601			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3602					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3603							      HDA_OUTPUT));
3604			if (err < 0)
3605				return err;
3606			sprintf(name, "%s Playback Switch", chname[i]);
3607			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3608					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3609							      HDA_INPUT));
3610			if (err < 0)
3611				return err;
3612		}
3613	}
3614	return 0;
3615}
3616
3617/* add playback controls for speaker and HP outputs */
3618static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3619					const char *pfx)
3620{
3621	hda_nid_t nid;
3622	int err;
3623	char name[32];
3624
3625	if (!pin)
3626		return 0;
3627
3628	if (alc880_is_fixed_pin(pin)) {
3629		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3630		/* specify the DAC as the extra output */
3631		if (!spec->multiout.hp_nid)
3632			spec->multiout.hp_nid = nid;
3633		else
3634			spec->multiout.extra_out_nid[0] = nid;
3635		/* control HP volume/switch on the output mixer amp */
3636		nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3637		sprintf(name, "%s Playback Volume", pfx);
3638		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3639				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3640		if (err < 0)
3641			return err;
3642		sprintf(name, "%s Playback Switch", pfx);
3643		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3644				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3645		if (err < 0)
3646			return err;
3647	} else if (alc880_is_multi_pin(pin)) {
3648		/* set manual connection */
3649		/* we have only a switch on HP-out PIN */
3650		sprintf(name, "%s Playback Switch", pfx);
3651		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3652				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3653		if (err < 0)
3654			return err;
3655	}
3656	return 0;
3657}
3658
3659/* create input playback/capture controls for the given pin */
3660static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3661			    const char *ctlname,
3662			    int idx, hda_nid_t mix_nid)
3663{
3664	char name[32];
3665	int err;
3666
3667	sprintf(name, "%s Playback Volume", ctlname);
3668	err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3669			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3670	if (err < 0)
3671		return err;
3672	sprintf(name, "%s Playback Switch", ctlname);
3673	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3674			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3675	if (err < 0)
3676		return err;
3677	return 0;
3678}
3679
3680/* create playback/capture controls for input pins */
3681static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3682						const struct auto_pin_cfg *cfg)
3683{
3684	struct hda_input_mux *imux = &spec->private_imux;
3685	int i, err, idx;
3686
3687	for (i = 0; i < AUTO_PIN_LAST; i++) {
3688		if (alc880_is_input_pin(cfg->input_pins[i])) {
3689			idx = alc880_input_pin_idx(cfg->input_pins[i]);
3690			err = new_analog_input(spec, cfg->input_pins[i],
3691					       auto_pin_cfg_labels[i],
3692					       idx, 0x0b);
3693			if (err < 0)
3694				return err;
3695			imux->items[imux->num_items].label =
3696				auto_pin_cfg_labels[i];
3697			imux->items[imux->num_items].index =
3698				alc880_input_pin_idx(cfg->input_pins[i]);
3699			imux->num_items++;
3700		}
3701	}
3702	return 0;
3703}
3704
3705static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
3706			       unsigned int pin_type)
3707{
3708	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3709			    pin_type);
3710	/* unmute pin */
3711	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3712			    AMP_OUT_UNMUTE);
3713}
3714
3715static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3716					      hda_nid_t nid, int pin_type,
3717					      int dac_idx)
3718{
3719	alc_set_pin_output(codec, nid, pin_type);
3720	/* need the manual connection? */
3721	if (alc880_is_multi_pin(nid)) {
3722		struct alc_spec *spec = codec->spec;
3723		int idx = alc880_multi_pin_idx(nid);
3724		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3725				    AC_VERB_SET_CONNECT_SEL,
3726				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3727	}
3728}
3729
3730static int get_pin_type(int line_out_type)
3731{
3732	if (line_out_type == AUTO_PIN_HP_OUT)
3733		return PIN_HP;
3734	else
3735		return PIN_OUT;
3736}
3737
3738static void alc880_auto_init_multi_out(struct hda_codec *codec)
3739{
3740	struct alc_spec *spec = codec->spec;
3741	int i;
3742
3743	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3744	for (i = 0; i < spec->autocfg.line_outs; i++) {
3745		hda_nid_t nid = spec->autocfg.line_out_pins[i];
3746		int pin_type = get_pin_type(spec->autocfg.line_out_type);
3747		alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3748	}
3749}
3750
3751static void alc880_auto_init_extra_out(struct hda_codec *codec)
3752{
3753	struct alc_spec *spec = codec->spec;
3754	hda_nid_t pin;
3755
3756	pin = spec->autocfg.speaker_pins[0];
3757	if (pin) /* connect to front */
3758		alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3759	pin = spec->autocfg.hp_pins[0];
3760	if (pin) /* connect to front */
3761		alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3762}
3763
3764static void alc880_auto_init_analog_input(struct hda_codec *codec)
3765{
3766	struct alc_spec *spec = codec->spec;
3767	int i;
3768
3769	for (i = 0; i < AUTO_PIN_LAST; i++) {
3770		hda_nid_t nid = spec->autocfg.input_pins[i];
3771		if (alc880_is_input_pin(nid)) {
3772			snd_hda_codec_write(codec, nid, 0,
3773					    AC_VERB_SET_PIN_WIDGET_CONTROL,
3774					    i <= AUTO_PIN_FRONT_MIC ?
3775					    PIN_VREF80 : PIN_IN);
3776			if (nid != ALC880_PIN_CD_NID)
3777				snd_hda_codec_write(codec, nid, 0,
3778						    AC_VERB_SET_AMP_GAIN_MUTE,
3779						    AMP_OUT_MUTE);
3780		}
3781	}
3782}
3783
3784/* parse the BIOS configuration and set up the alc_spec */
3785/* return 1 if successful, 0 if the proper config is not found,
3786 * or a negative error code
3787 */
3788static int alc880_parse_auto_config(struct hda_codec *codec)
3789{
3790	struct alc_spec *spec = codec->spec;
3791	int err;
3792	static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3793
3794	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3795					   alc880_ignore);
3796	if (err < 0)
3797		return err;
3798	if (!spec->autocfg.line_outs)
3799		return 0; /* can't find valid BIOS pin config */
3800
3801	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3802	if (err < 0)
3803		return err;
3804	err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3805	if (err < 0)
3806		return err;
3807	err = alc880_auto_create_extra_out(spec,
3808					   spec->autocfg.speaker_pins[0],
3809					   "Speaker");
3810	if (err < 0)
3811		return err;
3812	err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3813					   "Headphone");
3814	if (err < 0)
3815		return err;
3816	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3817	if (err < 0)
3818		return err;
3819
3820	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3821
3822	if (spec->autocfg.dig_out_pin)
3823		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3824	if (spec->autocfg.dig_in_pin)
3825		spec->dig_in_nid = ALC880_DIGIN_NID;
3826
3827	if (spec->kctl_alloc)
3828		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3829
3830	spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3831
3832	spec->num_mux_defs = 1;
3833	spec->input_mux = &spec->private_imux;
3834
3835	return 1;
3836}
3837
3838/* additional initialization for auto-configuration model */
3839static void alc880_auto_init(struct hda_codec *codec)
3840{
3841	struct alc_spec *spec = codec->spec;
3842	alc880_auto_init_multi_out(codec);
3843	alc880_auto_init_extra_out(codec);
3844	alc880_auto_init_analog_input(codec);
3845	if (spec->unsol_event)
3846		alc_inithook(codec);
3847}
3848
3849/*
3850 * OK, here we have finally the patch for ALC880
3851 */
3852
3853static int patch_alc880(struct hda_codec *codec)
3854{
3855	struct alc_spec *spec;
3856	int board_config;
3857	int err;
3858
3859	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3860	if (spec == NULL)
3861		return -ENOMEM;
3862
3863	codec->spec = spec;
3864
3865	board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3866						  alc880_models,
3867						  alc880_cfg_tbl);
3868	if (board_config < 0) {
3869		printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3870		       "trying auto-probe from BIOS...\n");
3871		board_config = ALC880_AUTO;
3872	}
3873
3874	if (board_config == ALC880_AUTO) {
3875		/* automatic parse from the BIOS config */
3876		err = alc880_parse_auto_config(codec);
3877		if (err < 0) {
3878			alc_free(codec);
3879			return err;
3880		} else if (!err) {
3881			printk(KERN_INFO
3882			       "hda_codec: Cannot set up configuration "
3883			       "from BIOS.  Using 3-stack mode...\n");
3884			board_config = ALC880_3ST;
3885		}
3886	}
3887
3888	if (board_config != ALC880_AUTO)
3889		setup_preset(spec, &alc880_presets[board_config]);
3890
3891	spec->stream_name_analog = "ALC880 Analog";
3892	spec->stream_analog_playback = &alc880_pcm_analog_playback;
3893	spec->stream_analog_capture = &alc880_pcm_analog_capture;
3894	spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
3895
3896	spec->stream_name_digital = "ALC880 Digital";
3897	spec->stream_digital_playback = &alc880_pcm_digital_playback;
3898	spec->stream_digital_capture = &alc880_pcm_digital_capture;
3899
3900	if (!spec->adc_nids && spec->input_mux) {
3901		/* check whether NID 0x07 is valid */
3902		unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3903		/* get type */
3904		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3905		if (wcap != AC_WID_AUD_IN) {
3906			spec->adc_nids = alc880_adc_nids_alt;
3907			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3908			spec->mixers[spec->num_mixers] =
3909				alc880_capture_alt_mixer;
3910			spec->num_mixers++;
3911		} else {
3912			spec->adc_nids = alc880_adc_nids;
3913			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3914			spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3915			spec->num_mixers++;
3916		}
3917	}
3918
3919	spec->vmaster_nid = 0x0c;
3920
3921	codec->patch_ops = alc_patch_ops;
3922	if (board_config == ALC880_AUTO)
3923		spec->init_hook = alc880_auto_init;
3924#ifdef CONFIG_SND_HDA_POWER_SAVE
3925	if (!spec->loopback.amplist)
3926		spec->loopback.amplist = alc880_loopbacks;
3927#endif
3928
3929	return 0;
3930}
3931
3932
3933/*
3934 * ALC260 support
3935 */
3936
3937static hda_nid_t alc260_dac_nids[1] = {
3938	/* front */
3939	0x02,
3940};
3941
3942static hda_nid_t alc260_adc_nids[1] = {
3943	/* ADC0 */
3944	0x04,
3945};
3946
3947static hda_nid_t alc260_adc_nids_alt[1] = {
3948	/* ADC1 */
3949	0x05,
3950};
3951
3952static hda_nid_t alc260_hp_adc_nids[2] = {
3953	/* ADC1, 0 */
3954	0x05, 0x04
3955};
3956
3957/* NIDs used when simultaneous access to both ADCs makes sense.  Note that
3958 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3959 */
3960static hda_nid_t alc260_dual_adc_nids[2] = {
3961	/* ADC0, ADC1 */
3962	0x04, 0x05
3963};
3964
3965#define ALC260_DIGOUT_NID	0x03
3966#define ALC260_DIGIN_NID	0x06
3967
3968static struct hda_input_mux alc260_capture_source = {
3969	.num_items = 4,
3970	.items = {
3971		{ "Mic", 0x0 },
3972		{ "Front Mic", 0x1 },
3973		{ "Line", 0x2 },
3974		{ "CD", 0x4 },
3975	},
3976};
3977
3978/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3979 * headphone jack and the internal CD lines since these are the only pins at
3980 * which audio can appear.  For flexibility, also allow the option of
3981 * recording the mixer output on the second ADC (ADC0 doesn't have a
3982 * connection to the mixer output).
3983 */
3984static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3985	{
3986		.num_items = 3,
3987		.items = {
3988			{ "Mic/Line", 0x0 },
3989			{ "CD", 0x4 },
3990			{ "Headphone", 0x2 },
3991		},
3992	},
3993	{
3994		.num_items = 4,
3995		.items = {
3996			{ "Mic/Line", 0x0 },
3997			{ "CD", 0x4 },
3998			{ "Headphone", 0x2 },
3999			{ "Mixer", 0x5 },
4000		},
4001	},
4002
4003};
4004
4005/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4006 * the Fujitsu S702x, but jacks are marked differently.
4007 */
4008static struct hda_input_mux alc260_acer_capture_sources[2] = {
4009	{
4010		.num_items = 4,
4011		.items = {
4012			{ "Mic", 0x0 },
4013			{ "Line", 0x2 },
4014			{ "CD", 0x4 },
4015			{ "Headphone", 0x5 },
4016		},
4017	},
4018	{
4019		.num_items = 5,
4020		.items = {
4021			{ "Mic", 0x0 },
4022			{ "Line", 0x2 },
4023			{ "CD", 0x4 },
4024			{ "Headphone", 0x6 },
4025			{ "Mixer", 0x5 },
4026		},
4027	},
4028};
4029/*
4030 * This is just place-holder, so there's something for alc_build_pcms to look
4031 * at when it calculates the maximum number of channels. ALC260 has no mixer
4032 * element which allows changing the channel mode, so the verb list is
4033 * never used.
4034 */
4035static struct hda_channel_mode alc260_modes[1] = {
4036	{ 2, NULL },
4037};
4038
4039
4040/* Mixer combinations
4041 *
4042 * basic: base_output + input + pc_beep + capture
4043 * HP: base_output + input + capture_alt
4044 * HP_3013: hp_3013 + input + capture
4045 * fujitsu: fujitsu + capture
4046 * acer: acer + capture
4047 */
4048
4049static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4050	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4051	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4052	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4053	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4054	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4055	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4056	{ } /* end */
4057};
4058
4059static struct snd_kcontrol_new alc260_input_mixer[] = {
4060	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4061	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4062	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4063	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4064	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4065	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4066	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4067	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4068	{ } /* end */
4069};
4070
4071static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
4072	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
4073	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
4074	{ } /* end */
4075};
4076
4077/* update HP, line and mono out pins according to the master switch */
4078static void alc260_hp_master_update(struct hda_codec *codec,
4079				    hda_nid_t hp, hda_nid_t line,
4080				    hda_nid_t mono)
4081{
4082	struct alc_spec *spec = codec->spec;
4083	unsigned int val = spec->master_sw ? PIN_HP : 0;
4084	/* change HP and line-out pins */
4085	snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4086			    val);
4087	snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4088			    val);
4089	/* mono (speaker) depending on the HP jack sense */
4090	val = (val && !spec->jack_present) ? PIN_OUT : 0;
4091	snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4092			    val);
4093}
4094
4095static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4096				   struct snd_ctl_elem_value *ucontrol)
4097{
4098	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4099	struct alc_spec *spec = codec->spec;
4100	*ucontrol->value.integer.value = spec->master_sw;
4101	return 0;
4102}
4103
4104static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4105				   struct snd_ctl_elem_value *ucontrol)
4106{
4107	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4108	struct alc_spec *spec = codec->spec;
4109	int val = !!*ucontrol->value.integer.value;
4110	hda_nid_t hp, line, mono;
4111
4112	if (val == spec->master_sw)
4113		return 0;
4114	spec->master_sw = val;
4115	hp = (kcontrol->private_value >> 16) & 0xff;
4116	line = (kcontrol->private_value >> 8) & 0xff;
4117	mono = kcontrol->private_value & 0xff;
4118	alc260_hp_master_update(codec, hp, line, mono);
4119	return 1;
4120}
4121
4122static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4123	{
4124		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4125		.name = "Master Playback Switch",
4126		.info = snd_ctl_boolean_mono_info,
4127		.get = alc260_hp_master_sw_get,
4128		.put = alc260_hp_master_sw_put,
4129		.private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4130	},
4131	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4132	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4133	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4134	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4135	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4136			      HDA_OUTPUT),
4137	HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4138	{ } /* end */
4139};
4140
4141static struct hda_verb alc260_hp_unsol_verbs[] = {
4142	{0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4143	{},
4144};
4145
4146static void alc260_hp_automute(struct hda_codec *codec)
4147{
4148	struct alc_spec *spec = codec->spec;
4149	unsigned int present;
4150
4151	present = snd_hda_codec_read(codec, 0x10, 0,
4152				     AC_VERB_GET_PIN_SENSE, 0);
4153	spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4154	alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4155}
4156
4157static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4158{
4159	if ((res >> 26) == ALC880_HP_EVENT)
4160		alc260_hp_automute(codec);
4161}
4162
4163static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4164	{
4165		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4166		.name = "Master Playback Switch",
4167		.info = snd_ctl_boolean_mono_info,
4168		.get = alc260_hp_master_sw_get,
4169		.put = alc260_hp_master_sw_put,
4170		.private_value = (0x10 << 16) | (0x15 << 8) | 0x11
4171	},
4172	HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4173	HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4174	HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4175	HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4176	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4177	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4178	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4179	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4180	{ } /* end */
4181};
4182
4183static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4184	.ops = &snd_hda_bind_vol,
4185	.values = {
4186		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4187		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4188		HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4189		0
4190	},
4191};
4192
4193static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4194	.ops = &snd_hda_bind_sw,
4195	.values = {
4196		HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4197		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4198		0
4199	},
4200};
4201
4202static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4203	HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4204	HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4205	HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4206	HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4207	{ } /* end */
4208};
4209
4210static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4211	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4212	{},
4213};
4214
4215static void alc260_hp_3013_automute(struct hda_codec *codec)
4216{
4217	struct alc_spec *spec = codec->spec;
4218	unsigned int present;
4219
4220	present = snd_hda_codec_read(codec, 0x15, 0,
4221				     AC_VERB_GET_PIN_SENSE, 0);
4222	spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4223	alc260_hp_master_update(codec, 0x10, 0x15, 0x11);
4224}
4225
4226static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4227				       unsigned int res)
4228{
4229	if ((res >> 26) == ALC880_HP_EVENT)
4230		alc260_hp_3013_automute(codec);
4231}
4232
4233static void alc260_hp_3012_automute(struct hda_codec *codec)
4234{
4235	unsigned int present, bits;
4236
4237	present = snd_hda_codec_read(codec, 0x10, 0,
4238			AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4239
4240	bits = present ? 0 : PIN_OUT;
4241	snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4242			    bits);
4243	snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4244			    bits);
4245	snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4246			    bits);
4247}
4248
4249static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4250				       unsigned int res)
4251{
4252	if ((res >> 26) == ALC880_HP_EVENT)
4253		alc260_hp_3012_automute(codec);
4254}
4255
4256/* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12,
4257 * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
4258 */
4259static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4260	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4261	HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4262	ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4263	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4264	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4265	HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4266	HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4267	ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4268	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4269	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4270	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4271	HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4272	{ } /* end */
4273};
4274
4275/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
4276 * versions of the ALC260 don't act on requests to enable mic bias from NID
4277 * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
4278 * datasheet doesn't mention this restriction.  At this stage it's not clear
4279 * whether this behaviour is intentional or is a hardware bug in chip
4280 * revisions available in early 2006.  Therefore for now allow the
4281 * "Headphone Jack Mode" control to span all choices, but if it turns out
4282 * that the lack of mic bias for this NID is intentional we could change the
4283 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4284 *
4285 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4286 * don't appear to make the mic bias available from the "line" jack, even
4287 * though the NID used for this jack (0x14) can supply it.  The theory is
4288 * that perhaps Acer have included blocking capacitors between the ALC260
4289 * and the output jack.  If this turns out to be the case for all such
4290 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4291 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4292 *
4293 * The C20x Tablet series have a mono internal speaker which is controlled
4294 * via the chip's Mono sum widget and pin complex, so include the necessary
4295 * controls for such models.  On models without a "mono speaker" the control
4296 * won't do anything.
4297 */
4298static struct snd_kcontrol_new alc260_acer_mixer[] = {
4299	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4300	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4301	ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4302	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4303			      HDA_OUTPUT),
4304	HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4305			   HDA_INPUT),
4306	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4307	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4308	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4309	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4310	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4311	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4312	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4313	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4314	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4315	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4316	{ } /* end */
4317};
4318
4319/* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4320 * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
4321 */
4322static struct snd_kcontrol_new alc260_will_mixer[] = {
4323	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4324	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4325	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4326	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4327	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4328	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4329	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4330	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4331	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4332	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4333	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4334	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4335	{ } /* end */
4336};
4337
4338/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4339 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4340 */
4341static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4342	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4343	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4344	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4345	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4346	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4347	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4348	HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4349	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4350	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4351	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4352	{ } /* end */
4353};
4354
4355/* capture mixer elements */
4356static struct snd_kcontrol_new alc260_capture_mixer[] = {
4357	HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
4358	HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
4359	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
4360	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
4361	{
4362		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4363		/* The multiple "Capture Source" controls confuse alsamixer
4364		 * So call somewhat different..
4365		 */
4366		/* .name = "Capture Source", */
4367		.name = "Input Source",
4368		.count = 2,
4369		.info = alc_mux_enum_info,
4370		.get = alc_mux_enum_get,
4371		.put = alc_mux_enum_put,
4372	},
4373	{ } /* end */
4374};
4375
4376static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
4377	HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
4378	HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
4379	{
4380		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4381		/* The multiple "Capture Source" controls confuse alsamixer
4382		 * So call somewhat different..
4383		 */
4384		/* .name = "Capture Source", */
4385		.name = "Input Source",
4386		.count = 1,
4387		.info = alc_mux_enum_info,
4388		.get = alc_mux_enum_get,
4389		.put = alc_mux_enum_put,
4390	},
4391	{ } /* end */
4392};
4393
4394/*
4395 * initialization verbs
4396 */
4397static struct hda_verb alc260_init_verbs[] = {
4398	/* Line In pin widget for input */
4399	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4400	/* CD pin widget for input */
4401	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4402	/* Mic1 (rear panel) pin widget for input and vref at 80% */
4403	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4404	/* Mic2 (front panel) pin widget for input and vref at 80% */
4405	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4406	/* LINE-2 is used for line-out in rear */
4407	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4408	/* select line-out */
4409	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4410	/* LINE-OUT pin */
4411	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4412	/* enable HP */
4413	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4414	/* enable Mono */
4415	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4416	/* mute capture amp left and right */
4417	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4418	/* set connection select to line in (default select for this ADC) */
4419	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4420	/* mute capture amp left and right */
4421	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4422	/* set connection select to line in (default select for this ADC) */
4423	{0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4424	/* set vol=0 Line-Out mixer amp left and right */
4425	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4426	/* unmute pin widget amp left and right (no gain on this amp) */
4427	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4428	/* set vol=0 HP mixer amp left and right */
4429	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4430	/* unmute pin widget amp left and right (no gain on this amp) */
4431	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4432	/* set vol=0 Mono mixer amp left and right */
4433	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4434	/* unmute pin widget amp left and right (no gain on this amp) */
4435	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4436	/* unmute LINE-2 out pin */
4437	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4438	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4439	 * Line In 2 = 0x03
4440	 */
4441	/* mute analog inputs */
4442	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4443	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4444	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4445	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4446	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4447	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4448	/* mute Front out path */
4449	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4450	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4451	/* mute Headphone out path */
4452	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4453	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4454	/* mute Mono out path */
4455	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4456	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4457	{ }
4458};
4459
4460#if 0 /* should be identical with alc260_init_verbs? */
4461static struct hda_verb alc260_hp_init_verbs[] = {
4462	/* Headphone and output */
4463	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4464	/* mono output */
4465	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4466	/* Mic1 (rear panel) pin widget for input and vref at 80% */
4467	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4468	/* Mic2 (front panel) pin widget for input and vref at 80% */
4469	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4470	/* Line In pin widget for input */
4471	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4472	/* Line-2 pin widget for output */
4473	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4474	/* CD pin widget for input */
4475	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4476	/* unmute amp left and right */
4477	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4478	/* set connection select to line in (default select for this ADC) */
4479	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4480	/* unmute Line-Out mixer amp left and right (volume = 0) */
4481	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4482	/* mute pin widget amp left and right (no gain on this amp) */
4483	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4484	/* unmute HP mixer amp left and right (volume = 0) */
4485	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4486	/* mute pin widget amp left and right (no gain on this amp) */
4487	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4488	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4489	 * Line In 2 = 0x03
4490	 */
4491	/* mute analog inputs */
4492	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4493	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4494	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4495	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4496	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4497	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4498	/* Unmute Front out path */
4499	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4500	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4501	/* Unmute Headphone out path */
4502	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4503	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4504	/* Unmute Mono out path */
4505	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4506	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4507	{ }
4508};
4509#endif
4510
4511static struct hda_verb alc260_hp_3013_init_verbs[] = {
4512	/* Line out and output */
4513	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4514	/* mono output */
4515	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4516	/* Mic1 (rear panel) pin widget for input and vref at 80% */
4517	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4518	/* Mic2 (front panel) pin widget for input and vref at 80% */
4519	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4520	/* Line In pin widget for input */
4521	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4522	/* Headphone pin widget for output */
4523	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4524	/* CD pin widget for input */
4525	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4526	/* unmute amp left and right */
4527	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4528	/* set connection select to line in (default select for this ADC) */
4529	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4530	/* unmute Line-Out mixer amp left and right (volume = 0) */
4531	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4532	/* mute pin widget amp left and right (no gain on this amp) */
4533	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4534	/* unmute HP mixer amp left and right (volume = 0) */
4535	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4536	/* mute pin widget amp left and right (no gain on this amp) */
4537	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4538	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4539	 * Line In 2 = 0x03
4540	 */
4541	/* mute analog inputs */
4542	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4543	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4544	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4545	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4546	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4547	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4548	/* Unmute Front out path */
4549	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4550	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4551	/* Unmute Headphone out path */
4552	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4553	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4554	/* Unmute Mono out path */
4555	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4556	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4557	{ }
4558};
4559
4560/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4561 * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4562 * audio = 0x16, internal speaker = 0x10.
4563 */
4564static struct hda_verb alc260_fujitsu_init_verbs[] = {
4565	/* Disable all GPIOs */
4566	{0x01, AC_VERB_SET_GPIO_MASK, 0},
4567	/* Internal speaker is connected to headphone pin */
4568	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4569	/* Headphone/Line-out jack connects to Line1 pin; make it an output */
4570	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4571	/* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4572	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4573	/* Ensure all other unused pins are disabled and muted. */
4574	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4575	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4576	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4577	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4578	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4579	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4580	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4581	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4582
4583	/* Disable digital (SPDIF) pins */
4584	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4585	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4586
4587	/* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4588	 * when acting as an output.
4589	 */
4590	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4591
4592	/* Start with output sum widgets muted and their output gains at min */
4593	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4594	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4595	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4596	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4597	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4598	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4599	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4600	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4601	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4602
4603	/* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4604	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4605	/* Unmute Line1 pin widget output buffer since it starts as an output.
4606	 * If the pin mode is changed by the user the pin mode control will
4607	 * take care of enabling the pin's input/output buffers as needed.
4608	 * Therefore there's no need to enable the input buffer at this
4609	 * stage.
4610	 */
4611	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4612	/* Unmute input buffer of pin widget used for Line-in (no equiv
4613	 * mixer ctrl)
4614	 */
4615	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4616
4617	/* Mute capture amp left and right */
4618	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4619	/* Set ADC connection select to match default mixer setting - line
4620	 * in (on mic1 pin)
4621	 */
4622	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4623
4624	/* Do the same for the second ADC: mute capture input amp and
4625	 * set ADC connection to line in (on mic1 pin)
4626	 */
4627	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4628	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4629
4630	/* Mute all inputs to mixer widget (even unconnected ones) */
4631	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4632	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4633	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4634	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4635	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4636	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4637	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4638	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4639
4640	{ }
4641};
4642
4643/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4644 * similar laptops (adapted from Fujitsu init verbs).
4645 */
4646static struct hda_verb alc260_acer_init_verbs[] = {
4647	/* On TravelMate laptops, GPIO 0 enables the internal speaker and
4648	 * the headphone jack.  Turn this on and rely on the standard mute
4649	 * methods whenever the user wants to turn these outputs off.
4650	 */
4651	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4652	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4653	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4654	/* Internal speaker/Headphone jack is connected to Line-out pin */
4655	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4656	/* Internal microphone/Mic jack is connected to Mic1 pin */
4657	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4658	/* Line In jack is connected to Line1 pin */
4659	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4660	/* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4661	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4662	/* Ensure all other unused pins are disabled and muted. */
4663	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4664	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4665	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4666	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4667	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4668	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4669	/* Disable digital (SPDIF) pins */
4670	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4671	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4672
4673	/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4674	 * bus when acting as outputs.
4675	 */
4676	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4677	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4678
4679	/* Start with output sum widgets muted and their output gains at min */
4680	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4681	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4682	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4683	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4684	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4685	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4686	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4687	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4688	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4689
4690	/* Unmute Line-out pin widget amp left and right
4691	 * (no equiv mixer ctrl)
4692	 */
4693	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4694	/* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4695	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4696	/* Unmute Mic1 and Line1 pin widget input buffers since they start as
4697	 * inputs. If the pin mode is changed by the user the pin mode control
4698	 * will take care of enabling the pin's input/output buffers as needed.
4699	 * Therefore there's no need to enable the input buffer at this
4700	 * stage.
4701	 */
4702	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4703	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4704
4705	/* Mute capture amp left and right */
4706	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4707	/* Set ADC connection select to match default mixer setting - mic
4708	 * (on mic1 pin)
4709	 */
4710	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4711
4712	/* Do similar with the second ADC: mute capture input amp and
4713	 * set ADC connection to mic to match ALSA's default state.
4714	 */
4715	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4716	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4717
4718	/* Mute all inputs to mixer widget (even unconnected ones) */
4719	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4720	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4721	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4722	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4723	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4724	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4725	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4726	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4727
4728	{ }
4729};
4730
4731static struct hda_verb alc260_will_verbs[] = {
4732	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4733	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4734	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4735	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4736	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4737	{0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4738	{}
4739};
4740
4741static struct hda_verb alc260_replacer_672v_verbs[] = {
4742	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4743	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4744	{0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4745
4746	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4747	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4748	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4749
4750	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4751	{}
4752};
4753
4754/* toggle speaker-output according to the hp-jack state */
4755static void alc260_replacer_672v_automute(struct hda_codec *codec)
4756{
4757        unsigned int present;
4758
4759	/* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4760        present = snd_hda_codec_read(codec, 0x0f, 0,
4761                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4762	if (present) {
4763		snd_hda_codec_write_cache(codec, 0x01, 0,
4764					  AC_VERB_SET_GPIO_DATA, 1);
4765		snd_hda_codec_write_cache(codec, 0x0f, 0,
4766					  AC_VERB_SET_PIN_WIDGET_CONTROL,
4767					  PIN_HP);
4768	} else {
4769		snd_hda_codec_write_cache(codec, 0x01, 0,
4770					  AC_VERB_SET_GPIO_DATA, 0);
4771		snd_hda_codec_write_cache(codec, 0x0f, 0,
4772					  AC_VERB_SET_PIN_WIDGET_CONTROL,
4773					  PIN_OUT);
4774	}
4775}
4776
4777static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4778                                       unsigned int res)
4779{
4780        if ((res >> 26) == ALC880_HP_EVENT)
4781                alc260_replacer_672v_automute(codec);
4782}
4783
4784static struct hda_verb alc260_hp_dc7600_verbs[] = {
4785	{0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
4786	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
4787	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4788	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4789	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4790	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4791	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4792	{0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4793	{0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4794	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4795	{}
4796};
4797
4798/* Test configuration for debugging, modelled after the ALC880 test
4799 * configuration.
4800 */
4801#ifdef CONFIG_SND_DEBUG
4802static hda_nid_t alc260_test_dac_nids[1] = {
4803	0x02,
4804};
4805static hda_nid_t alc260_test_adc_nids[2] = {
4806	0x04, 0x05,
4807};
4808/* For testing the ALC260, each input MUX needs its own definition since
4809 * the signal assignments are different.  This assumes that the first ADC
4810 * is NID 0x04.
4811 */
4812static struct hda_input_mux alc260_test_capture_sources[2] = {
4813	{
4814		.num_items = 7,
4815		.items = {
4816			{ "MIC1 pin", 0x0 },
4817			{ "MIC2 pin", 0x1 },
4818			{ "LINE1 pin", 0x2 },
4819			{ "LINE2 pin", 0x3 },
4820			{ "CD pin", 0x4 },
4821			{ "LINE-OUT pin", 0x5 },
4822			{ "HP-OUT pin", 0x6 },
4823		},
4824        },
4825	{
4826		.num_items = 8,
4827		.items = {
4828			{ "MIC1 pin", 0x0 },
4829			{ "MIC2 pin", 0x1 },
4830			{ "LINE1 pin", 0x2 },
4831			{ "LINE2 pin", 0x3 },
4832			{ "CD pin", 0x4 },
4833			{ "Mixer", 0x5 },
4834			{ "LINE-OUT pin", 0x6 },
4835			{ "HP-OUT pin", 0x7 },
4836		},
4837        },
4838};
4839static struct snd_kcontrol_new alc260_test_mixer[] = {
4840	/* Output driver widgets */
4841	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4842	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4843	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4844	HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4845	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4846	HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4847
4848	/* Modes for retasking pin widgets
4849	 * Note: the ALC260 doesn't seem to act on requests to enable mic
4850         * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
4851         * mention this restriction.  At this stage it's not clear whether
4852         * this behaviour is intentional or is a hardware bug in chip
4853         * revisions available at least up until early 2006.  Therefore for
4854         * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4855         * choices, but if it turns out that the lack of mic bias for these
4856         * NIDs is intentional we could change their modes from
4857         * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4858	 */
4859	ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4860	ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4861	ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4862	ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4863	ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4864	ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4865
4866	/* Loopback mixer controls */
4867	HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4868	HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4869	HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4870	HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4871	HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4872	HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4873	HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4874	HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4875	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4876	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4877	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4878	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4879	HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4880	HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4881	HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4882	HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4883
4884	/* Controls for GPIO pins, assuming they are configured as outputs */
4885	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4886	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4887	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4888	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4889
4890	/* Switches to allow the digital IO pins to be enabled.  The datasheet
4891	 * is ambigious as to which NID is which; testing on laptops which
4892	 * make this output available should provide clarification.
4893	 */
4894	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4895	ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4896
4897	/* A switch allowing EAPD to be enabled.  Some laptops seem to use
4898	 * this output to turn on an external amplifier.
4899	 */
4900	ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
4901	ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
4902
4903	{ } /* end */
4904};
4905static struct hda_verb alc260_test_init_verbs[] = {
4906	/* Enable all GPIOs as outputs with an initial value of 0 */
4907	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4908	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4909	{0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4910
4911	/* Enable retasking pins as output, initially without power amp */
4912	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4913	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4914	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4915	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4916	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4917	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4918
4919	/* Disable digital (SPDIF) pins initially, but users can enable
4920	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
4921	 * payload also sets the generation to 0, output to be in "consumer"
4922	 * PCM format, copyright asserted, no pre-emphasis and no validity
4923	 * control.
4924	 */
4925	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4926	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4927
4928	/* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
4929	 * OUT1 sum bus when acting as an output.
4930	 */
4931	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4932	{0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4933	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4934	{0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4935
4936	/* Start with output sum widgets muted and their output gains at min */
4937	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4938	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4939	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4940	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4941	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4942	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4943	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4944	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4945	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4946
4947	/* Unmute retasking pin widget output buffers since the default
4948	 * state appears to be output.  As the pin mode is changed by the
4949	 * user the pin mode control will take care of enabling the pin's
4950	 * input/output buffers as needed.
4951	 */
4952	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4953	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4954	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4955	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4956	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4957	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4958	/* Also unmute the mono-out pin widget */
4959	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4960
4961	/* Mute capture amp left and right */
4962	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4963	/* Set ADC connection select to match default mixer setting (mic1
4964	 * pin)
4965	 */
4966	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4967
4968	/* Do the same for the second ADC: mute capture input amp and
4969	 * set ADC connection to mic1 pin
4970	 */
4971	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4972	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4973
4974	/* Mute all inputs to mixer widget (even unconnected ones) */
4975	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4976	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4977	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4978	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4979	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4980	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4981	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4982	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4983
4984	{ }
4985};
4986#endif
4987
4988#define alc260_pcm_analog_playback	alc880_pcm_analog_alt_playback
4989#define alc260_pcm_analog_capture	alc880_pcm_analog_capture
4990
4991#define alc260_pcm_digital_playback	alc880_pcm_digital_playback
4992#define alc260_pcm_digital_capture	alc880_pcm_digital_capture
4993
4994/*
4995 * for BIOS auto-configuration
4996 */
4997
4998static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4999					const char *pfx)
5000{
5001	hda_nid_t nid_vol;
5002	unsigned long vol_val, sw_val;
5003	char name[32];
5004	int err;
5005
5006	if (nid >= 0x0f && nid < 0x11) {
5007		nid_vol = nid - 0x7;
5008		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5009		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5010	} else if (nid == 0x11) {
5011		nid_vol = nid - 0x7;
5012		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5013		sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5014	} else if (nid >= 0x12 && nid <= 0x15) {
5015		nid_vol = 0x08;
5016		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5017		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5018	} else
5019		return 0; /* N/A */
5020
5021	snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5022	err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5023	if (err < 0)
5024		return err;
5025	snprintf(name, sizeof(name), "%s Playback Switch", pfx);
5026	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5027	if (err < 0)
5028		return err;
5029	return 1;
5030}
5031
5032/* add playback controls from the parsed DAC table */
5033static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5034					     const struct auto_pin_cfg *cfg)
5035{
5036	hda_nid_t nid;
5037	int err;
5038
5039	spec->multiout.num_dacs = 1;
5040	spec->multiout.dac_nids = spec->private_dac_nids;
5041	spec->multiout.dac_nids[0] = 0x02;
5042
5043	nid = cfg->line_out_pins[0];
5044	if (nid) {
5045		err = alc260_add_playback_controls(spec, nid, "Front");
5046		if (err < 0)
5047			return err;
5048	}
5049
5050	nid = cfg->speaker_pins[0];
5051	if (nid) {
5052		err = alc260_add_playback_controls(spec, nid, "Speaker");
5053		if (err < 0)
5054			return err;
5055	}
5056
5057	nid = cfg->hp_pins[0];
5058	if (nid) {
5059		err = alc260_add_playback_controls(spec, nid, "Headphone");
5060		if (err < 0)
5061			return err;
5062	}
5063	return 0;
5064}
5065
5066/* create playback/capture controls for input pins */
5067static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5068						const struct auto_pin_cfg *cfg)
5069{
5070	struct hda_input_mux *imux = &spec->private_imux;
5071	int i, err, idx;
5072
5073	for (i = 0; i < AUTO_PIN_LAST; i++) {
5074		if (cfg->input_pins[i] >= 0x12) {
5075			idx = cfg->input_pins[i] - 0x12;
5076			err = new_analog_input(spec, cfg->input_pins[i],
5077					       auto_pin_cfg_labels[i], idx,
5078					       0x07);
5079			if (err < 0)
5080				return err;
5081			imux->items[imux->num_items].label =
5082				auto_pin_cfg_labels[i];
5083			imux->items[imux->num_items].index = idx;
5084			imux->num_items++;
5085		}
5086		if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
5087			idx = cfg->input_pins[i] - 0x09;
5088			err = new_analog_input(spec, cfg->input_pins[i],
5089					       auto_pin_cfg_labels[i], idx,
5090					       0x07);
5091			if (err < 0)
5092				return err;
5093			imux->items[imux->num_items].label =
5094				auto_pin_cfg_labels[i];
5095			imux->items[imux->num_items].index = idx;
5096			imux->num_items++;
5097		}
5098	}
5099	return 0;
5100}
5101
5102static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5103					      hda_nid_t nid, int pin_type,
5104					      int sel_idx)
5105{
5106	alc_set_pin_output(codec, nid, pin_type);
5107	/* need the manual connection? */
5108	if (nid >= 0x12) {
5109		int idx = nid - 0x12;
5110		snd_hda_codec_write(codec, idx + 0x0b, 0,
5111				    AC_VERB_SET_CONNECT_SEL, sel_idx);
5112	}
5113}
5114
5115static void alc260_auto_init_multi_out(struct hda_codec *codec)
5116{
5117	struct alc_spec *spec = codec->spec;
5118	hda_nid_t nid;
5119
5120	alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
5121	nid = spec->autocfg.line_out_pins[0];
5122	if (nid) {
5123		int pin_type = get_pin_type(spec->autocfg.line_out_type);
5124		alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5125	}
5126
5127	nid = spec->autocfg.speaker_pins[0];
5128	if (nid)
5129		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5130
5131	nid = spec->autocfg.hp_pins[0];
5132	if (nid)
5133		alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5134}
5135
5136#define ALC260_PIN_CD_NID		0x16
5137static void alc260_auto_init_analog_input(struct hda_codec *codec)
5138{
5139	struct alc_spec *spec = codec->spec;
5140	int i;
5141
5142	for (i = 0; i < AUTO_PIN_LAST; i++) {
5143		hda_nid_t nid = spec->autocfg.input_pins[i];
5144		if (nid >= 0x12) {
5145			snd_hda_codec_write(codec, nid, 0,
5146					    AC_VERB_SET_PIN_WIDGET_CONTROL,
5147					    i <= AUTO_PIN_FRONT_MIC ?
5148					    PIN_VREF80 : PIN_IN);
5149			if (nid != ALC260_PIN_CD_NID)
5150				snd_hda_codec_write(codec, nid, 0,
5151						    AC_VERB_SET_AMP_GAIN_MUTE,
5152						    AMP_OUT_MUTE);
5153		}
5154	}
5155}
5156
5157/*
5158 * generic initialization of ADC, input mixers and output mixers
5159 */
5160static struct hda_verb alc260_volume_init_verbs[] = {
5161	/*
5162	 * Unmute ADC0-1 and set the default input to mic-in
5163	 */
5164	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5165	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5166	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5167	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5168
5169	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5170	 * mixer widget
5171	 * Note: PASD motherboards uses the Line In 2 as the input for
5172	 * front panel mic (mic 2)
5173	 */
5174	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5175	/* mute analog inputs */
5176	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5177	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5178	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5179	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5180	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5181
5182	/*
5183	 * Set up output mixers (0x08 - 0x0a)
5184	 */
5185	/* set vol=0 to output mixers */
5186	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5187	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5188	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5189	/* set up input amps for analog loopback */
5190	/* Amp Indices: DAC = 0, mixer = 1 */
5191	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5192	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5193	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5194	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5195	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5196	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5197
5198	{ }
5199};
5200
5201static int alc260_parse_auto_config(struct hda_codec *codec)
5202{
5203	struct alc_spec *spec = codec->spec;
5204	unsigned int wcap;
5205	int err;
5206	static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5207
5208	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5209					   alc260_ignore);
5210	if (err < 0)
5211		return err;
5212	err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5213	if (err < 0)
5214		return err;
5215	if (!spec->kctl_alloc)
5216		return 0; /* can't find valid BIOS pin config */
5217	err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5218	if (err < 0)
5219		return err;
5220
5221	spec->multiout.max_channels = 2;
5222
5223	if (spec->autocfg.dig_out_pin)
5224		spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5225	if (spec->kctl_alloc)
5226		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
5227
5228	spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
5229
5230	spec->num_mux_defs = 1;
5231	spec->input_mux = &spec->private_imux;
5232
5233	/* check whether NID 0x04 is valid */
5234	wcap = get_wcaps(codec, 0x04);
5235	wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
5236	if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
5237		spec->adc_nids = alc260_adc_nids_alt;
5238		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
5239		spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
5240	} else {
5241		spec->adc_nids = alc260_adc_nids;
5242		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
5243		spec->mixers[spec->num_mixers] = alc260_capture_mixer;
5244	}
5245	spec->num_mixers++;
5246
5247	return 1;
5248}
5249
5250/* additional initialization for auto-configuration model */
5251static void alc260_auto_init(struct hda_codec *codec)
5252{
5253	struct alc_spec *spec = codec->spec;
5254	alc260_auto_init_multi_out(codec);
5255	alc260_auto_init_analog_input(codec);
5256	if (spec->unsol_event)
5257		alc_inithook(codec);
5258}
5259
5260#ifdef CONFIG_SND_HDA_POWER_SAVE
5261static struct hda_amp_list alc260_loopbacks[] = {
5262	{ 0x07, HDA_INPUT, 0 },
5263	{ 0x07, HDA_INPUT, 1 },
5264	{ 0x07, HDA_INPUT, 2 },
5265	{ 0x07, HDA_INPUT, 3 },
5266	{ 0x07, HDA_INPUT, 4 },
5267	{ } /* end */
5268};
5269#endif
5270
5271/*
5272 * ALC260 configurations
5273 */
5274static const char *alc260_models[ALC260_MODEL_LAST] = {
5275	[ALC260_BASIC]		= "basic",
5276	[ALC260_HP]		= "hp",
5277	[ALC260_HP_3013]	= "hp-3013",
5278	[ALC260_HP_DC7600]	= "hp-dc7600",
5279	[ALC260_FUJITSU_S702X]	= "fujitsu",
5280	[ALC260_ACER]		= "acer",
5281	[ALC260_WILL]		= "will",
5282	[ALC260_REPLACER_672V]	= "replacer",
5283#ifdef CONFIG_SND_DEBUG
5284	[ALC260_TEST]		= "test",
5285#endif
5286	[ALC260_AUTO]		= "auto",
5287};
5288
5289static struct snd_pci_quirk alc260_cfg_tbl[] = {
5290	SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5291	SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5292	SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5293	SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5294	SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5295	SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5296	SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
5297	SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5298	SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5299	SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5300	SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5301	SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5302	SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5303	SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5304	SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5305	SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5306	SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5307	SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5308	{}
5309};
5310
5311static struct alc_config_preset alc260_presets[] = {
5312	[ALC260_BASIC] = {
5313		.mixers = { alc260_base_output_mixer,
5314			    alc260_input_mixer,
5315			    alc260_pc_beep_mixer,
5316			    alc260_capture_mixer },
5317		.init_verbs = { alc260_init_verbs },
5318		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5319		.dac_nids = alc260_dac_nids,
5320		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5321		.adc_nids = alc260_adc_nids,
5322		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5323		.channel_mode = alc260_modes,
5324		.input_mux = &alc260_capture_source,
5325	},
5326	[ALC260_HP] = {
5327		.mixers = { alc260_hp_output_mixer,
5328			    alc260_input_mixer,
5329			    alc260_capture_alt_mixer },
5330		.init_verbs = { alc260_init_verbs,
5331				alc260_hp_unsol_verbs },
5332		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5333		.dac_nids = alc260_dac_nids,
5334		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5335		.adc_nids = alc260_hp_adc_nids,
5336		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5337		.channel_mode = alc260_modes,
5338		.input_mux = &alc260_capture_source,
5339		.unsol_event = alc260_hp_unsol_event,
5340		.init_hook = alc260_hp_automute,
5341	},
5342	[ALC260_HP_DC7600] = {
5343		.mixers = { alc260_hp_dc7600_mixer,
5344			    alc260_input_mixer,
5345			    alc260_capture_alt_mixer },
5346		.init_verbs = { alc260_init_verbs,
5347				alc260_hp_dc7600_verbs },
5348		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5349		.dac_nids = alc260_dac_nids,
5350		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5351		.adc_nids = alc260_hp_adc_nids,
5352		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5353		.channel_mode = alc260_modes,
5354		.input_mux = &alc260_capture_source,
5355		.unsol_event = alc260_hp_3012_unsol_event,
5356		.init_hook = alc260_hp_3012_automute,
5357	},
5358	[ALC260_HP_3013] = {
5359		.mixers = { alc260_hp_3013_mixer,
5360			    alc260_input_mixer,
5361			    alc260_capture_alt_mixer },
5362		.init_verbs = { alc260_hp_3013_init_verbs,
5363				alc260_hp_3013_unsol_verbs },
5364		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5365		.dac_nids = alc260_dac_nids,
5366		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5367		.adc_nids = alc260_hp_adc_nids,
5368		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5369		.channel_mode = alc260_modes,
5370		.input_mux = &alc260_capture_source,
5371		.unsol_event = alc260_hp_3013_unsol_event,
5372		.init_hook = alc260_hp_3013_automute,
5373	},
5374	[ALC260_FUJITSU_S702X] = {
5375		.mixers = { alc260_fujitsu_mixer,
5376			    alc260_capture_mixer },
5377		.init_verbs = { alc260_fujitsu_init_verbs },
5378		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5379		.dac_nids = alc260_dac_nids,
5380		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5381		.adc_nids = alc260_dual_adc_nids,
5382		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5383		.channel_mode = alc260_modes,
5384		.num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5385		.input_mux = alc260_fujitsu_capture_sources,
5386	},
5387	[ALC260_ACER] = {
5388		.mixers = { alc260_acer_mixer,
5389			    alc260_capture_mixer },
5390		.init_verbs = { alc260_acer_init_verbs },
5391		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5392		.dac_nids = alc260_dac_nids,
5393		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5394		.adc_nids = alc260_dual_adc_nids,
5395		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5396		.channel_mode = alc260_modes,
5397		.num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5398		.input_mux = alc260_acer_capture_sources,
5399	},
5400	[ALC260_WILL] = {
5401		.mixers = { alc260_will_mixer,
5402			    alc260_capture_mixer },
5403		.init_verbs = { alc260_init_verbs, alc260_will_verbs },
5404		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5405		.dac_nids = alc260_dac_nids,
5406		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5407		.adc_nids = alc260_adc_nids,
5408		.dig_out_nid = ALC260_DIGOUT_NID,
5409		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5410		.channel_mode = alc260_modes,
5411		.input_mux = &alc260_capture_source,
5412	},
5413	[ALC260_REPLACER_672V] = {
5414		.mixers = { alc260_replacer_672v_mixer,
5415			    alc260_capture_mixer },
5416		.init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5417		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5418		.dac_nids = alc260_dac_nids,
5419		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5420		.adc_nids = alc260_adc_nids,
5421		.dig_out_nid = ALC260_DIGOUT_NID,
5422		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5423		.channel_mode = alc260_modes,
5424		.input_mux = &alc260_capture_source,
5425		.unsol_event = alc260_replacer_672v_unsol_event,
5426		.init_hook = alc260_replacer_672v_automute,
5427	},
5428#ifdef CONFIG_SND_DEBUG
5429	[ALC260_TEST] = {
5430		.mixers = { alc260_test_mixer,
5431			    alc260_capture_mixer },
5432		.init_verbs = { alc260_test_init_verbs },
5433		.num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5434		.dac_nids = alc260_test_dac_nids,
5435		.num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5436		.adc_nids = alc260_test_adc_nids,
5437		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5438		.channel_mode = alc260_modes,
5439		.num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5440		.input_mux = alc260_test_capture_sources,
5441	},
5442#endif
5443};
5444
5445static int patch_alc260(struct hda_codec *codec)
5446{
5447	struct alc_spec *spec;
5448	int err, board_config;
5449
5450	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5451	if (spec == NULL)
5452		return -ENOMEM;
5453
5454	codec->spec = spec;
5455
5456	board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5457						  alc260_models,
5458						  alc260_cfg_tbl);
5459	if (board_config < 0) {
5460		snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5461			   "trying auto-probe from BIOS...\n");
5462		board_config = ALC260_AUTO;
5463	}
5464
5465	if (board_config == ALC260_AUTO) {
5466		/* automatic parse from the BIOS config */
5467		err = alc260_parse_auto_config(codec);
5468		if (err < 0) {
5469			alc_free(codec);
5470			return err;
5471		} else if (!err) {
5472			printk(KERN_INFO
5473			       "hda_codec: Cannot set up configuration "
5474			       "from BIOS.  Using base mode...\n");
5475			board_config = ALC260_BASIC;
5476		}
5477	}
5478
5479	if (board_config != ALC260_AUTO)
5480		setup_preset(spec, &alc260_presets[board_config]);
5481
5482	spec->stream_name_analog = "ALC260 Analog";
5483	spec->stream_analog_playback = &alc260_pcm_analog_playback;
5484	spec->stream_analog_capture = &alc260_pcm_analog_capture;
5485
5486	spec->stream_name_digital = "ALC260 Digital";
5487	spec->stream_digital_playback = &alc260_pcm_digital_playback;
5488	spec->stream_digital_capture = &alc260_pcm_digital_capture;
5489
5490	spec->vmaster_nid = 0x08;
5491
5492	codec->patch_ops = alc_patch_ops;
5493	if (board_config == ALC260_AUTO)
5494		spec->init_hook = alc260_auto_init;
5495#ifdef CONFIG_SND_HDA_POWER_SAVE
5496	if (!spec->loopback.amplist)
5497		spec->loopback.amplist = alc260_loopbacks;
5498#endif
5499
5500	return 0;
5501}
5502
5503
5504/*
5505 * ALC882 support
5506 *
5507 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5508 * configuration.  Each pin widget can choose any input DACs and a mixer.
5509 * Each ADC is connected from a mixer of all inputs.  This makes possible
5510 * 6-channel independent captures.
5511 *
5512 * In addition, an independent DAC for the multi-playback (not used in this
5513 * driver yet).
5514 */
5515#define ALC882_DIGOUT_NID	0x06
5516#define ALC882_DIGIN_NID	0x0a
5517
5518static struct hda_channel_mode alc882_ch_modes[1] = {
5519	{ 8, NULL }
5520};
5521
5522static hda_nid_t alc882_dac_nids[4] = {
5523	/* front, rear, clfe, rear_surr */
5524	0x02, 0x03, 0x04, 0x05
5525};
5526
5527/* identical with ALC880 */
5528#define alc882_adc_nids		alc880_adc_nids
5529#define alc882_adc_nids_alt	alc880_adc_nids_alt
5530
5531static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
5532static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
5533
5534/* input MUX */
5535/* FIXME: should be a matrix-type input source selection */
5536
5537static struct hda_input_mux alc882_capture_source = {
5538	.num_items = 4,
5539	.items = {
5540		{ "Mic", 0x0 },
5541		{ "Front Mic", 0x1 },
5542		{ "Line", 0x2 },
5543		{ "CD", 0x4 },
5544	},
5545};
5546#define alc882_mux_enum_info alc_mux_enum_info
5547#define alc882_mux_enum_get alc_mux_enum_get
5548
5549static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
5550			       struct snd_ctl_elem_value *ucontrol)
5551{
5552	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5553	struct alc_spec *spec = codec->spec;
5554	const struct hda_input_mux *imux = spec->input_mux;
5555	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5556	hda_nid_t nid = spec->capsrc_nids ?
5557		spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
5558	unsigned int *cur_val = &spec->cur_mux[adc_idx];
5559	unsigned int i, idx;
5560
5561	idx = ucontrol->value.enumerated.item[0];
5562	if (idx >= imux->num_items)
5563		idx = imux->num_items - 1;
5564	if (*cur_val == idx)
5565		return 0;
5566	for (i = 0; i < imux->num_items; i++) {
5567		unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5568		snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
5569					 imux->items[i].index,
5570					 HDA_AMP_MUTE, v);
5571	}
5572	*cur_val = idx;
5573	return 1;
5574}
5575
5576/*
5577 * 2ch mode
5578 */
5579static struct hda_verb alc882_3ST_ch2_init[] = {
5580	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5581	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5582	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5583	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5584	{ } /* end */
5585};
5586
5587/*
5588 * 6ch mode
5589 */
5590static struct hda_verb alc882_3ST_ch6_init[] = {
5591	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5592	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5593	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5594	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5595	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5596	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5597	{ } /* end */
5598};
5599
5600static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5601	{ 2, alc882_3ST_ch2_init },
5602	{ 6, alc882_3ST_ch6_init },
5603};
5604
5605/*
5606 * 6ch mode
5607 */
5608static struct hda_verb alc882_sixstack_ch6_init[] = {
5609	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5610	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5611	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5612	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5613	{ } /* end */
5614};
5615
5616/*
5617 * 8ch mode
5618 */
5619static struct hda_verb alc882_sixstack_ch8_init[] = {
5620	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5621	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5622	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5623	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5624	{ } /* end */
5625};
5626
5627static struct hda_channel_mode alc882_sixstack_modes[2] = {
5628	{ 6, alc882_sixstack_ch6_init },
5629	{ 8, alc882_sixstack_ch8_init },
5630};
5631
5632/*
5633 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5634 */
5635
5636/*
5637 * 2ch mode
5638 */
5639static struct hda_verb alc885_mbp_ch2_init[] = {
5640	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5641	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5642	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5643	{ } /* end */
5644};
5645
5646/*
5647 * 6ch mode
5648 */
5649static struct hda_verb alc885_mbp_ch6_init[] = {
5650	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5651	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5652	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5653	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5654	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5655	{ } /* end */
5656};
5657
5658static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5659	{ 2, alc885_mbp_ch2_init },
5660	{ 6, alc885_mbp_ch6_init },
5661};
5662
5663
5664/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5665 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5666 */
5667static struct snd_kcontrol_new alc882_base_mixer[] = {
5668	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5669	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5670	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5671	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5672	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5673	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5674	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5675	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5676	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5677	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5678	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5679	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5680	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5681	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5682	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5683	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5684	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5685	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5686	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5687	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5688	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5689	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5690	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5691	{ } /* end */
5692};
5693
5694static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5695	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5696	HDA_BIND_MUTE   ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
5697	HDA_CODEC_MUTE  ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
5698	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
5699	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5700	HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5701	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5702	HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5703	HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
5704	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5705	{ } /* end */
5706};
5707static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5708	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5709	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5710	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5711	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5712	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5713	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5714	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5715	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5716	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5717	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5718	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5719	{ } /* end */
5720};
5721
5722static struct snd_kcontrol_new alc882_targa_mixer[] = {
5723	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5724	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5725	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5726	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5727	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5728	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5729	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5730	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5731	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5732	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5733	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5734	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5735	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5736	{ } /* end */
5737};
5738
5739/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5740 *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5741 */
5742static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5743	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5744	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5745	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5746	HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5747	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5748	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5749	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5750	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5751	HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5752	HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5753	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5754	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5755	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5756	{ } /* end */
5757};
5758
5759static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5760	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5761	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5762	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5763	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5764	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5765	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5766	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5767	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5768	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5769	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5770	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5771	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5772	{ } /* end */
5773};
5774
5775static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5776	{
5777		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5778		.name = "Channel Mode",
5779		.info = alc_ch_mode_info,
5780		.get = alc_ch_mode_get,
5781		.put = alc_ch_mode_put,
5782	},
5783	{ } /* end */
5784};
5785
5786static struct hda_verb alc882_init_verbs[] = {
5787	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5788	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5789	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5790	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5791	/* Rear mixer */
5792	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5793	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5794	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5795	/* CLFE mixer */
5796	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5797	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5798	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5799	/* Side mixer */
5800	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5801	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5802	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5803
5804	/* Front Pin: output 0 (0x0c) */
5805	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5806	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5807	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5808	/* Rear Pin: output 1 (0x0d) */
5809	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5810	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5811	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5812	/* CLFE Pin: output 2 (0x0e) */
5813	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5814	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5815	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5816	/* Side Pin: output 3 (0x0f) */
5817	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5818	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5819	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5820	/* Mic (rear) pin: input vref at 80% */
5821	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5822	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5823	/* Front Mic pin: input vref at 80% */
5824	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5825	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5826	/* Line In pin: input */
5827	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5828	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5829	/* Line-2 In: Headphone output (output 0 - 0x0c) */
5830	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5831	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5832	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5833	/* CD pin widget for input */
5834	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5835
5836	/* FIXME: use matrix-type input source selection */
5837	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5838	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5839	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5840	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5841	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5842	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5843	/* Input mixer2 */
5844	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5845	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5846	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5847	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5848	/* Input mixer3 */
5849	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5850	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5851	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5852	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5853	/* ADC1: mute amp left and right */
5854	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5855	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5856	/* ADC2: mute amp left and right */
5857	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5858	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5859	/* ADC3: mute amp left and right */
5860	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5861	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5862
5863	{ }
5864};
5865
5866static struct hda_verb alc882_eapd_verbs[] = {
5867	/* change to EAPD mode */
5868	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5869	{0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5870	{ }
5871};
5872
5873/* Mac Pro test */
5874static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5875	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5876	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5877	HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5878	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5879	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5880	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5881	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5882	{ } /* end */
5883};
5884
5885static struct hda_verb alc882_macpro_init_verbs[] = {
5886	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5887	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5888	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5889	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5890	/* Front Pin: output 0 (0x0c) */
5891	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5892	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5893	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5894	/* Front Mic pin: input vref at 80% */
5895	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5896	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5897	/* Speaker:  output */
5898	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5899	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5900	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5901	/* Headphone output (output 0 - 0x0c) */
5902	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5903	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5904	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5905
5906	/* FIXME: use matrix-type input source selection */
5907	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5908	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5909	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5910	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5911	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5912	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5913	/* Input mixer2 */
5914	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5915	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5916	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5917	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5918	/* Input mixer3 */
5919	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5920	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5921	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5922	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5923	/* ADC1: mute amp left and right */
5924	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5925	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5926	/* ADC2: mute amp left and right */
5927	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5928	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5929	/* ADC3: mute amp left and right */
5930	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5931	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5932
5933	{ }
5934};
5935
5936/* Macbook Pro rev3 */
5937static struct hda_verb alc885_mbp3_init_verbs[] = {
5938	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5939	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5940	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5941	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5942	/* Rear mixer */
5943	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5944	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5945	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5946	/* Front Pin: output 0 (0x0c) */
5947	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5948	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5949	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5950	/* HP Pin: output 0 (0x0d) */
5951	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5952	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5953	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5954	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5955	/* Mic (rear) pin: input vref at 80% */
5956	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5957	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5958	/* Front Mic pin: input vref at 80% */
5959	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5960	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5961	/* Line In pin: use output 1 when in LineOut mode */
5962	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5963	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5964	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5965
5966	/* FIXME: use matrix-type input source selection */
5967	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5968	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5969	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5970	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5971	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5972	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5973	/* Input mixer2 */
5974	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5975	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5976	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5977	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5978	/* Input mixer3 */
5979	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5980	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5981	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5982	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5983	/* ADC1: mute amp left and right */
5984	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5985	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5986	/* ADC2: mute amp left and right */
5987	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5988	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5989	/* ADC3: mute amp left and right */
5990	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5991	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5992
5993	{ }
5994};
5995
5996/* iMac 24 mixer. */
5997static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5998	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5999	HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
6000	{ } /* end */
6001};
6002
6003/* iMac 24 init verbs. */
6004static struct hda_verb alc885_imac24_init_verbs[] = {
6005	/* Internal speakers: output 0 (0x0c) */
6006	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6007	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6008	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6009	/* Internal speakers: output 0 (0x0c) */
6010	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6011	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6012	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
6013	/* Headphone: output 0 (0x0c) */
6014	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6015	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6016	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6017	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6018	/* Front Mic: input vref at 80% */
6019	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6020	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6021	{ }
6022};
6023
6024/* Toggle speaker-output according to the hp-jack state */
6025static void alc885_imac24_automute(struct hda_codec *codec)
6026{
6027 	unsigned int present;
6028
6029 	present = snd_hda_codec_read(codec, 0x14, 0,
6030				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6031	snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
6032				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6033	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
6034				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6035}
6036
6037/* Processes unsolicited events. */
6038static void alc885_imac24_unsol_event(struct hda_codec *codec,
6039				      unsigned int res)
6040{
6041	/* Headphone insertion or removal. */
6042	if ((res >> 26) == ALC880_HP_EVENT)
6043		alc885_imac24_automute(codec);
6044}
6045
6046static void alc885_mbp3_automute(struct hda_codec *codec)
6047{
6048 	unsigned int present;
6049
6050 	present = snd_hda_codec_read(codec, 0x15, 0,
6051				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6052	snd_hda_codec_amp_stereo(codec, 0x14,  HDA_OUTPUT, 0,
6053				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6054	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6055				 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
6056
6057}
6058static void alc885_mbp3_unsol_event(struct hda_codec *codec,
6059				    unsigned int res)
6060{
6061	/* Headphone insertion or removal. */
6062	if ((res >> 26) == ALC880_HP_EVENT)
6063		alc885_mbp3_automute(codec);
6064}
6065
6066
6067static struct hda_verb alc882_targa_verbs[] = {
6068	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6069	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6070
6071	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6072	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6073
6074	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6075	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6076	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6077
6078	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6079	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6080	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6081	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6082	{ } /* end */
6083};
6084
6085/* toggle speaker-output according to the hp-jack state */
6086static void alc882_targa_automute(struct hda_codec *codec)
6087{
6088 	unsigned int present;
6089
6090 	present = snd_hda_codec_read(codec, 0x14, 0,
6091				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6092	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6093				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6094	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6095				  present ? 1 : 3);
6096}
6097
6098static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6099{
6100	/* Looks like the unsol event is incompatible with the standard
6101	 * definition.  4bit tag is placed at 26 bit!
6102	 */
6103	if (((res >> 26) == ALC880_HP_EVENT)) {
6104		alc882_targa_automute(codec);
6105	}
6106}
6107
6108static struct hda_verb alc882_asus_a7j_verbs[] = {
6109	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6110	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6111
6112	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6113	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6114	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6115
6116	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6117	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6118	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6119
6120	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6121	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6122	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6123	{ } /* end */
6124};
6125
6126static struct hda_verb alc882_asus_a7m_verbs[] = {
6127	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6128	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6129
6130	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6131	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6132	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6133
6134	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6135	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6136	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6137
6138	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6139	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6140	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6141 	{ } /* end */
6142};
6143
6144static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6145{
6146	unsigned int gpiostate, gpiomask, gpiodir;
6147
6148	gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6149				       AC_VERB_GET_GPIO_DATA, 0);
6150
6151	if (!muted)
6152		gpiostate |= (1 << pin);
6153	else
6154		gpiostate &= ~(1 << pin);
6155
6156	gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6157				      AC_VERB_GET_GPIO_MASK, 0);
6158	gpiomask |= (1 << pin);
6159
6160	gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6161				     AC_VERB_GET_GPIO_DIRECTION, 0);
6162	gpiodir |= (1 << pin);
6163
6164
6165	snd_hda_codec_write(codec, codec->afg, 0,
6166			    AC_VERB_SET_GPIO_MASK, gpiomask);
6167	snd_hda_codec_write(codec, codec->afg, 0,
6168			    AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6169
6170	msleep(1);
6171
6172	snd_hda_codec_write(codec, codec->afg, 0,
6173			    AC_VERB_SET_GPIO_DATA, gpiostate);
6174}
6175
6176/* set up GPIO at initialization */
6177static void alc885_macpro_init_hook(struct hda_codec *codec)
6178{
6179	alc882_gpio_mute(codec, 0, 0);
6180	alc882_gpio_mute(codec, 1, 0);
6181}
6182
6183/* set up GPIO and update auto-muting at initialization */
6184static void alc885_imac24_init_hook(struct hda_codec *codec)
6185{
6186	alc885_macpro_init_hook(codec);
6187	alc885_imac24_automute(codec);
6188}
6189
6190/*
6191 * generic initialization of ADC, input mixers and output mixers
6192 */
6193static struct hda_verb alc882_auto_init_verbs[] = {
6194	/*
6195	 * Unmute ADC0-2 and set the default input to mic-in
6196	 */
6197	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6198	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6199	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6200	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6201	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6202	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6203
6204	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6205	 * mixer widget
6206	 * Note: PASD motherboards uses the Line In 2 as the input for
6207	 * front panel mic (mic 2)
6208	 */
6209	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6210	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6211	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6212	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6213	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6214	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6215
6216	/*
6217	 * Set up output mixers (0x0c - 0x0f)
6218	 */
6219	/* set vol=0 to output mixers */
6220	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6221	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6222	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6223	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6224	/* set up input amps for analog loopback */
6225	/* Amp Indices: DAC = 0, mixer = 1 */
6226	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6227	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6228	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6229	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6230	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6231	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6232	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6233	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6234	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6235	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6236
6237	/* FIXME: use matrix-type input source selection */
6238	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6239	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6240	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6241	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6242	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6243	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6244	/* Input mixer2 */
6245	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6246	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6247	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6248	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6249	/* Input mixer3 */
6250	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6251	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6252	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6253	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6254
6255	{ }
6256};
6257
6258/* capture mixer elements */
6259static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
6260	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6261	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6262	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6263	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6264	{
6265		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6266		/* The multiple "Capture Source" controls confuse alsamixer
6267		 * So call somewhat different..
6268		 */
6269		/* .name = "Capture Source", */
6270		.name = "Input Source",
6271		.count = 2,
6272		.info = alc882_mux_enum_info,
6273		.get = alc882_mux_enum_get,
6274		.put = alc882_mux_enum_put,
6275	},
6276	{ } /* end */
6277};
6278
6279static struct snd_kcontrol_new alc882_capture_mixer[] = {
6280	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
6281	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
6282	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
6283	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
6284	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
6285	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
6286	{
6287		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6288		/* The multiple "Capture Source" controls confuse alsamixer
6289		 * So call somewhat different..
6290		 */
6291		/* .name = "Capture Source", */
6292		.name = "Input Source",
6293		.count = 3,
6294		.info = alc882_mux_enum_info,
6295		.get = alc882_mux_enum_get,
6296		.put = alc882_mux_enum_put,
6297	},
6298	{ } /* end */
6299};
6300
6301#ifdef CONFIG_SND_HDA_POWER_SAVE
6302#define alc882_loopbacks	alc880_loopbacks
6303#endif
6304
6305/* pcm configuration: identiacal with ALC880 */
6306#define alc882_pcm_analog_playback	alc880_pcm_analog_playback
6307#define alc882_pcm_analog_capture	alc880_pcm_analog_capture
6308#define alc882_pcm_digital_playback	alc880_pcm_digital_playback
6309#define alc882_pcm_digital_capture	alc880_pcm_digital_capture
6310
6311/*
6312 * configuration and preset
6313 */
6314static const char *alc882_models[ALC882_MODEL_LAST] = {
6315	[ALC882_3ST_DIG]	= "3stack-dig",
6316	[ALC882_6ST_DIG]	= "6stack-dig",
6317	[ALC882_ARIMA]		= "arima",
6318	[ALC882_W2JC]		= "w2jc",
6319	[ALC882_TARGA]		= "targa",
6320	[ALC882_ASUS_A7J]	= "asus-a7j",
6321	[ALC882_ASUS_A7M]	= "asus-a7m",
6322	[ALC885_MACPRO]		= "macpro",
6323	[ALC885_MBP3]		= "mbp3",
6324	[ALC885_IMAC24]		= "imac24",
6325	[ALC882_AUTO]		= "auto",
6326};
6327
6328static struct snd_pci_quirk alc882_cfg_tbl[] = {
6329	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6330	SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6331	SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6332	SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6333	SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6334	SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6335	SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6336	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6337	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6338	SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
6339	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6340	SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6341	{}
6342};
6343
6344static struct alc_config_preset alc882_presets[] = {
6345	[ALC882_3ST_DIG] = {
6346		.mixers = { alc882_base_mixer },
6347		.init_verbs = { alc882_init_verbs },
6348		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6349		.dac_nids = alc882_dac_nids,
6350		.dig_out_nid = ALC882_DIGOUT_NID,
6351		.dig_in_nid = ALC882_DIGIN_NID,
6352		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6353		.channel_mode = alc882_ch_modes,
6354		.need_dac_fix = 1,
6355		.input_mux = &alc882_capture_source,
6356	},
6357	[ALC882_6ST_DIG] = {
6358		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
6359		.init_verbs = { alc882_init_verbs },
6360		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6361		.dac_nids = alc882_dac_nids,
6362		.dig_out_nid = ALC882_DIGOUT_NID,
6363		.dig_in_nid = ALC882_DIGIN_NID,
6364		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6365		.channel_mode = alc882_sixstack_modes,
6366		.input_mux = &alc882_capture_source,
6367	},
6368	[ALC882_ARIMA] = {
6369		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
6370		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6371		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6372		.dac_nids = alc882_dac_nids,
6373		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6374		.channel_mode = alc882_sixstack_modes,
6375		.input_mux = &alc882_capture_source,
6376	},
6377	[ALC882_W2JC] = {
6378		.mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6379		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6380				alc880_gpio1_init_verbs },
6381		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6382		.dac_nids = alc882_dac_nids,
6383		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6384		.channel_mode = alc880_threestack_modes,
6385		.need_dac_fix = 1,
6386		.input_mux = &alc882_capture_source,
6387		.dig_out_nid = ALC882_DIGOUT_NID,
6388	},
6389	[ALC885_MBP3] = {
6390		.mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6391		.init_verbs = { alc885_mbp3_init_verbs,
6392				alc880_gpio1_init_verbs },
6393		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6394		.dac_nids = alc882_dac_nids,
6395		.channel_mode = alc885_mbp_6ch_modes,
6396		.num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6397		.input_mux = &alc882_capture_source,
6398		.dig_out_nid = ALC882_DIGOUT_NID,
6399		.dig_in_nid = ALC882_DIGIN_NID,
6400		.unsol_event = alc885_mbp3_unsol_event,
6401		.init_hook = alc885_mbp3_automute,
6402	},
6403	[ALC885_MACPRO] = {
6404		.mixers = { alc882_macpro_mixer },
6405		.init_verbs = { alc882_macpro_init_verbs },
6406		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6407		.dac_nids = alc882_dac_nids,
6408		.dig_out_nid = ALC882_DIGOUT_NID,
6409		.dig_in_nid = ALC882_DIGIN_NID,
6410		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6411		.channel_mode = alc882_ch_modes,
6412		.input_mux = &alc882_capture_source,
6413		.init_hook = alc885_macpro_init_hook,
6414	},
6415	[ALC885_IMAC24] = {
6416		.mixers = { alc885_imac24_mixer },
6417		.init_verbs = { alc885_imac24_init_verbs },
6418		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6419		.dac_nids = alc882_dac_nids,
6420		.dig_out_nid = ALC882_DIGOUT_NID,
6421		.dig_in_nid = ALC882_DIGIN_NID,
6422		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6423		.channel_mode = alc882_ch_modes,
6424		.input_mux = &alc882_capture_source,
6425		.unsol_event = alc885_imac24_unsol_event,
6426		.init_hook = alc885_imac24_init_hook,
6427	},
6428	[ALC882_TARGA] = {
6429		.mixers = { alc882_targa_mixer, alc882_chmode_mixer,
6430			    alc882_capture_mixer },
6431		.init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6432		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6433		.dac_nids = alc882_dac_nids,
6434		.dig_out_nid = ALC882_DIGOUT_NID,
6435		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6436		.adc_nids = alc882_adc_nids,
6437		.capsrc_nids = alc882_capsrc_nids,
6438		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6439		.channel_mode = alc882_3ST_6ch_modes,
6440		.need_dac_fix = 1,
6441		.input_mux = &alc882_capture_source,
6442		.unsol_event = alc882_targa_unsol_event,
6443		.init_hook = alc882_targa_automute,
6444	},
6445	[ALC882_ASUS_A7J] = {
6446		.mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
6447			    alc882_capture_mixer },
6448		.init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6449		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6450		.dac_nids = alc882_dac_nids,
6451		.dig_out_nid = ALC882_DIGOUT_NID,
6452		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6453		.adc_nids = alc882_adc_nids,
6454		.capsrc_nids = alc882_capsrc_nids,
6455		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6456		.channel_mode = alc882_3ST_6ch_modes,
6457		.need_dac_fix = 1,
6458		.input_mux = &alc882_capture_source,
6459	},
6460	[ALC882_ASUS_A7M] = {
6461		.mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6462		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6463				alc880_gpio1_init_verbs,
6464				alc882_asus_a7m_verbs },
6465		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6466		.dac_nids = alc882_dac_nids,
6467		.dig_out_nid = ALC882_DIGOUT_NID,
6468		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6469		.channel_mode = alc880_threestack_modes,
6470		.need_dac_fix = 1,
6471		.input_mux = &alc882_capture_source,
6472	},
6473};
6474
6475
6476/*
6477 * Pin config fixes
6478 */
6479enum {
6480	PINFIX_ABIT_AW9D_MAX
6481};
6482
6483static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6484	{ 0x15, 0x01080104 }, /* side */
6485	{ 0x16, 0x01011012 }, /* rear */
6486	{ 0x17, 0x01016011 }, /* clfe */
6487	{ }
6488};
6489
6490static const struct alc_pincfg *alc882_pin_fixes[] = {
6491	[PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6492};
6493
6494static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6495	SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6496	{}
6497};
6498
6499/*
6500 * BIOS auto configuration
6501 */
6502static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6503					      hda_nid_t nid, int pin_type,
6504					      int dac_idx)
6505{
6506	/* set as output */
6507	struct alc_spec *spec = codec->spec;
6508	int idx;
6509
6510	alc_set_pin_output(codec, nid, pin_type);
6511	if (spec->multiout.dac_nids[dac_idx] == 0x25)
6512		idx = 4;
6513	else
6514		idx = spec->multiout.dac_nids[dac_idx] - 2;
6515	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6516
6517}
6518
6519static void alc882_auto_init_multi_out(struct hda_codec *codec)
6520{
6521	struct alc_spec *spec = codec->spec;
6522	int i;
6523
6524	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6525	for (i = 0; i <= HDA_SIDE; i++) {
6526		hda_nid_t nid = spec->autocfg.line_out_pins[i];
6527		int pin_type = get_pin_type(spec->autocfg.line_out_type);
6528		if (nid)
6529			alc882_auto_set_output_and_unmute(codec, nid, pin_type,
6530							  i);
6531	}
6532}
6533
6534static void alc882_auto_init_hp_out(struct hda_codec *codec)
6535{
6536	struct alc_spec *spec = codec->spec;
6537	hda_nid_t pin;
6538
6539	pin = spec->autocfg.hp_pins[0];
6540	if (pin) /* connect to front */
6541		/* use dac 0 */
6542		alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6543	pin = spec->autocfg.speaker_pins[0];
6544	if (pin)
6545		alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
6546}
6547
6548#define alc882_is_input_pin(nid)	alc880_is_input_pin(nid)
6549#define ALC882_PIN_CD_NID		ALC880_PIN_CD_NID
6550
6551static void alc882_auto_init_analog_input(struct hda_codec *codec)
6552{
6553	struct alc_spec *spec = codec->spec;
6554	int i;
6555
6556	for (i = 0; i < AUTO_PIN_LAST; i++) {
6557		hda_nid_t nid = spec->autocfg.input_pins[i];
6558		unsigned int vref;
6559		if (!nid)
6560			continue;
6561		vref = PIN_IN;
6562		if (1 /*i <= AUTO_PIN_FRONT_MIC*/) {
6563			unsigned int pincap;
6564			pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
6565			if ((pincap >> AC_PINCAP_VREF_SHIFT) &
6566			    AC_PINCAP_VREF_80)
6567				vref = PIN_VREF80;
6568		}
6569		snd_hda_codec_write(codec, nid, 0,
6570				    AC_VERB_SET_PIN_WIDGET_CONTROL, vref);
6571		if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
6572			snd_hda_codec_write(codec, nid, 0,
6573					    AC_VERB_SET_AMP_GAIN_MUTE,
6574					    AMP_OUT_MUTE);
6575	}
6576}
6577
6578static void alc882_auto_init_input_src(struct hda_codec *codec)
6579{
6580	struct alc_spec *spec = codec->spec;
6581	const struct hda_input_mux *imux = spec->input_mux;
6582	int c;
6583
6584	for (c = 0; c < spec->num_adc_nids; c++) {
6585		hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
6586		hda_nid_t nid = spec->capsrc_nids[c];
6587		int conns, mute, idx, item;
6588
6589		conns = snd_hda_get_connections(codec, nid, conn_list,
6590						ARRAY_SIZE(conn_list));
6591		if (conns < 0)
6592			continue;
6593		for (idx = 0; idx < conns; idx++) {
6594			/* if the current connection is the selected one,
6595			 * unmute it as default - otherwise mute it
6596			 */
6597			mute = AMP_IN_MUTE(idx);
6598			for (item = 0; item < imux->num_items; item++) {
6599				if (imux->items[item].index == idx) {
6600					if (spec->cur_mux[c] == item)
6601						mute = AMP_IN_UNMUTE(idx);
6602					break;
6603				}
6604			}
6605			snd_hda_codec_write(codec, nid, 0,
6606					    AC_VERB_SET_AMP_GAIN_MUTE, mute);
6607		}
6608	}
6609}
6610
6611/* add mic boosts if needed */
6612static int alc_auto_add_mic_boost(struct hda_codec *codec)
6613{
6614	struct alc_spec *spec = codec->spec;
6615	int err;
6616	hda_nid_t nid;
6617
6618	nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
6619	if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6620		err = add_control(spec, ALC_CTL_WIDGET_VOL,
6621				  "Mic Boost",
6622				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6623		if (err < 0)
6624			return err;
6625	}
6626	nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6627	if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6628		err = add_control(spec, ALC_CTL_WIDGET_VOL,
6629				  "Front Mic Boost",
6630				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6631		if (err < 0)
6632			return err;
6633	}
6634	return 0;
6635}
6636
6637/* almost identical with ALC880 parser... */
6638static int alc882_parse_auto_config(struct hda_codec *codec)
6639{
6640	struct alc_spec *spec = codec->spec;
6641	int err = alc880_parse_auto_config(codec);
6642
6643	if (err < 0)
6644		return err;
6645	else if (!err)
6646		return 0; /* no config found */
6647
6648	err = alc_auto_add_mic_boost(codec);
6649	if (err < 0)
6650		return err;
6651
6652	/* hack - override the init verbs */
6653	spec->init_verbs[0] = alc882_auto_init_verbs;
6654
6655	return 1; /* config found */
6656}
6657
6658/* additional initialization for auto-configuration model */
6659static void alc882_auto_init(struct hda_codec *codec)
6660{
6661	struct alc_spec *spec = codec->spec;
6662	alc882_auto_init_multi_out(codec);
6663	alc882_auto_init_hp_out(codec);
6664	alc882_auto_init_analog_input(codec);
6665	alc882_auto_init_input_src(codec);
6666	if (spec->unsol_event)
6667		alc_inithook(codec);
6668}
6669
6670static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
6671
6672static int patch_alc882(struct hda_codec *codec)
6673{
6674	struct alc_spec *spec;
6675	int err, board_config;
6676
6677	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6678	if (spec == NULL)
6679		return -ENOMEM;
6680
6681	codec->spec = spec;
6682
6683	board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6684						  alc882_models,
6685						  alc882_cfg_tbl);
6686
6687	if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
6688		/* Pick up systems that don't supply PCI SSID */
6689		switch (codec->subsystem_id) {
6690		case 0x106b0c00: /* Mac Pro */
6691			board_config = ALC885_MACPRO;
6692			break;
6693		case 0x106b1000: /* iMac 24 */
6694		case 0x106b2800: /* AppleTV */
6695			board_config = ALC885_IMAC24;
6696			break;
6697		case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
6698		case 0x106b00a4: /* MacbookPro4,1 */
6699		case 0x106b2c00: /* Macbook Pro rev3 */
6700		case 0x106b3600: /* Macbook 3.1 */
6701			board_config = ALC885_MBP3;
6702			break;
6703		default:
6704			/* ALC889A is handled better as ALC888-compatible */
6705			if (codec->revision_id == 0x100101 ||
6706			    codec->revision_id == 0x100103) {
6707				alc_free(codec);
6708				return patch_alc883(codec);
6709			}
6710			printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6711		       			 "trying auto-probe from BIOS...\n");
6712			board_config = ALC882_AUTO;
6713		}
6714	}
6715
6716	alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6717
6718	if (board_config == ALC882_AUTO) {
6719		/* automatic parse from the BIOS config */
6720		err = alc882_parse_auto_config(codec);
6721		if (err < 0) {
6722			alc_free(codec);
6723			return err;
6724		} else if (!err) {
6725			printk(KERN_INFO
6726			       "hda_codec: Cannot set up configuration "
6727			       "from BIOS.  Using base mode...\n");
6728			board_config = ALC882_3ST_DIG;
6729		}
6730	}
6731
6732	if (board_config != ALC882_AUTO)
6733		setup_preset(spec, &alc882_presets[board_config]);
6734
6735	if (codec->vendor_id == 0x10ec0885) {
6736		spec->stream_name_analog = "ALC885 Analog";
6737		spec->stream_name_digital = "ALC885 Digital";
6738	} else {
6739		spec->stream_name_analog = "ALC882 Analog";
6740		spec->stream_name_digital = "ALC882 Digital";
6741	}
6742
6743	spec->stream_analog_playback = &alc882_pcm_analog_playback;
6744	spec->stream_analog_capture = &alc882_pcm_analog_capture;
6745	/* FIXME: setup DAC5 */
6746	/*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
6747	spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
6748
6749	spec->stream_digital_playback = &alc882_pcm_digital_playback;
6750	spec->stream_digital_capture = &alc882_pcm_digital_capture;
6751
6752	if (!spec->adc_nids && spec->input_mux) {
6753		/* check whether NID 0x07 is valid */
6754		unsigned int wcap = get_wcaps(codec, 0x07);
6755		/* get type */
6756		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6757		if (wcap != AC_WID_AUD_IN) {
6758			spec->adc_nids = alc882_adc_nids_alt;
6759			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6760			spec->capsrc_nids = alc882_capsrc_nids_alt;
6761			spec->mixers[spec->num_mixers] =
6762				alc882_capture_alt_mixer;
6763			spec->num_mixers++;
6764		} else {
6765			spec->adc_nids = alc882_adc_nids;
6766			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6767			spec->capsrc_nids = alc882_capsrc_nids;
6768			spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6769			spec->num_mixers++;
6770		}
6771	}
6772
6773	spec->vmaster_nid = 0x0c;
6774
6775	codec->patch_ops = alc_patch_ops;
6776	if (board_config == ALC882_AUTO)
6777		spec->init_hook = alc882_auto_init;
6778#ifdef CONFIG_SND_HDA_POWER_SAVE
6779	if (!spec->loopback.amplist)
6780		spec->loopback.amplist = alc882_loopbacks;
6781#endif
6782
6783	return 0;
6784}
6785
6786/*
6787 * ALC883 support
6788 *
6789 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6790 * configuration.  Each pin widget can choose any input DACs and a mixer.
6791 * Each ADC is connected from a mixer of all inputs.  This makes possible
6792 * 6-channel independent captures.
6793 *
6794 * In addition, an independent DAC for the multi-playback (not used in this
6795 * driver yet).
6796 */
6797#define ALC883_DIGOUT_NID	0x06
6798#define ALC883_DIGIN_NID	0x0a
6799
6800static hda_nid_t alc883_dac_nids[4] = {
6801	/* front, rear, clfe, rear_surr */
6802	0x02, 0x03, 0x04, 0x05
6803};
6804
6805static hda_nid_t alc883_adc_nids[2] = {
6806	/* ADC1-2 */
6807	0x08, 0x09,
6808};
6809
6810static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
6811
6812/* input MUX */
6813/* FIXME: should be a matrix-type input source selection */
6814
6815static struct hda_input_mux alc883_capture_source = {
6816	.num_items = 4,
6817	.items = {
6818		{ "Mic", 0x0 },
6819		{ "Front Mic", 0x1 },
6820		{ "Line", 0x2 },
6821		{ "CD", 0x4 },
6822	},
6823};
6824
6825static struct hda_input_mux alc883_3stack_6ch_intel = {
6826	.num_items = 4,
6827	.items = {
6828		{ "Mic", 0x1 },
6829		{ "Front Mic", 0x0 },
6830		{ "Line", 0x2 },
6831		{ "CD", 0x4 },
6832	},
6833};
6834
6835static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6836	.num_items = 2,
6837	.items = {
6838		{ "Mic", 0x1 },
6839		{ "Line", 0x2 },
6840	},
6841};
6842
6843static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6844	.num_items = 4,
6845	.items = {
6846		{ "Mic", 0x0 },
6847		{ "iMic", 0x1 },
6848		{ "Line", 0x2 },
6849		{ "CD", 0x4 },
6850	},
6851};
6852
6853static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6854	.num_items = 2,
6855	.items = {
6856		{ "Mic", 0x0 },
6857		{ "Int Mic", 0x1 },
6858	},
6859};
6860
6861static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6862	.num_items = 3,
6863	.items = {
6864		{ "Mic", 0x0 },
6865		{ "Front Mic", 0x1 },
6866		{ "Line", 0x4 },
6867	},
6868};
6869
6870static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6871	.num_items = 2,
6872	.items = {
6873		{ "Mic", 0x0 },
6874		{ "Line", 0x2 },
6875	},
6876};
6877
6878#define alc883_mux_enum_info alc_mux_enum_info
6879#define alc883_mux_enum_get alc_mux_enum_get
6880/* ALC883 has the ALC882-type input selection */
6881#define alc883_mux_enum_put alc882_mux_enum_put
6882
6883/*
6884 * 2ch mode
6885 */
6886static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6887	{ 2, NULL }
6888};
6889
6890/*
6891 * 2ch mode
6892 */
6893static struct hda_verb alc883_3ST_ch2_init[] = {
6894	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6895	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6896	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6897	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6898	{ } /* end */
6899};
6900
6901/*
6902 * 4ch mode
6903 */
6904static struct hda_verb alc883_3ST_ch4_init[] = {
6905	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6906	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6907	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6908	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6909	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6910	{ } /* end */
6911};
6912
6913/*
6914 * 6ch mode
6915 */
6916static struct hda_verb alc883_3ST_ch6_init[] = {
6917	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6918	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6919	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6920	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6921	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6922	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6923	{ } /* end */
6924};
6925
6926static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
6927	{ 2, alc883_3ST_ch2_init },
6928	{ 4, alc883_3ST_ch4_init },
6929	{ 6, alc883_3ST_ch6_init },
6930};
6931
6932/*
6933 * 2ch mode
6934 */
6935static struct hda_verb alc883_3ST_ch2_intel_init[] = {
6936	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6937	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6938	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6939	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6940	{ } /* end */
6941};
6942
6943/*
6944 * 4ch mode
6945 */
6946static struct hda_verb alc883_3ST_ch4_intel_init[] = {
6947	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6948	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6949	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6950	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6951	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6952	{ } /* end */
6953};
6954
6955/*
6956 * 6ch mode
6957 */
6958static struct hda_verb alc883_3ST_ch6_intel_init[] = {
6959	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6960	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6961	{ 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
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
6968static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
6969	{ 2, alc883_3ST_ch2_intel_init },
6970	{ 4, alc883_3ST_ch4_intel_init },
6971	{ 6, alc883_3ST_ch6_intel_init },
6972};
6973
6974/*
6975 * 6ch mode
6976 */
6977static struct hda_verb alc883_sixstack_ch6_init[] = {
6978	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6979	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6980	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6981	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6982	{ } /* end */
6983};
6984
6985/*
6986 * 8ch mode
6987 */
6988static struct hda_verb alc883_sixstack_ch8_init[] = {
6989	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6990	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6991	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6992	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6993	{ } /* end */
6994};
6995
6996static struct hda_channel_mode alc883_sixstack_modes[2] = {
6997	{ 6, alc883_sixstack_ch6_init },
6998	{ 8, alc883_sixstack_ch8_init },
6999};
7000
7001static struct hda_verb alc883_medion_eapd_verbs[] = {
7002        /* eanable EAPD on medion laptop */
7003	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7004	{0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7005	{ }
7006};
7007
7008/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7009 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7010 */
7011
7012static struct snd_kcontrol_new alc883_base_mixer[] = {
7013	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7014	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7015	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7016	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7017	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7018	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7019	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7020	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7021	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7022	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7023	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7024	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7025	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7026	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7027	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7028	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7029	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7030	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7031	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7032	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7033	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7034	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7035	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7036	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7037	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7038	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7039	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7040	{
7041		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7042		/* .name = "Capture Source", */
7043		.name = "Input Source",
7044		.count = 2,
7045		.info = alc883_mux_enum_info,
7046		.get = alc883_mux_enum_get,
7047		.put = alc883_mux_enum_put,
7048	},
7049	{ } /* end */
7050};
7051
7052static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7053	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7054	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7055	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7056	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7057	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7058	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7059	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7060	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7061	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7062	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7063	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7064	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7065	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7066	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7067	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7068	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7069	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7070	{
7071		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7072		/* .name = "Capture Source", */
7073		.name = "Input Source",
7074		.count = 2,
7075		.info = alc883_mux_enum_info,
7076		.get = alc883_mux_enum_get,
7077		.put = alc883_mux_enum_put,
7078	},
7079	{ } /* end */
7080};
7081
7082static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7083	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7084	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7085	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7086	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7087	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7088	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7089	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7090	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7091	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7092	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7093	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7094	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7095	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7096	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7097	{
7098		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7099		/* .name = "Capture Source", */
7100		.name = "Input Source",
7101		.count = 2,
7102		.info = alc883_mux_enum_info,
7103		.get = alc883_mux_enum_get,
7104		.put = alc883_mux_enum_put,
7105	},
7106	{ } /* end */
7107};
7108
7109static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7110	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7111	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7112	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7113	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7114	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7115	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7116	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7117	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7118	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7119	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7120	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7121	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7122	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7123	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7124	{
7125		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7126		/* .name = "Capture Source", */
7127		.name = "Input Source",
7128		.count = 2,
7129		.info = alc883_mux_enum_info,
7130		.get = alc883_mux_enum_get,
7131		.put = alc883_mux_enum_put,
7132	},
7133	{ } /* end */
7134};
7135
7136static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7137	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7138	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7139	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7140	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7141	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7142	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7143	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7144	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7145	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7146	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7147	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7148	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7149	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7150	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7151	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7152	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7153	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7154	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7155	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7156	{
7157		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7158		/* .name = "Capture Source", */
7159		.name = "Input Source",
7160		.count = 2,
7161		.info = alc883_mux_enum_info,
7162		.get = alc883_mux_enum_get,
7163		.put = alc883_mux_enum_put,
7164	},
7165	{ } /* end */
7166};
7167
7168static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7169	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7170	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7171	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7172	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7173	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7174	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7175	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7176	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7177	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7178	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7179	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7180	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7181	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7182	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7183	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7184	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7185	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7186	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7187	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7188	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7189	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7190	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7191	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7192	{
7193		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7194		/* .name = "Capture Source", */
7195		.name = "Input Source",
7196		.count = 1,
7197		.info = alc883_mux_enum_info,
7198		.get = alc883_mux_enum_get,
7199		.put = alc883_mux_enum_put,
7200	},
7201	{ } /* end */
7202};
7203
7204static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7205	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7206	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7207	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7208	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7209	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7210			      HDA_OUTPUT),
7211	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7212	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7213	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7214	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7215	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7216	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7217	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7218	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7219	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7220	HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7221	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7222	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7223	HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7224	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7225	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7226	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7227	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7228	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7229	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7230	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7231	{
7232		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7233		/* .name = "Capture Source", */
7234		.name = "Input Source",
7235		.count = 2,
7236		.info = alc883_mux_enum_info,
7237		.get = alc883_mux_enum_get,
7238		.put = alc883_mux_enum_put,
7239	},
7240	{ } /* end */
7241};
7242
7243static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7244	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7245	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7246	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7247	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7248	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7249	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7250	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7251	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7252	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7253	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7254	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7255	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7256	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7257	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7258	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7259	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7260	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7261	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7262	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7263	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7264	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7265	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7266	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7267
7268	{
7269		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7270		/* .name = "Capture Source", */
7271		.name = "Input Source",
7272		.count = 1,
7273		.info = alc883_mux_enum_info,
7274		.get = alc883_mux_enum_get,
7275		.put = alc883_mux_enum_put,
7276	},
7277	{ } /* end */
7278};
7279
7280static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7281	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7282	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7283	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7284	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7285	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7286	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7287	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7288	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7289	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7290	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7291	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7292	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7293	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7294	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7295	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7296	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7297	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7298	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7299	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7300	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7301	{
7302		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7303		/* .name = "Capture Source", */
7304		.name = "Input Source",
7305		.count = 2,
7306		.info = alc883_mux_enum_info,
7307		.get = alc883_mux_enum_get,
7308		.put = alc883_mux_enum_put,
7309	},
7310	{ } /* end */
7311};
7312
7313static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7314	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7315	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7316	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7317	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7318	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7319	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7320	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7321	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7322	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7323	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7324	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7325	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7326	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7327	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7328	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7329	{
7330		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7331		/* .name = "Capture Source", */
7332		.name = "Input Source",
7333		.count = 2,
7334		.info = alc883_mux_enum_info,
7335		.get = alc883_mux_enum_get,
7336		.put = alc883_mux_enum_put,
7337	},
7338	{ } /* end */
7339};
7340
7341static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7342	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7343	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7344	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7345	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7346	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7347	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7348	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7349	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7350	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7351	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7352	{
7353		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7354		/* .name = "Capture Source", */
7355		.name = "Input Source",
7356		.count = 1,
7357		.info = alc883_mux_enum_info,
7358		.get = alc883_mux_enum_get,
7359		.put = alc883_mux_enum_put,
7360	},
7361	{ } /* end */
7362};
7363
7364static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7365	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7366	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7367	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7368	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7369	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7370	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7371	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7372	HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7373	HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7374	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7375	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7376	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7377	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7378	{
7379		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7380		/* .name = "Capture Source", */
7381		.name = "Input Source",
7382		.count = 2,
7383		.info = alc883_mux_enum_info,
7384		.get = alc883_mux_enum_get,
7385		.put = alc883_mux_enum_put,
7386	},
7387	{ } /* end */
7388};
7389
7390static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7391	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7392	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7393	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7394	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7395	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7396	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7397	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7398	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7399	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7400	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7401	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7402	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7403	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7404	{
7405		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7406		/* .name = "Capture Source", */
7407		.name = "Input Source",
7408		.count = 2,
7409		.info = alc883_mux_enum_info,
7410		.get = alc883_mux_enum_get,
7411		.put = alc883_mux_enum_put,
7412	},
7413	{ } /* end */
7414};
7415
7416static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7417	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7418	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7419	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7420	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7421	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7422	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7423	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7424	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7425	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7426	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7427	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7428	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7429	{
7430		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7431		/* .name = "Capture Source", */
7432		.name = "Input Source",
7433		.count = 2,
7434		.info = alc883_mux_enum_info,
7435		.get = alc883_mux_enum_get,
7436		.put = alc883_mux_enum_put,
7437	},
7438	{ } /* end */
7439};
7440
7441static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7442	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7443	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7444	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7445	HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7446	HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7447						0x0d, 1, 0x0, HDA_OUTPUT),
7448	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7449	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7450	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7451	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7452	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7453	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7454	HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
7455	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7456	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7457	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7458	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7459	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7460	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7461	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7462	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7463	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7464	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7465	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7466	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7467	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7468	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7469	{
7470		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7471		/* .name = "Capture Source", */
7472		.name = "Input Source",
7473		.count = 2,
7474		.info = alc883_mux_enum_info,
7475		.get = alc883_mux_enum_get,
7476		.put = alc883_mux_enum_put,
7477	},
7478	{ } /* end */
7479};
7480
7481static struct hda_bind_ctls alc883_bind_cap_vol = {
7482	.ops = &snd_hda_bind_vol,
7483	.values = {
7484		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7485		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7486		0
7487	},
7488};
7489
7490static struct hda_bind_ctls alc883_bind_cap_switch = {
7491	.ops = &snd_hda_bind_sw,
7492	.values = {
7493		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7494		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7495		0
7496	},
7497};
7498
7499static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7500	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7501	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7502	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7503	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7504	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7505	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7506	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7507	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7508	HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7509	HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7510	{
7511		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7512		/* .name = "Capture Source", */
7513		.name = "Input Source",
7514		.count = 1,
7515		.info = alc883_mux_enum_info,
7516		.get = alc883_mux_enum_get,
7517		.put = alc883_mux_enum_put,
7518	},
7519	{ } /* end */
7520};
7521
7522static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7523	{
7524		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7525		.name = "Channel Mode",
7526		.info = alc_ch_mode_info,
7527		.get = alc_ch_mode_get,
7528		.put = alc_ch_mode_put,
7529	},
7530	{ } /* end */
7531};
7532
7533static struct hda_verb alc883_init_verbs[] = {
7534	/* ADC1: mute amp left and right */
7535	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7536	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7537	/* ADC2: mute amp left and right */
7538	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7539	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7540	/* Front mixer: unmute input/output amp left and right (volume = 0) */
7541	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7542	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7543	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7544	/* Rear mixer */
7545	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7546	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7547	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7548	/* CLFE mixer */
7549	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7550	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7551	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7552	/* Side mixer */
7553	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7554	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7555	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7556
7557	/* mute analog input loopbacks */
7558	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7559	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7560	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7561	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7562	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7563
7564	/* Front Pin: output 0 (0x0c) */
7565	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7566	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7567	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7568	/* Rear Pin: output 1 (0x0d) */
7569	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7570	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7571	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7572	/* CLFE Pin: output 2 (0x0e) */
7573	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7574	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7575	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7576	/* Side Pin: output 3 (0x0f) */
7577	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7578	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7579	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7580	/* Mic (rear) pin: input vref at 80% */
7581	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7582	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7583	/* Front Mic pin: input vref at 80% */
7584	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7585	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7586	/* Line In pin: input */
7587	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7588	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7589	/* Line-2 In: Headphone output (output 0 - 0x0c) */
7590	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7591	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7592	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7593	/* CD pin widget for input */
7594	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7595
7596	/* FIXME: use matrix-type input source selection */
7597	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7598	/* Input mixer2 */
7599	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7600	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7601	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7602	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7603	/* Input mixer3 */
7604	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7605	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7606	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7607	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7608	{ }
7609};
7610
7611/* toggle speaker-output according to the hp-jack state */
7612static void alc883_mitac_hp_automute(struct hda_codec *codec)
7613{
7614	unsigned int present;
7615
7616	present = snd_hda_codec_read(codec, 0x15, 0,
7617				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7618	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7619				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7620	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7621				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7622}
7623
7624/* auto-toggle front mic */
7625/*
7626static void alc883_mitac_mic_automute(struct hda_codec *codec)
7627{
7628	unsigned int present;
7629	unsigned char bits;
7630
7631	present = snd_hda_codec_read(codec, 0x18, 0,
7632				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7633	bits = present ? HDA_AMP_MUTE : 0;
7634	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7635}
7636*/
7637
7638static void alc883_mitac_automute(struct hda_codec *codec)
7639{
7640	alc883_mitac_hp_automute(codec);
7641	/* alc883_mitac_mic_automute(codec); */
7642}
7643
7644static void alc883_mitac_unsol_event(struct hda_codec *codec,
7645					   unsigned int res)
7646{
7647	switch (res >> 26) {
7648	case ALC880_HP_EVENT:
7649		alc883_mitac_hp_automute(codec);
7650		break;
7651	case ALC880_MIC_EVENT:
7652		/* alc883_mitac_mic_automute(codec); */
7653		break;
7654	}
7655}
7656
7657static struct hda_verb alc883_mitac_verbs[] = {
7658	/* HP */
7659	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7660	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7661	/* Subwoofer */
7662	{0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7663	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7664
7665	/* enable unsolicited event */
7666	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7667	/* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7668
7669	{ } /* end */
7670};
7671
7672static struct hda_verb alc883_clevo_m720_verbs[] = {
7673	/* HP */
7674	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7675	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7676	/* Int speaker */
7677	{0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
7678	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7679
7680	/* enable unsolicited event */
7681	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7682	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
7683
7684	{ } /* end */
7685};
7686
7687static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
7688	/* HP */
7689	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7690	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7691	/* Subwoofer */
7692	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7693	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7694
7695	/* enable unsolicited event */
7696	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7697
7698	{ } /* end */
7699};
7700
7701static struct hda_verb alc883_tagra_verbs[] = {
7702	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7703	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7704
7705	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7706	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7707
7708	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7709	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7710	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7711
7712	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7713	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7714	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7715	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
7716
7717	{ } /* end */
7718};
7719
7720static struct hda_verb alc883_lenovo_101e_verbs[] = {
7721	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7722	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7723        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7724	{ } /* end */
7725};
7726
7727static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7728        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7729	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7730        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7731        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7732	{ } /* end */
7733};
7734
7735static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7736	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7737	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7738	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7739	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7740	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
7741	{ } /* end */
7742};
7743
7744static struct hda_verb alc883_haier_w66_verbs[] = {
7745	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7746	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7747
7748	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7749
7750	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7751	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7752	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7753	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7754	{ } /* end */
7755};
7756
7757static struct hda_verb alc888_lenovo_sky_verbs[] = {
7758	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7759	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7760	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7761	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7762	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7763	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7764	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7765	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7766	{ } /* end */
7767};
7768
7769static struct hda_verb alc888_3st_hp_verbs[] = {
7770	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Front: output 0 (0x0c) */
7771	{0x16, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Rear : output 1 (0x0d) */
7772	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02},	/* CLFE : output 2 (0x0e) */
7773	{ }
7774};
7775
7776static struct hda_verb alc888_6st_dell_verbs[] = {
7777	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7778	{ }
7779};
7780
7781static struct hda_verb alc888_3st_hp_2ch_init[] = {
7782	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7783	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7784	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7785	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7786	{ }
7787};
7788
7789static struct hda_verb alc888_3st_hp_6ch_init[] = {
7790	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7791	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7792	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7793	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7794	{ }
7795};
7796
7797static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7798	{ 2, alc888_3st_hp_2ch_init },
7799	{ 6, alc888_3st_hp_6ch_init },
7800};
7801
7802/* toggle front-jack and RCA according to the hp-jack state */
7803static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7804{
7805 	unsigned int present;
7806
7807 	present = snd_hda_codec_read(codec, 0x1b, 0,
7808				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7809	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7810				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7811	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7812				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7813}
7814
7815/* toggle RCA according to the front-jack state */
7816static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7817{
7818 	unsigned int present;
7819
7820 	present = snd_hda_codec_read(codec, 0x14, 0,
7821				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7822	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7823				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7824}
7825
7826static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7827					     unsigned int res)
7828{
7829	if ((res >> 26) == ALC880_HP_EVENT)
7830		alc888_lenovo_ms7195_front_automute(codec);
7831	if ((res >> 26) == ALC880_FRONT_EVENT)
7832		alc888_lenovo_ms7195_rca_automute(codec);
7833}
7834
7835static struct hda_verb alc883_medion_md2_verbs[] = {
7836	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7837	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7838
7839	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7840
7841	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7842	{ } /* end */
7843};
7844
7845/* toggle speaker-output according to the hp-jack state */
7846static void alc883_medion_md2_automute(struct hda_codec *codec)
7847{
7848 	unsigned int present;
7849
7850 	present = snd_hda_codec_read(codec, 0x14, 0,
7851				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7852	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7853				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7854}
7855
7856static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7857					  unsigned int res)
7858{
7859	if ((res >> 26) == ALC880_HP_EVENT)
7860		alc883_medion_md2_automute(codec);
7861}
7862
7863/* toggle speaker-output according to the hp-jack state */
7864static void alc883_tagra_automute(struct hda_codec *codec)
7865{
7866 	unsigned int present;
7867	unsigned char bits;
7868
7869 	present = snd_hda_codec_read(codec, 0x14, 0,
7870				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7871	bits = present ? HDA_AMP_MUTE : 0;
7872	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7873				 HDA_AMP_MUTE, bits);
7874	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7875				  present ? 1 : 3);
7876}
7877
7878static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7879{
7880	if ((res >> 26) == ALC880_HP_EVENT)
7881		alc883_tagra_automute(codec);
7882}
7883
7884/* toggle speaker-output according to the hp-jack state */
7885static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
7886{
7887	unsigned int present;
7888	unsigned char bits;
7889
7890	present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
7891		& AC_PINSENSE_PRESENCE;
7892	bits = present ? HDA_AMP_MUTE : 0;
7893	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7894				 HDA_AMP_MUTE, bits);
7895}
7896
7897static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
7898{
7899	unsigned int present;
7900
7901	present = snd_hda_codec_read(codec, 0x18, 0,
7902				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7903	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
7904				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7905}
7906
7907static void alc883_clevo_m720_automute(struct hda_codec *codec)
7908{
7909	alc883_clevo_m720_hp_automute(codec);
7910	alc883_clevo_m720_mic_automute(codec);
7911}
7912
7913static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
7914					   unsigned int res)
7915{
7916	switch (res >> 26) {
7917	case ALC880_HP_EVENT:
7918		alc883_clevo_m720_hp_automute(codec);
7919		break;
7920	case ALC880_MIC_EVENT:
7921		alc883_clevo_m720_mic_automute(codec);
7922		break;
7923	}
7924}
7925
7926/* toggle speaker-output according to the hp-jack state */
7927static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
7928{
7929 	unsigned int present;
7930	unsigned char bits;
7931
7932 	present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
7933		& AC_PINSENSE_PRESENCE;
7934	bits = present ? HDA_AMP_MUTE : 0;
7935	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7936				 HDA_AMP_MUTE, bits);
7937}
7938
7939static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
7940						  unsigned int res)
7941{
7942	if ((res >> 26) == ALC880_HP_EVENT)
7943		alc883_2ch_fujitsu_pi2515_automute(codec);
7944}
7945
7946static void alc883_haier_w66_automute(struct hda_codec *codec)
7947{
7948	unsigned int present;
7949	unsigned char bits;
7950
7951	present = snd_hda_codec_read(codec, 0x1b, 0,
7952				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7953	bits = present ? 0x80 : 0;
7954	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7955				 0x80, bits);
7956}
7957
7958static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7959					 unsigned int res)
7960{
7961	if ((res >> 26) == ALC880_HP_EVENT)
7962		alc883_haier_w66_automute(codec);
7963}
7964
7965static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7966{
7967 	unsigned int present;
7968	unsigned char bits;
7969
7970 	present = snd_hda_codec_read(codec, 0x14, 0,
7971				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7972	bits = present ? HDA_AMP_MUTE : 0;
7973	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7974				 HDA_AMP_MUTE, bits);
7975}
7976
7977static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7978{
7979 	unsigned int present;
7980	unsigned char bits;
7981
7982 	present = snd_hda_codec_read(codec, 0x1b, 0,
7983				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7984	bits = present ? HDA_AMP_MUTE : 0;
7985	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7986				 HDA_AMP_MUTE, bits);
7987	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7988				 HDA_AMP_MUTE, bits);
7989}
7990
7991static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7992					   unsigned int res)
7993{
7994	if ((res >> 26) == ALC880_HP_EVENT)
7995		alc883_lenovo_101e_all_automute(codec);
7996	if ((res >> 26) == ALC880_FRONT_EVENT)
7997		alc883_lenovo_101e_ispeaker_automute(codec);
7998}
7999
8000/* toggle speaker-output according to the hp-jack state */
8001static void alc883_acer_aspire_automute(struct hda_codec *codec)
8002{
8003 	unsigned int present;
8004
8005 	present = snd_hda_codec_read(codec, 0x14, 0,
8006				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8007	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8008				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8009	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8010				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8011}
8012
8013static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
8014					   unsigned int res)
8015{
8016	if ((res >> 26) == ALC880_HP_EVENT)
8017		alc883_acer_aspire_automute(codec);
8018}
8019
8020static struct hda_verb alc883_acer_eapd_verbs[] = {
8021	/* HP Pin: output 0 (0x0c) */
8022	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8023	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8024	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8025	/* Front Pin: output 0 (0x0c) */
8026	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8027	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8028	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8029	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8030        /* eanable EAPD on medion laptop */
8031	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8032	{0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8033	/* enable unsolicited event */
8034	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8035	{ }
8036};
8037
8038static void alc888_6st_dell_front_automute(struct hda_codec *codec)
8039{
8040 	unsigned int present;
8041
8042 	present = snd_hda_codec_read(codec, 0x1b, 0,
8043				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8044	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8045				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8046	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8047				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8048	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8049				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8050	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8051				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8052}
8053
8054static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
8055					     unsigned int res)
8056{
8057	switch (res >> 26) {
8058	case ALC880_HP_EVENT:
8059		printk("hp_event\n");
8060		alc888_6st_dell_front_automute(codec);
8061		break;
8062	}
8063}
8064
8065static void alc888_lenovo_sky_front_automute(struct hda_codec *codec)
8066{
8067	unsigned int mute;
8068	unsigned int present;
8069
8070	snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8071	present = snd_hda_codec_read(codec, 0x1b, 0,
8072				     AC_VERB_GET_PIN_SENSE, 0);
8073	present = (present & 0x80000000) != 0;
8074	if (present) {
8075		/* mute internal speaker */
8076		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8077					 HDA_AMP_MUTE, HDA_AMP_MUTE);
8078		snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8079					 HDA_AMP_MUTE, HDA_AMP_MUTE);
8080		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8081					 HDA_AMP_MUTE, HDA_AMP_MUTE);
8082		snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8083					 HDA_AMP_MUTE, HDA_AMP_MUTE);
8084		snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8085					 HDA_AMP_MUTE, HDA_AMP_MUTE);
8086	} else {
8087		/* unmute internal speaker if necessary */
8088		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8089		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8090					 HDA_AMP_MUTE, mute);
8091		snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8092					 HDA_AMP_MUTE, mute);
8093		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8094					 HDA_AMP_MUTE, mute);
8095		snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8096					 HDA_AMP_MUTE, mute);
8097		snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8098					 HDA_AMP_MUTE, mute);
8099	}
8100}
8101
8102static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec,
8103					     unsigned int res)
8104{
8105	if ((res >> 26) == ALC880_HP_EVENT)
8106		alc888_lenovo_sky_front_automute(codec);
8107}
8108
8109/*
8110 * generic initialization of ADC, input mixers and output mixers
8111 */
8112static struct hda_verb alc883_auto_init_verbs[] = {
8113	/*
8114	 * Unmute ADC0-2 and set the default input to mic-in
8115	 */
8116	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8117	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8118	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8119	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8120
8121	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8122	 * mixer widget
8123	 * Note: PASD motherboards uses the Line In 2 as the input for
8124	 * front panel mic (mic 2)
8125	 */
8126	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8127	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8128	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8129	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8130	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8131	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8132
8133	/*
8134	 * Set up output mixers (0x0c - 0x0f)
8135	 */
8136	/* set vol=0 to output mixers */
8137	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8138	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8139	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8140	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8141	/* set up input amps for analog loopback */
8142	/* Amp Indices: DAC = 0, mixer = 1 */
8143	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8144	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8145	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8146	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8147	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8148	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8149	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8150	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8151	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8152	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8153
8154	/* FIXME: use matrix-type input source selection */
8155	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8156	/* Input mixer1 */
8157	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8158	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8159	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8160	/* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8161	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8162	/* Input mixer2 */
8163	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8164	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8165	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8166	/* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8167	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8168
8169	{ }
8170};
8171
8172/* capture mixer elements */
8173static struct snd_kcontrol_new alc883_capture_mixer[] = {
8174	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8175	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8176	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
8177	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
8178	{
8179		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8180		/* The multiple "Capture Source" controls confuse alsamixer
8181		 * So call somewhat different..
8182		 */
8183		/* .name = "Capture Source", */
8184		.name = "Input Source",
8185		.count = 2,
8186		.info = alc882_mux_enum_info,
8187		.get = alc882_mux_enum_get,
8188		.put = alc882_mux_enum_put,
8189	},
8190	{ } /* end */
8191};
8192
8193static struct hda_verb alc888_asus_m90v_verbs[] = {
8194	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8195	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8196	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8197	/* enable unsolicited event */
8198	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8199	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8200	{ } /* end */
8201};
8202
8203static void alc883_nb_mic_automute(struct hda_codec *codec)
8204{
8205	unsigned int present;
8206
8207	present = snd_hda_codec_read(codec, 0x18, 0,
8208				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8209	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8210			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8211	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8212			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8213}
8214
8215static void alc883_M90V_speaker_automute(struct hda_codec *codec)
8216{
8217	unsigned int present;
8218	unsigned char bits;
8219
8220	present = snd_hda_codec_read(codec, 0x1b, 0,
8221				     AC_VERB_GET_PIN_SENSE, 0)
8222		& AC_PINSENSE_PRESENCE;
8223	bits = present ? 0 : PIN_OUT;
8224	snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8225			    bits);
8226	snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8227			    bits);
8228	snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8229			    bits);
8230}
8231
8232static void alc883_mode2_unsol_event(struct hda_codec *codec,
8233					   unsigned int res)
8234{
8235	switch (res >> 26) {
8236	case ALC880_HP_EVENT:
8237		alc883_M90V_speaker_automute(codec);
8238		break;
8239	case ALC880_MIC_EVENT:
8240		alc883_nb_mic_automute(codec);
8241		break;
8242	}
8243}
8244
8245static void alc883_mode2_inithook(struct hda_codec *codec)
8246{
8247	alc883_M90V_speaker_automute(codec);
8248	alc883_nb_mic_automute(codec);
8249}
8250
8251static struct hda_verb alc888_asus_eee1601_verbs[] = {
8252	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8253	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8254	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8255	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8256	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8257	{0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8258	{0x20, AC_VERB_SET_PROC_COEF,  0x0838},
8259	/* enable unsolicited event */
8260	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8261	{ } /* end */
8262};
8263
8264static void alc883_eee1601_speaker_automute(struct hda_codec *codec)
8265{
8266	unsigned int present;
8267	unsigned char bits;
8268
8269	present = snd_hda_codec_read(codec, 0x14, 0,
8270				     AC_VERB_GET_PIN_SENSE, 0)
8271		& AC_PINSENSE_PRESENCE;
8272	bits = present ? 0 : PIN_OUT;
8273	snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8274			    bits);
8275}
8276
8277static void alc883_eee1601_unsol_event(struct hda_codec *codec,
8278					   unsigned int res)
8279{
8280	switch (res >> 26) {
8281	case ALC880_HP_EVENT:
8282		alc883_eee1601_speaker_automute(codec);
8283		break;
8284	}
8285}
8286
8287static void alc883_eee1601_inithook(struct hda_codec *codec)
8288{
8289	alc883_eee1601_speaker_automute(codec);
8290}
8291
8292#ifdef CONFIG_SND_HDA_POWER_SAVE
8293#define alc883_loopbacks	alc880_loopbacks
8294#endif
8295
8296/* pcm configuration: identiacal with ALC880 */
8297#define alc883_pcm_analog_playback	alc880_pcm_analog_playback
8298#define alc883_pcm_analog_capture	alc880_pcm_analog_capture
8299#define alc883_pcm_analog_alt_capture	alc880_pcm_analog_alt_capture
8300#define alc883_pcm_digital_playback	alc880_pcm_digital_playback
8301#define alc883_pcm_digital_capture	alc880_pcm_digital_capture
8302
8303/*
8304 * configuration and preset
8305 */
8306static const char *alc883_models[ALC883_MODEL_LAST] = {
8307	[ALC883_3ST_2ch_DIG]	= "3stack-dig",
8308	[ALC883_3ST_6ch_DIG]	= "3stack-6ch-dig",
8309	[ALC883_3ST_6ch]	= "3stack-6ch",
8310	[ALC883_6ST_DIG]	= "6stack-dig",
8311	[ALC883_TARGA_DIG]	= "targa-dig",
8312	[ALC883_TARGA_2ch_DIG]	= "targa-2ch-dig",
8313	[ALC883_ACER]		= "acer",
8314	[ALC883_ACER_ASPIRE]	= "acer-aspire",
8315	[ALC883_MEDION]		= "medion",
8316	[ALC883_MEDION_MD2]	= "medion-md2",
8317	[ALC883_LAPTOP_EAPD]	= "laptop-eapd",
8318	[ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8319	[ALC883_LENOVO_NB0763]	= "lenovo-nb0763",
8320	[ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8321	[ALC888_LENOVO_SKY] = "lenovo-sky",
8322	[ALC883_HAIER_W66] 	= "haier-w66",
8323	[ALC888_3ST_HP]		= "3stack-hp",
8324	[ALC888_6ST_DELL]	= "6stack-dell",
8325	[ALC883_MITAC]		= "mitac",
8326	[ALC883_CLEVO_M720]	= "clevo-m720",
8327	[ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8328	[ALC883_3ST_6ch_INTEL]	= "3stack-6ch-intel",
8329	[ALC883_AUTO]		= "auto",
8330};
8331
8332static struct snd_pci_quirk alc883_cfg_tbl[] = {
8333	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
8334	SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8335	SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8336	SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8337	SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8338	SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
8339	SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8340	SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8341	SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8342	SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8343	SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8344	SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8345	SND_PCI_QUIRK(0x1043, 0x8317, "Asus M90V", ALC888_ASUS_M90V),
8346	SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8347	SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8348	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
8349	SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8350	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8351	SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8352	SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8353	SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
8354	SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8355	SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8356	SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8357	SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8358	SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8359	SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8360	SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8361	SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8362	SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8363	SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8364	SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8365	SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8366	SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8367	SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8368	SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8369	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8370	SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8371	SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8372	SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8373	SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8374	SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8375	SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8376	SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8377	SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8378	SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8379	SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
8380	SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8381	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8382	SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515),
8383	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8384	SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8385	SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8386	SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8387	SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8388	SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8389	SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8390	SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8391	SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8392	SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8393	SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8394	{}
8395};
8396
8397static struct alc_config_preset alc883_presets[] = {
8398	[ALC883_3ST_2ch_DIG] = {
8399		.mixers = { alc883_3ST_2ch_mixer },
8400		.init_verbs = { alc883_init_verbs },
8401		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8402		.dac_nids = alc883_dac_nids,
8403		.dig_out_nid = ALC883_DIGOUT_NID,
8404		.dig_in_nid = ALC883_DIGIN_NID,
8405		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8406		.channel_mode = alc883_3ST_2ch_modes,
8407		.input_mux = &alc883_capture_source,
8408	},
8409	[ALC883_3ST_6ch_DIG] = {
8410		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8411		.init_verbs = { alc883_init_verbs },
8412		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8413		.dac_nids = alc883_dac_nids,
8414		.dig_out_nid = ALC883_DIGOUT_NID,
8415		.dig_in_nid = ALC883_DIGIN_NID,
8416		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8417		.channel_mode = alc883_3ST_6ch_modes,
8418		.need_dac_fix = 1,
8419		.input_mux = &alc883_capture_source,
8420	},
8421	[ALC883_3ST_6ch] = {
8422		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8423		.init_verbs = { alc883_init_verbs },
8424		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8425		.dac_nids = alc883_dac_nids,
8426		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8427		.channel_mode = alc883_3ST_6ch_modes,
8428		.need_dac_fix = 1,
8429		.input_mux = &alc883_capture_source,
8430	},
8431	[ALC883_3ST_6ch_INTEL] = {
8432		.mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8433		.init_verbs = { alc883_init_verbs },
8434		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8435		.dac_nids = alc883_dac_nids,
8436		.dig_out_nid = ALC883_DIGOUT_NID,
8437		.dig_in_nid = ALC883_DIGIN_NID,
8438		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8439		.channel_mode = alc883_3ST_6ch_intel_modes,
8440		.need_dac_fix = 1,
8441		.input_mux = &alc883_3stack_6ch_intel,
8442	},
8443	[ALC883_6ST_DIG] = {
8444		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
8445		.init_verbs = { alc883_init_verbs },
8446		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8447		.dac_nids = alc883_dac_nids,
8448		.dig_out_nid = ALC883_DIGOUT_NID,
8449		.dig_in_nid = ALC883_DIGIN_NID,
8450		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8451		.channel_mode = alc883_sixstack_modes,
8452		.input_mux = &alc883_capture_source,
8453	},
8454	[ALC883_TARGA_DIG] = {
8455		.mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8456		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8457		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8458		.dac_nids = alc883_dac_nids,
8459		.dig_out_nid = ALC883_DIGOUT_NID,
8460		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8461		.channel_mode = alc883_3ST_6ch_modes,
8462		.need_dac_fix = 1,
8463		.input_mux = &alc883_capture_source,
8464		.unsol_event = alc883_tagra_unsol_event,
8465		.init_hook = alc883_tagra_automute,
8466	},
8467	[ALC883_TARGA_2ch_DIG] = {
8468		.mixers = { alc883_tagra_2ch_mixer},
8469		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8470		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8471		.dac_nids = alc883_dac_nids,
8472		.dig_out_nid = ALC883_DIGOUT_NID,
8473		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8474		.channel_mode = alc883_3ST_2ch_modes,
8475		.input_mux = &alc883_capture_source,
8476		.unsol_event = alc883_tagra_unsol_event,
8477		.init_hook = alc883_tagra_automute,
8478	},
8479	[ALC883_ACER] = {
8480		.mixers = { alc883_base_mixer },
8481		/* On TravelMate laptops, GPIO 0 enables the internal speaker
8482		 * and the headphone jack.  Turn this on and rely on the
8483		 * standard mute methods whenever the user wants to turn
8484		 * these outputs off.
8485		 */
8486		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8487		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8488		.dac_nids = alc883_dac_nids,
8489		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8490		.channel_mode = alc883_3ST_2ch_modes,
8491		.input_mux = &alc883_capture_source,
8492	},
8493	[ALC883_ACER_ASPIRE] = {
8494		.mixers = { alc883_acer_aspire_mixer },
8495		.init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
8496		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8497		.dac_nids = alc883_dac_nids,
8498		.dig_out_nid = ALC883_DIGOUT_NID,
8499		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8500		.channel_mode = alc883_3ST_2ch_modes,
8501		.input_mux = &alc883_capture_source,
8502		.unsol_event = alc883_acer_aspire_unsol_event,
8503		.init_hook = alc883_acer_aspire_automute,
8504	},
8505	[ALC883_MEDION] = {
8506		.mixers = { alc883_fivestack_mixer,
8507			    alc883_chmode_mixer },
8508		.init_verbs = { alc883_init_verbs,
8509				alc883_medion_eapd_verbs },
8510		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8511		.dac_nids = alc883_dac_nids,
8512		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8513		.channel_mode = alc883_sixstack_modes,
8514		.input_mux = &alc883_capture_source,
8515	},
8516	[ALC883_MEDION_MD2] = {
8517		.mixers = { alc883_medion_md2_mixer},
8518		.init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8519		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8520		.dac_nids = alc883_dac_nids,
8521		.dig_out_nid = ALC883_DIGOUT_NID,
8522		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8523		.channel_mode = alc883_3ST_2ch_modes,
8524		.input_mux = &alc883_capture_source,
8525		.unsol_event = alc883_medion_md2_unsol_event,
8526		.init_hook = alc883_medion_md2_automute,
8527	},
8528	[ALC883_LAPTOP_EAPD] = {
8529		.mixers = { alc883_base_mixer },
8530		.init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8531		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8532		.dac_nids = alc883_dac_nids,
8533		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8534		.channel_mode = alc883_3ST_2ch_modes,
8535		.input_mux = &alc883_capture_source,
8536	},
8537	[ALC883_CLEVO_M720] = {
8538		.mixers = { alc883_clevo_m720_mixer },
8539		.init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
8540		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8541		.dac_nids = alc883_dac_nids,
8542		.dig_out_nid = ALC883_DIGOUT_NID,
8543		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8544		.channel_mode = alc883_3ST_2ch_modes,
8545		.input_mux = &alc883_capture_source,
8546		.unsol_event = alc883_clevo_m720_unsol_event,
8547		.init_hook = alc883_clevo_m720_automute,
8548	},
8549	[ALC883_LENOVO_101E_2ch] = {
8550		.mixers = { alc883_lenovo_101e_2ch_mixer},
8551		.init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8552		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8553		.dac_nids = alc883_dac_nids,
8554		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8555		.channel_mode = alc883_3ST_2ch_modes,
8556		.input_mux = &alc883_lenovo_101e_capture_source,
8557		.unsol_event = alc883_lenovo_101e_unsol_event,
8558		.init_hook = alc883_lenovo_101e_all_automute,
8559	},
8560	[ALC883_LENOVO_NB0763] = {
8561		.mixers = { alc883_lenovo_nb0763_mixer },
8562		.init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8563		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8564		.dac_nids = alc883_dac_nids,
8565		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8566		.channel_mode = alc883_3ST_2ch_modes,
8567		.need_dac_fix = 1,
8568		.input_mux = &alc883_lenovo_nb0763_capture_source,
8569		.unsol_event = alc883_medion_md2_unsol_event,
8570		.init_hook = alc883_medion_md2_automute,
8571	},
8572	[ALC888_LENOVO_MS7195_DIG] = {
8573		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8574		.init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8575		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8576		.dac_nids = alc883_dac_nids,
8577		.dig_out_nid = ALC883_DIGOUT_NID,
8578		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8579		.channel_mode = alc883_3ST_6ch_modes,
8580		.need_dac_fix = 1,
8581		.input_mux = &alc883_capture_source,
8582		.unsol_event = alc883_lenovo_ms7195_unsol_event,
8583		.init_hook = alc888_lenovo_ms7195_front_automute,
8584	},
8585	[ALC883_HAIER_W66] = {
8586		.mixers = { alc883_tagra_2ch_mixer},
8587		.init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8588		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8589		.dac_nids = alc883_dac_nids,
8590		.dig_out_nid = ALC883_DIGOUT_NID,
8591		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8592		.channel_mode = alc883_3ST_2ch_modes,
8593		.input_mux = &alc883_capture_source,
8594		.unsol_event = alc883_haier_w66_unsol_event,
8595		.init_hook = alc883_haier_w66_automute,
8596	},
8597	[ALC888_3ST_HP] = {
8598		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8599		.init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8600		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8601		.dac_nids = alc883_dac_nids,
8602		.num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
8603		.channel_mode = alc888_3st_hp_modes,
8604		.need_dac_fix = 1,
8605		.input_mux = &alc883_capture_source,
8606	},
8607	[ALC888_6ST_DELL] = {
8608		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
8609		.init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
8610		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8611		.dac_nids = alc883_dac_nids,
8612		.dig_out_nid = ALC883_DIGOUT_NID,
8613		.dig_in_nid = ALC883_DIGIN_NID,
8614		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8615		.channel_mode = alc883_sixstack_modes,
8616		.input_mux = &alc883_capture_source,
8617		.unsol_event = alc888_6st_dell_unsol_event,
8618		.init_hook = alc888_6st_dell_front_automute,
8619	},
8620	[ALC883_MITAC] = {
8621		.mixers = { alc883_mitac_mixer },
8622		.init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8623		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8624		.dac_nids = alc883_dac_nids,
8625		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8626		.channel_mode = alc883_3ST_2ch_modes,
8627		.input_mux = &alc883_capture_source,
8628		.unsol_event = alc883_mitac_unsol_event,
8629		.init_hook = alc883_mitac_automute,
8630	},
8631	[ALC883_FUJITSU_PI2515] = {
8632		.mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8633		.init_verbs = { alc883_init_verbs,
8634				alc883_2ch_fujitsu_pi2515_verbs},
8635		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8636		.dac_nids = alc883_dac_nids,
8637		.dig_out_nid = ALC883_DIGOUT_NID,
8638		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8639		.channel_mode = alc883_3ST_2ch_modes,
8640		.input_mux = &alc883_fujitsu_pi2515_capture_source,
8641		.unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
8642		.init_hook = alc883_2ch_fujitsu_pi2515_automute,
8643	},
8644	[ALC888_LENOVO_SKY] = {
8645		.mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
8646		.init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
8647		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8648		.dac_nids = alc883_dac_nids,
8649		.dig_out_nid = ALC883_DIGOUT_NID,
8650		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
8651		.adc_nids = alc883_adc_nids,
8652		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8653		.channel_mode = alc883_sixstack_modes,
8654		.need_dac_fix = 1,
8655		.input_mux = &alc883_lenovo_sky_capture_source,
8656		.unsol_event = alc883_lenovo_sky_unsol_event,
8657		.init_hook = alc888_lenovo_sky_front_automute,
8658	},
8659	[ALC888_ASUS_M90V] = {
8660		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8661		.init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
8662		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8663		.dac_nids = alc883_dac_nids,
8664		.dig_out_nid = ALC883_DIGOUT_NID,
8665		.dig_in_nid = ALC883_DIGIN_NID,
8666		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8667		.channel_mode = alc883_3ST_6ch_modes,
8668		.need_dac_fix = 1,
8669		.input_mux = &alc883_fujitsu_pi2515_capture_source,
8670		.unsol_event = alc883_mode2_unsol_event,
8671		.init_hook = alc883_mode2_inithook,
8672	},
8673	[ALC888_ASUS_EEE1601] = {
8674		.mixers = { alc883_asus_eee1601_mixer },
8675		.init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
8676		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8677		.dac_nids = alc883_dac_nids,
8678		.dig_out_nid = ALC883_DIGOUT_NID,
8679		.dig_in_nid = ALC883_DIGIN_NID,
8680		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8681		.channel_mode = alc883_3ST_2ch_modes,
8682		.need_dac_fix = 1,
8683		.input_mux = &alc883_asus_eee1601_capture_source,
8684		.unsol_event = alc883_eee1601_unsol_event,
8685		.init_hook = alc883_eee1601_inithook,
8686	},
8687};
8688
8689
8690/*
8691 * BIOS auto configuration
8692 */
8693static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
8694					      hda_nid_t nid, int pin_type,
8695					      int dac_idx)
8696{
8697	/* set as output */
8698	struct alc_spec *spec = codec->spec;
8699	int idx;
8700
8701	alc_set_pin_output(codec, nid, pin_type);
8702	if (spec->multiout.dac_nids[dac_idx] == 0x25)
8703		idx = 4;
8704	else
8705		idx = spec->multiout.dac_nids[dac_idx] - 2;
8706	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
8707
8708}
8709
8710static void alc883_auto_init_multi_out(struct hda_codec *codec)
8711{
8712	struct alc_spec *spec = codec->spec;
8713	int i;
8714
8715	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
8716	for (i = 0; i <= HDA_SIDE; i++) {
8717		hda_nid_t nid = spec->autocfg.line_out_pins[i];
8718		int pin_type = get_pin_type(spec->autocfg.line_out_type);
8719		if (nid)
8720			alc883_auto_set_output_and_unmute(codec, nid, pin_type,
8721							  i);
8722	}
8723}
8724
8725static void alc883_auto_init_hp_out(struct hda_codec *codec)
8726{
8727	struct alc_spec *spec = codec->spec;
8728	hda_nid_t pin;
8729
8730	pin = spec->autocfg.hp_pins[0];
8731	if (pin) /* connect to front */
8732		/* use dac 0 */
8733		alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
8734	pin = spec->autocfg.speaker_pins[0];
8735	if (pin)
8736		alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
8737}
8738
8739#define alc883_is_input_pin(nid)	alc880_is_input_pin(nid)
8740#define ALC883_PIN_CD_NID		ALC880_PIN_CD_NID
8741
8742static void alc883_auto_init_analog_input(struct hda_codec *codec)
8743{
8744	struct alc_spec *spec = codec->spec;
8745	int i;
8746
8747	for (i = 0; i < AUTO_PIN_LAST; i++) {
8748		hda_nid_t nid = spec->autocfg.input_pins[i];
8749		if (alc883_is_input_pin(nid)) {
8750			snd_hda_codec_write(codec, nid, 0,
8751					    AC_VERB_SET_PIN_WIDGET_CONTROL,
8752					    (i <= AUTO_PIN_FRONT_MIC ?
8753					     PIN_VREF80 : PIN_IN));
8754			if (nid != ALC883_PIN_CD_NID)
8755				snd_hda_codec_write(codec, nid, 0,
8756						    AC_VERB_SET_AMP_GAIN_MUTE,
8757						    AMP_OUT_MUTE);
8758		}
8759	}
8760}
8761
8762#define alc883_auto_init_input_src	alc882_auto_init_input_src
8763
8764/* almost identical with ALC880 parser... */
8765static int alc883_parse_auto_config(struct hda_codec *codec)
8766{
8767	struct alc_spec *spec = codec->spec;
8768	int err = alc880_parse_auto_config(codec);
8769
8770	if (err < 0)
8771		return err;
8772	else if (!err)
8773		return 0; /* no config found */
8774
8775	err = alc_auto_add_mic_boost(codec);
8776	if (err < 0)
8777		return err;
8778
8779	/* hack - override the init verbs */
8780	spec->init_verbs[0] = alc883_auto_init_verbs;
8781	spec->mixers[spec->num_mixers] = alc883_capture_mixer;
8782	spec->num_mixers++;
8783
8784	return 1; /* config found */
8785}
8786
8787/* additional initialization for auto-configuration model */
8788static void alc883_auto_init(struct hda_codec *codec)
8789{
8790	struct alc_spec *spec = codec->spec;
8791	alc883_auto_init_multi_out(codec);
8792	alc883_auto_init_hp_out(codec);
8793	alc883_auto_init_analog_input(codec);
8794	alc883_auto_init_input_src(codec);
8795	if (spec->unsol_event)
8796		alc_inithook(codec);
8797}
8798
8799static int patch_alc883(struct hda_codec *codec)
8800{
8801	struct alc_spec *spec;
8802	int err, board_config;
8803
8804	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8805	if (spec == NULL)
8806		return -ENOMEM;
8807
8808	codec->spec = spec;
8809
8810	alc_fix_pll_init(codec, 0x20, 0x0a, 10);
8811
8812	board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
8813						  alc883_models,
8814						  alc883_cfg_tbl);
8815	if (board_config < 0) {
8816		printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
8817		       "trying auto-probe from BIOS...\n");
8818		board_config = ALC883_AUTO;
8819	}
8820
8821	if (board_config == ALC883_AUTO) {
8822		/* automatic parse from the BIOS config */
8823		err = alc883_parse_auto_config(codec);
8824		if (err < 0) {
8825			alc_free(codec);
8826			return err;
8827		} else if (!err) {
8828			printk(KERN_INFO
8829			       "hda_codec: Cannot set up configuration "
8830			       "from BIOS.  Using base mode...\n");
8831			board_config = ALC883_3ST_2ch_DIG;
8832		}
8833	}
8834
8835	if (board_config != ALC883_AUTO)
8836		setup_preset(spec, &alc883_presets[board_config]);
8837
8838	switch (codec->vendor_id) {
8839	case 0x10ec0888:
8840		spec->stream_name_analog = "ALC888 Analog";
8841		spec->stream_name_digital = "ALC888 Digital";
8842		break;
8843	case 0x10ec0889:
8844		spec->stream_name_analog = "ALC889 Analog";
8845		spec->stream_name_digital = "ALC889 Digital";
8846		break;
8847	default:
8848		spec->stream_name_analog = "ALC883 Analog";
8849		spec->stream_name_digital = "ALC883 Digital";
8850		break;
8851	}
8852
8853	spec->stream_analog_playback = &alc883_pcm_analog_playback;
8854	spec->stream_analog_capture = &alc883_pcm_analog_capture;
8855	spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
8856
8857	spec->stream_digital_playback = &alc883_pcm_digital_playback;
8858	spec->stream_digital_capture = &alc883_pcm_digital_capture;
8859
8860	spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8861	spec->adc_nids = alc883_adc_nids;
8862	spec->capsrc_nids = alc883_capsrc_nids;
8863
8864	spec->vmaster_nid = 0x0c;
8865
8866	codec->patch_ops = alc_patch_ops;
8867	if (board_config == ALC883_AUTO)
8868		spec->init_hook = alc883_auto_init;
8869
8870#ifdef CONFIG_SND_HDA_POWER_SAVE
8871	if (!spec->loopback.amplist)
8872		spec->loopback.amplist = alc883_loopbacks;
8873#endif
8874
8875	return 0;
8876}
8877
8878/*
8879 * ALC262 support
8880 */
8881
8882#define ALC262_DIGOUT_NID	ALC880_DIGOUT_NID
8883#define ALC262_DIGIN_NID	ALC880_DIGIN_NID
8884
8885#define alc262_dac_nids		alc260_dac_nids
8886#define alc262_adc_nids		alc882_adc_nids
8887#define alc262_adc_nids_alt	alc882_adc_nids_alt
8888#define alc262_capsrc_nids	alc882_capsrc_nids
8889#define alc262_capsrc_nids_alt	alc882_capsrc_nids_alt
8890
8891#define alc262_modes		alc260_modes
8892#define alc262_capture_source	alc882_capture_source
8893
8894static hda_nid_t alc262_dmic_adc_nids[1] = {
8895	/* ADC0 */
8896	0x09
8897};
8898
8899static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
8900
8901static struct snd_kcontrol_new alc262_base_mixer[] = {
8902	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8903	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8904	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8905	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8906	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8907	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8908	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8909	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8910	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8911	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8912	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8913	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8914	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8915	   HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8916	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
8917	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8918	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8919	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
8920	{ } /* end */
8921};
8922
8923static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
8924	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8925	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8926	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8927	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8928	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8929	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8930	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8931	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8932	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8933	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8934	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8935	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8936	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8937	   HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8938	/*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
8939	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8940	{ } /* end */
8941};
8942
8943/* update HP, line and mono-out pins according to the master switch */
8944static void alc262_hp_master_update(struct hda_codec *codec)
8945{
8946	struct alc_spec *spec = codec->spec;
8947	int val = spec->master_sw;
8948
8949	/* HP & line-out */
8950	snd_hda_codec_write_cache(codec, 0x1b, 0,
8951				  AC_VERB_SET_PIN_WIDGET_CONTROL,
8952				  val ? PIN_HP : 0);
8953	snd_hda_codec_write_cache(codec, 0x15, 0,
8954				  AC_VERB_SET_PIN_WIDGET_CONTROL,
8955				  val ? PIN_HP : 0);
8956	/* mono (speaker) depending on the HP jack sense */
8957	val = val && !spec->jack_present;
8958	snd_hda_codec_write_cache(codec, 0x16, 0,
8959				  AC_VERB_SET_PIN_WIDGET_CONTROL,
8960				  val ? PIN_OUT : 0);
8961}
8962
8963static void alc262_hp_bpc_automute(struct hda_codec *codec)
8964{
8965	struct alc_spec *spec = codec->spec;
8966	unsigned int presence;
8967	presence = snd_hda_codec_read(codec, 0x1b, 0,
8968				      AC_VERB_GET_PIN_SENSE, 0);
8969	spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8970	alc262_hp_master_update(codec);
8971}
8972
8973static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
8974{
8975	if ((res >> 26) != ALC880_HP_EVENT)
8976		return;
8977	alc262_hp_bpc_automute(codec);
8978}
8979
8980static void alc262_hp_wildwest_automute(struct hda_codec *codec)
8981{
8982	struct alc_spec *spec = codec->spec;
8983	unsigned int presence;
8984	presence = snd_hda_codec_read(codec, 0x15, 0,
8985				      AC_VERB_GET_PIN_SENSE, 0);
8986	spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8987	alc262_hp_master_update(codec);
8988}
8989
8990static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
8991					   unsigned int res)
8992{
8993	if ((res >> 26) != ALC880_HP_EVENT)
8994		return;
8995	alc262_hp_wildwest_automute(codec);
8996}
8997
8998static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
8999				   struct snd_ctl_elem_value *ucontrol)
9000{
9001	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9002	struct alc_spec *spec = codec->spec;
9003	*ucontrol->value.integer.value = spec->master_sw;
9004	return 0;
9005}
9006
9007static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9008				   struct snd_ctl_elem_value *ucontrol)
9009{
9010	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9011	struct alc_spec *spec = codec->spec;
9012	int val = !!*ucontrol->value.integer.value;
9013
9014	if (val == spec->master_sw)
9015		return 0;
9016	spec->master_sw = val;
9017	alc262_hp_master_update(codec);
9018	return 1;
9019}
9020
9021static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
9022	{
9023		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9024		.name = "Master Playback Switch",
9025		.info = snd_ctl_boolean_mono_info,
9026		.get = alc262_hp_master_sw_get,
9027		.put = alc262_hp_master_sw_put,
9028	},
9029	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9030	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9031	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9032	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9033			      HDA_OUTPUT),
9034	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9035			    HDA_OUTPUT),
9036	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9037	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9038	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9039	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9040	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9041	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9042	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9043	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9044	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9045	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9046	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9047	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9048	HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9049	HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9050	{ } /* end */
9051};
9052
9053static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
9054	{
9055		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9056		.name = "Master Playback Switch",
9057		.info = snd_ctl_boolean_mono_info,
9058		.get = alc262_hp_master_sw_get,
9059		.put = alc262_hp_master_sw_put,
9060	},
9061	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9062	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9063	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9064	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9065	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9066			      HDA_OUTPUT),
9067	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9068			    HDA_OUTPUT),
9069	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9070	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
9071	HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
9072	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9073	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9074	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9075	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9076	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9077	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9078	{ } /* end */
9079};
9080
9081static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9082	HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9083	HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9084	HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
9085	{ } /* end */
9086};
9087
9088/* mute/unmute internal speaker according to the hp jack and mute state */
9089static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
9090{
9091	struct alc_spec *spec = codec->spec;
9092
9093	if (force || !spec->sense_updated) {
9094		unsigned int present;
9095		present = snd_hda_codec_read(codec, 0x15, 0,
9096					     AC_VERB_GET_PIN_SENSE, 0);
9097		spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9098		spec->sense_updated = 1;
9099	}
9100	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
9101				 spec->jack_present ? HDA_AMP_MUTE : 0);
9102}
9103
9104static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
9105					unsigned int res)
9106{
9107	if ((res >> 26) != ALC880_HP_EVENT)
9108		return;
9109	alc262_hp_t5735_automute(codec, 1);
9110}
9111
9112static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9113{
9114	alc262_hp_t5735_automute(codec, 1);
9115}
9116
9117static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
9118	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9119	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9120	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9121	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9122	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9123	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9124	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9125	{ } /* end */
9126};
9127
9128static struct hda_verb alc262_hp_t5735_verbs[] = {
9129	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9130	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9131
9132	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9133	{ }
9134};
9135
9136static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
9137	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9138	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9139	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9140	HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
9141	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9142	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9143	{ } /* end */
9144};
9145
9146static struct hda_verb alc262_hp_rp5700_verbs[] = {
9147	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9148	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9149	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9150	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9151	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9152	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9153	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9154	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9155	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9156	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9157	{}
9158};
9159
9160static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9161	.num_items = 1,
9162	.items = {
9163		{ "Line", 0x1 },
9164	},
9165};
9166
9167/* bind hp and internal speaker mute (with plug check) */
9168static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
9169				     struct snd_ctl_elem_value *ucontrol)
9170{
9171	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9172	long *valp = ucontrol->value.integer.value;
9173	int change;
9174
9175	/* change hp mute */
9176	change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
9177					  HDA_AMP_MUTE,
9178					  valp[0] ? 0 : HDA_AMP_MUTE);
9179	change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
9180					   HDA_AMP_MUTE,
9181					   valp[1] ? 0 : HDA_AMP_MUTE);
9182	if (change) {
9183		/* change speaker according to HP jack state */
9184		struct alc_spec *spec = codec->spec;
9185		unsigned int mute;
9186		if (spec->jack_present)
9187			mute = HDA_AMP_MUTE;
9188		else
9189			mute = snd_hda_codec_amp_read(codec, 0x15, 0,
9190						      HDA_OUTPUT, 0);
9191		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9192					 HDA_AMP_MUTE, mute);
9193	}
9194	return change;
9195}
9196
9197static struct snd_kcontrol_new alc262_sony_mixer[] = {
9198	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9199	{
9200		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9201		.name = "Master Playback Switch",
9202		.info = snd_hda_mixer_amp_switch_info,
9203		.get = snd_hda_mixer_amp_switch_get,
9204		.put = alc262_sony_master_sw_put,
9205		.private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9206	},
9207	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9208	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9209	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9210	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9211	{ } /* end */
9212};
9213
9214static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9215	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9216	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9217	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9218	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9219	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9220	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9221	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9222	{ } /* end */
9223};
9224
9225#define alc262_capture_mixer		alc882_capture_mixer
9226#define alc262_capture_alt_mixer	alc882_capture_alt_mixer
9227
9228/*
9229 * generic initialization of ADC, input mixers and output mixers
9230 */
9231static struct hda_verb alc262_init_verbs[] = {
9232	/*
9233	 * Unmute ADC0-2 and set the default input to mic-in
9234	 */
9235	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9236	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9237	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9238	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9239	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9240	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9241
9242	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9243	 * mixer widget
9244	 * Note: PASD motherboards uses the Line In 2 as the input for
9245	 * front panel mic (mic 2)
9246	 */
9247	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9248	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9249	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9250	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9251	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9252	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9253
9254	/*
9255	 * Set up output mixers (0x0c - 0x0e)
9256	 */
9257	/* set vol=0 to output mixers */
9258	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9259	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9260	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9261	/* set up input amps for analog loopback */
9262	/* Amp Indices: DAC = 0, mixer = 1 */
9263	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9264	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9265	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9266	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9267	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9268	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9269
9270	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9271	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9272	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9273	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9274	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9275	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9276
9277	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9278	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9279	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9280	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9281	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9282
9283	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9284	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9285
9286	/* FIXME: use matrix-type input source selection */
9287	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9288	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9289	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9290	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9291	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9292	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9293	/* Input mixer2 */
9294	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9295	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9296	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9297	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9298	/* Input mixer3 */
9299	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9300	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9301	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9302	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9303
9304	{ }
9305};
9306
9307static struct hda_verb alc262_eapd_verbs[] = {
9308	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9309	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9310	{ }
9311};
9312
9313static struct hda_verb alc262_hippo_unsol_verbs[] = {
9314	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9315	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9316	{}
9317};
9318
9319static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9320	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9321	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9322	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9323
9324	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9325	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9326	{}
9327};
9328
9329static struct hda_verb alc262_sony_unsol_verbs[] = {
9330	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9331	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9332	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},	// Front Mic
9333
9334	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9335	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9336	{}
9337};
9338
9339static struct hda_input_mux alc262_dmic_capture_source = {
9340	.num_items = 2,
9341	.items = {
9342		{ "Int DMic", 0x9 },
9343		{ "Mic", 0x0 },
9344	},
9345};
9346
9347static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9348	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9349	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9350	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9351	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9352	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9353	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9354	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9355	{
9356		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9357		/* The multiple "Capture Source" controls confuse alsamixer
9358		 * So call somewhat different..
9359		 */
9360		/* .name = "Capture Source", */
9361		.name = "Input Source",
9362		.count = 1,
9363		.info = alc_mux_enum_info,
9364		.get = alc_mux_enum_get,
9365		.put = alc_mux_enum_put,
9366	},
9367	{ } /* end */
9368};
9369
9370static struct hda_verb alc262_toshiba_s06_verbs[] = {
9371	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9372	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9373	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9374	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9375	{0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9376	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9377	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9378	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9379	{}
9380};
9381
9382static void alc262_dmic_automute(struct hda_codec *codec)
9383{
9384	unsigned int present;
9385
9386	present = snd_hda_codec_read(codec, 0x18, 0,
9387					AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9388	snd_hda_codec_write(codec, 0x22, 0,
9389				AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9390}
9391
9392/* toggle speaker-output according to the hp-jack state */
9393static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
9394{
9395	unsigned int present;
9396	unsigned char bits;
9397
9398	present = snd_hda_codec_read(codec, 0x15, 0,
9399					AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9400	bits = present ? 0 : PIN_OUT;
9401	snd_hda_codec_write(codec, 0x14, 0,
9402					AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
9403}
9404
9405
9406
9407/* unsolicited event for HP jack sensing */
9408static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9409				       unsigned int res)
9410{
9411	if ((res >> 26) == ALC880_HP_EVENT)
9412		alc262_toshiba_s06_speaker_automute(codec);
9413	if ((res >> 26) == ALC880_MIC_EVENT)
9414		alc262_dmic_automute(codec);
9415
9416}
9417
9418static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9419{
9420	alc262_toshiba_s06_speaker_automute(codec);
9421	alc262_dmic_automute(codec);
9422}
9423
9424/* mute/unmute internal speaker according to the hp jack and mute state */
9425static void alc262_hippo_automute(struct hda_codec *codec)
9426{
9427	struct alc_spec *spec = codec->spec;
9428	unsigned int mute;
9429	unsigned int present;
9430
9431	/* need to execute and sync at first */
9432	snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9433	present = snd_hda_codec_read(codec, 0x15, 0,
9434				     AC_VERB_GET_PIN_SENSE, 0);
9435	spec->jack_present = (present & 0x80000000) != 0;
9436	if (spec->jack_present) {
9437		/* mute internal speaker */
9438		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9439					 HDA_AMP_MUTE, HDA_AMP_MUTE);
9440	} else {
9441		/* unmute internal speaker if necessary */
9442		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
9443		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9444					 HDA_AMP_MUTE, mute);
9445	}
9446}
9447
9448/* unsolicited event for HP jack sensing */
9449static void alc262_hippo_unsol_event(struct hda_codec *codec,
9450				       unsigned int res)
9451{
9452	if ((res >> 26) != ALC880_HP_EVENT)
9453		return;
9454	alc262_hippo_automute(codec);
9455}
9456
9457static void alc262_hippo1_automute(struct hda_codec *codec)
9458{
9459	unsigned int mute;
9460	unsigned int present;
9461
9462	snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9463	present = snd_hda_codec_read(codec, 0x1b, 0,
9464				     AC_VERB_GET_PIN_SENSE, 0);
9465	present = (present & 0x80000000) != 0;
9466	if (present) {
9467		/* mute internal speaker */
9468		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9469					 HDA_AMP_MUTE, HDA_AMP_MUTE);
9470	} else {
9471		/* unmute internal speaker if necessary */
9472		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9473		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9474					 HDA_AMP_MUTE, mute);
9475	}
9476}
9477
9478/* unsolicited event for HP jack sensing */
9479static void alc262_hippo1_unsol_event(struct hda_codec *codec,
9480				       unsigned int res)
9481{
9482	if ((res >> 26) != ALC880_HP_EVENT)
9483		return;
9484	alc262_hippo1_automute(codec);
9485}
9486
9487/*
9488 * nec model
9489 *  0x15 = headphone
9490 *  0x16 = internal speaker
9491 *  0x18 = external mic
9492 */
9493
9494static struct snd_kcontrol_new alc262_nec_mixer[] = {
9495	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9496	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
9497
9498	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9499	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9500	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9501
9502	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9503	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9504	{ } /* end */
9505};
9506
9507static struct hda_verb alc262_nec_verbs[] = {
9508	/* Unmute Speaker */
9509	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9510
9511	/* Headphone */
9512	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9513	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9514
9515	/* External mic to headphone */
9516	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9517	/* External mic to speaker */
9518	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9519	{}
9520};
9521
9522/*
9523 * fujitsu model
9524 *  0x14 = headphone/spdif-out, 0x15 = internal speaker,
9525 *  0x1b = port replicator headphone out
9526 */
9527
9528#define ALC_HP_EVENT	0x37
9529
9530static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
9531	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9532	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9533	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9534	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9535	{}
9536};
9537
9538static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
9539	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9540	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9541	{}
9542};
9543
9544static struct hda_input_mux alc262_fujitsu_capture_source = {
9545	.num_items = 3,
9546	.items = {
9547		{ "Mic", 0x0 },
9548		{ "Int Mic", 0x1 },
9549		{ "CD", 0x4 },
9550	},
9551};
9552
9553static struct hda_input_mux alc262_HP_capture_source = {
9554	.num_items = 5,
9555	.items = {
9556		{ "Mic", 0x0 },
9557		{ "Front Mic", 0x1 },
9558		{ "Line", 0x2 },
9559		{ "CD", 0x4 },
9560		{ "AUX IN", 0x6 },
9561	},
9562};
9563
9564static struct hda_input_mux alc262_HP_D7000_capture_source = {
9565	.num_items = 4,
9566	.items = {
9567		{ "Mic", 0x0 },
9568		{ "Front Mic", 0x2 },
9569		{ "Line", 0x1 },
9570		{ "CD", 0x4 },
9571	},
9572};
9573
9574/* mute/unmute internal speaker according to the hp jacks and mute state */
9575static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
9576{
9577	struct alc_spec *spec = codec->spec;
9578	unsigned int mute;
9579
9580	if (force || !spec->sense_updated) {
9581		unsigned int present;
9582		/* need to execute and sync at first */
9583		snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
9584		/* check laptop HP jack */
9585		present = snd_hda_codec_read(codec, 0x14, 0,
9586					     AC_VERB_GET_PIN_SENSE, 0);
9587		/* need to execute and sync at first */
9588		snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9589		/* check docking HP jack */
9590		present |= snd_hda_codec_read(codec, 0x1b, 0,
9591					      AC_VERB_GET_PIN_SENSE, 0);
9592		if (present & AC_PINSENSE_PRESENCE)
9593			spec->jack_present = 1;
9594		else
9595			spec->jack_present = 0;
9596		spec->sense_updated = 1;
9597	}
9598	/* unmute internal speaker only if both HPs are unplugged and
9599	 * master switch is on
9600	 */
9601	if (spec->jack_present)
9602		mute = HDA_AMP_MUTE;
9603	else
9604		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9605	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9606				 HDA_AMP_MUTE, mute);
9607}
9608
9609/* unsolicited event for HP jack sensing */
9610static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
9611				       unsigned int res)
9612{
9613	if ((res >> 26) != ALC_HP_EVENT)
9614		return;
9615	alc262_fujitsu_automute(codec, 1);
9616}
9617
9618static void alc262_fujitsu_init_hook(struct hda_codec *codec)
9619{
9620	alc262_fujitsu_automute(codec, 1);
9621}
9622
9623/* bind volumes of both NID 0x0c and 0x0d */
9624static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
9625	.ops = &snd_hda_bind_vol,
9626	.values = {
9627		HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
9628		HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
9629		0
9630	},
9631};
9632
9633/* mute/unmute internal speaker according to the hp jack and mute state */
9634static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
9635{
9636	struct alc_spec *spec = codec->spec;
9637	unsigned int mute;
9638
9639	if (force || !spec->sense_updated) {
9640		unsigned int present_int_hp;
9641		/* need to execute and sync at first */
9642		snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9643		present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
9644					AC_VERB_GET_PIN_SENSE, 0);
9645		spec->jack_present = (present_int_hp & 0x80000000) != 0;
9646		spec->sense_updated = 1;
9647	}
9648	if (spec->jack_present) {
9649		/* mute internal speaker */
9650		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9651					 HDA_AMP_MUTE, HDA_AMP_MUTE);
9652		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9653					 HDA_AMP_MUTE, HDA_AMP_MUTE);
9654	} else {
9655		/* unmute internal speaker if necessary */
9656		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9657		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9658					 HDA_AMP_MUTE, mute);
9659		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9660					 HDA_AMP_MUTE, mute);
9661	}
9662}
9663
9664/* unsolicited event for HP jack sensing */
9665static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
9666				       unsigned int res)
9667{
9668	if ((res >> 26) != ALC_HP_EVENT)
9669		return;
9670	alc262_lenovo_3000_automute(codec, 1);
9671}
9672
9673/* bind hp and internal speaker mute (with plug check) */
9674static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
9675					 struct snd_ctl_elem_value *ucontrol)
9676{
9677	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9678	long *valp = ucontrol->value.integer.value;
9679	int change;
9680
9681	change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9682						 HDA_AMP_MUTE,
9683						 valp ? 0 : HDA_AMP_MUTE);
9684	change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9685						 HDA_AMP_MUTE,
9686						 valp ? 0 : HDA_AMP_MUTE);
9687
9688	if (change)
9689		alc262_fujitsu_automute(codec, 0);
9690	return change;
9691}
9692
9693static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
9694	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9695	{
9696		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9697		.name = "Master Playback Switch",
9698		.info = snd_hda_mixer_amp_switch_info,
9699		.get = snd_hda_mixer_amp_switch_get,
9700		.put = alc262_fujitsu_master_sw_put,
9701		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9702	},
9703	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9704	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9705	HDA_CODEC_VOLUME("PC Speaker Volume", 0x0b, 0x05, HDA_INPUT),
9706	HDA_CODEC_MUTE("PC Speaker Switch", 0x0b, 0x05, HDA_INPUT),
9707	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9708	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9709	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9710	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9711	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9712	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9713	{ } /* end */
9714};
9715
9716/* bind hp and internal speaker mute (with plug check) */
9717static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
9718					 struct snd_ctl_elem_value *ucontrol)
9719{
9720	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9721	long *valp = ucontrol->value.integer.value;
9722	int change;
9723
9724	change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9725						 HDA_AMP_MUTE,
9726						 valp ? 0 : HDA_AMP_MUTE);
9727
9728	if (change)
9729		alc262_lenovo_3000_automute(codec, 0);
9730	return change;
9731}
9732
9733static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
9734	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9735	{
9736		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9737		.name = "Master Playback Switch",
9738		.info = snd_hda_mixer_amp_switch_info,
9739		.get = snd_hda_mixer_amp_switch_get,
9740		.put = alc262_lenovo_3000_master_sw_put,
9741		.private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
9742	},
9743	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9744	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9745	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9746	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9747	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9748	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9749	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9750	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9751	{ } /* end */
9752};
9753
9754static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
9755	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9756	{
9757		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9758		.name = "Master Playback Switch",
9759		.info = snd_hda_mixer_amp_switch_info,
9760		.get = snd_hda_mixer_amp_switch_get,
9761		.put = alc262_sony_master_sw_put,
9762		.private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9763	},
9764	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9765	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9766	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9767	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9768	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9769	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9770	{ } /* end */
9771};
9772
9773/* additional init verbs for Benq laptops */
9774static struct hda_verb alc262_EAPD_verbs[] = {
9775	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9776	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
9777	{}
9778};
9779
9780static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
9781	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9782	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9783
9784	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9785	{0x20, AC_VERB_SET_PROC_COEF,  0x3050},
9786	{}
9787};
9788
9789/* Samsung Q1 Ultra Vista model setup */
9790static struct snd_kcontrol_new alc262_ultra_mixer[] = {
9791	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9792	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9793	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9794	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9795	HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
9796	HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
9797	{ } /* end */
9798};
9799
9800static struct hda_verb alc262_ultra_verbs[] = {
9801	/* output mixer */
9802	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9803	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9804	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9805	/* speaker */
9806	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9807	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9808	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9809	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9810	/* HP */
9811	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9812	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9813	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9814	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9815	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9816	/* internal mic */
9817	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9818	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9819	/* ADC, choose mic */
9820	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9821	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9822	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9823	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9824	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9825	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9826	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9827	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9828	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
9829	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
9830	{}
9831};
9832
9833/* mute/unmute internal speaker according to the hp jack and mute state */
9834static void alc262_ultra_automute(struct hda_codec *codec)
9835{
9836	struct alc_spec *spec = codec->spec;
9837	unsigned int mute;
9838
9839	mute = 0;
9840	/* auto-mute only when HP is used as HP */
9841	if (!spec->cur_mux[0]) {
9842		unsigned int present;
9843		/* need to execute and sync at first */
9844		snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9845		present = snd_hda_codec_read(codec, 0x15, 0,
9846					     AC_VERB_GET_PIN_SENSE, 0);
9847		spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9848		if (spec->jack_present)
9849			mute = HDA_AMP_MUTE;
9850	}
9851	/* mute/unmute internal speaker */
9852	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9853				 HDA_AMP_MUTE, mute);
9854	/* mute/unmute HP */
9855	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9856				 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
9857}
9858
9859/* unsolicited event for HP jack sensing */
9860static void alc262_ultra_unsol_event(struct hda_codec *codec,
9861				       unsigned int res)
9862{
9863	if ((res >> 26) != ALC880_HP_EVENT)
9864		return;
9865	alc262_ultra_automute(codec);
9866}
9867
9868static struct hda_input_mux alc262_ultra_capture_source = {
9869	.num_items = 2,
9870	.items = {
9871		{ "Mic", 0x1 },
9872		{ "Headphone", 0x7 },
9873	},
9874};
9875
9876static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
9877				     struct snd_ctl_elem_value *ucontrol)
9878{
9879	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9880	struct alc_spec *spec = codec->spec;
9881	int ret;
9882
9883	ret = alc882_mux_enum_put(kcontrol, ucontrol);
9884	if (!ret)
9885		return 0;
9886	/* reprogram the HP pin as mic or HP according to the input source */
9887	snd_hda_codec_write_cache(codec, 0x15, 0,
9888				  AC_VERB_SET_PIN_WIDGET_CONTROL,
9889				  spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
9890	alc262_ultra_automute(codec); /* mute/unmute HP */
9891	return ret;
9892}
9893
9894static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
9895	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
9896	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
9897	{
9898		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9899		.name = "Capture Source",
9900		.info = alc882_mux_enum_info,
9901		.get = alc882_mux_enum_get,
9902		.put = alc262_ultra_mux_enum_put,
9903	},
9904	{ } /* end */
9905};
9906
9907/* add playback controls from the parsed DAC table */
9908static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
9909					     const struct auto_pin_cfg *cfg)
9910{
9911	hda_nid_t nid;
9912	int err;
9913
9914	spec->multiout.num_dacs = 1;	/* only use one dac */
9915	spec->multiout.dac_nids = spec->private_dac_nids;
9916	spec->multiout.dac_nids[0] = 2;
9917
9918	nid = cfg->line_out_pins[0];
9919	if (nid) {
9920		err = add_control(spec, ALC_CTL_WIDGET_VOL,
9921				  "Front Playback Volume",
9922				  HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
9923		if (err < 0)
9924			return err;
9925		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9926				  "Front Playback Switch",
9927				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9928		if (err < 0)
9929			return err;
9930	}
9931
9932	nid = cfg->speaker_pins[0];
9933	if (nid) {
9934		if (nid == 0x16) {
9935			err = add_control(spec, ALC_CTL_WIDGET_VOL,
9936					  "Speaker Playback Volume",
9937					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9938							      HDA_OUTPUT));
9939			if (err < 0)
9940				return err;
9941			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9942					  "Speaker Playback Switch",
9943					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9944							      HDA_OUTPUT));
9945			if (err < 0)
9946				return err;
9947		} else {
9948			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9949					  "Speaker Playback Switch",
9950					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9951							      HDA_OUTPUT));
9952			if (err < 0)
9953				return err;
9954		}
9955	}
9956	nid = cfg->hp_pins[0];
9957	if (nid) {
9958		/* spec->multiout.hp_nid = 2; */
9959		if (nid == 0x16) {
9960			err = add_control(spec, ALC_CTL_WIDGET_VOL,
9961					  "Headphone Playback Volume",
9962					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9963							      HDA_OUTPUT));
9964			if (err < 0)
9965				return err;
9966			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9967					  "Headphone Playback Switch",
9968					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9969							      HDA_OUTPUT));
9970			if (err < 0)
9971				return err;
9972		} else {
9973			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9974					  "Headphone Playback Switch",
9975					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9976							      HDA_OUTPUT));
9977			if (err < 0)
9978				return err;
9979		}
9980	}
9981	return 0;
9982}
9983
9984/* identical with ALC880 */
9985#define alc262_auto_create_analog_input_ctls \
9986	alc880_auto_create_analog_input_ctls
9987
9988/*
9989 * generic initialization of ADC, input mixers and output mixers
9990 */
9991static struct hda_verb alc262_volume_init_verbs[] = {
9992	/*
9993	 * Unmute ADC0-2 and set the default input to mic-in
9994	 */
9995	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9996	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9997	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9998	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9999	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10000	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10001
10002	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10003	 * mixer widget
10004	 * Note: PASD motherboards uses the Line In 2 as the input for
10005	 * front panel mic (mic 2)
10006	 */
10007	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10008	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10009	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10010	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10011	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10012	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10013
10014	/*
10015	 * Set up output mixers (0x0c - 0x0f)
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	/* FIXME: use matrix-type input source selection */
10032	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10033	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10034	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10035	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10036	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10037	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10038	/* Input mixer2 */
10039	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10040	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10041	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10042	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10043	/* Input mixer3 */
10044	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10045	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10046	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10047	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10048
10049	{ }
10050};
10051
10052static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10053	/*
10054	 * Unmute ADC0-2 and set the default input to mic-in
10055	 */
10056	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10057	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10058	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10059	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10060	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10061	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10062
10063	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10064	 * mixer widget
10065	 * Note: PASD motherboards uses the Line In 2 as the input for
10066	 * front panel mic (mic 2)
10067	 */
10068	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10069	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10070	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10071	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10072	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10073	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10074	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10075        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10076
10077	/*
10078	 * Set up output mixers (0x0c - 0x0e)
10079	 */
10080	/* set vol=0 to output mixers */
10081	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10082	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10083	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10084
10085	/* set up input amps for analog loopback */
10086	/* Amp Indices: DAC = 0, mixer = 1 */
10087	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10088	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10089	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10090	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10091	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10092	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10093
10094	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10095	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10096	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10097
10098	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10099	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10100
10101	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10102	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10103
10104	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10105	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10106        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10107	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10108	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10109
10110	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10111	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10112        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10113	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10114	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10115	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10116
10117
10118	/* FIXME: use matrix-type input source selection */
10119	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10120	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10121	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10122	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10123	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10124	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10125	/* Input mixer2 */
10126	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10127	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10128	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10129	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10130	/* Input mixer3 */
10131	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10132	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10133	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10134	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10135
10136	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10137
10138	{ }
10139};
10140
10141static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10142	/*
10143	 * Unmute ADC0-2 and set the default input to mic-in
10144	 */
10145	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10146	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10147	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10148	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10149	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10150	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10151
10152	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10153	 * mixer widget
10154	 * Note: PASD motherboards uses the Line In 2 as the input for front
10155	 * panel mic (mic 2)
10156	 */
10157	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10158	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10159	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10160	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10161	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10162	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10163	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10164	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10165	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10166	/*
10167	 * Set up output mixers (0x0c - 0x0e)
10168	 */
10169	/* set vol=0 to output mixers */
10170	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10171	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10172	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10173
10174	/* set up input amps for analog loopback */
10175	/* Amp Indices: DAC = 0, mixer = 1 */
10176	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10177	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10178	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10179	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10180	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10181	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10182
10183
10184	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },	/* HP */
10185	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Mono */
10186	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* rear MIC */
10187	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* Line in */
10188	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* Front MIC */
10189	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Line out */
10190	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* CD in */
10191
10192	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10193	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10194
10195	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10196	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10197
10198	/* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10199	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10200	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10201	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10202	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10203	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10204
10205	/* FIXME: use matrix-type input source selection */
10206	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10207	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10208	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10209	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10210	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10211	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10212	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10213        /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
10214	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10215	/* Input mixer2 */
10216	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10217	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10218	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10219	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10220	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10221        /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10222	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10223	/* Input mixer3 */
10224	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10225	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10226	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10227	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10228	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10229        /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10230	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10231
10232	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10233
10234	{ }
10235};
10236
10237static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10238
10239	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Front Speaker */
10240	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10241	{0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10242
10243	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* MIC jack */
10244	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* Front MIC */
10245	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10246	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10247
10248	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },	/* HP  jack */
10249	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10250	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10251	{}
10252};
10253
10254
10255#ifdef CONFIG_SND_HDA_POWER_SAVE
10256#define alc262_loopbacks	alc880_loopbacks
10257#endif
10258
10259/* pcm configuration: identiacal with ALC880 */
10260#define alc262_pcm_analog_playback	alc880_pcm_analog_playback
10261#define alc262_pcm_analog_capture	alc880_pcm_analog_capture
10262#define alc262_pcm_digital_playback	alc880_pcm_digital_playback
10263#define alc262_pcm_digital_capture	alc880_pcm_digital_capture
10264
10265/*
10266 * BIOS auto configuration
10267 */
10268static int alc262_parse_auto_config(struct hda_codec *codec)
10269{
10270	struct alc_spec *spec = codec->spec;
10271	int err;
10272	static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10273
10274	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10275					   alc262_ignore);
10276	if (err < 0)
10277		return err;
10278	if (!spec->autocfg.line_outs)
10279		return 0; /* can't find valid BIOS pin config */
10280	err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10281	if (err < 0)
10282		return err;
10283	err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10284	if (err < 0)
10285		return err;
10286
10287	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10288
10289	if (spec->autocfg.dig_out_pin)
10290		spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10291	if (spec->autocfg.dig_in_pin)
10292		spec->dig_in_nid = ALC262_DIGIN_NID;
10293
10294	if (spec->kctl_alloc)
10295		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10296
10297	spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
10298	spec->num_mux_defs = 1;
10299	spec->input_mux = &spec->private_imux;
10300
10301	err = alc_auto_add_mic_boost(codec);
10302	if (err < 0)
10303		return err;
10304
10305	return 1;
10306}
10307
10308#define alc262_auto_init_multi_out	alc882_auto_init_multi_out
10309#define alc262_auto_init_hp_out		alc882_auto_init_hp_out
10310#define alc262_auto_init_analog_input	alc882_auto_init_analog_input
10311#define alc262_auto_init_input_src	alc882_auto_init_input_src
10312
10313
10314/* init callback for auto-configuration model -- overriding the default init */
10315static void alc262_auto_init(struct hda_codec *codec)
10316{
10317	struct alc_spec *spec = codec->spec;
10318	alc262_auto_init_multi_out(codec);
10319	alc262_auto_init_hp_out(codec);
10320	alc262_auto_init_analog_input(codec);
10321	alc262_auto_init_input_src(codec);
10322	if (spec->unsol_event)
10323		alc_inithook(codec);
10324}
10325
10326/*
10327 * configuration and preset
10328 */
10329static const char *alc262_models[ALC262_MODEL_LAST] = {
10330	[ALC262_BASIC]		= "basic",
10331	[ALC262_HIPPO]		= "hippo",
10332	[ALC262_HIPPO_1]	= "hippo_1",
10333	[ALC262_FUJITSU]	= "fujitsu",
10334	[ALC262_HP_BPC]		= "hp-bpc",
10335	[ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
10336	[ALC262_HP_TC_T5735]	= "hp-tc-t5735",
10337	[ALC262_HP_RP5700]	= "hp-rp5700",
10338	[ALC262_BENQ_ED8]	= "benq",
10339	[ALC262_BENQ_T31]	= "benq-t31",
10340	[ALC262_SONY_ASSAMD]	= "sony-assamd",
10341	[ALC262_TOSHIBA_S06]	= "toshiba-s06",
10342	[ALC262_TOSHIBA_RX1]	= "toshiba-rx1",
10343	[ALC262_ULTRA]		= "ultra",
10344	[ALC262_LENOVO_3000]	= "lenovo-3000",
10345	[ALC262_NEC]		= "nec",
10346	[ALC262_AUTO]		= "auto",
10347};
10348
10349static struct snd_pci_quirk alc262_cfg_tbl[] = {
10350	SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10351	SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
10352	SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
10353	SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
10354	SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
10355	SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
10356	SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
10357	SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
10358	SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
10359	SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
10360	SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
10361	SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
10362	SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
10363	SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
10364	SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
10365	SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
10366	SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
10367	SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
10368	SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10369	SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10370	SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
10371	SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10372		      ALC262_HP_TC_T5735),
10373	SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
10374	SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10375	SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
10376	SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10377	SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10378	SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
10379	SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10380		      ALC262_TOSHIBA_RX1),
10381	SND_PCI_QUIRK(0x1179, 0x0268, "Toshiba S06", ALC262_TOSHIBA_S06),
10382	SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
10383	SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
10384	SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
10385	SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA),
10386	SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
10387	SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10388	SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10389	SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
10390	{}
10391};
10392
10393static struct alc_config_preset alc262_presets[] = {
10394	[ALC262_BASIC] = {
10395		.mixers = { alc262_base_mixer },
10396		.init_verbs = { alc262_init_verbs },
10397		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10398		.dac_nids = alc262_dac_nids,
10399		.hp_nid = 0x03,
10400		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10401		.channel_mode = alc262_modes,
10402		.input_mux = &alc262_capture_source,
10403	},
10404	[ALC262_HIPPO] = {
10405		.mixers = { alc262_base_mixer },
10406		.init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10407		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10408		.dac_nids = alc262_dac_nids,
10409		.hp_nid = 0x03,
10410		.dig_out_nid = ALC262_DIGOUT_NID,
10411		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10412		.channel_mode = alc262_modes,
10413		.input_mux = &alc262_capture_source,
10414		.unsol_event = alc262_hippo_unsol_event,
10415		.init_hook = alc262_hippo_automute,
10416	},
10417	[ALC262_HIPPO_1] = {
10418		.mixers = { alc262_hippo1_mixer },
10419		.init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10420		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10421		.dac_nids = alc262_dac_nids,
10422		.hp_nid = 0x02,
10423		.dig_out_nid = ALC262_DIGOUT_NID,
10424		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10425		.channel_mode = alc262_modes,
10426		.input_mux = &alc262_capture_source,
10427		.unsol_event = alc262_hippo1_unsol_event,
10428		.init_hook = alc262_hippo1_automute,
10429	},
10430	[ALC262_FUJITSU] = {
10431		.mixers = { alc262_fujitsu_mixer },
10432		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10433				alc262_fujitsu_unsol_verbs },
10434		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10435		.dac_nids = alc262_dac_nids,
10436		.hp_nid = 0x03,
10437		.dig_out_nid = ALC262_DIGOUT_NID,
10438		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10439		.channel_mode = alc262_modes,
10440		.input_mux = &alc262_fujitsu_capture_source,
10441		.unsol_event = alc262_fujitsu_unsol_event,
10442		.init_hook = alc262_fujitsu_init_hook,
10443	},
10444	[ALC262_HP_BPC] = {
10445		.mixers = { alc262_HP_BPC_mixer },
10446		.init_verbs = { alc262_HP_BPC_init_verbs },
10447		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10448		.dac_nids = alc262_dac_nids,
10449		.hp_nid = 0x03,
10450		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10451		.channel_mode = alc262_modes,
10452		.input_mux = &alc262_HP_capture_source,
10453		.unsol_event = alc262_hp_bpc_unsol_event,
10454		.init_hook = alc262_hp_bpc_automute,
10455	},
10456	[ALC262_HP_BPC_D7000_WF] = {
10457		.mixers = { alc262_HP_BPC_WildWest_mixer },
10458		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10459		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10460		.dac_nids = alc262_dac_nids,
10461		.hp_nid = 0x03,
10462		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10463		.channel_mode = alc262_modes,
10464		.input_mux = &alc262_HP_D7000_capture_source,
10465		.unsol_event = alc262_hp_wildwest_unsol_event,
10466		.init_hook = alc262_hp_wildwest_automute,
10467	},
10468	[ALC262_HP_BPC_D7000_WL] = {
10469		.mixers = { alc262_HP_BPC_WildWest_mixer,
10470			    alc262_HP_BPC_WildWest_option_mixer },
10471		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10472		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10473		.dac_nids = alc262_dac_nids,
10474		.hp_nid = 0x03,
10475		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10476		.channel_mode = alc262_modes,
10477		.input_mux = &alc262_HP_D7000_capture_source,
10478		.unsol_event = alc262_hp_wildwest_unsol_event,
10479		.init_hook = alc262_hp_wildwest_automute,
10480	},
10481	[ALC262_HP_TC_T5735] = {
10482		.mixers = { alc262_hp_t5735_mixer },
10483		.init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
10484		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10485		.dac_nids = alc262_dac_nids,
10486		.hp_nid = 0x03,
10487		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10488		.channel_mode = alc262_modes,
10489		.input_mux = &alc262_capture_source,
10490		.unsol_event = alc262_hp_t5735_unsol_event,
10491		.init_hook = alc262_hp_t5735_init_hook,
10492	},
10493	[ALC262_HP_RP5700] = {
10494		.mixers = { alc262_hp_rp5700_mixer },
10495		.init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
10496		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10497		.dac_nids = alc262_dac_nids,
10498		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10499		.channel_mode = alc262_modes,
10500		.input_mux = &alc262_hp_rp5700_capture_source,
10501        },
10502	[ALC262_BENQ_ED8] = {
10503		.mixers = { alc262_base_mixer },
10504		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
10505		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10506		.dac_nids = alc262_dac_nids,
10507		.hp_nid = 0x03,
10508		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10509		.channel_mode = alc262_modes,
10510		.input_mux = &alc262_capture_source,
10511	},
10512	[ALC262_SONY_ASSAMD] = {
10513		.mixers = { alc262_sony_mixer },
10514		.init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
10515		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10516		.dac_nids = alc262_dac_nids,
10517		.hp_nid = 0x02,
10518		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10519		.channel_mode = alc262_modes,
10520		.input_mux = &alc262_capture_source,
10521		.unsol_event = alc262_hippo_unsol_event,
10522		.init_hook = alc262_hippo_automute,
10523	},
10524	[ALC262_BENQ_T31] = {
10525		.mixers = { alc262_benq_t31_mixer },
10526		.init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
10527		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10528		.dac_nids = alc262_dac_nids,
10529		.hp_nid = 0x03,
10530		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10531		.channel_mode = alc262_modes,
10532		.input_mux = &alc262_capture_source,
10533		.unsol_event = alc262_hippo_unsol_event,
10534		.init_hook = alc262_hippo_automute,
10535	},
10536	[ALC262_ULTRA] = {
10537		.mixers = { alc262_ultra_mixer, alc262_ultra_capture_mixer },
10538		.init_verbs = { alc262_ultra_verbs },
10539		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10540		.dac_nids = alc262_dac_nids,
10541		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10542		.channel_mode = alc262_modes,
10543		.input_mux = &alc262_ultra_capture_source,
10544		.adc_nids = alc262_adc_nids, /* ADC0 */
10545		.capsrc_nids = alc262_capsrc_nids,
10546		.num_adc_nids = 1, /* single ADC */
10547		.unsol_event = alc262_ultra_unsol_event,
10548		.init_hook = alc262_ultra_automute,
10549	},
10550	[ALC262_LENOVO_3000] = {
10551		.mixers = { alc262_lenovo_3000_mixer },
10552		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10553				alc262_lenovo_3000_unsol_verbs },
10554		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10555		.dac_nids = alc262_dac_nids,
10556		.hp_nid = 0x03,
10557		.dig_out_nid = ALC262_DIGOUT_NID,
10558		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10559		.channel_mode = alc262_modes,
10560		.input_mux = &alc262_fujitsu_capture_source,
10561		.unsol_event = alc262_lenovo_3000_unsol_event,
10562	},
10563	[ALC262_NEC] = {
10564		.mixers = { alc262_nec_mixer },
10565		.init_verbs = { alc262_nec_verbs },
10566		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10567		.dac_nids = alc262_dac_nids,
10568		.hp_nid = 0x03,
10569		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10570		.channel_mode = alc262_modes,
10571		.input_mux = &alc262_capture_source,
10572	},
10573	[ALC262_TOSHIBA_S06] = {
10574		.mixers = { alc262_toshiba_s06_mixer },
10575		.init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
10576							alc262_eapd_verbs },
10577		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10578		.capsrc_nids = alc262_dmic_capsrc_nids,
10579		.dac_nids = alc262_dac_nids,
10580		.adc_nids = alc262_dmic_adc_nids, /* ADC0 */
10581		.dig_out_nid = ALC262_DIGOUT_NID,
10582		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10583		.channel_mode = alc262_modes,
10584		.input_mux = &alc262_dmic_capture_source,
10585		.unsol_event = alc262_toshiba_s06_unsol_event,
10586		.init_hook = alc262_toshiba_s06_init_hook,
10587	},
10588	[ALC262_TOSHIBA_RX1] = {
10589		.mixers = { alc262_toshiba_rx1_mixer },
10590		.init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
10591		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10592		.dac_nids = alc262_dac_nids,
10593		.hp_nid = 0x03,
10594		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10595		.channel_mode = alc262_modes,
10596		.input_mux = &alc262_capture_source,
10597		.unsol_event = alc262_hippo_unsol_event,
10598		.init_hook = alc262_hippo_automute,
10599	},
10600};
10601
10602static int patch_alc262(struct hda_codec *codec)
10603{
10604	struct alc_spec *spec;
10605	int board_config;
10606	int err;
10607
10608	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10609	if (spec == NULL)
10610		return -ENOMEM;
10611
10612	codec->spec = spec;
10613#if 0
10614	/* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
10615	 * under-run
10616	 */
10617	{
10618	int tmp;
10619	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10620	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
10621	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10622	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
10623	}
10624#endif
10625
10626	alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10627
10628	board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
10629						  alc262_models,
10630						  alc262_cfg_tbl);
10631
10632	if (board_config < 0) {
10633		printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
10634		       "trying auto-probe from BIOS...\n");
10635		board_config = ALC262_AUTO;
10636	}
10637
10638	if (board_config == ALC262_AUTO) {
10639		/* automatic parse from the BIOS config */
10640		err = alc262_parse_auto_config(codec);
10641		if (err < 0) {
10642			alc_free(codec);
10643			return err;
10644		} else if (!err) {
10645			printk(KERN_INFO
10646			       "hda_codec: Cannot set up configuration "
10647			       "from BIOS.  Using base mode...\n");
10648			board_config = ALC262_BASIC;
10649		}
10650	}
10651
10652	if (board_config != ALC262_AUTO)
10653		setup_preset(spec, &alc262_presets[board_config]);
10654
10655	spec->stream_name_analog = "ALC262 Analog";
10656	spec->stream_analog_playback = &alc262_pcm_analog_playback;
10657	spec->stream_analog_capture = &alc262_pcm_analog_capture;
10658
10659	spec->stream_name_digital = "ALC262 Digital";
10660	spec->stream_digital_playback = &alc262_pcm_digital_playback;
10661	spec->stream_digital_capture = &alc262_pcm_digital_capture;
10662
10663	if (!spec->adc_nids && spec->input_mux) {
10664		/* check whether NID 0x07 is valid */
10665		unsigned int wcap = get_wcaps(codec, 0x07);
10666
10667		/* get type */
10668		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
10669		if (wcap != AC_WID_AUD_IN) {
10670			spec->adc_nids = alc262_adc_nids_alt;
10671			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
10672			spec->capsrc_nids = alc262_capsrc_nids_alt;
10673			spec->mixers[spec->num_mixers] =
10674				alc262_capture_alt_mixer;
10675			spec->num_mixers++;
10676		} else {
10677			spec->adc_nids = alc262_adc_nids;
10678			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
10679			spec->capsrc_nids = alc262_capsrc_nids;
10680			spec->mixers[spec->num_mixers] = alc262_capture_mixer;
10681			spec->num_mixers++;
10682		}
10683	}
10684
10685	spec->vmaster_nid = 0x0c;
10686
10687	codec->patch_ops = alc_patch_ops;
10688	if (board_config == ALC262_AUTO)
10689		spec->init_hook = alc262_auto_init;
10690#ifdef CONFIG_SND_HDA_POWER_SAVE
10691	if (!spec->loopback.amplist)
10692		spec->loopback.amplist = alc262_loopbacks;
10693#endif
10694
10695	return 0;
10696}
10697
10698/*
10699 *  ALC268 channel source setting (2 channel)
10700 */
10701#define ALC268_DIGOUT_NID	ALC880_DIGOUT_NID
10702#define alc268_modes		alc260_modes
10703
10704static hda_nid_t alc268_dac_nids[2] = {
10705	/* front, hp */
10706	0x02, 0x03
10707};
10708
10709static hda_nid_t alc268_adc_nids[2] = {
10710	/* ADC0-1 */
10711	0x08, 0x07
10712};
10713
10714static hda_nid_t alc268_adc_nids_alt[1] = {
10715	/* ADC0 */
10716	0x08
10717};
10718
10719static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
10720
10721static struct snd_kcontrol_new alc268_base_mixer[] = {
10722	/* output mixer control */
10723	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10724	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10725	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10726	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10727	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10728	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10729	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10730	{ }
10731};
10732
10733/* bind Beep switches of both NID 0x0f and 0x10 */
10734static struct hda_bind_ctls alc268_bind_beep_sw = {
10735	.ops = &snd_hda_bind_sw,
10736	.values = {
10737		HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
10738		HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
10739		0
10740	},
10741};
10742
10743static struct snd_kcontrol_new alc268_beep_mixer[] = {
10744	HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
10745	HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
10746	{ }
10747};
10748
10749static struct hda_verb alc268_eapd_verbs[] = {
10750	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10751	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10752	{ }
10753};
10754
10755/* Toshiba specific */
10756#define alc268_toshiba_automute	alc262_hippo_automute
10757
10758static struct hda_verb alc268_toshiba_verbs[] = {
10759	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10760	{ } /* end */
10761};
10762
10763static struct hda_input_mux alc268_acer_lc_capture_source = {
10764	.num_items = 2,
10765	.items = {
10766		{ "i-Mic", 0x6 },
10767		{ "E-Mic", 0x0 },
10768	},
10769};
10770
10771/* Acer specific */
10772/* bind volumes of both NID 0x02 and 0x03 */
10773static struct hda_bind_ctls alc268_acer_bind_master_vol = {
10774	.ops = &snd_hda_bind_vol,
10775	.values = {
10776		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
10777		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
10778		0
10779	},
10780};
10781
10782/* mute/unmute internal speaker according to the hp jack and mute state */
10783static void alc268_acer_automute(struct hda_codec *codec, int force)
10784{
10785	struct alc_spec *spec = codec->spec;
10786	unsigned int mute;
10787
10788	if (force || !spec->sense_updated) {
10789		unsigned int present;
10790		present = snd_hda_codec_read(codec, 0x14, 0,
10791				    	 AC_VERB_GET_PIN_SENSE, 0);
10792		spec->jack_present = (present & 0x80000000) != 0;
10793		spec->sense_updated = 1;
10794	}
10795	if (spec->jack_present)
10796		mute = HDA_AMP_MUTE; /* mute internal speaker */
10797	else /* unmute internal speaker if necessary */
10798		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10799	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10800				 HDA_AMP_MUTE, mute);
10801}
10802
10803
10804/* bind hp and internal speaker mute (with plug check) */
10805static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
10806				     struct snd_ctl_elem_value *ucontrol)
10807{
10808	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10809	long *valp = ucontrol->value.integer.value;
10810	int change;
10811
10812	change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10813					  HDA_AMP_MUTE,
10814					  valp[0] ? 0 : HDA_AMP_MUTE);
10815	change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10816					   HDA_AMP_MUTE,
10817					   valp[1] ? 0 : HDA_AMP_MUTE);
10818	if (change)
10819		alc268_acer_automute(codec, 0);
10820	return change;
10821}
10822
10823static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
10824	/* output mixer control */
10825	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10826	{
10827		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10828		.name = "Master Playback Switch",
10829		.info = snd_hda_mixer_amp_switch_info,
10830		.get = snd_hda_mixer_amp_switch_get,
10831		.put = alc268_acer_master_sw_put,
10832		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10833	},
10834	HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
10835	{ }
10836};
10837
10838static struct snd_kcontrol_new alc268_acer_mixer[] = {
10839	/* output mixer control */
10840	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10841	{
10842		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10843		.name = "Master Playback Switch",
10844		.info = snd_hda_mixer_amp_switch_info,
10845		.get = snd_hda_mixer_amp_switch_get,
10846		.put = alc268_acer_master_sw_put,
10847		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10848	},
10849	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10850	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10851	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10852	{ }
10853};
10854
10855static struct hda_verb alc268_acer_aspire_one_verbs[] = {
10856	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10857	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10858	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10859	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10860	{0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
10861	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
10862	{ }
10863};
10864
10865static struct hda_verb alc268_acer_verbs[] = {
10866	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
10867	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10868	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10869	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10870	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10871	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10872	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10873	{ }
10874};
10875
10876/* unsolicited event for HP jack sensing */
10877static void alc268_toshiba_unsol_event(struct hda_codec *codec,
10878				       unsigned int res)
10879{
10880	if ((res >> 26) != ALC880_HP_EVENT)
10881		return;
10882	alc268_toshiba_automute(codec);
10883}
10884
10885static void alc268_acer_unsol_event(struct hda_codec *codec,
10886				       unsigned int res)
10887{
10888	if ((res >> 26) != ALC880_HP_EVENT)
10889		return;
10890	alc268_acer_automute(codec, 1);
10891}
10892
10893static void alc268_acer_init_hook(struct hda_codec *codec)
10894{
10895	alc268_acer_automute(codec, 1);
10896}
10897
10898/* toggle speaker-output according to the hp-jack state */
10899static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
10900{
10901	unsigned int present;
10902	unsigned char bits;
10903
10904	present = snd_hda_codec_read(codec, 0x15, 0,
10905				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10906	bits = present ? AMP_IN_MUTE(0) : 0;
10907	snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
10908				AMP_IN_MUTE(0), bits);
10909	snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
10910				AMP_IN_MUTE(0), bits);
10911}
10912
10913
10914static void alc268_acer_mic_automute(struct hda_codec *codec)
10915{
10916	unsigned int present;
10917
10918	present = snd_hda_codec_read(codec, 0x18, 0,
10919				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10920	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
10921			    present ? 0x0 : 0x6);
10922}
10923
10924static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
10925				    unsigned int res)
10926{
10927	if ((res >> 26) == ALC880_HP_EVENT)
10928		alc268_aspire_one_speaker_automute(codec);
10929	if ((res >> 26) == ALC880_MIC_EVENT)
10930		alc268_acer_mic_automute(codec);
10931}
10932
10933static void alc268_acer_lc_init_hook(struct hda_codec *codec)
10934{
10935	alc268_aspire_one_speaker_automute(codec);
10936	alc268_acer_mic_automute(codec);
10937}
10938
10939static struct snd_kcontrol_new alc268_dell_mixer[] = {
10940	/* output mixer control */
10941	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10942	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10943	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10944	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10945	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10946	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10947	{ }
10948};
10949
10950static struct hda_verb alc268_dell_verbs[] = {
10951	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10952	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10953	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10954	{ }
10955};
10956
10957/* mute/unmute internal speaker according to the hp jack and mute state */
10958static void alc268_dell_automute(struct hda_codec *codec)
10959{
10960	unsigned int present;
10961	unsigned int mute;
10962
10963	present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
10964	if (present & 0x80000000)
10965		mute = HDA_AMP_MUTE;
10966	else
10967		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
10968	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10969				 HDA_AMP_MUTE, mute);
10970}
10971
10972static void alc268_dell_unsol_event(struct hda_codec *codec,
10973				    unsigned int res)
10974{
10975	if ((res >> 26) != ALC880_HP_EVENT)
10976		return;
10977	alc268_dell_automute(codec);
10978}
10979
10980#define alc268_dell_init_hook	alc268_dell_automute
10981
10982static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
10983	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10984	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10985	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10986	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10987	HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10988	HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
10989	HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
10990	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10991	{ }
10992};
10993
10994static struct hda_verb alc267_quanta_il1_verbs[] = {
10995	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10996	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
10997	{ }
10998};
10999
11000static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
11001{
11002	unsigned int present;
11003
11004	present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
11005		& AC_PINSENSE_PRESENCE;
11006	snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
11007			    present ? 0 : PIN_OUT);
11008}
11009
11010static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11011{
11012	unsigned int present;
11013
11014	present = snd_hda_codec_read(codec, 0x18, 0,
11015				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11016	snd_hda_codec_write(codec, 0x23, 0,
11017			    AC_VERB_SET_CONNECT_SEL,
11018			    present ? 0x00 : 0x01);
11019}
11020
11021static void alc267_quanta_il1_automute(struct hda_codec *codec)
11022{
11023	alc267_quanta_il1_hp_automute(codec);
11024	alc267_quanta_il1_mic_automute(codec);
11025}
11026
11027static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
11028					   unsigned int res)
11029{
11030	switch (res >> 26) {
11031	case ALC880_HP_EVENT:
11032		alc267_quanta_il1_hp_automute(codec);
11033		break;
11034	case ALC880_MIC_EVENT:
11035		alc267_quanta_il1_mic_automute(codec);
11036		break;
11037	}
11038}
11039
11040/*
11041 * generic initialization of ADC, input mixers and output mixers
11042 */
11043static struct hda_verb alc268_base_init_verbs[] = {
11044	/* Unmute DAC0-1 and set vol = 0 */
11045	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11046	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11047	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11048	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11049	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11050	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11051
11052	/*
11053	 * Set up output mixers (0x0c - 0x0e)
11054	 */
11055	/* set vol=0 to output mixers */
11056	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11057	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11058	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11059        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
11060
11061	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11062	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11063
11064	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11065	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11066	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11067	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11068	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11069	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11070	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11071	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11072
11073	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11074	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11075	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11076	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11077	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11078	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11079	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11080
11081	/* set PCBEEP vol = 0, mute connections */
11082	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11083	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11084	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11085
11086	/* Unmute Selector 23h,24h and set the default input to mic-in */
11087
11088	{0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11089	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11090	{0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11091	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11092
11093	{ }
11094};
11095
11096/*
11097 * generic initialization of ADC, input mixers and output mixers
11098 */
11099static struct hda_verb alc268_volume_init_verbs[] = {
11100	/* set output DAC */
11101	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11102	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11103	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11104	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11105
11106	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11107	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11108	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11109	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11110	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11111
11112	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11113	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11114	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11115	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11116	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11117
11118	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11119	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11120	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11121	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11122
11123	/* set PCBEEP vol = 0, mute connections */
11124	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11125	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11126	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11127
11128	{ }
11129};
11130
11131#define alc268_mux_enum_info alc_mux_enum_info
11132#define alc268_mux_enum_get alc_mux_enum_get
11133#define alc268_mux_enum_put alc_mux_enum_put
11134
11135static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11136	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11137	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11138	{
11139		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11140		/* The multiple "Capture Source" controls confuse alsamixer
11141		 * So call somewhat different..
11142		 */
11143		/* .name = "Capture Source", */
11144		.name = "Input Source",
11145		.count = 1,
11146		.info = alc268_mux_enum_info,
11147		.get = alc268_mux_enum_get,
11148		.put = alc268_mux_enum_put,
11149	},
11150	{ } /* end */
11151};
11152
11153static struct snd_kcontrol_new alc268_capture_mixer[] = {
11154	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11155	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11156	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11157	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11158	{
11159		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11160		/* The multiple "Capture Source" controls confuse alsamixer
11161		 * So call somewhat different..
11162		 */
11163		/* .name = "Capture Source", */
11164		.name = "Input Source",
11165		.count = 2,
11166		.info = alc268_mux_enum_info,
11167		.get = alc268_mux_enum_get,
11168		.put = alc268_mux_enum_put,
11169	},
11170	{ } /* end */
11171};
11172
11173static struct hda_input_mux alc268_capture_source = {
11174	.num_items = 4,
11175	.items = {
11176		{ "Mic", 0x0 },
11177		{ "Front Mic", 0x1 },
11178		{ "Line", 0x2 },
11179		{ "CD", 0x3 },
11180	},
11181};
11182
11183static struct hda_input_mux alc268_acer_capture_source = {
11184	.num_items = 3,
11185	.items = {
11186		{ "Mic", 0x0 },
11187		{ "Internal Mic", 0x6 },
11188		{ "Line", 0x2 },
11189	},
11190};
11191
11192#ifdef CONFIG_SND_DEBUG
11193static struct snd_kcontrol_new alc268_test_mixer[] = {
11194	/* Volume widgets */
11195	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11196	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11197	HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11198	HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11199	HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11200	HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11201	HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11202	HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11203	HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11204	HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11205	HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11206	HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11207	HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11208	/* The below appears problematic on some hardwares */
11209	/*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11210	HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11211	HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11212	HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11213	HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11214
11215	/* Modes for retasking pin widgets */
11216	ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11217	ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11218	ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11219	ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11220
11221	/* Controls for GPIO pins, assuming they are configured as outputs */
11222	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11223	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11224	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11225	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11226
11227	/* Switches to allow the digital SPDIF output pin to be enabled.
11228	 * The ALC268 does not have an SPDIF input.
11229	 */
11230	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11231
11232	/* A switch allowing EAPD to be enabled.  Some laptops seem to use
11233	 * this output to turn on an external amplifier.
11234	 */
11235	ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11236	ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11237
11238	{ } /* end */
11239};
11240#endif
11241
11242/* create input playback/capture controls for the given pin */
11243static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11244				    const char *ctlname, int idx)
11245{
11246	char name[32];
11247	int err;
11248
11249	sprintf(name, "%s Playback Volume", ctlname);
11250	if (nid == 0x14) {
11251		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11252				  HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11253						      HDA_OUTPUT));
11254		if (err < 0)
11255			return err;
11256	} else if (nid == 0x15) {
11257		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11258				  HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11259						      HDA_OUTPUT));
11260		if (err < 0)
11261			return err;
11262	} else
11263		return -1;
11264	sprintf(name, "%s Playback Switch", ctlname);
11265	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11266			  HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11267	if (err < 0)
11268		return err;
11269	return 0;
11270}
11271
11272/* add playback controls from the parsed DAC table */
11273static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11274					     const struct auto_pin_cfg *cfg)
11275{
11276	hda_nid_t nid;
11277	int err;
11278
11279	spec->multiout.num_dacs = 2;	/* only use one dac */
11280	spec->multiout.dac_nids = spec->private_dac_nids;
11281	spec->multiout.dac_nids[0] = 2;
11282	spec->multiout.dac_nids[1] = 3;
11283
11284	nid = cfg->line_out_pins[0];
11285	if (nid)
11286		alc268_new_analog_output(spec, nid, "Front", 0);
11287
11288	nid = cfg->speaker_pins[0];
11289	if (nid == 0x1d) {
11290		err = add_control(spec, ALC_CTL_WIDGET_VOL,
11291				  "Speaker Playback Volume",
11292				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11293		if (err < 0)
11294			return err;
11295	}
11296	nid = cfg->hp_pins[0];
11297	if (nid)
11298		alc268_new_analog_output(spec, nid, "Headphone", 0);
11299
11300	nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11301	if (nid == 0x16) {
11302		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11303				  "Mono Playback Switch",
11304				  HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11305		if (err < 0)
11306			return err;
11307	}
11308	return 0;
11309}
11310
11311/* create playback/capture controls for input pins */
11312static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11313						const struct auto_pin_cfg *cfg)
11314{
11315	struct hda_input_mux *imux = &spec->private_imux;
11316	int i, idx1;
11317
11318	for (i = 0; i < AUTO_PIN_LAST; i++) {
11319		switch(cfg->input_pins[i]) {
11320		case 0x18:
11321			idx1 = 0;	/* Mic 1 */
11322			break;
11323		case 0x19:
11324			idx1 = 1;	/* Mic 2 */
11325			break;
11326		case 0x1a:
11327			idx1 = 2;	/* Line In */
11328			break;
11329		case 0x1c:
11330			idx1 = 3;	/* CD */
11331			break;
11332		case 0x12:
11333		case 0x13:
11334			idx1 = 6;	/* digital mics */
11335			break;
11336		default:
11337			continue;
11338		}
11339		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11340		imux->items[imux->num_items].index = idx1;
11341		imux->num_items++;
11342	}
11343	return 0;
11344}
11345
11346static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11347{
11348	struct alc_spec *spec = codec->spec;
11349	hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11350	hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11351	hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11352	unsigned int	dac_vol1, dac_vol2;
11353
11354	if (speaker_nid) {
11355		snd_hda_codec_write(codec, speaker_nid, 0,
11356				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11357		snd_hda_codec_write(codec, 0x0f, 0,
11358				    AC_VERB_SET_AMP_GAIN_MUTE,
11359				    AMP_IN_UNMUTE(1));
11360		snd_hda_codec_write(codec, 0x10, 0,
11361				    AC_VERB_SET_AMP_GAIN_MUTE,
11362				    AMP_IN_UNMUTE(1));
11363	} else {
11364		snd_hda_codec_write(codec, 0x0f, 0,
11365				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11366		snd_hda_codec_write(codec, 0x10, 0,
11367				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11368	}
11369
11370	dac_vol1 = dac_vol2 = 0xb000 | 0x40;	/* set max volume  */
11371	if (line_nid == 0x14)
11372		dac_vol2 = AMP_OUT_ZERO;
11373	else if (line_nid == 0x15)
11374		dac_vol1 = AMP_OUT_ZERO;
11375	if (hp_nid == 0x14)
11376		dac_vol2 = AMP_OUT_ZERO;
11377	else if (hp_nid == 0x15)
11378		dac_vol1 = AMP_OUT_ZERO;
11379	if (line_nid != 0x16 || hp_nid != 0x16 ||
11380	    spec->autocfg.line_out_pins[1] != 0x16 ||
11381	    spec->autocfg.line_out_pins[2] != 0x16)
11382		dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11383
11384	snd_hda_codec_write(codec, 0x02, 0,
11385			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11386	snd_hda_codec_write(codec, 0x03, 0,
11387			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11388}
11389
11390/* pcm configuration: identiacal with ALC880 */
11391#define alc268_pcm_analog_playback	alc880_pcm_analog_playback
11392#define alc268_pcm_analog_capture	alc880_pcm_analog_capture
11393#define alc268_pcm_analog_alt_capture	alc880_pcm_analog_alt_capture
11394#define alc268_pcm_digital_playback	alc880_pcm_digital_playback
11395
11396/*
11397 * BIOS auto configuration
11398 */
11399static int alc268_parse_auto_config(struct hda_codec *codec)
11400{
11401	struct alc_spec *spec = codec->spec;
11402	int err;
11403	static hda_nid_t alc268_ignore[] = { 0 };
11404
11405	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11406					   alc268_ignore);
11407	if (err < 0)
11408		return err;
11409	if (!spec->autocfg.line_outs)
11410		return 0; /* can't find valid BIOS pin config */
11411
11412	err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11413	if (err < 0)
11414		return err;
11415	err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11416	if (err < 0)
11417		return err;
11418
11419	spec->multiout.max_channels = 2;
11420
11421	/* digital only support output */
11422	if (spec->autocfg.dig_out_pin)
11423		spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
11424
11425	if (spec->kctl_alloc)
11426		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11427
11428	if (spec->autocfg.speaker_pins[0] != 0x1d)
11429		spec->mixers[spec->num_mixers++] = alc268_beep_mixer;
11430
11431	spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
11432	spec->num_mux_defs = 1;
11433	spec->input_mux = &spec->private_imux;
11434
11435	err = alc_auto_add_mic_boost(codec);
11436	if (err < 0)
11437		return err;
11438
11439	return 1;
11440}
11441
11442#define alc268_auto_init_multi_out	alc882_auto_init_multi_out
11443#define alc268_auto_init_hp_out		alc882_auto_init_hp_out
11444#define alc268_auto_init_analog_input	alc882_auto_init_analog_input
11445
11446/* init callback for auto-configuration model -- overriding the default init */
11447static void alc268_auto_init(struct hda_codec *codec)
11448{
11449	struct alc_spec *spec = codec->spec;
11450	alc268_auto_init_multi_out(codec);
11451	alc268_auto_init_hp_out(codec);
11452	alc268_auto_init_mono_speaker_out(codec);
11453	alc268_auto_init_analog_input(codec);
11454	if (spec->unsol_event)
11455		alc_inithook(codec);
11456}
11457
11458/*
11459 * configuration and preset
11460 */
11461static const char *alc268_models[ALC268_MODEL_LAST] = {
11462	[ALC267_QUANTA_IL1]	= "quanta-il1",
11463	[ALC268_3ST]		= "3stack",
11464	[ALC268_TOSHIBA]	= "toshiba",
11465	[ALC268_ACER]		= "acer",
11466	[ALC268_ACER_ASPIRE_ONE]	= "acer-aspire",
11467	[ALC268_DELL]		= "dell",
11468	[ALC268_ZEPTO]		= "zepto",
11469#ifdef CONFIG_SND_DEBUG
11470	[ALC268_TEST]		= "test",
11471#endif
11472	[ALC268_AUTO]		= "auto",
11473};
11474
11475static struct snd_pci_quirk alc268_cfg_tbl[] = {
11476	SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
11477	SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
11478	SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
11479	SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
11480	SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
11481	SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
11482						ALC268_ACER_ASPIRE_ONE),
11483	SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
11484	SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
11485	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
11486	SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
11487	SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
11488	SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
11489	SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
11490	SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
11491	SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
11492	SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
11493	{}
11494};
11495
11496static struct alc_config_preset alc268_presets[] = {
11497	[ALC267_QUANTA_IL1] = {
11498		.mixers = { alc267_quanta_il1_mixer },
11499		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11500				alc267_quanta_il1_verbs },
11501		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11502		.dac_nids = alc268_dac_nids,
11503		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11504		.adc_nids = alc268_adc_nids_alt,
11505		.hp_nid = 0x03,
11506		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11507		.channel_mode = alc268_modes,
11508		.input_mux = &alc268_capture_source,
11509		.unsol_event = alc267_quanta_il1_unsol_event,
11510		.init_hook = alc267_quanta_il1_automute,
11511	},
11512	[ALC268_3ST] = {
11513		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11514			    alc268_beep_mixer },
11515		.init_verbs = { alc268_base_init_verbs },
11516		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11517		.dac_nids = alc268_dac_nids,
11518                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11519                .adc_nids = alc268_adc_nids_alt,
11520		.capsrc_nids = alc268_capsrc_nids,
11521		.hp_nid = 0x03,
11522		.dig_out_nid = ALC268_DIGOUT_NID,
11523		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11524		.channel_mode = alc268_modes,
11525		.input_mux = &alc268_capture_source,
11526	},
11527	[ALC268_TOSHIBA] = {
11528		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11529			    alc268_beep_mixer },
11530		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11531				alc268_toshiba_verbs },
11532		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11533		.dac_nids = alc268_dac_nids,
11534		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11535		.adc_nids = alc268_adc_nids_alt,
11536		.capsrc_nids = alc268_capsrc_nids,
11537		.hp_nid = 0x03,
11538		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11539		.channel_mode = alc268_modes,
11540		.input_mux = &alc268_capture_source,
11541		.unsol_event = alc268_toshiba_unsol_event,
11542		.init_hook = alc268_toshiba_automute,
11543	},
11544	[ALC268_ACER] = {
11545		.mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
11546			    alc268_beep_mixer },
11547		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11548				alc268_acer_verbs },
11549		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11550		.dac_nids = alc268_dac_nids,
11551		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11552		.adc_nids = alc268_adc_nids_alt,
11553		.capsrc_nids = alc268_capsrc_nids,
11554		.hp_nid = 0x02,
11555		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11556		.channel_mode = alc268_modes,
11557		.input_mux = &alc268_acer_capture_source,
11558		.unsol_event = alc268_acer_unsol_event,
11559		.init_hook = alc268_acer_init_hook,
11560	},
11561	[ALC268_ACER_ASPIRE_ONE] = {
11562		.mixers = { alc268_acer_aspire_one_mixer,
11563				alc268_capture_alt_mixer },
11564		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11565				alc268_acer_aspire_one_verbs },
11566		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11567		.dac_nids = alc268_dac_nids,
11568		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11569		.adc_nids = alc268_adc_nids_alt,
11570		.capsrc_nids = alc268_capsrc_nids,
11571		.hp_nid = 0x03,
11572		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11573		.channel_mode = alc268_modes,
11574		.input_mux = &alc268_acer_lc_capture_source,
11575		.unsol_event = alc268_acer_lc_unsol_event,
11576		.init_hook = alc268_acer_lc_init_hook,
11577	},
11578	[ALC268_DELL] = {
11579		.mixers = { alc268_dell_mixer, alc268_beep_mixer },
11580		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11581				alc268_dell_verbs },
11582		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11583		.dac_nids = alc268_dac_nids,
11584		.hp_nid = 0x02,
11585		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11586		.channel_mode = alc268_modes,
11587		.unsol_event = alc268_dell_unsol_event,
11588		.init_hook = alc268_dell_init_hook,
11589		.input_mux = &alc268_capture_source,
11590	},
11591	[ALC268_ZEPTO] = {
11592		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11593			    alc268_beep_mixer },
11594		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11595				alc268_toshiba_verbs },
11596		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11597		.dac_nids = alc268_dac_nids,
11598		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11599		.adc_nids = alc268_adc_nids_alt,
11600		.capsrc_nids = alc268_capsrc_nids,
11601		.hp_nid = 0x03,
11602		.dig_out_nid = ALC268_DIGOUT_NID,
11603		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11604		.channel_mode = alc268_modes,
11605		.input_mux = &alc268_capture_source,
11606		.unsol_event = alc268_toshiba_unsol_event,
11607		.init_hook = alc268_toshiba_automute
11608	},
11609#ifdef CONFIG_SND_DEBUG
11610	[ALC268_TEST] = {
11611		.mixers = { alc268_test_mixer, alc268_capture_mixer },
11612		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11613				alc268_volume_init_verbs },
11614		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11615		.dac_nids = alc268_dac_nids,
11616		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11617		.adc_nids = alc268_adc_nids_alt,
11618		.capsrc_nids = alc268_capsrc_nids,
11619		.hp_nid = 0x03,
11620		.dig_out_nid = ALC268_DIGOUT_NID,
11621		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11622		.channel_mode = alc268_modes,
11623		.input_mux = &alc268_capture_source,
11624	},
11625#endif
11626};
11627
11628static int patch_alc268(struct hda_codec *codec)
11629{
11630	struct alc_spec *spec;
11631	int board_config;
11632	int err;
11633
11634	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
11635	if (spec == NULL)
11636		return -ENOMEM;
11637
11638	codec->spec = spec;
11639
11640	board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
11641						  alc268_models,
11642						  alc268_cfg_tbl);
11643
11644	if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
11645		printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
11646		       "trying auto-probe from BIOS...\n");
11647		board_config = ALC268_AUTO;
11648	}
11649
11650	if (board_config == ALC268_AUTO) {
11651		/* automatic parse from the BIOS config */
11652		err = alc268_parse_auto_config(codec);
11653		if (err < 0) {
11654			alc_free(codec);
11655			return err;
11656		} else if (!err) {
11657			printk(KERN_INFO
11658			       "hda_codec: Cannot set up configuration "
11659			       "from BIOS.  Using base mode...\n");
11660			board_config = ALC268_3ST;
11661		}
11662	}
11663
11664	if (board_config != ALC268_AUTO)
11665		setup_preset(spec, &alc268_presets[board_config]);
11666
11667	if (codec->vendor_id == 0x10ec0267) {
11668		spec->stream_name_analog = "ALC267 Analog";
11669		spec->stream_name_digital = "ALC267 Digital";
11670	} else {
11671		spec->stream_name_analog = "ALC268 Analog";
11672		spec->stream_name_digital = "ALC268 Digital";
11673	}
11674
11675	spec->stream_analog_playback = &alc268_pcm_analog_playback;
11676	spec->stream_analog_capture = &alc268_pcm_analog_capture;
11677	spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
11678
11679	spec->stream_digital_playback = &alc268_pcm_digital_playback;
11680
11681	if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
11682		/* override the amp caps for beep generator */
11683		snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
11684					  (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
11685					  (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
11686					  (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
11687					  (0 << AC_AMPCAP_MUTE_SHIFT));
11688
11689	if (!spec->adc_nids && spec->input_mux) {
11690		/* check whether NID 0x07 is valid */
11691		unsigned int wcap = get_wcaps(codec, 0x07);
11692		int i;
11693
11694		/* get type */
11695		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11696		if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
11697			spec->adc_nids = alc268_adc_nids_alt;
11698			spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
11699			spec->mixers[spec->num_mixers] =
11700					alc268_capture_alt_mixer;
11701			spec->num_mixers++;
11702		} else {
11703			spec->adc_nids = alc268_adc_nids;
11704			spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
11705			spec->mixers[spec->num_mixers] =
11706				alc268_capture_mixer;
11707			spec->num_mixers++;
11708		}
11709		spec->capsrc_nids = alc268_capsrc_nids;
11710		/* set default input source */
11711		for (i = 0; i < spec->num_adc_nids; i++)
11712			snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
11713				0, AC_VERB_SET_CONNECT_SEL,
11714				spec->input_mux->items[0].index);
11715	}
11716
11717	spec->vmaster_nid = 0x02;
11718
11719	codec->patch_ops = alc_patch_ops;
11720	if (board_config == ALC268_AUTO)
11721		spec->init_hook = alc268_auto_init;
11722
11723	return 0;
11724}
11725
11726/*
11727 *  ALC269 channel source setting (2 channel)
11728 */
11729#define ALC269_DIGOUT_NID	ALC880_DIGOUT_NID
11730
11731#define alc269_dac_nids		alc260_dac_nids
11732
11733static hda_nid_t alc269_adc_nids[1] = {
11734	/* ADC1 */
11735	0x08,
11736};
11737
11738static hda_nid_t alc269_capsrc_nids[1] = {
11739	0x23,
11740};
11741
11742/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
11743 *       not a mux!
11744 */
11745
11746static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
11747	.num_items = 2,
11748	.items = {
11749		{ "i-Mic", 0x5 },
11750		{ "e-Mic", 0x0 },
11751	},
11752};
11753
11754static struct hda_input_mux alc269_eeepc_amic_capture_source = {
11755	.num_items = 2,
11756	.items = {
11757		{ "i-Mic", 0x1 },
11758		{ "e-Mic", 0x0 },
11759	},
11760};
11761
11762#define alc269_modes		alc260_modes
11763#define alc269_capture_source	alc880_lg_lw_capture_source
11764
11765static struct snd_kcontrol_new alc269_base_mixer[] = {
11766	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11767	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11768	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11769	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11770	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11771	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11772	HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11773	HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11774	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11775	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11776	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11777	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11778	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11779	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11780	{ } /* end */
11781};
11782
11783static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
11784	/* output mixer control */
11785	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11786	{
11787		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11788		.name = "Master Playback Switch",
11789		.info = snd_hda_mixer_amp_switch_info,
11790		.get = snd_hda_mixer_amp_switch_get,
11791		.put = alc268_acer_master_sw_put,
11792		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11793	},
11794	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11795	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11796	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11797	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11798	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11799	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11800	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
11801	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
11802	{ }
11803};
11804
11805/* bind volumes of both NID 0x0c and 0x0d */
11806static struct hda_bind_ctls alc269_epc_bind_vol = {
11807	.ops = &snd_hda_bind_vol,
11808	.values = {
11809		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11810		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11811		0
11812	},
11813};
11814
11815static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
11816	HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11817	HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
11818	HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11819	{ } /* end */
11820};
11821
11822/* capture mixer elements */
11823static struct snd_kcontrol_new alc269_capture_mixer[] = {
11824	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11825	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11826	{
11827		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11828		/* The multiple "Capture Source" controls confuse alsamixer
11829		 * So call somewhat different..
11830		 */
11831		/* .name = "Capture Source", */
11832		.name = "Input Source",
11833		.count = 1,
11834		.info = alc_mux_enum_info,
11835		.get = alc_mux_enum_get,
11836		.put = alc_mux_enum_put,
11837	},
11838	{ } /* end */
11839};
11840
11841/* capture mixer elements */
11842static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
11843	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11844	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11845	{ } /* end */
11846};
11847
11848/* beep control */
11849static struct snd_kcontrol_new alc269_beep_mixer[] = {
11850	HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11851	HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11852	{ } /* end */
11853};
11854
11855static struct hda_verb alc269_quanta_fl1_verbs[] = {
11856	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11857	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11858	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11859	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11860	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11861	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11862	{ }
11863};
11864
11865/* toggle speaker-output according to the hp-jack state */
11866static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
11867{
11868	unsigned int present;
11869	unsigned char bits;
11870
11871	present = snd_hda_codec_read(codec, 0x15, 0,
11872			AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11873	bits = present ? AMP_IN_MUTE(0) : 0;
11874	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11875			AMP_IN_MUTE(0), bits);
11876	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11877			AMP_IN_MUTE(0), bits);
11878
11879	snd_hda_codec_write(codec, 0x20, 0,
11880			AC_VERB_SET_COEF_INDEX, 0x0c);
11881	snd_hda_codec_write(codec, 0x20, 0,
11882			AC_VERB_SET_PROC_COEF, 0x680);
11883
11884	snd_hda_codec_write(codec, 0x20, 0,
11885			AC_VERB_SET_COEF_INDEX, 0x0c);
11886	snd_hda_codec_write(codec, 0x20, 0,
11887			AC_VERB_SET_PROC_COEF, 0x480);
11888}
11889
11890static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
11891{
11892	unsigned int present;
11893
11894	present = snd_hda_codec_read(codec, 0x18, 0,
11895				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11896	snd_hda_codec_write(codec, 0x23, 0,
11897			    AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
11898}
11899
11900static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
11901				    unsigned int res)
11902{
11903	if ((res >> 26) == ALC880_HP_EVENT)
11904		alc269_quanta_fl1_speaker_automute(codec);
11905	if ((res >> 26) == ALC880_MIC_EVENT)
11906		alc269_quanta_fl1_mic_automute(codec);
11907}
11908
11909static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
11910{
11911	alc269_quanta_fl1_speaker_automute(codec);
11912	alc269_quanta_fl1_mic_automute(codec);
11913}
11914
11915static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
11916	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11917	{0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
11918	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11919	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
11920	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11921	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11922	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11923	{}
11924};
11925
11926static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
11927	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11928	{0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
11929	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11930	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
11931	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11932	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11933	{}
11934};
11935
11936/* toggle speaker-output according to the hp-jack state */
11937static void alc269_speaker_automute(struct hda_codec *codec)
11938{
11939	unsigned int present;
11940	unsigned char bits;
11941
11942	present = snd_hda_codec_read(codec, 0x15, 0,
11943				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11944	bits = present ? AMP_IN_MUTE(0) : 0;
11945	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11946				AMP_IN_MUTE(0), bits);
11947	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11948				AMP_IN_MUTE(0), bits);
11949}
11950
11951static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
11952{
11953	unsigned int present;
11954
11955	present = snd_hda_codec_read(codec, 0x18, 0,
11956				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11957	snd_hda_codec_write(codec, 0x23, 0,
11958				AC_VERB_SET_CONNECT_SEL,  (present ? 0 : 5));
11959}
11960
11961static void alc269_eeepc_amic_automute(struct hda_codec *codec)
11962{
11963	unsigned int present;
11964
11965	present = snd_hda_codec_read(codec, 0x18, 0,
11966				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11967	snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11968				0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
11969	snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11970				0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
11971}
11972
11973/* unsolicited event for HP jack sensing */
11974static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
11975				     unsigned int res)
11976{
11977	if ((res >> 26) == ALC880_HP_EVENT)
11978		alc269_speaker_automute(codec);
11979
11980	if ((res >> 26) == ALC880_MIC_EVENT)
11981		alc269_eeepc_dmic_automute(codec);
11982}
11983
11984static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
11985{
11986	alc269_speaker_automute(codec);
11987	alc269_eeepc_dmic_automute(codec);
11988}
11989
11990/* unsolicited event for HP jack sensing */
11991static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
11992				     unsigned int res)
11993{
11994	if ((res >> 26) == ALC880_HP_EVENT)
11995		alc269_speaker_automute(codec);
11996
11997	if ((res >> 26) == ALC880_MIC_EVENT)
11998		alc269_eeepc_amic_automute(codec);
11999}
12000
12001static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
12002{
12003	alc269_speaker_automute(codec);
12004	alc269_eeepc_amic_automute(codec);
12005}
12006
12007/*
12008 * generic initialization of ADC, input mixers and output mixers
12009 */
12010static struct hda_verb alc269_init_verbs[] = {
12011	/*
12012	 * Unmute ADC0 and set the default input to mic-in
12013	 */
12014	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12015
12016	/* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12017	 * analog-loopback mixer widget
12018	 * Note: PASD motherboards uses the Line In 2 as the input for
12019	 * front panel mic (mic 2)
12020	 */
12021	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12022	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12023	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12024	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12025	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12026	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12027
12028	/*
12029	 * Set up output mixers (0x0c - 0x0e)
12030	 */
12031	/* set vol=0 to output mixers */
12032	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12033	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12034
12035	/* set up input amps for analog loopback */
12036	/* Amp Indices: DAC = 0, mixer = 1 */
12037	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12038	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12039	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12040	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12041	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12042	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12043
12044	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12045	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12046	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12047	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12048	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12049	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12050	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12051
12052	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12053	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12054	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12055	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12056	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12057	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12058	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12059
12060	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12061	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12062
12063	/* FIXME: use matrix-type input source selection */
12064	/* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12065	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12066	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12067	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12068	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12069	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12070
12071	/* set EAPD */
12072	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12073	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12074	{ }
12075};
12076
12077/* add playback controls from the parsed DAC table */
12078static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12079					     const struct auto_pin_cfg *cfg)
12080{
12081	hda_nid_t nid;
12082	int err;
12083
12084	spec->multiout.num_dacs = 1;	/* only use one dac */
12085	spec->multiout.dac_nids = spec->private_dac_nids;
12086	spec->multiout.dac_nids[0] = 2;
12087
12088	nid = cfg->line_out_pins[0];
12089	if (nid) {
12090		err = add_control(spec, ALC_CTL_WIDGET_VOL,
12091				  "Front Playback Volume",
12092				  HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12093		if (err < 0)
12094			return err;
12095		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12096				  "Front Playback Switch",
12097				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12098		if (err < 0)
12099			return err;
12100	}
12101
12102	nid = cfg->speaker_pins[0];
12103	if (nid) {
12104		if (!cfg->line_out_pins[0]) {
12105			err = add_control(spec, ALC_CTL_WIDGET_VOL,
12106					  "Speaker Playback Volume",
12107					  HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12108							      HDA_OUTPUT));
12109			if (err < 0)
12110				return err;
12111		}
12112		if (nid == 0x16) {
12113			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12114					  "Speaker Playback Switch",
12115					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12116							      HDA_OUTPUT));
12117			if (err < 0)
12118				return err;
12119		} else {
12120			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12121					  "Speaker Playback Switch",
12122					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12123							      HDA_OUTPUT));
12124			if (err < 0)
12125				return err;
12126		}
12127	}
12128	nid = cfg->hp_pins[0];
12129	if (nid) {
12130		/* spec->multiout.hp_nid = 2; */
12131		if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12132			err = add_control(spec, ALC_CTL_WIDGET_VOL,
12133					  "Headphone Playback Volume",
12134					  HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12135							      HDA_OUTPUT));
12136			if (err < 0)
12137				return err;
12138		}
12139		if (nid == 0x16) {
12140			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12141					  "Headphone Playback Switch",
12142					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12143							      HDA_OUTPUT));
12144			if (err < 0)
12145				return err;
12146		} else {
12147			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12148					  "Headphone Playback Switch",
12149					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12150							      HDA_OUTPUT));
12151			if (err < 0)
12152				return err;
12153		}
12154	}
12155	return 0;
12156}
12157
12158#define alc269_auto_create_analog_input_ctls \
12159	alc880_auto_create_analog_input_ctls
12160
12161#ifdef CONFIG_SND_HDA_POWER_SAVE
12162#define alc269_loopbacks	alc880_loopbacks
12163#endif
12164
12165/* pcm configuration: identiacal with ALC880 */
12166#define alc269_pcm_analog_playback	alc880_pcm_analog_playback
12167#define alc269_pcm_analog_capture	alc880_pcm_analog_capture
12168#define alc269_pcm_digital_playback	alc880_pcm_digital_playback
12169#define alc269_pcm_digital_capture	alc880_pcm_digital_capture
12170
12171/*
12172 * BIOS auto configuration
12173 */
12174static int alc269_parse_auto_config(struct hda_codec *codec)
12175{
12176	struct alc_spec *spec = codec->spec;
12177	int i, err;
12178	static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12179
12180	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12181					   alc269_ignore);
12182	if (err < 0)
12183		return err;
12184
12185	err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12186	if (err < 0)
12187		return err;
12188	err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12189	if (err < 0)
12190		return err;
12191
12192	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12193
12194	if (spec->autocfg.dig_out_pin)
12195		spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12196
12197	if (spec->kctl_alloc)
12198		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
12199
12200	/* create a beep mixer control if the pin 0x1d isn't assigned */
12201	for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++)
12202		if (spec->autocfg.input_pins[i] == 0x1d)
12203			break;
12204	if (i >= ARRAY_SIZE(spec->autocfg.input_pins))
12205		spec->mixers[spec->num_mixers++] = alc269_beep_mixer;
12206
12207	spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
12208	spec->num_mux_defs = 1;
12209	spec->input_mux = &spec->private_imux;
12210	/* set default input source */
12211	snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12212				  0, AC_VERB_SET_CONNECT_SEL,
12213				  spec->input_mux->items[0].index);
12214
12215	err = alc_auto_add_mic_boost(codec);
12216	if (err < 0)
12217		return err;
12218
12219	spec->mixers[spec->num_mixers] = alc269_capture_mixer;
12220	spec->num_mixers++;
12221
12222	return 1;
12223}
12224
12225#define alc269_auto_init_multi_out	alc882_auto_init_multi_out
12226#define alc269_auto_init_hp_out		alc882_auto_init_hp_out
12227#define alc269_auto_init_analog_input	alc882_auto_init_analog_input
12228
12229
12230/* init callback for auto-configuration model -- overriding the default init */
12231static void alc269_auto_init(struct hda_codec *codec)
12232{
12233	struct alc_spec *spec = codec->spec;
12234	alc269_auto_init_multi_out(codec);
12235	alc269_auto_init_hp_out(codec);
12236	alc269_auto_init_analog_input(codec);
12237	if (spec->unsol_event)
12238		alc_inithook(codec);
12239}
12240
12241/*
12242 * configuration and preset
12243 */
12244static const char *alc269_models[ALC269_MODEL_LAST] = {
12245	[ALC269_BASIC]			= "basic",
12246	[ALC269_QUANTA_FL1]		= "quanta",
12247	[ALC269_ASUS_EEEPC_P703]	= "eeepc-p703",
12248	[ALC269_ASUS_EEEPC_P901]	= "eeepc-p901"
12249};
12250
12251static struct snd_pci_quirk alc269_cfg_tbl[] = {
12252	SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
12253	SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12254		      ALC269_ASUS_EEEPC_P703),
12255	SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12256		      ALC269_ASUS_EEEPC_P901),
12257	SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12258		      ALC269_ASUS_EEEPC_P901),
12259	{}
12260};
12261
12262static struct alc_config_preset alc269_presets[] = {
12263	[ALC269_BASIC] = {
12264		.mixers = { alc269_base_mixer, alc269_capture_mixer },
12265		.init_verbs = { alc269_init_verbs },
12266		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
12267		.dac_nids = alc269_dac_nids,
12268		.hp_nid = 0x03,
12269		.num_channel_mode = ARRAY_SIZE(alc269_modes),
12270		.channel_mode = alc269_modes,
12271		.input_mux = &alc269_capture_source,
12272	},
12273	[ALC269_QUANTA_FL1] = {
12274		.mixers = { alc269_quanta_fl1_mixer },
12275		.init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
12276		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
12277		.dac_nids = alc269_dac_nids,
12278		.hp_nid = 0x03,
12279		.num_channel_mode = ARRAY_SIZE(alc269_modes),
12280		.channel_mode = alc269_modes,
12281		.input_mux = &alc269_capture_source,
12282		.unsol_event = alc269_quanta_fl1_unsol_event,
12283		.init_hook = alc269_quanta_fl1_init_hook,
12284	},
12285	[ALC269_ASUS_EEEPC_P703] = {
12286		.mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer },
12287		.init_verbs = { alc269_init_verbs,
12288				alc269_eeepc_amic_init_verbs },
12289		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
12290		.dac_nids = alc269_dac_nids,
12291		.hp_nid = 0x03,
12292		.num_channel_mode = ARRAY_SIZE(alc269_modes),
12293		.channel_mode = alc269_modes,
12294		.input_mux = &alc269_eeepc_amic_capture_source,
12295		.unsol_event = alc269_eeepc_amic_unsol_event,
12296		.init_hook = alc269_eeepc_amic_inithook,
12297	},
12298	[ALC269_ASUS_EEEPC_P901] = {
12299		.mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer},
12300		.init_verbs = { alc269_init_verbs,
12301				alc269_eeepc_dmic_init_verbs },
12302		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
12303		.dac_nids = alc269_dac_nids,
12304		.hp_nid = 0x03,
12305		.num_channel_mode = ARRAY_SIZE(alc269_modes),
12306		.channel_mode = alc269_modes,
12307		.input_mux = &alc269_eeepc_dmic_capture_source,
12308		.unsol_event = alc269_eeepc_dmic_unsol_event,
12309		.init_hook = alc269_eeepc_dmic_inithook,
12310	},
12311};
12312
12313static int patch_alc269(struct hda_codec *codec)
12314{
12315	struct alc_spec *spec;
12316	int board_config;
12317	int err;
12318
12319	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12320	if (spec == NULL)
12321		return -ENOMEM;
12322
12323	codec->spec = spec;
12324
12325	alc_fix_pll_init(codec, 0x20, 0x04, 15);
12326
12327	board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
12328						  alc269_models,
12329						  alc269_cfg_tbl);
12330
12331	if (board_config < 0) {
12332		printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
12333		       "trying auto-probe from BIOS...\n");
12334		board_config = ALC269_AUTO;
12335	}
12336
12337	if (board_config == ALC269_AUTO) {
12338		/* automatic parse from the BIOS config */
12339		err = alc269_parse_auto_config(codec);
12340		if (err < 0) {
12341			alc_free(codec);
12342			return err;
12343		} else if (!err) {
12344			printk(KERN_INFO
12345			       "hda_codec: Cannot set up configuration "
12346			       "from BIOS.  Using base mode...\n");
12347			board_config = ALC269_BASIC;
12348		}
12349	}
12350
12351	if (board_config != ALC269_AUTO)
12352		setup_preset(spec, &alc269_presets[board_config]);
12353
12354	spec->stream_name_analog = "ALC269 Analog";
12355	spec->stream_analog_playback = &alc269_pcm_analog_playback;
12356	spec->stream_analog_capture = &alc269_pcm_analog_capture;
12357
12358	spec->stream_name_digital = "ALC269 Digital";
12359	spec->stream_digital_playback = &alc269_pcm_digital_playback;
12360	spec->stream_digital_capture = &alc269_pcm_digital_capture;
12361
12362	spec->adc_nids = alc269_adc_nids;
12363	spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
12364	spec->capsrc_nids = alc269_capsrc_nids;
12365
12366	codec->patch_ops = alc_patch_ops;
12367	if (board_config == ALC269_AUTO)
12368		spec->init_hook = alc269_auto_init;
12369#ifdef CONFIG_SND_HDA_POWER_SAVE
12370	if (!spec->loopback.amplist)
12371		spec->loopback.amplist = alc269_loopbacks;
12372#endif
12373
12374	return 0;
12375}
12376
12377/*
12378 *  ALC861 channel source setting (2/6 channel selection for 3-stack)
12379 */
12380
12381/*
12382 * set the path ways for 2 channel output
12383 * need to set the codec line out and mic 1 pin widgets to inputs
12384 */
12385static struct hda_verb alc861_threestack_ch2_init[] = {
12386	/* set pin widget 1Ah (line in) for input */
12387	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12388	/* set pin widget 18h (mic1/2) for input, for mic also enable
12389	 * the vref
12390	 */
12391	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12392
12393	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12394#if 0
12395	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12396	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12397#endif
12398	{ } /* end */
12399};
12400/*
12401 * 6ch mode
12402 * need to set the codec line out and mic 1 pin widgets to outputs
12403 */
12404static struct hda_verb alc861_threestack_ch6_init[] = {
12405	/* set pin widget 1Ah (line in) for output (Back Surround)*/
12406	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12407	/* set pin widget 18h (mic1) for output (CLFE)*/
12408	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12409
12410	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12411	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12412
12413	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12414#if 0
12415	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12416	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12417#endif
12418	{ } /* end */
12419};
12420
12421static struct hda_channel_mode alc861_threestack_modes[2] = {
12422	{ 2, alc861_threestack_ch2_init },
12423	{ 6, alc861_threestack_ch6_init },
12424};
12425/* Set mic1 as input and unmute the mixer */
12426static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
12427	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12428	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12429	{ } /* end */
12430};
12431/* Set mic1 as output and mute mixer */
12432static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
12433	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12434	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12435	{ } /* end */
12436};
12437
12438static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
12439	{ 2, alc861_uniwill_m31_ch2_init },
12440	{ 4, alc861_uniwill_m31_ch4_init },
12441};
12442
12443/* Set mic1 and line-in as input and unmute the mixer */
12444static struct hda_verb alc861_asus_ch2_init[] = {
12445	/* set pin widget 1Ah (line in) for input */
12446	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12447	/* set pin widget 18h (mic1/2) for input, for mic also enable
12448	 * the vref
12449	 */
12450	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12451
12452	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12453#if 0
12454	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12455	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12456#endif
12457	{ } /* end */
12458};
12459/* Set mic1 nad line-in as output and mute mixer */
12460static struct hda_verb alc861_asus_ch6_init[] = {
12461	/* set pin widget 1Ah (line in) for output (Back Surround)*/
12462	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12463	/* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12464	/* set pin widget 18h (mic1) for output (CLFE)*/
12465	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12466	/* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12467	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12468	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12469
12470	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12471#if 0
12472	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12473	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12474#endif
12475	{ } /* end */
12476};
12477
12478static struct hda_channel_mode alc861_asus_modes[2] = {
12479	{ 2, alc861_asus_ch2_init },
12480	{ 6, alc861_asus_ch6_init },
12481};
12482
12483/* patch-ALC861 */
12484
12485static struct snd_kcontrol_new alc861_base_mixer[] = {
12486        /* output mixer control */
12487	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12488	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12489	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12490	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12491	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12492
12493        /*Input mixer control */
12494	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12495	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12496	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12497	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12498	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12499	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12500	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12501	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12502	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12503	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12504
12505        /* Capture mixer control */
12506	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12507	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12508	{
12509		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12510		.name = "Capture Source",
12511		.count = 1,
12512		.info = alc_mux_enum_info,
12513		.get = alc_mux_enum_get,
12514		.put = alc_mux_enum_put,
12515	},
12516	{ } /* end */
12517};
12518
12519static struct snd_kcontrol_new alc861_3ST_mixer[] = {
12520        /* output mixer control */
12521	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12522	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12523	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12524	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12525	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12526
12527	/* Input mixer control */
12528	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12529	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12530	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12531	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12532	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12533	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12534	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12535	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12536	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12537	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12538
12539	/* Capture mixer control */
12540	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12541	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12542	{
12543		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12544		.name = "Capture Source",
12545		.count = 1,
12546		.info = alc_mux_enum_info,
12547		.get = alc_mux_enum_get,
12548		.put = alc_mux_enum_put,
12549	},
12550	{
12551		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12552		.name = "Channel Mode",
12553		.info = alc_ch_mode_info,
12554		.get = alc_ch_mode_get,
12555		.put = alc_ch_mode_put,
12556                .private_value = ARRAY_SIZE(alc861_threestack_modes),
12557	},
12558	{ } /* end */
12559};
12560
12561static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
12562        /* output mixer control */
12563	HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12564	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12565	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12566
12567        /*Capture mixer control */
12568	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12569	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12570	{
12571		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12572		.name = "Capture Source",
12573		.count = 1,
12574		.info = alc_mux_enum_info,
12575		.get = alc_mux_enum_get,
12576		.put = alc_mux_enum_put,
12577	},
12578
12579	{ } /* end */
12580};
12581
12582static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
12583        /* output mixer control */
12584	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12585	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12586	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12587	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12588	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12589
12590	/* Input mixer control */
12591	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12592	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12593	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12594	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12595	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12596	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12597	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12598	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12599	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12600	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12601
12602	/* Capture mixer control */
12603	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12604	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12605	{
12606		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12607		.name = "Capture Source",
12608		.count = 1,
12609		.info = alc_mux_enum_info,
12610		.get = alc_mux_enum_get,
12611		.put = alc_mux_enum_put,
12612	},
12613	{
12614		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12615		.name = "Channel Mode",
12616		.info = alc_ch_mode_info,
12617		.get = alc_ch_mode_get,
12618		.put = alc_ch_mode_put,
12619                .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
12620	},
12621	{ } /* end */
12622};
12623
12624static struct snd_kcontrol_new alc861_asus_mixer[] = {
12625        /* output mixer control */
12626	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12627	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12628	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12629	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12630	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12631
12632	/* Input mixer control */
12633	HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12634	HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12635	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12636	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12637	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12638	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12639	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12640	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12641	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12642	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
12643
12644	/* Capture mixer control */
12645	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12646	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12647	{
12648		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12649		.name = "Capture Source",
12650		.count = 1,
12651		.info = alc_mux_enum_info,
12652		.get = alc_mux_enum_get,
12653		.put = alc_mux_enum_put,
12654	},
12655	{
12656		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12657		.name = "Channel Mode",
12658		.info = alc_ch_mode_info,
12659		.get = alc_ch_mode_get,
12660		.put = alc_ch_mode_put,
12661                .private_value = ARRAY_SIZE(alc861_asus_modes),
12662	},
12663	{ }
12664};
12665
12666/* additional mixer */
12667static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
12668	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12669	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12670	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
12671	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
12672	{ }
12673};
12674
12675/*
12676 * generic initialization of ADC, input mixers and output mixers
12677 */
12678static struct hda_verb alc861_base_init_verbs[] = {
12679	/*
12680	 * Unmute ADC0 and set the default input to mic-in
12681	 */
12682	/* port-A for surround (rear panel) */
12683	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12684	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
12685	/* port-B for mic-in (rear panel) with vref */
12686	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12687	/* port-C for line-in (rear panel) */
12688	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12689	/* port-D for Front */
12690	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12691	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12692	/* port-E for HP out (front panel) */
12693	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12694	/* route front PCM to HP */
12695	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12696	/* port-F for mic-in (front panel) with vref */
12697	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12698	/* port-G for CLFE (rear panel) */
12699	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12700	{ 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12701	/* port-H for side (rear panel) */
12702	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12703	{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
12704	/* CD-in */
12705	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12706	/* route front mic to ADC1*/
12707	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12708	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12709
12710	/* Unmute DAC0~3 & spdif out*/
12711	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12712	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12713	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12714	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12715	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12716
12717	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12718	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12719        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12720	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12721        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12722
12723	/* Unmute Stereo Mixer 15 */
12724	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12725	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12726	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12727	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12728
12729	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12730	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12731	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12732	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12733	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12734	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12735	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12736	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12737	/* hp used DAC 3 (Front) */
12738	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12739        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12740
12741	{ }
12742};
12743
12744static struct hda_verb alc861_threestack_init_verbs[] = {
12745	/*
12746	 * Unmute ADC0 and set the default input to mic-in
12747	 */
12748	/* port-A for surround (rear panel) */
12749	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12750	/* port-B for mic-in (rear panel) with vref */
12751	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12752	/* port-C for line-in (rear panel) */
12753	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12754	/* port-D for Front */
12755	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12756	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12757	/* port-E for HP out (front panel) */
12758	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12759	/* route front PCM to HP */
12760	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12761	/* port-F for mic-in (front panel) with vref */
12762	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12763	/* port-G for CLFE (rear panel) */
12764	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12765	/* port-H for side (rear panel) */
12766	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12767	/* CD-in */
12768	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12769	/* route front mic to ADC1*/
12770	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12771	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12772	/* Unmute DAC0~3 & spdif out*/
12773	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12774	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12775	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12776	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12777	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12778
12779	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12780	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12781        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12782	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12783        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12784
12785	/* Unmute Stereo Mixer 15 */
12786	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12787	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12788	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12789	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12790
12791	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12792	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12793	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12794	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12795	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12796	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12797	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12798	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12799	/* hp used DAC 3 (Front) */
12800	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12801        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12802	{ }
12803};
12804
12805static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
12806	/*
12807	 * Unmute ADC0 and set the default input to mic-in
12808	 */
12809	/* port-A for surround (rear panel) */
12810	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12811	/* port-B for mic-in (rear panel) with vref */
12812	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12813	/* port-C for line-in (rear panel) */
12814	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12815	/* port-D for Front */
12816	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12817	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12818	/* port-E for HP out (front panel) */
12819	/* this has to be set to VREF80 */
12820	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12821	/* route front PCM to HP */
12822	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12823	/* port-F for mic-in (front panel) with vref */
12824	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12825	/* port-G for CLFE (rear panel) */
12826	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12827	/* port-H for side (rear panel) */
12828	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12829	/* CD-in */
12830	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12831	/* route front mic to ADC1*/
12832	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12833	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12834	/* Unmute DAC0~3 & spdif out*/
12835	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12836	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12837	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12838	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12839	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12840
12841	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12842	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12843        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12844	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12845        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12846
12847	/* Unmute Stereo Mixer 15 */
12848	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12849	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12850	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12851	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12852
12853	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12854	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12855	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12856	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12857	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12858	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12859	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12860	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12861	/* hp used DAC 3 (Front) */
12862	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12863        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12864	{ }
12865};
12866
12867static struct hda_verb alc861_asus_init_verbs[] = {
12868	/*
12869	 * Unmute ADC0 and set the default input to mic-in
12870	 */
12871	/* port-A for surround (rear panel)
12872	 * according to codec#0 this is the HP jack
12873	 */
12874	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
12875	/* route front PCM to HP */
12876	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
12877	/* port-B for mic-in (rear panel) with vref */
12878	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12879	/* port-C for line-in (rear panel) */
12880	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12881	/* port-D for Front */
12882	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12883	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12884	/* port-E for HP out (front panel) */
12885	/* this has to be set to VREF80 */
12886	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12887	/* route front PCM to HP */
12888	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12889	/* port-F for mic-in (front panel) with vref */
12890	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12891	/* port-G for CLFE (rear panel) */
12892	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12893	/* port-H for side (rear panel) */
12894	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12895	/* CD-in */
12896	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12897	/* route front mic to ADC1*/
12898	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12899	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12900	/* Unmute DAC0~3 & spdif out*/
12901	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12902	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12903	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12904	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12905	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12906	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12907	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12908        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12909	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12910        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12911
12912	/* Unmute Stereo Mixer 15 */
12913	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12914	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12915	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12916	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12917
12918	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12919	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12920	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12921	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12922	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12923	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12924	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12925	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12926	/* hp used DAC 3 (Front) */
12927	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12928	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12929	{ }
12930};
12931
12932/* additional init verbs for ASUS laptops */
12933static struct hda_verb alc861_asus_laptop_init_verbs[] = {
12934	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
12935	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
12936	{ }
12937};
12938
12939/*
12940 * generic initialization of ADC, input mixers and output mixers
12941 */
12942static struct hda_verb alc861_auto_init_verbs[] = {
12943	/*
12944	 * Unmute ADC0 and set the default input to mic-in
12945	 */
12946	/* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
12947	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12948
12949	/* Unmute DAC0~3 & spdif out*/
12950	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12951	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12952	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12953	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12954	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12955
12956	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12957	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12958	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12959	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12960	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12961
12962	/* Unmute Stereo Mixer 15 */
12963	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12964	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12965	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12966	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
12967
12968	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12969	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12970	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12971	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12972	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12973	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12974	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12975	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12976
12977	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12978	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12979	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12980	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12981	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12982	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12983	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12984	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12985
12986	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},	/* set Mic 1 */
12987
12988	{ }
12989};
12990
12991static struct hda_verb alc861_toshiba_init_verbs[] = {
12992	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12993
12994	{ }
12995};
12996
12997/* toggle speaker-output according to the hp-jack state */
12998static void alc861_toshiba_automute(struct hda_codec *codec)
12999{
13000	unsigned int present;
13001
13002	present = snd_hda_codec_read(codec, 0x0f, 0,
13003				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13004	snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
13005				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13006	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
13007				 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
13008}
13009
13010static void alc861_toshiba_unsol_event(struct hda_codec *codec,
13011				       unsigned int res)
13012{
13013	if ((res >> 26) == ALC880_HP_EVENT)
13014		alc861_toshiba_automute(codec);
13015}
13016
13017/* pcm configuration: identiacal with ALC880 */
13018#define alc861_pcm_analog_playback	alc880_pcm_analog_playback
13019#define alc861_pcm_analog_capture	alc880_pcm_analog_capture
13020#define alc861_pcm_digital_playback	alc880_pcm_digital_playback
13021#define alc861_pcm_digital_capture	alc880_pcm_digital_capture
13022
13023
13024#define ALC861_DIGOUT_NID	0x07
13025
13026static struct hda_channel_mode alc861_8ch_modes[1] = {
13027	{ 8, NULL }
13028};
13029
13030static hda_nid_t alc861_dac_nids[4] = {
13031	/* front, surround, clfe, side */
13032	0x03, 0x06, 0x05, 0x04
13033};
13034
13035static hda_nid_t alc660_dac_nids[3] = {
13036	/* front, clfe, surround */
13037	0x03, 0x05, 0x06
13038};
13039
13040static hda_nid_t alc861_adc_nids[1] = {
13041	/* ADC0-2 */
13042	0x08,
13043};
13044
13045static struct hda_input_mux alc861_capture_source = {
13046	.num_items = 5,
13047	.items = {
13048		{ "Mic", 0x0 },
13049		{ "Front Mic", 0x3 },
13050		{ "Line", 0x1 },
13051		{ "CD", 0x4 },
13052		{ "Mixer", 0x5 },
13053	},
13054};
13055
13056/* fill in the dac_nids table from the parsed pin configuration */
13057static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
13058				     const struct auto_pin_cfg *cfg)
13059{
13060	int i;
13061	hda_nid_t nid;
13062
13063	spec->multiout.dac_nids = spec->private_dac_nids;
13064	for (i = 0; i < cfg->line_outs; i++) {
13065		nid = cfg->line_out_pins[i];
13066		if (nid) {
13067			if (i >= ARRAY_SIZE(alc861_dac_nids))
13068				continue;
13069			spec->multiout.dac_nids[i] = alc861_dac_nids[i];
13070		}
13071	}
13072	spec->multiout.num_dacs = cfg->line_outs;
13073	return 0;
13074}
13075
13076/* add playback controls from the parsed DAC table */
13077static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
13078					     const struct auto_pin_cfg *cfg)
13079{
13080	char name[32];
13081	static const char *chname[4] = {
13082		"Front", "Surround", NULL /*CLFE*/, "Side"
13083	};
13084	hda_nid_t nid;
13085	int i, idx, err;
13086
13087	for (i = 0; i < cfg->line_outs; i++) {
13088		nid = spec->multiout.dac_nids[i];
13089		if (!nid)
13090			continue;
13091		if (nid == 0x05) {
13092			/* Center/LFE */
13093			err = add_control(spec, ALC_CTL_BIND_MUTE,
13094					  "Center Playback Switch",
13095					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13096							      HDA_OUTPUT));
13097			if (err < 0)
13098				return err;
13099			err = add_control(spec, ALC_CTL_BIND_MUTE,
13100					  "LFE Playback Switch",
13101					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13102							      HDA_OUTPUT));
13103			if (err < 0)
13104				return err;
13105		} else {
13106			for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13107			     idx++)
13108				if (nid == alc861_dac_nids[idx])
13109					break;
13110			sprintf(name, "%s Playback Switch", chname[idx]);
13111			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13112					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13113							      HDA_OUTPUT));
13114			if (err < 0)
13115				return err;
13116		}
13117	}
13118	return 0;
13119}
13120
13121static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13122{
13123	int err;
13124	hda_nid_t nid;
13125
13126	if (!pin)
13127		return 0;
13128
13129	if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13130		nid = 0x03;
13131		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13132				  "Headphone Playback Switch",
13133				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13134		if (err < 0)
13135			return err;
13136		spec->multiout.hp_nid = nid;
13137	}
13138	return 0;
13139}
13140
13141/* create playback/capture controls for input pins */
13142static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13143						const struct auto_pin_cfg *cfg)
13144{
13145	struct hda_input_mux *imux = &spec->private_imux;
13146	int i, err, idx, idx1;
13147
13148	for (i = 0; i < AUTO_PIN_LAST; i++) {
13149		switch (cfg->input_pins[i]) {
13150		case 0x0c:
13151			idx1 = 1;
13152			idx = 2;	/* Line In */
13153			break;
13154		case 0x0f:
13155			idx1 = 2;
13156			idx = 2;	/* Line In */
13157			break;
13158		case 0x0d:
13159			idx1 = 0;
13160			idx = 1;	/* Mic In */
13161			break;
13162		case 0x10:
13163			idx1 = 3;
13164			idx = 1;	/* Mic In */
13165			break;
13166		case 0x11:
13167			idx1 = 4;
13168			idx = 0;	/* CD */
13169			break;
13170		default:
13171			continue;
13172		}
13173
13174		err = new_analog_input(spec, cfg->input_pins[i],
13175				       auto_pin_cfg_labels[i], idx, 0x15);
13176		if (err < 0)
13177			return err;
13178
13179		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
13180		imux->items[imux->num_items].index = idx1;
13181		imux->num_items++;
13182	}
13183	return 0;
13184}
13185
13186static struct snd_kcontrol_new alc861_capture_mixer[] = {
13187	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13188	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13189
13190	{
13191		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13192		/* The multiple "Capture Source" controls confuse alsamixer
13193		 * So call somewhat different..
13194		 */
13195		/* .name = "Capture Source", */
13196		.name = "Input Source",
13197		.count = 1,
13198		.info = alc_mux_enum_info,
13199		.get = alc_mux_enum_get,
13200		.put = alc_mux_enum_put,
13201	},
13202	{ } /* end */
13203};
13204
13205static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13206					      hda_nid_t nid,
13207					      int pin_type, int dac_idx)
13208{
13209	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13210			    pin_type);
13211	snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13212			    AMP_OUT_UNMUTE);
13213}
13214
13215static void alc861_auto_init_multi_out(struct hda_codec *codec)
13216{
13217	struct alc_spec *spec = codec->spec;
13218	int i;
13219
13220	alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
13221	for (i = 0; i < spec->autocfg.line_outs; i++) {
13222		hda_nid_t nid = spec->autocfg.line_out_pins[i];
13223		int pin_type = get_pin_type(spec->autocfg.line_out_type);
13224		if (nid)
13225			alc861_auto_set_output_and_unmute(codec, nid, pin_type,
13226							  spec->multiout.dac_nids[i]);
13227	}
13228}
13229
13230static void alc861_auto_init_hp_out(struct hda_codec *codec)
13231{
13232	struct alc_spec *spec = codec->spec;
13233	hda_nid_t pin;
13234
13235	pin = spec->autocfg.hp_pins[0];
13236	if (pin) /* connect to front */
13237		alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13238						  spec->multiout.dac_nids[0]);
13239	pin = spec->autocfg.speaker_pins[0];
13240	if (pin)
13241		alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13242}
13243
13244static void alc861_auto_init_analog_input(struct hda_codec *codec)
13245{
13246	struct alc_spec *spec = codec->spec;
13247	int i;
13248
13249	for (i = 0; i < AUTO_PIN_LAST; i++) {
13250		hda_nid_t nid = spec->autocfg.input_pins[i];
13251		if (nid >= 0x0c && nid <= 0x11) {
13252			snd_hda_codec_write(codec, nid, 0,
13253					    AC_VERB_SET_PIN_WIDGET_CONTROL,
13254					    i <= AUTO_PIN_FRONT_MIC ?
13255					    PIN_VREF80 : PIN_IN);
13256		}
13257	}
13258}
13259
13260/* parse the BIOS configuration and set up the alc_spec */
13261/* return 1 if successful, 0 if the proper config is not found,
13262 * or a negative error code
13263 */
13264static int alc861_parse_auto_config(struct hda_codec *codec)
13265{
13266	struct alc_spec *spec = codec->spec;
13267	int err;
13268	static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13269
13270	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13271					   alc861_ignore);
13272	if (err < 0)
13273		return err;
13274	if (!spec->autocfg.line_outs)
13275		return 0; /* can't find valid BIOS pin config */
13276
13277	err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13278	if (err < 0)
13279		return err;
13280	err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13281	if (err < 0)
13282		return err;
13283	err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13284	if (err < 0)
13285		return err;
13286	err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13287	if (err < 0)
13288		return err;
13289
13290	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13291
13292	if (spec->autocfg.dig_out_pin)
13293		spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13294
13295	if (spec->kctl_alloc)
13296		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
13297
13298	spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
13299
13300	spec->num_mux_defs = 1;
13301	spec->input_mux = &spec->private_imux;
13302
13303	spec->adc_nids = alc861_adc_nids;
13304	spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
13305	spec->mixers[spec->num_mixers] = alc861_capture_mixer;
13306	spec->num_mixers++;
13307
13308	return 1;
13309}
13310
13311/* additional initialization for auto-configuration model */
13312static void alc861_auto_init(struct hda_codec *codec)
13313{
13314	struct alc_spec *spec = codec->spec;
13315	alc861_auto_init_multi_out(codec);
13316	alc861_auto_init_hp_out(codec);
13317	alc861_auto_init_analog_input(codec);
13318	if (spec->unsol_event)
13319		alc_inithook(codec);
13320}
13321
13322#ifdef CONFIG_SND_HDA_POWER_SAVE
13323static struct hda_amp_list alc861_loopbacks[] = {
13324	{ 0x15, HDA_INPUT, 0 },
13325	{ 0x15, HDA_INPUT, 1 },
13326	{ 0x15, HDA_INPUT, 2 },
13327	{ 0x15, HDA_INPUT, 3 },
13328	{ } /* end */
13329};
13330#endif
13331
13332
13333/*
13334 * configuration and preset
13335 */
13336static const char *alc861_models[ALC861_MODEL_LAST] = {
13337	[ALC861_3ST]		= "3stack",
13338	[ALC660_3ST]		= "3stack-660",
13339	[ALC861_3ST_DIG]	= "3stack-dig",
13340	[ALC861_6ST_DIG]	= "6stack-dig",
13341	[ALC861_UNIWILL_M31]	= "uniwill-m31",
13342	[ALC861_TOSHIBA]	= "toshiba",
13343	[ALC861_ASUS]		= "asus",
13344	[ALC861_ASUS_LAPTOP]	= "asus-laptop",
13345	[ALC861_AUTO]		= "auto",
13346};
13347
13348static struct snd_pci_quirk alc861_cfg_tbl[] = {
13349	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
13350	SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13351	SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13352	SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
13353	SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
13354	SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
13355	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
13356	/* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
13357	 *        Any other models that need this preset?
13358	 */
13359	/* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
13360	SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
13361	SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
13362	SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
13363	SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
13364	SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
13365	/* FIXME: the below seems conflict */
13366	/* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
13367	SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
13368	SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
13369	{}
13370};
13371
13372static struct alc_config_preset alc861_presets[] = {
13373	[ALC861_3ST] = {
13374		.mixers = { alc861_3ST_mixer },
13375		.init_verbs = { alc861_threestack_init_verbs },
13376		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13377		.dac_nids = alc861_dac_nids,
13378		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13379		.channel_mode = alc861_threestack_modes,
13380		.need_dac_fix = 1,
13381		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13382		.adc_nids = alc861_adc_nids,
13383		.input_mux = &alc861_capture_source,
13384	},
13385	[ALC861_3ST_DIG] = {
13386		.mixers = { alc861_base_mixer },
13387		.init_verbs = { alc861_threestack_init_verbs },
13388		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13389		.dac_nids = alc861_dac_nids,
13390		.dig_out_nid = ALC861_DIGOUT_NID,
13391		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13392		.channel_mode = alc861_threestack_modes,
13393		.need_dac_fix = 1,
13394		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13395		.adc_nids = alc861_adc_nids,
13396		.input_mux = &alc861_capture_source,
13397	},
13398	[ALC861_6ST_DIG] = {
13399		.mixers = { alc861_base_mixer },
13400		.init_verbs = { alc861_base_init_verbs },
13401		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13402		.dac_nids = alc861_dac_nids,
13403		.dig_out_nid = ALC861_DIGOUT_NID,
13404		.num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
13405		.channel_mode = alc861_8ch_modes,
13406		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13407		.adc_nids = alc861_adc_nids,
13408		.input_mux = &alc861_capture_source,
13409	},
13410	[ALC660_3ST] = {
13411		.mixers = { alc861_3ST_mixer },
13412		.init_verbs = { alc861_threestack_init_verbs },
13413		.num_dacs = ARRAY_SIZE(alc660_dac_nids),
13414		.dac_nids = alc660_dac_nids,
13415		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13416		.channel_mode = alc861_threestack_modes,
13417		.need_dac_fix = 1,
13418		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13419		.adc_nids = alc861_adc_nids,
13420		.input_mux = &alc861_capture_source,
13421	},
13422	[ALC861_UNIWILL_M31] = {
13423		.mixers = { alc861_uniwill_m31_mixer },
13424		.init_verbs = { alc861_uniwill_m31_init_verbs },
13425		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13426		.dac_nids = alc861_dac_nids,
13427		.dig_out_nid = ALC861_DIGOUT_NID,
13428		.num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
13429		.channel_mode = alc861_uniwill_m31_modes,
13430		.need_dac_fix = 1,
13431		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13432		.adc_nids = alc861_adc_nids,
13433		.input_mux = &alc861_capture_source,
13434	},
13435	[ALC861_TOSHIBA] = {
13436		.mixers = { alc861_toshiba_mixer },
13437		.init_verbs = { alc861_base_init_verbs,
13438				alc861_toshiba_init_verbs },
13439		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13440		.dac_nids = alc861_dac_nids,
13441		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13442		.channel_mode = alc883_3ST_2ch_modes,
13443		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13444		.adc_nids = alc861_adc_nids,
13445		.input_mux = &alc861_capture_source,
13446		.unsol_event = alc861_toshiba_unsol_event,
13447		.init_hook = alc861_toshiba_automute,
13448	},
13449	[ALC861_ASUS] = {
13450		.mixers = { alc861_asus_mixer },
13451		.init_verbs = { alc861_asus_init_verbs },
13452		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13453		.dac_nids = alc861_dac_nids,
13454		.dig_out_nid = ALC861_DIGOUT_NID,
13455		.num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
13456		.channel_mode = alc861_asus_modes,
13457		.need_dac_fix = 1,
13458		.hp_nid = 0x06,
13459		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13460		.adc_nids = alc861_adc_nids,
13461		.input_mux = &alc861_capture_source,
13462	},
13463	[ALC861_ASUS_LAPTOP] = {
13464		.mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
13465		.init_verbs = { alc861_asus_init_verbs,
13466				alc861_asus_laptop_init_verbs },
13467		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13468		.dac_nids = alc861_dac_nids,
13469		.dig_out_nid = ALC861_DIGOUT_NID,
13470		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13471		.channel_mode = alc883_3ST_2ch_modes,
13472		.need_dac_fix = 1,
13473		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13474		.adc_nids = alc861_adc_nids,
13475		.input_mux = &alc861_capture_source,
13476	},
13477};
13478
13479
13480static int patch_alc861(struct hda_codec *codec)
13481{
13482	struct alc_spec *spec;
13483	int board_config;
13484	int err;
13485
13486	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13487	if (spec == NULL)
13488		return -ENOMEM;
13489
13490	codec->spec = spec;
13491
13492        board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
13493						  alc861_models,
13494						  alc861_cfg_tbl);
13495
13496	if (board_config < 0) {
13497		printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
13498		       "trying auto-probe from BIOS...\n");
13499		board_config = ALC861_AUTO;
13500	}
13501
13502	if (board_config == ALC861_AUTO) {
13503		/* automatic parse from the BIOS config */
13504		err = alc861_parse_auto_config(codec);
13505		if (err < 0) {
13506			alc_free(codec);
13507			return err;
13508		} else if (!err) {
13509			printk(KERN_INFO
13510			       "hda_codec: Cannot set up configuration "
13511			       "from BIOS.  Using base mode...\n");
13512		   board_config = ALC861_3ST_DIG;
13513		}
13514	}
13515
13516	if (board_config != ALC861_AUTO)
13517		setup_preset(spec, &alc861_presets[board_config]);
13518
13519	spec->stream_name_analog = "ALC861 Analog";
13520	spec->stream_analog_playback = &alc861_pcm_analog_playback;
13521	spec->stream_analog_capture = &alc861_pcm_analog_capture;
13522
13523	spec->stream_name_digital = "ALC861 Digital";
13524	spec->stream_digital_playback = &alc861_pcm_digital_playback;
13525	spec->stream_digital_capture = &alc861_pcm_digital_capture;
13526
13527	spec->vmaster_nid = 0x03;
13528
13529	codec->patch_ops = alc_patch_ops;
13530	if (board_config == ALC861_AUTO)
13531		spec->init_hook = alc861_auto_init;
13532#ifdef CONFIG_SND_HDA_POWER_SAVE
13533	if (!spec->loopback.amplist)
13534		spec->loopback.amplist = alc861_loopbacks;
13535#endif
13536
13537	return 0;
13538}
13539
13540/*
13541 * ALC861-VD support
13542 *
13543 * Based on ALC882
13544 *
13545 * In addition, an independent DAC
13546 */
13547#define ALC861VD_DIGOUT_NID	0x06
13548
13549static hda_nid_t alc861vd_dac_nids[4] = {
13550	/* front, surr, clfe, side surr */
13551	0x02, 0x03, 0x04, 0x05
13552};
13553
13554/* dac_nids for ALC660vd are in a different order - according to
13555 * Realtek's driver.
13556 * This should probably tesult in a different mixer for 6stack models
13557 * of ALC660vd codecs, but for now there is only 3stack mixer
13558 * - and it is the same as in 861vd.
13559 * adc_nids in ALC660vd are (is) the same as in 861vd
13560 */
13561static hda_nid_t alc660vd_dac_nids[3] = {
13562	/* front, rear, clfe, rear_surr */
13563	0x02, 0x04, 0x03
13564};
13565
13566static hda_nid_t alc861vd_adc_nids[1] = {
13567	/* ADC0 */
13568	0x09,
13569};
13570
13571static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
13572
13573/* input MUX */
13574/* FIXME: should be a matrix-type input source selection */
13575static struct hda_input_mux alc861vd_capture_source = {
13576	.num_items = 4,
13577	.items = {
13578		{ "Mic", 0x0 },
13579		{ "Front Mic", 0x1 },
13580		{ "Line", 0x2 },
13581		{ "CD", 0x4 },
13582	},
13583};
13584
13585static struct hda_input_mux alc861vd_dallas_capture_source = {
13586	.num_items = 2,
13587	.items = {
13588		{ "Ext Mic", 0x0 },
13589		{ "Int Mic", 0x1 },
13590	},
13591};
13592
13593static struct hda_input_mux alc861vd_hp_capture_source = {
13594	.num_items = 2,
13595	.items = {
13596		{ "Front Mic", 0x0 },
13597		{ "ATAPI Mic", 0x1 },
13598	},
13599};
13600
13601#define alc861vd_mux_enum_info alc_mux_enum_info
13602#define alc861vd_mux_enum_get alc_mux_enum_get
13603/* ALC861VD has the ALC882-type input selection (but has only one ADC) */
13604#define alc861vd_mux_enum_put alc882_mux_enum_put
13605
13606/*
13607 * 2ch mode
13608 */
13609static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
13610	{ 2, NULL }
13611};
13612
13613/*
13614 * 6ch mode
13615 */
13616static struct hda_verb alc861vd_6stack_ch6_init[] = {
13617	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13618	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13619	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13620	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13621	{ } /* end */
13622};
13623
13624/*
13625 * 8ch mode
13626 */
13627static struct hda_verb alc861vd_6stack_ch8_init[] = {
13628	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13629	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13630	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13631	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13632	{ } /* end */
13633};
13634
13635static struct hda_channel_mode alc861vd_6stack_modes[2] = {
13636	{ 6, alc861vd_6stack_ch6_init },
13637	{ 8, alc861vd_6stack_ch8_init },
13638};
13639
13640static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
13641	{
13642		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13643		.name = "Channel Mode",
13644		.info = alc_ch_mode_info,
13645		.get = alc_ch_mode_get,
13646		.put = alc_ch_mode_put,
13647	},
13648	{ } /* end */
13649};
13650
13651static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
13652	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13653	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13654
13655	{
13656		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13657		/* The multiple "Capture Source" controls confuse alsamixer
13658		 * So call somewhat different..
13659		 */
13660		/* .name = "Capture Source", */
13661		.name = "Input Source",
13662		.count = 1,
13663		.info = alc861vd_mux_enum_info,
13664		.get = alc861vd_mux_enum_get,
13665		.put = alc861vd_mux_enum_put,
13666	},
13667	{ } /* end */
13668};
13669
13670/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
13671 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
13672 */
13673static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
13674	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13675	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13676
13677	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13678	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
13679
13680	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
13681				HDA_OUTPUT),
13682	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
13683				HDA_OUTPUT),
13684	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13685	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
13686
13687	HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
13688	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
13689
13690	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13691
13692	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13693	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13694	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13695
13696	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13697	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13698	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13699
13700	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13701	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13702
13703	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13704	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13705
13706	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13707	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13708
13709	{ } /* end */
13710};
13711
13712static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
13713	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13714	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13715
13716	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13717
13718	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13719	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13720	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13721
13722	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13723	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13724	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13725
13726	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13727	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13728
13729	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13730	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13731
13732	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13733	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13734
13735	{ } /* end */
13736};
13737
13738static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
13739	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13740	/*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
13741	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13742
13743	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13744
13745	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13746	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13747	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13748
13749	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13750	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13751	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13752
13753	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13754	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13755
13756	{ } /* end */
13757};
13758
13759/* Pin assignment: Speaker=0x14, HP = 0x15,
13760 *                 Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
13761 */
13762static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
13763	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13764	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
13765	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13766	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13767	HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
13768	HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13769	HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13770	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
13771	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13772	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13773	HDA_CODEC_VOLUME("PC Beep Volume", 0x0b, 0x05, HDA_INPUT),
13774	HDA_CODEC_MUTE("PC Beep Switch", 0x0b, 0x05, HDA_INPUT),
13775	{ } /* end */
13776};
13777
13778/* Pin assignment: Speaker=0x14, Line-out = 0x15,
13779 *                 Front Mic=0x18, ATAPI Mic = 0x19,
13780 */
13781static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
13782	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13783	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13784	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13785	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13786	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13787	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13788	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13789	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13790
13791	{ } /* end */
13792};
13793
13794/*
13795 * generic initialization of ADC, input mixers and output mixers
13796 */
13797static struct hda_verb alc861vd_volume_init_verbs[] = {
13798	/*
13799	 * Unmute ADC0 and set the default input to mic-in
13800	 */
13801	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13802	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13803
13804	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
13805	 * the analog-loopback mixer widget
13806	 */
13807	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13808	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13809	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13810	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13811	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13812	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13813
13814	/* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
13815	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13816	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13817	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13818	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
13819
13820	/*
13821	 * Set up output mixers (0x02 - 0x05)
13822	 */
13823	/* set vol=0 to output mixers */
13824	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13825	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13826	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13827	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13828
13829	/* set up input amps for analog loopback */
13830	/* Amp Indices: DAC = 0, mixer = 1 */
13831	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13832	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13833	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13834	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13835	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13836	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13837	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13838	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13839
13840	{ }
13841};
13842
13843/*
13844 * 3-stack pin configuration:
13845 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
13846 */
13847static struct hda_verb alc861vd_3stack_init_verbs[] = {
13848	/*
13849	 * Set pin mode and muting
13850	 */
13851	/* set front pin widgets 0x14 for output */
13852	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13853	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13854	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13855
13856	/* Mic (rear) pin: input vref at 80% */
13857	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13858	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13859	/* Front Mic pin: input vref at 80% */
13860	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13861	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13862	/* Line In pin: input */
13863	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13864	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13865	/* Line-2 In: Headphone output (output 0 - 0x0c) */
13866	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13867	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13868	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13869	/* CD pin widget for input */
13870	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13871
13872	{ }
13873};
13874
13875/*
13876 * 6-stack pin configuration:
13877 */
13878static struct hda_verb alc861vd_6stack_init_verbs[] = {
13879	/*
13880	 * Set pin mode and muting
13881	 */
13882	/* set front pin widgets 0x14 for output */
13883	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13884	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13885	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13886
13887	/* Rear Pin: output 1 (0x0d) */
13888	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13889	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13890	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13891	/* CLFE Pin: output 2 (0x0e) */
13892	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13893	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13894	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
13895	/* Side Pin: output 3 (0x0f) */
13896	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13897	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13898	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
13899
13900	/* Mic (rear) pin: input vref at 80% */
13901	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13902	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13903	/* Front Mic pin: input vref at 80% */
13904	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13905	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13906	/* Line In pin: input */
13907	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13908	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13909	/* Line-2 In: Headphone output (output 0 - 0x0c) */
13910	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13911	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13912	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13913	/* CD pin widget for input */
13914	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13915
13916	{ }
13917};
13918
13919static struct hda_verb alc861vd_eapd_verbs[] = {
13920	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13921	{ }
13922};
13923
13924static struct hda_verb alc660vd_eapd_verbs[] = {
13925	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13926	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13927	{ }
13928};
13929
13930static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
13931	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13932	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13933	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
13934	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13935	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13936	{}
13937};
13938
13939/* toggle speaker-output according to the hp-jack state */
13940static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
13941{
13942	unsigned int present;
13943	unsigned char bits;
13944
13945	present = snd_hda_codec_read(codec, 0x1b, 0,
13946				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13947	bits = present ? HDA_AMP_MUTE : 0;
13948	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13949				 HDA_AMP_MUTE, bits);
13950}
13951
13952static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
13953{
13954	unsigned int present;
13955	unsigned char bits;
13956
13957	present = snd_hda_codec_read(codec, 0x18, 0,
13958				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13959	bits = present ? HDA_AMP_MUTE : 0;
13960	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
13961				 HDA_AMP_MUTE, bits);
13962}
13963
13964static void alc861vd_lenovo_automute(struct hda_codec *codec)
13965{
13966	alc861vd_lenovo_hp_automute(codec);
13967	alc861vd_lenovo_mic_automute(codec);
13968}
13969
13970static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
13971					unsigned int res)
13972{
13973	switch (res >> 26) {
13974	case ALC880_HP_EVENT:
13975		alc861vd_lenovo_hp_automute(codec);
13976		break;
13977	case ALC880_MIC_EVENT:
13978		alc861vd_lenovo_mic_automute(codec);
13979		break;
13980	}
13981}
13982
13983static struct hda_verb alc861vd_dallas_verbs[] = {
13984	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13985	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13986	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13987	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13988
13989	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13990	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13991	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13992	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13993	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13994	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13995	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13996	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13997
13998	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13999	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14000	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14001	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14002	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14003	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14004	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14005	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14006
14007	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14008	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14009	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14010	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14011	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14012	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14013	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14014	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14015
14016	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14017	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14018	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14019	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14020
14021	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14022	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14023	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14024
14025	{ } /* end */
14026};
14027
14028/* toggle speaker-output according to the hp-jack state */
14029static void alc861vd_dallas_automute(struct hda_codec *codec)
14030{
14031	unsigned int present;
14032
14033	present = snd_hda_codec_read(codec, 0x15, 0,
14034				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14035	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14036				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
14037}
14038
14039static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
14040{
14041	if ((res >> 26) == ALC880_HP_EVENT)
14042		alc861vd_dallas_automute(codec);
14043}
14044
14045#ifdef CONFIG_SND_HDA_POWER_SAVE
14046#define alc861vd_loopbacks	alc880_loopbacks
14047#endif
14048
14049/* pcm configuration: identiacal with ALC880 */
14050#define alc861vd_pcm_analog_playback	alc880_pcm_analog_playback
14051#define alc861vd_pcm_analog_capture	alc880_pcm_analog_capture
14052#define alc861vd_pcm_digital_playback	alc880_pcm_digital_playback
14053#define alc861vd_pcm_digital_capture	alc880_pcm_digital_capture
14054
14055/*
14056 * configuration and preset
14057 */
14058static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14059	[ALC660VD_3ST]		= "3stack-660",
14060	[ALC660VD_3ST_DIG]	= "3stack-660-digout",
14061	[ALC861VD_3ST]		= "3stack",
14062	[ALC861VD_3ST_DIG]	= "3stack-digout",
14063	[ALC861VD_6ST_DIG]	= "6stack-digout",
14064	[ALC861VD_LENOVO]	= "lenovo",
14065	[ALC861VD_DALLAS]	= "dallas",
14066	[ALC861VD_HP]		= "hp",
14067	[ALC861VD_AUTO]		= "auto",
14068};
14069
14070static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
14071	SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14072	SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
14073	SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
14074	SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
14075	SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC861VD_LENOVO),
14076	SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
14077	SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
14078	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
14079	/*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
14080	SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
14081	SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
14082	SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
14083	SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
14084	SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
14085	SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
14086	SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO),
14087	SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
14088	{}
14089};
14090
14091static struct alc_config_preset alc861vd_presets[] = {
14092	[ALC660VD_3ST] = {
14093		.mixers = { alc861vd_3st_mixer },
14094		.init_verbs = { alc861vd_volume_init_verbs,
14095				 alc861vd_3stack_init_verbs },
14096		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14097		.dac_nids = alc660vd_dac_nids,
14098		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14099		.channel_mode = alc861vd_3stack_2ch_modes,
14100		.input_mux = &alc861vd_capture_source,
14101	},
14102	[ALC660VD_3ST_DIG] = {
14103		.mixers = { alc861vd_3st_mixer },
14104		.init_verbs = { alc861vd_volume_init_verbs,
14105				 alc861vd_3stack_init_verbs },
14106		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14107		.dac_nids = alc660vd_dac_nids,
14108		.dig_out_nid = ALC861VD_DIGOUT_NID,
14109		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14110		.channel_mode = alc861vd_3stack_2ch_modes,
14111		.input_mux = &alc861vd_capture_source,
14112	},
14113	[ALC861VD_3ST] = {
14114		.mixers = { alc861vd_3st_mixer },
14115		.init_verbs = { alc861vd_volume_init_verbs,
14116				 alc861vd_3stack_init_verbs },
14117		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14118		.dac_nids = alc861vd_dac_nids,
14119		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14120		.channel_mode = alc861vd_3stack_2ch_modes,
14121		.input_mux = &alc861vd_capture_source,
14122	},
14123	[ALC861VD_3ST_DIG] = {
14124		.mixers = { alc861vd_3st_mixer },
14125		.init_verbs = { alc861vd_volume_init_verbs,
14126		 		 alc861vd_3stack_init_verbs },
14127		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14128		.dac_nids = alc861vd_dac_nids,
14129		.dig_out_nid = ALC861VD_DIGOUT_NID,
14130		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14131		.channel_mode = alc861vd_3stack_2ch_modes,
14132		.input_mux = &alc861vd_capture_source,
14133	},
14134	[ALC861VD_6ST_DIG] = {
14135		.mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14136		.init_verbs = { alc861vd_volume_init_verbs,
14137				alc861vd_6stack_init_verbs },
14138		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14139		.dac_nids = alc861vd_dac_nids,
14140		.dig_out_nid = ALC861VD_DIGOUT_NID,
14141		.num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14142		.channel_mode = alc861vd_6stack_modes,
14143		.input_mux = &alc861vd_capture_source,
14144	},
14145	[ALC861VD_LENOVO] = {
14146		.mixers = { alc861vd_lenovo_mixer },
14147		.init_verbs = { alc861vd_volume_init_verbs,
14148				alc861vd_3stack_init_verbs,
14149				alc861vd_eapd_verbs,
14150				alc861vd_lenovo_unsol_verbs },
14151		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14152		.dac_nids = alc660vd_dac_nids,
14153		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14154		.channel_mode = alc861vd_3stack_2ch_modes,
14155		.input_mux = &alc861vd_capture_source,
14156		.unsol_event = alc861vd_lenovo_unsol_event,
14157		.init_hook = alc861vd_lenovo_automute,
14158	},
14159	[ALC861VD_DALLAS] = {
14160		.mixers = { alc861vd_dallas_mixer },
14161		.init_verbs = { alc861vd_dallas_verbs },
14162		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14163		.dac_nids = alc861vd_dac_nids,
14164		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14165		.channel_mode = alc861vd_3stack_2ch_modes,
14166		.input_mux = &alc861vd_dallas_capture_source,
14167		.unsol_event = alc861vd_dallas_unsol_event,
14168		.init_hook = alc861vd_dallas_automute,
14169	},
14170	[ALC861VD_HP] = {
14171		.mixers = { alc861vd_hp_mixer },
14172		.init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14173		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14174		.dac_nids = alc861vd_dac_nids,
14175		.dig_out_nid = ALC861VD_DIGOUT_NID,
14176		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14177		.channel_mode = alc861vd_3stack_2ch_modes,
14178		.input_mux = &alc861vd_hp_capture_source,
14179		.unsol_event = alc861vd_dallas_unsol_event,
14180		.init_hook = alc861vd_dallas_automute,
14181	},
14182};
14183
14184/*
14185 * BIOS auto configuration
14186 */
14187static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14188				hda_nid_t nid, int pin_type, int dac_idx)
14189{
14190	alc_set_pin_output(codec, nid, pin_type);
14191}
14192
14193static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14194{
14195	struct alc_spec *spec = codec->spec;
14196	int i;
14197
14198	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
14199	for (i = 0; i <= HDA_SIDE; i++) {
14200		hda_nid_t nid = spec->autocfg.line_out_pins[i];
14201		int pin_type = get_pin_type(spec->autocfg.line_out_type);
14202		if (nid)
14203			alc861vd_auto_set_output_and_unmute(codec, nid,
14204							    pin_type, i);
14205	}
14206}
14207
14208
14209static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14210{
14211	struct alc_spec *spec = codec->spec;
14212	hda_nid_t pin;
14213
14214	pin = spec->autocfg.hp_pins[0];
14215	if (pin) /* connect to front and  use dac 0 */
14216		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
14217	pin = spec->autocfg.speaker_pins[0];
14218	if (pin)
14219		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14220}
14221
14222#define alc861vd_is_input_pin(nid)	alc880_is_input_pin(nid)
14223#define ALC861VD_PIN_CD_NID		ALC880_PIN_CD_NID
14224
14225static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14226{
14227	struct alc_spec *spec = codec->spec;
14228	int i;
14229
14230	for (i = 0; i < AUTO_PIN_LAST; i++) {
14231		hda_nid_t nid = spec->autocfg.input_pins[i];
14232		if (alc861vd_is_input_pin(nid)) {
14233			snd_hda_codec_write(codec, nid, 0,
14234					AC_VERB_SET_PIN_WIDGET_CONTROL,
14235					i <= AUTO_PIN_FRONT_MIC ?
14236							PIN_VREF80 : PIN_IN);
14237			if (nid != ALC861VD_PIN_CD_NID)
14238				snd_hda_codec_write(codec, nid, 0,
14239						AC_VERB_SET_AMP_GAIN_MUTE,
14240						AMP_OUT_MUTE);
14241		}
14242	}
14243}
14244
14245#define alc861vd_auto_init_input_src	alc882_auto_init_input_src
14246
14247#define alc861vd_idx_to_mixer_vol(nid)		((nid) + 0x02)
14248#define alc861vd_idx_to_mixer_switch(nid)	((nid) + 0x0c)
14249
14250/* add playback controls from the parsed DAC table */
14251/* Based on ALC880 version. But ALC861VD has separate,
14252 * different NIDs for mute/unmute switch and volume control */
14253static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14254					     const struct auto_pin_cfg *cfg)
14255{
14256	char name[32];
14257	static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14258	hda_nid_t nid_v, nid_s;
14259	int i, err;
14260
14261	for (i = 0; i < cfg->line_outs; i++) {
14262		if (!spec->multiout.dac_nids[i])
14263			continue;
14264		nid_v = alc861vd_idx_to_mixer_vol(
14265				alc880_dac_to_idx(
14266					spec->multiout.dac_nids[i]));
14267		nid_s = alc861vd_idx_to_mixer_switch(
14268				alc880_dac_to_idx(
14269					spec->multiout.dac_nids[i]));
14270
14271		if (i == 2) {
14272			/* Center/LFE */
14273			err = add_control(spec, ALC_CTL_WIDGET_VOL,
14274					  "Center Playback Volume",
14275					  HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14276							      HDA_OUTPUT));
14277			if (err < 0)
14278				return err;
14279			err = add_control(spec, ALC_CTL_WIDGET_VOL,
14280					  "LFE Playback Volume",
14281					  HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14282							      HDA_OUTPUT));
14283			if (err < 0)
14284				return err;
14285			err = add_control(spec, ALC_CTL_BIND_MUTE,
14286					  "Center Playback Switch",
14287					  HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14288							      HDA_INPUT));
14289			if (err < 0)
14290				return err;
14291			err = add_control(spec, ALC_CTL_BIND_MUTE,
14292					  "LFE Playback Switch",
14293					  HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14294							      HDA_INPUT));
14295			if (err < 0)
14296				return err;
14297		} else {
14298			sprintf(name, "%s Playback Volume", chname[i]);
14299			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14300					  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14301							      HDA_OUTPUT));
14302			if (err < 0)
14303				return err;
14304			sprintf(name, "%s Playback Switch", chname[i]);
14305			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14306					  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
14307							      HDA_INPUT));
14308			if (err < 0)
14309				return err;
14310		}
14311	}
14312	return 0;
14313}
14314
14315/* add playback controls for speaker and HP outputs */
14316/* Based on ALC880 version. But ALC861VD has separate,
14317 * different NIDs for mute/unmute switch and volume control */
14318static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
14319					hda_nid_t pin, const char *pfx)
14320{
14321	hda_nid_t nid_v, nid_s;
14322	int err;
14323	char name[32];
14324
14325	if (!pin)
14326		return 0;
14327
14328	if (alc880_is_fixed_pin(pin)) {
14329		nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14330		/* specify the DAC as the extra output */
14331		if (!spec->multiout.hp_nid)
14332			spec->multiout.hp_nid = nid_v;
14333		else
14334			spec->multiout.extra_out_nid[0] = nid_v;
14335		/* control HP volume/switch on the output mixer amp */
14336		nid_v = alc861vd_idx_to_mixer_vol(
14337				alc880_fixed_pin_idx(pin));
14338		nid_s = alc861vd_idx_to_mixer_switch(
14339				alc880_fixed_pin_idx(pin));
14340
14341		sprintf(name, "%s Playback Volume", pfx);
14342		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14343				  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
14344		if (err < 0)
14345			return err;
14346		sprintf(name, "%s Playback Switch", pfx);
14347		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14348				  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
14349		if (err < 0)
14350			return err;
14351	} else if (alc880_is_multi_pin(pin)) {
14352		/* set manual connection */
14353		/* we have only a switch on HP-out PIN */
14354		sprintf(name, "%s Playback Switch", pfx);
14355		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14356				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
14357		if (err < 0)
14358			return err;
14359	}
14360	return 0;
14361}
14362
14363/* parse the BIOS configuration and set up the alc_spec
14364 * return 1 if successful, 0 if the proper config is not found,
14365 * or a negative error code
14366 * Based on ALC880 version - had to change it to override
14367 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
14368static int alc861vd_parse_auto_config(struct hda_codec *codec)
14369{
14370	struct alc_spec *spec = codec->spec;
14371	int err;
14372	static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
14373
14374	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14375					   alc861vd_ignore);
14376	if (err < 0)
14377		return err;
14378	if (!spec->autocfg.line_outs)
14379		return 0; /* can't find valid BIOS pin config */
14380
14381	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
14382	if (err < 0)
14383		return err;
14384	err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
14385	if (err < 0)
14386		return err;
14387	err = alc861vd_auto_create_extra_out(spec,
14388					     spec->autocfg.speaker_pins[0],
14389					     "Speaker");
14390	if (err < 0)
14391		return err;
14392	err = alc861vd_auto_create_extra_out(spec,
14393					     spec->autocfg.hp_pins[0],
14394					     "Headphone");
14395	if (err < 0)
14396		return err;
14397	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
14398	if (err < 0)
14399		return err;
14400
14401	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14402
14403	if (spec->autocfg.dig_out_pin)
14404		spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
14405
14406	if (spec->kctl_alloc)
14407		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
14408
14409	spec->init_verbs[spec->num_init_verbs++]
14410		= alc861vd_volume_init_verbs;
14411
14412	spec->num_mux_defs = 1;
14413	spec->input_mux = &spec->private_imux;
14414
14415	err = alc_auto_add_mic_boost(codec);
14416	if (err < 0)
14417		return err;
14418
14419	return 1;
14420}
14421
14422/* additional initialization for auto-configuration model */
14423static void alc861vd_auto_init(struct hda_codec *codec)
14424{
14425	struct alc_spec *spec = codec->spec;
14426	alc861vd_auto_init_multi_out(codec);
14427	alc861vd_auto_init_hp_out(codec);
14428	alc861vd_auto_init_analog_input(codec);
14429	alc861vd_auto_init_input_src(codec);
14430	if (spec->unsol_event)
14431		alc_inithook(codec);
14432}
14433
14434static int patch_alc861vd(struct hda_codec *codec)
14435{
14436	struct alc_spec *spec;
14437	int err, board_config;
14438
14439	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14440	if (spec == NULL)
14441		return -ENOMEM;
14442
14443	codec->spec = spec;
14444
14445	board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
14446						  alc861vd_models,
14447						  alc861vd_cfg_tbl);
14448
14449	if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
14450		printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
14451			"ALC861VD, trying auto-probe from BIOS...\n");
14452		board_config = ALC861VD_AUTO;
14453	}
14454
14455	if (board_config == ALC861VD_AUTO) {
14456		/* automatic parse from the BIOS config */
14457		err = alc861vd_parse_auto_config(codec);
14458		if (err < 0) {
14459			alc_free(codec);
14460			return err;
14461		} else if (!err) {
14462			printk(KERN_INFO
14463			       "hda_codec: Cannot set up configuration "
14464			       "from BIOS.  Using base mode...\n");
14465			board_config = ALC861VD_3ST;
14466		}
14467	}
14468
14469	if (board_config != ALC861VD_AUTO)
14470		setup_preset(spec, &alc861vd_presets[board_config]);
14471
14472	if (codec->vendor_id == 0x10ec0660) {
14473		spec->stream_name_analog = "ALC660-VD Analog";
14474		spec->stream_name_digital = "ALC660-VD Digital";
14475		/* always turn on EAPD */
14476		spec->init_verbs[spec->num_init_verbs++] = alc660vd_eapd_verbs;
14477	} else {
14478		spec->stream_name_analog = "ALC861VD Analog";
14479		spec->stream_name_digital = "ALC861VD Digital";
14480	}
14481
14482	spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
14483	spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
14484
14485	spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
14486	spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
14487
14488	spec->adc_nids = alc861vd_adc_nids;
14489	spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
14490	spec->capsrc_nids = alc861vd_capsrc_nids;
14491
14492	spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
14493	spec->num_mixers++;
14494
14495	spec->vmaster_nid = 0x02;
14496
14497	codec->patch_ops = alc_patch_ops;
14498
14499	if (board_config == ALC861VD_AUTO)
14500		spec->init_hook = alc861vd_auto_init;
14501#ifdef CONFIG_SND_HDA_POWER_SAVE
14502	if (!spec->loopback.amplist)
14503		spec->loopback.amplist = alc861vd_loopbacks;
14504#endif
14505
14506	return 0;
14507}
14508
14509/*
14510 * ALC662 support
14511 *
14512 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
14513 * configuration.  Each pin widget can choose any input DACs and a mixer.
14514 * Each ADC is connected from a mixer of all inputs.  This makes possible
14515 * 6-channel independent captures.
14516 *
14517 * In addition, an independent DAC for the multi-playback (not used in this
14518 * driver yet).
14519 */
14520#define ALC662_DIGOUT_NID	0x06
14521#define ALC662_DIGIN_NID	0x0a
14522
14523static hda_nid_t alc662_dac_nids[4] = {
14524	/* front, rear, clfe, rear_surr */
14525	0x02, 0x03, 0x04
14526};
14527
14528static hda_nid_t alc662_adc_nids[1] = {
14529	/* ADC1-2 */
14530	0x09,
14531};
14532
14533static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
14534
14535/* input MUX */
14536/* FIXME: should be a matrix-type input source selection */
14537static struct hda_input_mux alc662_capture_source = {
14538	.num_items = 4,
14539	.items = {
14540		{ "Mic", 0x0 },
14541		{ "Front Mic", 0x1 },
14542		{ "Line", 0x2 },
14543		{ "CD", 0x4 },
14544	},
14545};
14546
14547static struct hda_input_mux alc662_lenovo_101e_capture_source = {
14548	.num_items = 2,
14549	.items = {
14550		{ "Mic", 0x1 },
14551		{ "Line", 0x2 },
14552	},
14553};
14554
14555static struct hda_input_mux alc662_eeepc_capture_source = {
14556	.num_items = 2,
14557	.items = {
14558		{ "i-Mic", 0x1 },
14559		{ "e-Mic", 0x0 },
14560	},
14561};
14562
14563static struct hda_input_mux alc663_capture_source = {
14564	.num_items = 3,
14565	.items = {
14566		{ "Mic", 0x0 },
14567		{ "Front Mic", 0x1 },
14568		{ "Line", 0x2 },
14569	},
14570};
14571
14572static struct hda_input_mux alc663_m51va_capture_source = {
14573	.num_items = 2,
14574	.items = {
14575		{ "Ext-Mic", 0x0 },
14576		{ "D-Mic", 0x9 },
14577	},
14578};
14579
14580#define alc662_mux_enum_info alc_mux_enum_info
14581#define alc662_mux_enum_get alc_mux_enum_get
14582#define alc662_mux_enum_put alc882_mux_enum_put
14583
14584/*
14585 * 2ch mode
14586 */
14587static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
14588	{ 2, NULL }
14589};
14590
14591/*
14592 * 2ch mode
14593 */
14594static struct hda_verb alc662_3ST_ch2_init[] = {
14595	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
14596	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14597	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
14598	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14599	{ } /* end */
14600};
14601
14602/*
14603 * 6ch mode
14604 */
14605static struct hda_verb alc662_3ST_ch6_init[] = {
14606	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14607	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14608	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
14609	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14610	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14611	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
14612	{ } /* end */
14613};
14614
14615static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
14616	{ 2, alc662_3ST_ch2_init },
14617	{ 6, alc662_3ST_ch6_init },
14618};
14619
14620/*
14621 * 2ch mode
14622 */
14623static struct hda_verb alc662_sixstack_ch6_init[] = {
14624	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14625	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14626	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14627	{ } /* end */
14628};
14629
14630/*
14631 * 6ch mode
14632 */
14633static struct hda_verb alc662_sixstack_ch8_init[] = {
14634	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14635	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14636	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14637	{ } /* end */
14638};
14639
14640static struct hda_channel_mode alc662_5stack_modes[2] = {
14641	{ 2, alc662_sixstack_ch6_init },
14642	{ 6, alc662_sixstack_ch8_init },
14643};
14644
14645/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14646 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14647 */
14648
14649static struct snd_kcontrol_new alc662_base_mixer[] = {
14650	/* output mixer control */
14651	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
14652	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14653	HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
14654	HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14655	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14656	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14657	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14658	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14659	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14660
14661	/*Input mixer control */
14662	HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
14663	HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
14664	HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
14665	HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
14666	HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
14667	HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
14668	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
14669	HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
14670	{ } /* end */
14671};
14672
14673static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
14674	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14675	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14676	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14677	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14678	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14679	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14680	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14681	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14682	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14683	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14684	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14685	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14686	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14687	{ } /* end */
14688};
14689
14690static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
14691	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14692	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14693	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14694	HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14695	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14696	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14697	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14698	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14699	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14700	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14701	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14702	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14703	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14704	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14705	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14706	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14707	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14708	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14709	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14710	{ } /* end */
14711};
14712
14713static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
14714	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14715	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
14716	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14717	HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
14718	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14719	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14720	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14721	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14722	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14723	{ } /* end */
14724};
14725
14726static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
14727	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14728
14729	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14730	HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14731
14732	HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
14733	HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14734	HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14735
14736	HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
14737	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14738	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14739	{ } /* end */
14740};
14741
14742static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
14743	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14744	HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14745	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14746	HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
14747	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14748	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14749	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
14750	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
14751	HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14752	HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
14753	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14754	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14755	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14756	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14757	{ } /* end */
14758};
14759
14760static struct hda_bind_ctls alc663_asus_bind_master_vol = {
14761	.ops = &snd_hda_bind_vol,
14762	.values = {
14763		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14764		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
14765		0
14766	},
14767};
14768
14769static struct hda_bind_ctls alc663_asus_one_bind_switch = {
14770	.ops = &snd_hda_bind_sw,
14771	.values = {
14772		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14773		HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14774		0
14775	},
14776};
14777
14778static struct snd_kcontrol_new alc663_m51va_mixer[] = {
14779	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14780	HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
14781	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14782	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14783	{ } /* end */
14784};
14785
14786static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
14787	.ops = &snd_hda_bind_sw,
14788	.values = {
14789		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14790		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14791		HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14792		0
14793	},
14794};
14795
14796static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
14797	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14798	HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
14799	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14800	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14801	HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14802	HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14803
14804	{ } /* end */
14805};
14806
14807static struct hda_bind_ctls alc663_asus_four_bind_switch = {
14808	.ops = &snd_hda_bind_sw,
14809	.values = {
14810		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14811		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14812		HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
14813		0
14814	},
14815};
14816
14817static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
14818	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14819	HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
14820	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14821	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14822	HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14823	HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14824	{ } /* end */
14825};
14826
14827static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
14828	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14829	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14830	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14831	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14832	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14833	HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14834	HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14835	{ } /* end */
14836};
14837
14838static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
14839	.ops = &snd_hda_bind_vol,
14840	.values = {
14841		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14842		HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
14843		0
14844	},
14845};
14846
14847static struct hda_bind_ctls alc663_asus_two_bind_switch = {
14848	.ops = &snd_hda_bind_sw,
14849	.values = {
14850		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14851		HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
14852		0
14853	},
14854};
14855
14856static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
14857	HDA_BIND_VOL("Master Playback Volume",
14858				&alc663_asus_two_bind_master_vol),
14859	HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14860	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14861	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14862	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14863	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14864	{ } /* end */
14865};
14866
14867static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
14868	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14869	HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14870	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14871	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14872	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14873	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14874	{ } /* end */
14875};
14876
14877static struct snd_kcontrol_new alc663_g71v_mixer[] = {
14878	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14879	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14880	HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14881	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14882	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14883
14884	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14885	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14886	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14887	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14888	{ } /* end */
14889};
14890
14891static struct snd_kcontrol_new alc663_g50v_mixer[] = {
14892	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14893	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14894	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14895
14896	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14897	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14898	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14899	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14900	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14901	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14902	{ } /* end */
14903};
14904
14905static struct snd_kcontrol_new alc662_chmode_mixer[] = {
14906	{
14907		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14908		.name = "Channel Mode",
14909		.info = alc_ch_mode_info,
14910		.get = alc_ch_mode_get,
14911		.put = alc_ch_mode_put,
14912	},
14913	{ } /* end */
14914};
14915
14916static struct hda_verb alc662_init_verbs[] = {
14917	/* ADC: mute amp left and right */
14918	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14919	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14920	/* Front mixer: unmute input/output amp left and right (volume = 0) */
14921
14922	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14923	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14924	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14925	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14926	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14927
14928	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14929	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14930	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14931	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14932	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14933	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14934
14935	/* Front Pin: output 0 (0x0c) */
14936	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14937	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14938
14939	/* Rear Pin: output 1 (0x0d) */
14940	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14941	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14942
14943	/* CLFE Pin: output 2 (0x0e) */
14944	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14945	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14946
14947	/* Mic (rear) pin: input vref at 80% */
14948	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14949	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14950	/* Front Mic pin: input vref at 80% */
14951	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14952	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14953	/* Line In pin: input */
14954	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14955	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14956	/* Line-2 In: Headphone output (output 0 - 0x0c) */
14957	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14958	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14959	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14960	/* CD pin widget for input */
14961	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14962
14963	/* FIXME: use matrix-type input source selection */
14964	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
14965	/* Input mixer */
14966	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14967	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14968	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14969	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14970
14971	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14972	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14973	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14974	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14975
14976	/* always trun on EAPD */
14977	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14978	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14979
14980	{ }
14981};
14982
14983static struct hda_verb alc662_sue_init_verbs[] = {
14984	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
14985	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
14986	{}
14987};
14988
14989static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
14990	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14991	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14992	{}
14993};
14994
14995/* Set Unsolicited Event*/
14996static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
14997	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14998	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14999	{}
15000};
15001
15002/*
15003 * generic initialization of ADC, input mixers and output mixers
15004 */
15005static struct hda_verb alc662_auto_init_verbs[] = {
15006	/*
15007	 * Unmute ADC and set the default input to mic-in
15008	 */
15009	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15010	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15011
15012	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
15013	 * mixer widget
15014	 * Note: PASD motherboards uses the Line In 2 as the input for front
15015	 * panel mic (mic 2)
15016	 */
15017	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
15018	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15019	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15020	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15021	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15022	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15023
15024	/*
15025	 * Set up output mixers (0x0c - 0x0f)
15026	 */
15027	/* set vol=0 to output mixers */
15028	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15029	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15030	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15031
15032	/* set up input amps for analog loopback */
15033	/* Amp Indices: DAC = 0, mixer = 1 */
15034	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15035	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15036	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15037	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15038	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15039	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15040
15041
15042	/* FIXME: use matrix-type input source selection */
15043	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15044	/* Input mixer */
15045	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15046	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15047	{ }
15048};
15049
15050/* additional verbs for ALC663 */
15051static struct hda_verb alc663_auto_init_verbs[] = {
15052	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15053	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15054	{ }
15055};
15056
15057static struct hda_verb alc663_m51va_init_verbs[] = {
15058	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15059	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15060	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15061	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15062	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
15063	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15064	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15065	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15066	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15067	{}
15068};
15069
15070static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15071	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15072	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15073	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
15074	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15075	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15076	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15077	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15078	{}
15079};
15080
15081static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15082	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15083	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15084	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15085	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
15086	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15087	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15088	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15089	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15090	{}
15091};
15092
15093static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15094	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15095	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15096	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
15097	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15098	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15099	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15100	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15101	{}
15102};
15103
15104static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15105	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15106	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15107	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15108	{0x21, AC_VERB_SET_CONNECT_SEL, 0x0},	/* Headphone */
15109	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15110	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15111	{0x15, AC_VERB_SET_CONNECT_SEL, 0x0},	/* Headphone */
15112	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15113	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15114	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15115	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15116	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15117	{}
15118};
15119
15120static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15121	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15122	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15123	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15124	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
15125	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15126	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15127	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
15128	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15129	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15130	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15131	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15132	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15133	{}
15134};
15135
15136static struct hda_verb alc663_g71v_init_verbs[] = {
15137	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15138	/* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15139	/* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15140
15141	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15142	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15143	{0x21, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
15144
15145	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15146	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15147	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15148	{}
15149};
15150
15151static struct hda_verb alc663_g50v_init_verbs[] = {
15152	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15153	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15154	{0x21, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
15155
15156	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15157	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15158	{}
15159};
15160
15161static struct hda_verb alc662_ecs_init_verbs[] = {
15162	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15163	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15164	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15165	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15166	{}
15167};
15168
15169/* capture mixer elements */
15170static struct snd_kcontrol_new alc662_capture_mixer[] = {
15171	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15172	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15173	{
15174		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15175		/* The multiple "Capture Source" controls confuse alsamixer
15176		 * So call somewhat different..
15177		 */
15178		/* .name = "Capture Source", */
15179		.name = "Input Source",
15180		.count = 1,
15181		.info = alc662_mux_enum_info,
15182		.get = alc662_mux_enum_get,
15183		.put = alc662_mux_enum_put,
15184	},
15185	{ } /* end */
15186};
15187
15188static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15189	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15190	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15191	{ } /* end */
15192};
15193
15194static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15195{
15196	unsigned int present;
15197	unsigned char bits;
15198
15199	present = snd_hda_codec_read(codec, 0x14, 0,
15200				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15201	bits = present ? HDA_AMP_MUTE : 0;
15202	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15203				 HDA_AMP_MUTE, bits);
15204}
15205
15206static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15207{
15208	unsigned int present;
15209	unsigned char bits;
15210
15211 	present = snd_hda_codec_read(codec, 0x1b, 0,
15212				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15213	bits = present ? HDA_AMP_MUTE : 0;
15214	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15215				 HDA_AMP_MUTE, bits);
15216	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15217				 HDA_AMP_MUTE, bits);
15218}
15219
15220static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15221					   unsigned int res)
15222{
15223	if ((res >> 26) == ALC880_HP_EVENT)
15224		alc662_lenovo_101e_all_automute(codec);
15225	if ((res >> 26) == ALC880_FRONT_EVENT)
15226		alc662_lenovo_101e_ispeaker_automute(codec);
15227}
15228
15229static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15230{
15231	unsigned int present;
15232
15233	present = snd_hda_codec_read(codec, 0x18, 0,
15234				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15235	snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15236			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15237	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15238			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15239	snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15240			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15241	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15242			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15243}
15244
15245/* unsolicited event for HP jack sensing */
15246static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15247				     unsigned int res)
15248{
15249	if ((res >> 26) == ALC880_HP_EVENT)
15250		alc262_hippo1_automute( codec );
15251
15252	if ((res >> 26) == ALC880_MIC_EVENT)
15253		alc662_eeepc_mic_automute(codec);
15254}
15255
15256static void alc662_eeepc_inithook(struct hda_codec *codec)
15257{
15258	alc262_hippo1_automute( codec );
15259	alc662_eeepc_mic_automute(codec);
15260}
15261
15262static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
15263{
15264	unsigned int mute;
15265	unsigned int present;
15266
15267	snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
15268	present = snd_hda_codec_read(codec, 0x14, 0,
15269				     AC_VERB_GET_PIN_SENSE, 0);
15270	present = (present & 0x80000000) != 0;
15271	if (present) {
15272		/* mute internal speaker */
15273		snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15274					HDA_AMP_MUTE, HDA_AMP_MUTE);
15275	} else {
15276		/* unmute internal speaker if necessary */
15277		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
15278		snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15279					HDA_AMP_MUTE, mute);
15280	}
15281}
15282
15283/* unsolicited event for HP jack sensing */
15284static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
15285					  unsigned int res)
15286{
15287	if ((res >> 26) == ALC880_HP_EVENT)
15288		alc662_eeepc_ep20_automute(codec);
15289}
15290
15291static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
15292{
15293	alc662_eeepc_ep20_automute(codec);
15294}
15295
15296static void alc663_m51va_speaker_automute(struct hda_codec *codec)
15297{
15298	unsigned int present;
15299	unsigned char bits;
15300
15301	present = snd_hda_codec_read(codec, 0x21, 0,
15302			AC_VERB_GET_PIN_SENSE, 0)
15303			& AC_PINSENSE_PRESENCE;
15304	bits = present ? HDA_AMP_MUTE : 0;
15305	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15306				AMP_IN_MUTE(0), bits);
15307	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15308				AMP_IN_MUTE(0), bits);
15309}
15310
15311static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
15312{
15313	unsigned int present;
15314	unsigned char bits;
15315
15316	present = snd_hda_codec_read(codec, 0x21, 0,
15317			AC_VERB_GET_PIN_SENSE, 0)
15318			& AC_PINSENSE_PRESENCE;
15319	bits = present ? HDA_AMP_MUTE : 0;
15320	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15321				AMP_IN_MUTE(0), bits);
15322	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15323				AMP_IN_MUTE(0), bits);
15324	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15325				AMP_IN_MUTE(0), bits);
15326	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15327				AMP_IN_MUTE(0), bits);
15328}
15329
15330static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
15331{
15332	unsigned int present;
15333	unsigned char bits;
15334
15335	present = snd_hda_codec_read(codec, 0x15, 0,
15336			AC_VERB_GET_PIN_SENSE, 0)
15337			& AC_PINSENSE_PRESENCE;
15338	bits = present ? HDA_AMP_MUTE : 0;
15339	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15340				AMP_IN_MUTE(0), bits);
15341	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15342				AMP_IN_MUTE(0), bits);
15343	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15344				AMP_IN_MUTE(0), bits);
15345	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15346				AMP_IN_MUTE(0), bits);
15347}
15348
15349static void alc662_f5z_speaker_automute(struct hda_codec *codec)
15350{
15351	unsigned int present;
15352	unsigned char bits;
15353
15354	present = snd_hda_codec_read(codec, 0x1b, 0,
15355			AC_VERB_GET_PIN_SENSE, 0)
15356			& AC_PINSENSE_PRESENCE;
15357	bits = present ? 0 : PIN_OUT;
15358	snd_hda_codec_write(codec, 0x14, 0,
15359			 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
15360}
15361
15362static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
15363{
15364	unsigned int present1, present2;
15365
15366	present1 = snd_hda_codec_read(codec, 0x21, 0,
15367			AC_VERB_GET_PIN_SENSE, 0)
15368			& AC_PINSENSE_PRESENCE;
15369	present2 = snd_hda_codec_read(codec, 0x15, 0,
15370			AC_VERB_GET_PIN_SENSE, 0)
15371			& AC_PINSENSE_PRESENCE;
15372
15373	if (present1 || present2) {
15374		snd_hda_codec_write_cache(codec, 0x14, 0,
15375			AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
15376	} else {
15377		snd_hda_codec_write_cache(codec, 0x14, 0,
15378			AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
15379	}
15380}
15381
15382static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
15383{
15384	unsigned int present1, present2;
15385
15386	present1 = snd_hda_codec_read(codec, 0x1b, 0,
15387				AC_VERB_GET_PIN_SENSE, 0)
15388				& AC_PINSENSE_PRESENCE;
15389	present2 = snd_hda_codec_read(codec, 0x15, 0,
15390				AC_VERB_GET_PIN_SENSE, 0)
15391				& AC_PINSENSE_PRESENCE;
15392
15393	if (present1 || present2) {
15394		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15395				AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15396		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15397				AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15398	} else {
15399		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15400				AMP_IN_MUTE(0), 0);
15401		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15402				AMP_IN_MUTE(0), 0);
15403	}
15404}
15405
15406static void alc663_m51va_mic_automute(struct hda_codec *codec)
15407{
15408	unsigned int present;
15409
15410	present = snd_hda_codec_read(codec, 0x18, 0,
15411			AC_VERB_GET_PIN_SENSE, 0)
15412			& AC_PINSENSE_PRESENCE;
15413	snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15414			0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15415	snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15416			0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15417	snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15418			0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15419	snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15420			0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15421}
15422
15423static void alc663_m51va_unsol_event(struct hda_codec *codec,
15424					   unsigned int res)
15425{
15426	switch (res >> 26) {
15427	case ALC880_HP_EVENT:
15428		alc663_m51va_speaker_automute(codec);
15429		break;
15430	case ALC880_MIC_EVENT:
15431		alc663_m51va_mic_automute(codec);
15432		break;
15433	}
15434}
15435
15436static void alc663_m51va_inithook(struct hda_codec *codec)
15437{
15438	alc663_m51va_speaker_automute(codec);
15439	alc663_m51va_mic_automute(codec);
15440}
15441
15442/* ***************** Mode1 ******************************/
15443static void alc663_mode1_unsol_event(struct hda_codec *codec,
15444					   unsigned int res)
15445{
15446	switch (res >> 26) {
15447	case ALC880_HP_EVENT:
15448		alc663_m51va_speaker_automute(codec);
15449		break;
15450	case ALC880_MIC_EVENT:
15451		alc662_eeepc_mic_automute(codec);
15452		break;
15453	}
15454}
15455
15456static void alc663_mode1_inithook(struct hda_codec *codec)
15457{
15458	alc663_m51va_speaker_automute(codec);
15459	alc662_eeepc_mic_automute(codec);
15460}
15461/* ***************** Mode2 ******************************/
15462static void alc662_mode2_unsol_event(struct hda_codec *codec,
15463					   unsigned int res)
15464{
15465	switch (res >> 26) {
15466	case ALC880_HP_EVENT:
15467		alc662_f5z_speaker_automute(codec);
15468		break;
15469	case ALC880_MIC_EVENT:
15470		alc662_eeepc_mic_automute(codec);
15471		break;
15472	}
15473}
15474
15475static void alc662_mode2_inithook(struct hda_codec *codec)
15476{
15477	alc662_f5z_speaker_automute(codec);
15478	alc662_eeepc_mic_automute(codec);
15479}
15480/* ***************** Mode3 ******************************/
15481static void alc663_mode3_unsol_event(struct hda_codec *codec,
15482					   unsigned int res)
15483{
15484	switch (res >> 26) {
15485	case ALC880_HP_EVENT:
15486		alc663_two_hp_m1_speaker_automute(codec);
15487		break;
15488	case ALC880_MIC_EVENT:
15489		alc662_eeepc_mic_automute(codec);
15490		break;
15491	}
15492}
15493
15494static void alc663_mode3_inithook(struct hda_codec *codec)
15495{
15496	alc663_two_hp_m1_speaker_automute(codec);
15497	alc662_eeepc_mic_automute(codec);
15498}
15499/* ***************** Mode4 ******************************/
15500static void alc663_mode4_unsol_event(struct hda_codec *codec,
15501					   unsigned int res)
15502{
15503	switch (res >> 26) {
15504	case ALC880_HP_EVENT:
15505		alc663_21jd_two_speaker_automute(codec);
15506		break;
15507	case ALC880_MIC_EVENT:
15508		alc662_eeepc_mic_automute(codec);
15509		break;
15510	}
15511}
15512
15513static void alc663_mode4_inithook(struct hda_codec *codec)
15514{
15515	alc663_21jd_two_speaker_automute(codec);
15516	alc662_eeepc_mic_automute(codec);
15517}
15518/* ***************** Mode5 ******************************/
15519static void alc663_mode5_unsol_event(struct hda_codec *codec,
15520					   unsigned int res)
15521{
15522	switch (res >> 26) {
15523	case ALC880_HP_EVENT:
15524		alc663_15jd_two_speaker_automute(codec);
15525		break;
15526	case ALC880_MIC_EVENT:
15527		alc662_eeepc_mic_automute(codec);
15528		break;
15529	}
15530}
15531
15532static void alc663_mode5_inithook(struct hda_codec *codec)
15533{
15534	alc663_15jd_two_speaker_automute(codec);
15535	alc662_eeepc_mic_automute(codec);
15536}
15537/* ***************** Mode6 ******************************/
15538static void alc663_mode6_unsol_event(struct hda_codec *codec,
15539					   unsigned int res)
15540{
15541	switch (res >> 26) {
15542	case ALC880_HP_EVENT:
15543		alc663_two_hp_m2_speaker_automute(codec);
15544		break;
15545	case ALC880_MIC_EVENT:
15546		alc662_eeepc_mic_automute(codec);
15547		break;
15548	}
15549}
15550
15551static void alc663_mode6_inithook(struct hda_codec *codec)
15552{
15553	alc663_two_hp_m2_speaker_automute(codec);
15554	alc662_eeepc_mic_automute(codec);
15555}
15556
15557static void alc663_g71v_hp_automute(struct hda_codec *codec)
15558{
15559	unsigned int present;
15560	unsigned char bits;
15561
15562	present = snd_hda_codec_read(codec, 0x21, 0,
15563				     AC_VERB_GET_PIN_SENSE, 0)
15564		& AC_PINSENSE_PRESENCE;
15565	bits = present ? HDA_AMP_MUTE : 0;
15566	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15567				 HDA_AMP_MUTE, bits);
15568	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15569				 HDA_AMP_MUTE, bits);
15570}
15571
15572static void alc663_g71v_front_automute(struct hda_codec *codec)
15573{
15574	unsigned int present;
15575	unsigned char bits;
15576
15577	present = snd_hda_codec_read(codec, 0x15, 0,
15578				     AC_VERB_GET_PIN_SENSE, 0)
15579		& AC_PINSENSE_PRESENCE;
15580	bits = present ? HDA_AMP_MUTE : 0;
15581	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15582				 HDA_AMP_MUTE, bits);
15583}
15584
15585static void alc663_g71v_unsol_event(struct hda_codec *codec,
15586					   unsigned int res)
15587{
15588	switch (res >> 26) {
15589	case ALC880_HP_EVENT:
15590		alc663_g71v_hp_automute(codec);
15591		break;
15592	case ALC880_FRONT_EVENT:
15593		alc663_g71v_front_automute(codec);
15594		break;
15595	case ALC880_MIC_EVENT:
15596		alc662_eeepc_mic_automute(codec);
15597		break;
15598	}
15599}
15600
15601static void alc663_g71v_inithook(struct hda_codec *codec)
15602{
15603	alc663_g71v_front_automute(codec);
15604	alc663_g71v_hp_automute(codec);
15605	alc662_eeepc_mic_automute(codec);
15606}
15607
15608static void alc663_g50v_unsol_event(struct hda_codec *codec,
15609					   unsigned int res)
15610{
15611	switch (res >> 26) {
15612	case ALC880_HP_EVENT:
15613		alc663_m51va_speaker_automute(codec);
15614		break;
15615	case ALC880_MIC_EVENT:
15616		alc662_eeepc_mic_automute(codec);
15617		break;
15618	}
15619}
15620
15621static void alc663_g50v_inithook(struct hda_codec *codec)
15622{
15623	alc663_m51va_speaker_automute(codec);
15624	alc662_eeepc_mic_automute(codec);
15625}
15626
15627/* bind hp and internal speaker mute (with plug check) */
15628static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol,
15629				     struct snd_ctl_elem_value *ucontrol)
15630{
15631	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
15632	long *valp = ucontrol->value.integer.value;
15633	int change;
15634
15635	change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
15636					  HDA_AMP_MUTE,
15637					  valp[0] ? 0 : HDA_AMP_MUTE);
15638	change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
15639					   HDA_AMP_MUTE,
15640					   valp[1] ? 0 : HDA_AMP_MUTE);
15641	if (change)
15642		alc262_hippo1_automute(codec);
15643	return change;
15644}
15645
15646static struct snd_kcontrol_new alc662_ecs_mixer[] = {
15647	HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15648	{
15649		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15650		.name = "Master Playback Switch",
15651		.info = snd_hda_mixer_amp_switch_info,
15652		.get = snd_hda_mixer_amp_switch_get,
15653		.put = alc662_ecs_master_sw_put,
15654		.private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15655	},
15656
15657	HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
15658	HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
15659	HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
15660
15661	HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15662	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15663	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15664	{ } /* end */
15665};
15666
15667#ifdef CONFIG_SND_HDA_POWER_SAVE
15668#define alc662_loopbacks	alc880_loopbacks
15669#endif
15670
15671
15672/* pcm configuration: identiacal with ALC880 */
15673#define alc662_pcm_analog_playback	alc880_pcm_analog_playback
15674#define alc662_pcm_analog_capture	alc880_pcm_analog_capture
15675#define alc662_pcm_digital_playback	alc880_pcm_digital_playback
15676#define alc662_pcm_digital_capture	alc880_pcm_digital_capture
15677
15678/*
15679 * configuration and preset
15680 */
15681static const char *alc662_models[ALC662_MODEL_LAST] = {
15682	[ALC662_3ST_2ch_DIG]	= "3stack-dig",
15683	[ALC662_3ST_6ch_DIG]	= "3stack-6ch-dig",
15684	[ALC662_3ST_6ch]	= "3stack-6ch",
15685	[ALC662_5ST_DIG]	= "6stack-dig",
15686	[ALC662_LENOVO_101E]	= "lenovo-101e",
15687	[ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
15688	[ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
15689	[ALC662_ECS] = "ecs",
15690	[ALC663_ASUS_M51VA] = "m51va",
15691	[ALC663_ASUS_G71V] = "g71v",
15692	[ALC663_ASUS_H13] = "h13",
15693	[ALC663_ASUS_G50V] = "g50v",
15694	[ALC663_ASUS_MODE1] = "asus-mode1",
15695	[ALC662_ASUS_MODE2] = "asus-mode2",
15696	[ALC663_ASUS_MODE3] = "asus-mode3",
15697	[ALC663_ASUS_MODE4] = "asus-mode4",
15698	[ALC663_ASUS_MODE5] = "asus-mode5",
15699	[ALC663_ASUS_MODE6] = "asus-mode6",
15700	[ALC662_AUTO]		= "auto",
15701};
15702
15703static struct snd_pci_quirk alc662_cfg_tbl[] = {
15704	SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
15705	SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS M51VA", ALC663_ASUS_G50V),
15706	SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
15707	SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
15708	SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
15709	SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
15710	SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),
15711	SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
15712	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
15713	SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
15714	SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),
15715	SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
15716	SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
15717	SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
15718	SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
15719	SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
15720	SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
15721	SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
15722	SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
15723	SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
15724	SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
15725	SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
15726	SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
15727	SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
15728	SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
15729	SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
15730	SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
15731	SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
15732	SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
15733	SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
15734	SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
15735	SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
15736	SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
15737	SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
15738	SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
15739	SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
15740	SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
15741		      ALC662_3ST_6ch_DIG),
15742	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
15743	SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
15744	SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
15745	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
15746		      ALC662_3ST_6ch_DIG),
15747	SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
15748	SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
15749					ALC662_3ST_6ch_DIG),
15750	SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13),
15751	SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13),
15752	SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13),
15753	{}
15754};
15755
15756static struct alc_config_preset alc662_presets[] = {
15757	[ALC662_3ST_2ch_DIG] = {
15758		.mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
15759		.init_verbs = { alc662_init_verbs },
15760		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15761		.dac_nids = alc662_dac_nids,
15762		.dig_out_nid = ALC662_DIGOUT_NID,
15763		.dig_in_nid = ALC662_DIGIN_NID,
15764		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15765		.channel_mode = alc662_3ST_2ch_modes,
15766		.input_mux = &alc662_capture_source,
15767	},
15768	[ALC662_3ST_6ch_DIG] = {
15769		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
15770			    alc662_capture_mixer },
15771		.init_verbs = { alc662_init_verbs },
15772		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15773		.dac_nids = alc662_dac_nids,
15774		.dig_out_nid = ALC662_DIGOUT_NID,
15775		.dig_in_nid = ALC662_DIGIN_NID,
15776		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15777		.channel_mode = alc662_3ST_6ch_modes,
15778		.need_dac_fix = 1,
15779		.input_mux = &alc662_capture_source,
15780	},
15781	[ALC662_3ST_6ch] = {
15782		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
15783			    alc662_capture_mixer },
15784		.init_verbs = { alc662_init_verbs },
15785		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15786		.dac_nids = alc662_dac_nids,
15787		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15788		.channel_mode = alc662_3ST_6ch_modes,
15789		.need_dac_fix = 1,
15790		.input_mux = &alc662_capture_source,
15791	},
15792	[ALC662_5ST_DIG] = {
15793		.mixers = { alc662_base_mixer, alc662_chmode_mixer,
15794			    alc662_capture_mixer },
15795		.init_verbs = { alc662_init_verbs },
15796		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15797		.dac_nids = alc662_dac_nids,
15798		.dig_out_nid = ALC662_DIGOUT_NID,
15799		.dig_in_nid = ALC662_DIGIN_NID,
15800		.num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
15801		.channel_mode = alc662_5stack_modes,
15802		.input_mux = &alc662_capture_source,
15803	},
15804	[ALC662_LENOVO_101E] = {
15805		.mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
15806		.init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
15807		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15808		.dac_nids = alc662_dac_nids,
15809		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15810		.channel_mode = alc662_3ST_2ch_modes,
15811		.input_mux = &alc662_lenovo_101e_capture_source,
15812		.unsol_event = alc662_lenovo_101e_unsol_event,
15813		.init_hook = alc662_lenovo_101e_all_automute,
15814	},
15815	[ALC662_ASUS_EEEPC_P701] = {
15816		.mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
15817		.init_verbs = { alc662_init_verbs,
15818				alc662_eeepc_sue_init_verbs },
15819		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15820		.dac_nids = alc662_dac_nids,
15821		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15822		.channel_mode = alc662_3ST_2ch_modes,
15823		.input_mux = &alc662_eeepc_capture_source,
15824		.unsol_event = alc662_eeepc_unsol_event,
15825		.init_hook = alc662_eeepc_inithook,
15826	},
15827	[ALC662_ASUS_EEEPC_EP20] = {
15828		.mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer,
15829			    alc662_chmode_mixer },
15830		.init_verbs = { alc662_init_verbs,
15831				alc662_eeepc_ep20_sue_init_verbs },
15832		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15833		.dac_nids = alc662_dac_nids,
15834		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15835		.channel_mode = alc662_3ST_6ch_modes,
15836		.input_mux = &alc662_lenovo_101e_capture_source,
15837		.unsol_event = alc662_eeepc_ep20_unsol_event,
15838		.init_hook = alc662_eeepc_ep20_inithook,
15839	},
15840	[ALC662_ECS] = {
15841		.mixers = { alc662_ecs_mixer, alc662_capture_mixer },
15842		.init_verbs = { alc662_init_verbs,
15843				alc662_ecs_init_verbs },
15844		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15845		.dac_nids = alc662_dac_nids,
15846		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15847		.channel_mode = alc662_3ST_2ch_modes,
15848		.input_mux = &alc662_eeepc_capture_source,
15849		.unsol_event = alc662_eeepc_unsol_event,
15850		.init_hook = alc662_eeepc_inithook,
15851	},
15852	[ALC663_ASUS_M51VA] = {
15853		.mixers = { alc663_m51va_mixer, alc662_capture_mixer},
15854		.init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15855		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15856		.dac_nids = alc662_dac_nids,
15857		.dig_out_nid = ALC662_DIGOUT_NID,
15858		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15859		.channel_mode = alc662_3ST_2ch_modes,
15860		.input_mux = &alc663_m51va_capture_source,
15861		.unsol_event = alc663_m51va_unsol_event,
15862		.init_hook = alc663_m51va_inithook,
15863	},
15864	[ALC663_ASUS_G71V] = {
15865		.mixers = { alc663_g71v_mixer, alc662_capture_mixer},
15866		.init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
15867		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15868		.dac_nids = alc662_dac_nids,
15869		.dig_out_nid = ALC662_DIGOUT_NID,
15870		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15871		.channel_mode = alc662_3ST_2ch_modes,
15872		.input_mux = &alc662_eeepc_capture_source,
15873		.unsol_event = alc663_g71v_unsol_event,
15874		.init_hook = alc663_g71v_inithook,
15875	},
15876	[ALC663_ASUS_H13] = {
15877		.mixers = { alc663_m51va_mixer, alc662_capture_mixer},
15878		.init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15879		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15880		.dac_nids = alc662_dac_nids,
15881		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15882		.channel_mode = alc662_3ST_2ch_modes,
15883		.input_mux = &alc663_m51va_capture_source,
15884		.unsol_event = alc663_m51va_unsol_event,
15885		.init_hook = alc663_m51va_inithook,
15886	},
15887	[ALC663_ASUS_G50V] = {
15888		.mixers = { alc663_g50v_mixer, alc662_capture_mixer},
15889		.init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
15890		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15891		.dac_nids = alc662_dac_nids,
15892		.dig_out_nid = ALC662_DIGOUT_NID,
15893		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15894		.channel_mode = alc662_3ST_6ch_modes,
15895		.input_mux = &alc663_capture_source,
15896		.unsol_event = alc663_g50v_unsol_event,
15897		.init_hook = alc663_g50v_inithook,
15898	},
15899	[ALC663_ASUS_MODE1] = {
15900		.mixers = { alc663_m51va_mixer, alc662_auto_capture_mixer },
15901		.init_verbs = { alc662_init_verbs,
15902				alc663_21jd_amic_init_verbs },
15903		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15904		.hp_nid = 0x03,
15905		.dac_nids = alc662_dac_nids,
15906		.dig_out_nid = ALC662_DIGOUT_NID,
15907		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15908		.channel_mode = alc662_3ST_2ch_modes,
15909		.input_mux = &alc662_eeepc_capture_source,
15910		.unsol_event = alc663_mode1_unsol_event,
15911		.init_hook = alc663_mode1_inithook,
15912	},
15913	[ALC662_ASUS_MODE2] = {
15914		.mixers = { alc662_1bjd_mixer, alc662_auto_capture_mixer },
15915		.init_verbs = { alc662_init_verbs,
15916				alc662_1bjd_amic_init_verbs },
15917		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15918		.dac_nids = alc662_dac_nids,
15919		.dig_out_nid = ALC662_DIGOUT_NID,
15920		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15921		.channel_mode = alc662_3ST_2ch_modes,
15922		.input_mux = &alc662_eeepc_capture_source,
15923		.unsol_event = alc662_mode2_unsol_event,
15924		.init_hook = alc662_mode2_inithook,
15925	},
15926	[ALC663_ASUS_MODE3] = {
15927		.mixers = { alc663_two_hp_m1_mixer, alc662_auto_capture_mixer },
15928		.init_verbs = { alc662_init_verbs,
15929				alc663_two_hp_amic_m1_init_verbs },
15930		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15931		.hp_nid = 0x03,
15932		.dac_nids = alc662_dac_nids,
15933		.dig_out_nid = ALC662_DIGOUT_NID,
15934		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15935		.channel_mode = alc662_3ST_2ch_modes,
15936		.input_mux = &alc662_eeepc_capture_source,
15937		.unsol_event = alc663_mode3_unsol_event,
15938		.init_hook = alc663_mode3_inithook,
15939	},
15940	[ALC663_ASUS_MODE4] = {
15941		.mixers = { alc663_asus_21jd_clfe_mixer,
15942				alc662_auto_capture_mixer},
15943		.init_verbs = { alc662_init_verbs,
15944				alc663_21jd_amic_init_verbs},
15945		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15946		.hp_nid = 0x03,
15947		.dac_nids = alc662_dac_nids,
15948		.dig_out_nid = ALC662_DIGOUT_NID,
15949		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15950		.channel_mode = alc662_3ST_2ch_modes,
15951		.input_mux = &alc662_eeepc_capture_source,
15952		.unsol_event = alc663_mode4_unsol_event,
15953		.init_hook = alc663_mode4_inithook,
15954	},
15955	[ALC663_ASUS_MODE5] = {
15956		.mixers = { alc663_asus_15jd_clfe_mixer,
15957				alc662_auto_capture_mixer },
15958		.init_verbs = { alc662_init_verbs,
15959				alc663_15jd_amic_init_verbs },
15960		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15961		.hp_nid = 0x03,
15962		.dac_nids = alc662_dac_nids,
15963		.dig_out_nid = ALC662_DIGOUT_NID,
15964		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15965		.channel_mode = alc662_3ST_2ch_modes,
15966		.input_mux = &alc662_eeepc_capture_source,
15967		.unsol_event = alc663_mode5_unsol_event,
15968		.init_hook = alc663_mode5_inithook,
15969	},
15970	[ALC663_ASUS_MODE6] = {
15971		.mixers = { alc663_two_hp_m2_mixer, alc662_auto_capture_mixer },
15972		.init_verbs = { alc662_init_verbs,
15973				alc663_two_hp_amic_m2_init_verbs },
15974		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15975		.hp_nid = 0x03,
15976		.dac_nids = alc662_dac_nids,
15977		.dig_out_nid = ALC662_DIGOUT_NID,
15978		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15979		.channel_mode = alc662_3ST_2ch_modes,
15980		.input_mux = &alc662_eeepc_capture_source,
15981		.unsol_event = alc663_mode6_unsol_event,
15982		.init_hook = alc663_mode6_inithook,
15983	},
15984};
15985
15986
15987/*
15988 * BIOS auto configuration
15989 */
15990
15991/* add playback controls from the parsed DAC table */
15992static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
15993					     const struct auto_pin_cfg *cfg)
15994{
15995	char name[32];
15996	static const char *chname[4] = {
15997		"Front", "Surround", NULL /*CLFE*/, "Side"
15998	};
15999	hda_nid_t nid;
16000	int i, err;
16001
16002	for (i = 0; i < cfg->line_outs; i++) {
16003		if (!spec->multiout.dac_nids[i])
16004			continue;
16005		nid = alc880_idx_to_dac(i);
16006		if (i == 2) {
16007			/* Center/LFE */
16008			err = add_control(spec, ALC_CTL_WIDGET_VOL,
16009					  "Center Playback Volume",
16010					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
16011							      HDA_OUTPUT));
16012			if (err < 0)
16013				return err;
16014			err = add_control(spec, ALC_CTL_WIDGET_VOL,
16015					  "LFE Playback Volume",
16016					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
16017							      HDA_OUTPUT));
16018			if (err < 0)
16019				return err;
16020			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16021					  "Center Playback Switch",
16022					  HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
16023							      HDA_INPUT));
16024			if (err < 0)
16025				return err;
16026			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16027					  "LFE Playback Switch",
16028					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
16029							      HDA_INPUT));
16030			if (err < 0)
16031				return err;
16032		} else {
16033			sprintf(name, "%s Playback Volume", chname[i]);
16034			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16035					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
16036							      HDA_OUTPUT));
16037			if (err < 0)
16038				return err;
16039			sprintf(name, "%s Playback Switch", chname[i]);
16040			err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16041				HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16042						    3, 0, HDA_INPUT));
16043			if (err < 0)
16044				return err;
16045		}
16046	}
16047	return 0;
16048}
16049
16050/* add playback controls for speaker and HP outputs */
16051static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16052					const char *pfx)
16053{
16054	hda_nid_t nid;
16055	int err;
16056	char name[32];
16057
16058	if (!pin)
16059		return 0;
16060
16061	if (pin == 0x17) {
16062		/* ALC663 has a mono output pin on 0x17 */
16063		sprintf(name, "%s Playback Switch", pfx);
16064		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16065				  HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16066		return err;
16067	}
16068
16069	if (alc880_is_fixed_pin(pin)) {
16070		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16071                /* printk("DAC nid=%x\n",nid); */
16072		/* specify the DAC as the extra output */
16073		if (!spec->multiout.hp_nid)
16074			spec->multiout.hp_nid = nid;
16075		else
16076			spec->multiout.extra_out_nid[0] = nid;
16077		/* control HP volume/switch on the output mixer amp */
16078		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16079		sprintf(name, "%s Playback Volume", pfx);
16080		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16081				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16082		if (err < 0)
16083			return err;
16084		sprintf(name, "%s Playback Switch", pfx);
16085		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
16086				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
16087		if (err < 0)
16088			return err;
16089	} else if (alc880_is_multi_pin(pin)) {
16090		/* set manual connection */
16091		/* we have only a switch on HP-out PIN */
16092		sprintf(name, "%s Playback Switch", pfx);
16093		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16094				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16095		if (err < 0)
16096			return err;
16097	}
16098	return 0;
16099}
16100
16101/* create playback/capture controls for input pins */
16102static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
16103						const struct auto_pin_cfg *cfg)
16104{
16105	struct hda_input_mux *imux = &spec->private_imux;
16106	int i, err, idx;
16107
16108	for (i = 0; i < AUTO_PIN_LAST; i++) {
16109		if (alc880_is_input_pin(cfg->input_pins[i])) {
16110			idx = alc880_input_pin_idx(cfg->input_pins[i]);
16111			err = new_analog_input(spec, cfg->input_pins[i],
16112					       auto_pin_cfg_labels[i],
16113					       idx, 0x0b);
16114			if (err < 0)
16115				return err;
16116			imux->items[imux->num_items].label =
16117				auto_pin_cfg_labels[i];
16118			imux->items[imux->num_items].index =
16119				alc880_input_pin_idx(cfg->input_pins[i]);
16120			imux->num_items++;
16121		}
16122	}
16123	return 0;
16124}
16125
16126static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16127					      hda_nid_t nid, int pin_type,
16128					      int dac_idx)
16129{
16130	alc_set_pin_output(codec, nid, pin_type);
16131	/* need the manual connection? */
16132	if (alc880_is_multi_pin(nid)) {
16133		struct alc_spec *spec = codec->spec;
16134		int idx = alc880_multi_pin_idx(nid);
16135		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16136				    AC_VERB_SET_CONNECT_SEL,
16137				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16138	}
16139}
16140
16141static void alc662_auto_init_multi_out(struct hda_codec *codec)
16142{
16143	struct alc_spec *spec = codec->spec;
16144	int i;
16145
16146	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
16147	for (i = 0; i <= HDA_SIDE; i++) {
16148		hda_nid_t nid = spec->autocfg.line_out_pins[i];
16149		int pin_type = get_pin_type(spec->autocfg.line_out_type);
16150		if (nid)
16151			alc662_auto_set_output_and_unmute(codec, nid, pin_type,
16152							  i);
16153	}
16154}
16155
16156static void alc662_auto_init_hp_out(struct hda_codec *codec)
16157{
16158	struct alc_spec *spec = codec->spec;
16159	hda_nid_t pin;
16160
16161	pin = spec->autocfg.hp_pins[0];
16162	if (pin) /* connect to front */
16163		/* use dac 0 */
16164		alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
16165	pin = spec->autocfg.speaker_pins[0];
16166	if (pin)
16167		alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
16168}
16169
16170#define alc662_is_input_pin(nid)	alc880_is_input_pin(nid)
16171#define ALC662_PIN_CD_NID		ALC880_PIN_CD_NID
16172
16173static void alc662_auto_init_analog_input(struct hda_codec *codec)
16174{
16175	struct alc_spec *spec = codec->spec;
16176	int i;
16177
16178	for (i = 0; i < AUTO_PIN_LAST; i++) {
16179		hda_nid_t nid = spec->autocfg.input_pins[i];
16180		if (alc662_is_input_pin(nid)) {
16181			snd_hda_codec_write(codec, nid, 0,
16182					    AC_VERB_SET_PIN_WIDGET_CONTROL,
16183					    (i <= AUTO_PIN_FRONT_MIC ?
16184					     PIN_VREF80 : PIN_IN));
16185			if (nid != ALC662_PIN_CD_NID)
16186				snd_hda_codec_write(codec, nid, 0,
16187						    AC_VERB_SET_AMP_GAIN_MUTE,
16188						    AMP_OUT_MUTE);
16189		}
16190	}
16191}
16192
16193#define alc662_auto_init_input_src	alc882_auto_init_input_src
16194
16195static int alc662_parse_auto_config(struct hda_codec *codec)
16196{
16197	struct alc_spec *spec = codec->spec;
16198	int err;
16199	static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
16200
16201	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16202					   alc662_ignore);
16203	if (err < 0)
16204		return err;
16205	if (!spec->autocfg.line_outs)
16206		return 0; /* can't find valid BIOS pin config */
16207
16208	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16209	if (err < 0)
16210		return err;
16211	err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
16212	if (err < 0)
16213		return err;
16214	err = alc662_auto_create_extra_out(spec,
16215					   spec->autocfg.speaker_pins[0],
16216					   "Speaker");
16217	if (err < 0)
16218		return err;
16219	err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
16220					   "Headphone");
16221	if (err < 0)
16222		return err;
16223	err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
16224	if (err < 0)
16225		return err;
16226
16227	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16228
16229	if (spec->autocfg.dig_out_pin)
16230		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
16231
16232	if (spec->kctl_alloc)
16233		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
16234
16235	spec->num_mux_defs = 1;
16236	spec->input_mux = &spec->private_imux;
16237
16238	spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
16239	if (codec->vendor_id == 0x10ec0663)
16240		spec->init_verbs[spec->num_init_verbs++] =
16241			alc663_auto_init_verbs;
16242
16243	err = alc_auto_add_mic_boost(codec);
16244	if (err < 0)
16245		return err;
16246
16247	spec->mixers[spec->num_mixers] = alc662_capture_mixer;
16248	spec->num_mixers++;
16249	return 1;
16250}
16251
16252/* additional initialization for auto-configuration model */
16253static void alc662_auto_init(struct hda_codec *codec)
16254{
16255	struct alc_spec *spec = codec->spec;
16256	alc662_auto_init_multi_out(codec);
16257	alc662_auto_init_hp_out(codec);
16258	alc662_auto_init_analog_input(codec);
16259	alc662_auto_init_input_src(codec);
16260	if (spec->unsol_event)
16261		alc_inithook(codec);
16262}
16263
16264static int patch_alc662(struct hda_codec *codec)
16265{
16266	struct alc_spec *spec;
16267	int err, board_config;
16268
16269	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16270	if (!spec)
16271		return -ENOMEM;
16272
16273	codec->spec = spec;
16274
16275	alc_fix_pll_init(codec, 0x20, 0x04, 15);
16276
16277	board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
16278						  alc662_models,
16279			  	                  alc662_cfg_tbl);
16280	if (board_config < 0) {
16281		printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
16282		       "trying auto-probe from BIOS...\n");
16283		board_config = ALC662_AUTO;
16284	}
16285
16286	if (board_config == ALC662_AUTO) {
16287		/* automatic parse from the BIOS config */
16288		err = alc662_parse_auto_config(codec);
16289		if (err < 0) {
16290			alc_free(codec);
16291			return err;
16292		} else if (!err) {
16293			printk(KERN_INFO
16294			       "hda_codec: Cannot set up configuration "
16295			       "from BIOS.  Using base mode...\n");
16296			board_config = ALC662_3ST_2ch_DIG;
16297		}
16298	}
16299
16300	if (board_config != ALC662_AUTO)
16301		setup_preset(spec, &alc662_presets[board_config]);
16302
16303	if (codec->vendor_id == 0x10ec0663) {
16304		spec->stream_name_analog = "ALC663 Analog";
16305		spec->stream_name_digital = "ALC663 Digital";
16306	} else {
16307		spec->stream_name_analog = "ALC662 Analog";
16308		spec->stream_name_digital = "ALC662 Digital";
16309	}
16310
16311	spec->stream_analog_playback = &alc662_pcm_analog_playback;
16312	spec->stream_analog_capture = &alc662_pcm_analog_capture;
16313
16314	spec->stream_digital_playback = &alc662_pcm_digital_playback;
16315	spec->stream_digital_capture = &alc662_pcm_digital_capture;
16316
16317	spec->adc_nids = alc662_adc_nids;
16318	spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
16319	spec->capsrc_nids = alc662_capsrc_nids;
16320
16321	spec->vmaster_nid = 0x02;
16322
16323	codec->patch_ops = alc_patch_ops;
16324	if (board_config == ALC662_AUTO)
16325		spec->init_hook = alc662_auto_init;
16326#ifdef CONFIG_SND_HDA_POWER_SAVE
16327	if (!spec->loopback.amplist)
16328		spec->loopback.amplist = alc662_loopbacks;
16329#endif
16330
16331	return 0;
16332}
16333
16334/*
16335 * patch entries
16336 */
16337struct hda_codec_preset snd_hda_preset_realtek[] = {
16338	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
16339	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
16340	{ .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
16341	{ .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
16342	{ .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
16343	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
16344	  .patch = patch_alc861 },
16345	{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
16346	{ .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
16347	{ .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
16348	{ .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
16349	  .patch = patch_alc883 },
16350	{ .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
16351	  .patch = patch_alc662 },
16352	{ .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
16353	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
16354	{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
16355	{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
16356	{ .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
16357	  .patch = patch_alc882 }, /* should be patch_alc883() in future */
16358	{ .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
16359	  .patch = patch_alc882 }, /* should be patch_alc883() in future */
16360	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
16361	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
16362	{ .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
16363	{} /* terminator */
16364};
16365