patch_realtek.c revision 80ffe86925a226f513b36d0ce13e049133841970
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, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8345	SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
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		if (codec->revision_id == 0x100101) {
8841			spec->stream_name_analog = "ALC1200 Analog";
8842			spec->stream_name_digital = "ALC1200 Digital";
8843		} else {
8844			spec->stream_name_analog = "ALC888 Analog";
8845			spec->stream_name_digital = "ALC888 Digital";
8846		}
8847		break;
8848	case 0x10ec0889:
8849		spec->stream_name_analog = "ALC889 Analog";
8850		spec->stream_name_digital = "ALC889 Digital";
8851		break;
8852	default:
8853		spec->stream_name_analog = "ALC883 Analog";
8854		spec->stream_name_digital = "ALC883 Digital";
8855		break;
8856	}
8857
8858	spec->stream_analog_playback = &alc883_pcm_analog_playback;
8859	spec->stream_analog_capture = &alc883_pcm_analog_capture;
8860	spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
8861
8862	spec->stream_digital_playback = &alc883_pcm_digital_playback;
8863	spec->stream_digital_capture = &alc883_pcm_digital_capture;
8864
8865	spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8866	spec->adc_nids = alc883_adc_nids;
8867	spec->capsrc_nids = alc883_capsrc_nids;
8868
8869	spec->vmaster_nid = 0x0c;
8870
8871	codec->patch_ops = alc_patch_ops;
8872	if (board_config == ALC883_AUTO)
8873		spec->init_hook = alc883_auto_init;
8874
8875#ifdef CONFIG_SND_HDA_POWER_SAVE
8876	if (!spec->loopback.amplist)
8877		spec->loopback.amplist = alc883_loopbacks;
8878#endif
8879
8880	return 0;
8881}
8882
8883/*
8884 * ALC262 support
8885 */
8886
8887#define ALC262_DIGOUT_NID	ALC880_DIGOUT_NID
8888#define ALC262_DIGIN_NID	ALC880_DIGIN_NID
8889
8890#define alc262_dac_nids		alc260_dac_nids
8891#define alc262_adc_nids		alc882_adc_nids
8892#define alc262_adc_nids_alt	alc882_adc_nids_alt
8893#define alc262_capsrc_nids	alc882_capsrc_nids
8894#define alc262_capsrc_nids_alt	alc882_capsrc_nids_alt
8895
8896#define alc262_modes		alc260_modes
8897#define alc262_capture_source	alc882_capture_source
8898
8899static hda_nid_t alc262_dmic_adc_nids[1] = {
8900	/* ADC0 */
8901	0x09
8902};
8903
8904static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
8905
8906static struct snd_kcontrol_new alc262_base_mixer[] = {
8907	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8908	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8909	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8910	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8911	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8912	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8913	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8914	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8915	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8916	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8917	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8918	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8919	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8920	   HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8921	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
8922	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8923	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8924	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
8925	{ } /* end */
8926};
8927
8928static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
8929	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8930	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8931	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8932	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8933	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8934	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8935	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8936	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8937	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8938	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8939	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8940	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8941	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8942	   HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8943	/*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
8944	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8945	{ } /* end */
8946};
8947
8948/* update HP, line and mono-out pins according to the master switch */
8949static void alc262_hp_master_update(struct hda_codec *codec)
8950{
8951	struct alc_spec *spec = codec->spec;
8952	int val = spec->master_sw;
8953
8954	/* HP & line-out */
8955	snd_hda_codec_write_cache(codec, 0x1b, 0,
8956				  AC_VERB_SET_PIN_WIDGET_CONTROL,
8957				  val ? PIN_HP : 0);
8958	snd_hda_codec_write_cache(codec, 0x15, 0,
8959				  AC_VERB_SET_PIN_WIDGET_CONTROL,
8960				  val ? PIN_HP : 0);
8961	/* mono (speaker) depending on the HP jack sense */
8962	val = val && !spec->jack_present;
8963	snd_hda_codec_write_cache(codec, 0x16, 0,
8964				  AC_VERB_SET_PIN_WIDGET_CONTROL,
8965				  val ? PIN_OUT : 0);
8966}
8967
8968static void alc262_hp_bpc_automute(struct hda_codec *codec)
8969{
8970	struct alc_spec *spec = codec->spec;
8971	unsigned int presence;
8972	presence = snd_hda_codec_read(codec, 0x1b, 0,
8973				      AC_VERB_GET_PIN_SENSE, 0);
8974	spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8975	alc262_hp_master_update(codec);
8976}
8977
8978static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
8979{
8980	if ((res >> 26) != ALC880_HP_EVENT)
8981		return;
8982	alc262_hp_bpc_automute(codec);
8983}
8984
8985static void alc262_hp_wildwest_automute(struct hda_codec *codec)
8986{
8987	struct alc_spec *spec = codec->spec;
8988	unsigned int presence;
8989	presence = snd_hda_codec_read(codec, 0x15, 0,
8990				      AC_VERB_GET_PIN_SENSE, 0);
8991	spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8992	alc262_hp_master_update(codec);
8993}
8994
8995static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
8996					   unsigned int res)
8997{
8998	if ((res >> 26) != ALC880_HP_EVENT)
8999		return;
9000	alc262_hp_wildwest_automute(codec);
9001}
9002
9003static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
9004				   struct snd_ctl_elem_value *ucontrol)
9005{
9006	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9007	struct alc_spec *spec = codec->spec;
9008	*ucontrol->value.integer.value = spec->master_sw;
9009	return 0;
9010}
9011
9012static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9013				   struct snd_ctl_elem_value *ucontrol)
9014{
9015	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9016	struct alc_spec *spec = codec->spec;
9017	int val = !!*ucontrol->value.integer.value;
9018
9019	if (val == spec->master_sw)
9020		return 0;
9021	spec->master_sw = val;
9022	alc262_hp_master_update(codec);
9023	return 1;
9024}
9025
9026static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
9027	{
9028		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9029		.name = "Master Playback Switch",
9030		.info = snd_ctl_boolean_mono_info,
9031		.get = alc262_hp_master_sw_get,
9032		.put = alc262_hp_master_sw_put,
9033	},
9034	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9035	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9036	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9037	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9038			      HDA_OUTPUT),
9039	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9040			    HDA_OUTPUT),
9041	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9042	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9043	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9044	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9045	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9046	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9047	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9048	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9049	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9050	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9051	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9052	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9053	HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9054	HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9055	{ } /* end */
9056};
9057
9058static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
9059	{
9060		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9061		.name = "Master Playback Switch",
9062		.info = snd_ctl_boolean_mono_info,
9063		.get = alc262_hp_master_sw_get,
9064		.put = alc262_hp_master_sw_put,
9065	},
9066	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9067	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9068	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9069	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9070	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9071			      HDA_OUTPUT),
9072	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9073			    HDA_OUTPUT),
9074	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9075	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
9076	HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
9077	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9078	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9079	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9080	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9081	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9082	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9083	{ } /* end */
9084};
9085
9086static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9087	HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9088	HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9089	HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
9090	{ } /* end */
9091};
9092
9093/* mute/unmute internal speaker according to the hp jack and mute state */
9094static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
9095{
9096	struct alc_spec *spec = codec->spec;
9097
9098	if (force || !spec->sense_updated) {
9099		unsigned int present;
9100		present = snd_hda_codec_read(codec, 0x15, 0,
9101					     AC_VERB_GET_PIN_SENSE, 0);
9102		spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9103		spec->sense_updated = 1;
9104	}
9105	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
9106				 spec->jack_present ? HDA_AMP_MUTE : 0);
9107}
9108
9109static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
9110					unsigned int res)
9111{
9112	if ((res >> 26) != ALC880_HP_EVENT)
9113		return;
9114	alc262_hp_t5735_automute(codec, 1);
9115}
9116
9117static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9118{
9119	alc262_hp_t5735_automute(codec, 1);
9120}
9121
9122static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
9123	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9124	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9125	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9126	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9127	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9128	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9129	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9130	{ } /* end */
9131};
9132
9133static struct hda_verb alc262_hp_t5735_verbs[] = {
9134	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9135	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9136
9137	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9138	{ }
9139};
9140
9141static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
9142	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9143	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9144	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9145	HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
9146	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9147	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9148	{ } /* end */
9149};
9150
9151static struct hda_verb alc262_hp_rp5700_verbs[] = {
9152	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9153	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9154	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9155	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9156	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9157	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9158	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9159	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9160	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9161	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9162	{}
9163};
9164
9165static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9166	.num_items = 1,
9167	.items = {
9168		{ "Line", 0x1 },
9169	},
9170};
9171
9172/* bind hp and internal speaker mute (with plug check) */
9173static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
9174				     struct snd_ctl_elem_value *ucontrol)
9175{
9176	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9177	long *valp = ucontrol->value.integer.value;
9178	int change;
9179
9180	/* change hp mute */
9181	change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
9182					  HDA_AMP_MUTE,
9183					  valp[0] ? 0 : HDA_AMP_MUTE);
9184	change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
9185					   HDA_AMP_MUTE,
9186					   valp[1] ? 0 : HDA_AMP_MUTE);
9187	if (change) {
9188		/* change speaker according to HP jack state */
9189		struct alc_spec *spec = codec->spec;
9190		unsigned int mute;
9191		if (spec->jack_present)
9192			mute = HDA_AMP_MUTE;
9193		else
9194			mute = snd_hda_codec_amp_read(codec, 0x15, 0,
9195						      HDA_OUTPUT, 0);
9196		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9197					 HDA_AMP_MUTE, mute);
9198	}
9199	return change;
9200}
9201
9202static struct snd_kcontrol_new alc262_sony_mixer[] = {
9203	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9204	{
9205		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9206		.name = "Master Playback Switch",
9207		.info = snd_hda_mixer_amp_switch_info,
9208		.get = snd_hda_mixer_amp_switch_get,
9209		.put = alc262_sony_master_sw_put,
9210		.private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9211	},
9212	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9213	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9214	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9215	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9216	{ } /* end */
9217};
9218
9219static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9220	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9221	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9222	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9223	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9224	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9225	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9226	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9227	{ } /* end */
9228};
9229
9230#define alc262_capture_mixer		alc882_capture_mixer
9231#define alc262_capture_alt_mixer	alc882_capture_alt_mixer
9232
9233/*
9234 * generic initialization of ADC, input mixers and output mixers
9235 */
9236static struct hda_verb alc262_init_verbs[] = {
9237	/*
9238	 * Unmute ADC0-2 and set the default input to mic-in
9239	 */
9240	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9241	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9242	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9243	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9244	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9245	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9246
9247	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9248	 * mixer widget
9249	 * Note: PASD motherboards uses the Line In 2 as the input for
9250	 * front panel mic (mic 2)
9251	 */
9252	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9253	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9254	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9255	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9256	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9257	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9258
9259	/*
9260	 * Set up output mixers (0x0c - 0x0e)
9261	 */
9262	/* set vol=0 to output mixers */
9263	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9264	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9265	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9266	/* set up input amps for analog loopback */
9267	/* Amp Indices: DAC = 0, mixer = 1 */
9268	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9269	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9270	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9271	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9272	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9273	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9274
9275	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9276	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9277	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9278	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9279	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9280	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9281
9282	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9283	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9284	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9285	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9286	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9287
9288	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9289	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9290
9291	/* FIXME: use matrix-type input source selection */
9292	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9293	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9294	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9295	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9296	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9297	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9298	/* Input mixer2 */
9299	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9300	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9301	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9302	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9303	/* Input mixer3 */
9304	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9305	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9306	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9307	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9308
9309	{ }
9310};
9311
9312static struct hda_verb alc262_eapd_verbs[] = {
9313	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9314	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9315	{ }
9316};
9317
9318static struct hda_verb alc262_hippo_unsol_verbs[] = {
9319	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9320	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9321	{}
9322};
9323
9324static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9325	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9326	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9327	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9328
9329	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9330	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9331	{}
9332};
9333
9334static struct hda_verb alc262_sony_unsol_verbs[] = {
9335	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9336	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9337	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},	// Front Mic
9338
9339	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9340	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9341	{}
9342};
9343
9344static struct hda_input_mux alc262_dmic_capture_source = {
9345	.num_items = 2,
9346	.items = {
9347		{ "Int DMic", 0x9 },
9348		{ "Mic", 0x0 },
9349	},
9350};
9351
9352static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9353	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9354	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9355	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9356	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9357	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9358	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9359	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9360	{
9361		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9362		/* The multiple "Capture Source" controls confuse alsamixer
9363		 * So call somewhat different..
9364		 */
9365		/* .name = "Capture Source", */
9366		.name = "Input Source",
9367		.count = 1,
9368		.info = alc_mux_enum_info,
9369		.get = alc_mux_enum_get,
9370		.put = alc_mux_enum_put,
9371	},
9372	{ } /* end */
9373};
9374
9375static struct hda_verb alc262_toshiba_s06_verbs[] = {
9376	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9377	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9378	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9379	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9380	{0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9381	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9382	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9383	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9384	{}
9385};
9386
9387static void alc262_dmic_automute(struct hda_codec *codec)
9388{
9389	unsigned int present;
9390
9391	present = snd_hda_codec_read(codec, 0x18, 0,
9392					AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9393	snd_hda_codec_write(codec, 0x22, 0,
9394				AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9395}
9396
9397/* toggle speaker-output according to the hp-jack state */
9398static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
9399{
9400	unsigned int present;
9401	unsigned char bits;
9402
9403	present = snd_hda_codec_read(codec, 0x15, 0,
9404					AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9405	bits = present ? 0 : PIN_OUT;
9406	snd_hda_codec_write(codec, 0x14, 0,
9407					AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
9408}
9409
9410
9411
9412/* unsolicited event for HP jack sensing */
9413static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9414				       unsigned int res)
9415{
9416	if ((res >> 26) == ALC880_HP_EVENT)
9417		alc262_toshiba_s06_speaker_automute(codec);
9418	if ((res >> 26) == ALC880_MIC_EVENT)
9419		alc262_dmic_automute(codec);
9420
9421}
9422
9423static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9424{
9425	alc262_toshiba_s06_speaker_automute(codec);
9426	alc262_dmic_automute(codec);
9427}
9428
9429/* mute/unmute internal speaker according to the hp jack and mute state */
9430static void alc262_hippo_automute(struct hda_codec *codec)
9431{
9432	struct alc_spec *spec = codec->spec;
9433	unsigned int mute;
9434	unsigned int present;
9435
9436	/* need to execute and sync at first */
9437	snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9438	present = snd_hda_codec_read(codec, 0x15, 0,
9439				     AC_VERB_GET_PIN_SENSE, 0);
9440	spec->jack_present = (present & 0x80000000) != 0;
9441	if (spec->jack_present) {
9442		/* mute internal speaker */
9443		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9444					 HDA_AMP_MUTE, HDA_AMP_MUTE);
9445	} else {
9446		/* unmute internal speaker if necessary */
9447		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
9448		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9449					 HDA_AMP_MUTE, mute);
9450	}
9451}
9452
9453/* unsolicited event for HP jack sensing */
9454static void alc262_hippo_unsol_event(struct hda_codec *codec,
9455				       unsigned int res)
9456{
9457	if ((res >> 26) != ALC880_HP_EVENT)
9458		return;
9459	alc262_hippo_automute(codec);
9460}
9461
9462static void alc262_hippo1_automute(struct hda_codec *codec)
9463{
9464	unsigned int mute;
9465	unsigned int present;
9466
9467	snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9468	present = snd_hda_codec_read(codec, 0x1b, 0,
9469				     AC_VERB_GET_PIN_SENSE, 0);
9470	present = (present & 0x80000000) != 0;
9471	if (present) {
9472		/* mute internal speaker */
9473		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9474					 HDA_AMP_MUTE, HDA_AMP_MUTE);
9475	} else {
9476		/* unmute internal speaker if necessary */
9477		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9478		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9479					 HDA_AMP_MUTE, mute);
9480	}
9481}
9482
9483/* unsolicited event for HP jack sensing */
9484static void alc262_hippo1_unsol_event(struct hda_codec *codec,
9485				       unsigned int res)
9486{
9487	if ((res >> 26) != ALC880_HP_EVENT)
9488		return;
9489	alc262_hippo1_automute(codec);
9490}
9491
9492/*
9493 * nec model
9494 *  0x15 = headphone
9495 *  0x16 = internal speaker
9496 *  0x18 = external mic
9497 */
9498
9499static struct snd_kcontrol_new alc262_nec_mixer[] = {
9500	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9501	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
9502
9503	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9504	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9505	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9506
9507	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9508	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9509	{ } /* end */
9510};
9511
9512static struct hda_verb alc262_nec_verbs[] = {
9513	/* Unmute Speaker */
9514	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9515
9516	/* Headphone */
9517	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9518	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9519
9520	/* External mic to headphone */
9521	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9522	/* External mic to speaker */
9523	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9524	{}
9525};
9526
9527/*
9528 * fujitsu model
9529 *  0x14 = headphone/spdif-out, 0x15 = internal speaker,
9530 *  0x1b = port replicator headphone out
9531 */
9532
9533#define ALC_HP_EVENT	0x37
9534
9535static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
9536	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9537	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9538	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9539	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9540	{}
9541};
9542
9543static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
9544	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9545	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9546	{}
9547};
9548
9549static struct hda_input_mux alc262_fujitsu_capture_source = {
9550	.num_items = 3,
9551	.items = {
9552		{ "Mic", 0x0 },
9553		{ "Int Mic", 0x1 },
9554		{ "CD", 0x4 },
9555	},
9556};
9557
9558static struct hda_input_mux alc262_HP_capture_source = {
9559	.num_items = 5,
9560	.items = {
9561		{ "Mic", 0x0 },
9562		{ "Front Mic", 0x1 },
9563		{ "Line", 0x2 },
9564		{ "CD", 0x4 },
9565		{ "AUX IN", 0x6 },
9566	},
9567};
9568
9569static struct hda_input_mux alc262_HP_D7000_capture_source = {
9570	.num_items = 4,
9571	.items = {
9572		{ "Mic", 0x0 },
9573		{ "Front Mic", 0x2 },
9574		{ "Line", 0x1 },
9575		{ "CD", 0x4 },
9576	},
9577};
9578
9579/* mute/unmute internal speaker according to the hp jacks and mute state */
9580static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
9581{
9582	struct alc_spec *spec = codec->spec;
9583	unsigned int mute;
9584
9585	if (force || !spec->sense_updated) {
9586		unsigned int present;
9587		/* need to execute and sync at first */
9588		snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
9589		/* check laptop HP jack */
9590		present = snd_hda_codec_read(codec, 0x14, 0,
9591					     AC_VERB_GET_PIN_SENSE, 0);
9592		/* need to execute and sync at first */
9593		snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9594		/* check docking HP jack */
9595		present |= snd_hda_codec_read(codec, 0x1b, 0,
9596					      AC_VERB_GET_PIN_SENSE, 0);
9597		if (present & AC_PINSENSE_PRESENCE)
9598			spec->jack_present = 1;
9599		else
9600			spec->jack_present = 0;
9601		spec->sense_updated = 1;
9602	}
9603	/* unmute internal speaker only if both HPs are unplugged and
9604	 * master switch is on
9605	 */
9606	if (spec->jack_present)
9607		mute = HDA_AMP_MUTE;
9608	else
9609		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9610	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9611				 HDA_AMP_MUTE, mute);
9612}
9613
9614/* unsolicited event for HP jack sensing */
9615static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
9616				       unsigned int res)
9617{
9618	if ((res >> 26) != ALC_HP_EVENT)
9619		return;
9620	alc262_fujitsu_automute(codec, 1);
9621}
9622
9623static void alc262_fujitsu_init_hook(struct hda_codec *codec)
9624{
9625	alc262_fujitsu_automute(codec, 1);
9626}
9627
9628/* bind volumes of both NID 0x0c and 0x0d */
9629static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
9630	.ops = &snd_hda_bind_vol,
9631	.values = {
9632		HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
9633		HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
9634		0
9635	},
9636};
9637
9638/* mute/unmute internal speaker according to the hp jack and mute state */
9639static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
9640{
9641	struct alc_spec *spec = codec->spec;
9642	unsigned int mute;
9643
9644	if (force || !spec->sense_updated) {
9645		unsigned int present_int_hp;
9646		/* need to execute and sync at first */
9647		snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9648		present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
9649					AC_VERB_GET_PIN_SENSE, 0);
9650		spec->jack_present = (present_int_hp & 0x80000000) != 0;
9651		spec->sense_updated = 1;
9652	}
9653	if (spec->jack_present) {
9654		/* mute internal speaker */
9655		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9656					 HDA_AMP_MUTE, HDA_AMP_MUTE);
9657		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9658					 HDA_AMP_MUTE, HDA_AMP_MUTE);
9659	} else {
9660		/* unmute internal speaker if necessary */
9661		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9662		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9663					 HDA_AMP_MUTE, mute);
9664		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9665					 HDA_AMP_MUTE, mute);
9666	}
9667}
9668
9669/* unsolicited event for HP jack sensing */
9670static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
9671				       unsigned int res)
9672{
9673	if ((res >> 26) != ALC_HP_EVENT)
9674		return;
9675	alc262_lenovo_3000_automute(codec, 1);
9676}
9677
9678/* bind hp and internal speaker mute (with plug check) */
9679static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
9680					 struct snd_ctl_elem_value *ucontrol)
9681{
9682	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9683	long *valp = ucontrol->value.integer.value;
9684	int change;
9685
9686	change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9687						 HDA_AMP_MUTE,
9688						 valp ? 0 : HDA_AMP_MUTE);
9689	change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9690						 HDA_AMP_MUTE,
9691						 valp ? 0 : HDA_AMP_MUTE);
9692
9693	if (change)
9694		alc262_fujitsu_automute(codec, 0);
9695	return change;
9696}
9697
9698static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
9699	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9700	{
9701		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9702		.name = "Master Playback Switch",
9703		.info = snd_hda_mixer_amp_switch_info,
9704		.get = snd_hda_mixer_amp_switch_get,
9705		.put = alc262_fujitsu_master_sw_put,
9706		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9707	},
9708	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9709	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9710	HDA_CODEC_VOLUME("PC Speaker Volume", 0x0b, 0x05, HDA_INPUT),
9711	HDA_CODEC_MUTE("PC Speaker Switch", 0x0b, 0x05, HDA_INPUT),
9712	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9713	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9714	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9715	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9716	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9717	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9718	{ } /* end */
9719};
9720
9721/* bind hp and internal speaker mute (with plug check) */
9722static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
9723					 struct snd_ctl_elem_value *ucontrol)
9724{
9725	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9726	long *valp = ucontrol->value.integer.value;
9727	int change;
9728
9729	change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9730						 HDA_AMP_MUTE,
9731						 valp ? 0 : HDA_AMP_MUTE);
9732
9733	if (change)
9734		alc262_lenovo_3000_automute(codec, 0);
9735	return change;
9736}
9737
9738static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
9739	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9740	{
9741		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9742		.name = "Master Playback Switch",
9743		.info = snd_hda_mixer_amp_switch_info,
9744		.get = snd_hda_mixer_amp_switch_get,
9745		.put = alc262_lenovo_3000_master_sw_put,
9746		.private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
9747	},
9748	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9749	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9750	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9751	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9752	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9753	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9754	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9755	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9756	{ } /* end */
9757};
9758
9759static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
9760	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9761	{
9762		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9763		.name = "Master Playback Switch",
9764		.info = snd_hda_mixer_amp_switch_info,
9765		.get = snd_hda_mixer_amp_switch_get,
9766		.put = alc262_sony_master_sw_put,
9767		.private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9768	},
9769	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9770	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9771	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9772	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9773	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9774	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9775	{ } /* end */
9776};
9777
9778/* additional init verbs for Benq laptops */
9779static struct hda_verb alc262_EAPD_verbs[] = {
9780	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9781	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
9782	{}
9783};
9784
9785static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
9786	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9787	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9788
9789	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9790	{0x20, AC_VERB_SET_PROC_COEF,  0x3050},
9791	{}
9792};
9793
9794/* Samsung Q1 Ultra Vista model setup */
9795static struct snd_kcontrol_new alc262_ultra_mixer[] = {
9796	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9797	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9798	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9799	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9800	HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
9801	HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
9802	{ } /* end */
9803};
9804
9805static struct hda_verb alc262_ultra_verbs[] = {
9806	/* output mixer */
9807	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9808	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9809	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9810	/* speaker */
9811	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9812	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9813	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9814	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9815	/* HP */
9816	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9817	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9818	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9819	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9820	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9821	/* internal mic */
9822	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9823	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9824	/* ADC, choose mic */
9825	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9826	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9827	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9828	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9829	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9830	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9831	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9832	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9833	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
9834	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
9835	{}
9836};
9837
9838/* mute/unmute internal speaker according to the hp jack and mute state */
9839static void alc262_ultra_automute(struct hda_codec *codec)
9840{
9841	struct alc_spec *spec = codec->spec;
9842	unsigned int mute;
9843
9844	mute = 0;
9845	/* auto-mute only when HP is used as HP */
9846	if (!spec->cur_mux[0]) {
9847		unsigned int present;
9848		/* need to execute and sync at first */
9849		snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9850		present = snd_hda_codec_read(codec, 0x15, 0,
9851					     AC_VERB_GET_PIN_SENSE, 0);
9852		spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9853		if (spec->jack_present)
9854			mute = HDA_AMP_MUTE;
9855	}
9856	/* mute/unmute internal speaker */
9857	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9858				 HDA_AMP_MUTE, mute);
9859	/* mute/unmute HP */
9860	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9861				 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
9862}
9863
9864/* unsolicited event for HP jack sensing */
9865static void alc262_ultra_unsol_event(struct hda_codec *codec,
9866				       unsigned int res)
9867{
9868	if ((res >> 26) != ALC880_HP_EVENT)
9869		return;
9870	alc262_ultra_automute(codec);
9871}
9872
9873static struct hda_input_mux alc262_ultra_capture_source = {
9874	.num_items = 2,
9875	.items = {
9876		{ "Mic", 0x1 },
9877		{ "Headphone", 0x7 },
9878	},
9879};
9880
9881static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
9882				     struct snd_ctl_elem_value *ucontrol)
9883{
9884	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9885	struct alc_spec *spec = codec->spec;
9886	int ret;
9887
9888	ret = alc882_mux_enum_put(kcontrol, ucontrol);
9889	if (!ret)
9890		return 0;
9891	/* reprogram the HP pin as mic or HP according to the input source */
9892	snd_hda_codec_write_cache(codec, 0x15, 0,
9893				  AC_VERB_SET_PIN_WIDGET_CONTROL,
9894				  spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
9895	alc262_ultra_automute(codec); /* mute/unmute HP */
9896	return ret;
9897}
9898
9899static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
9900	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
9901	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
9902	{
9903		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9904		.name = "Capture Source",
9905		.info = alc882_mux_enum_info,
9906		.get = alc882_mux_enum_get,
9907		.put = alc262_ultra_mux_enum_put,
9908	},
9909	{ } /* end */
9910};
9911
9912/* add playback controls from the parsed DAC table */
9913static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
9914					     const struct auto_pin_cfg *cfg)
9915{
9916	hda_nid_t nid;
9917	int err;
9918
9919	spec->multiout.num_dacs = 1;	/* only use one dac */
9920	spec->multiout.dac_nids = spec->private_dac_nids;
9921	spec->multiout.dac_nids[0] = 2;
9922
9923	nid = cfg->line_out_pins[0];
9924	if (nid) {
9925		err = add_control(spec, ALC_CTL_WIDGET_VOL,
9926				  "Front Playback Volume",
9927				  HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
9928		if (err < 0)
9929			return err;
9930		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9931				  "Front Playback Switch",
9932				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9933		if (err < 0)
9934			return err;
9935	}
9936
9937	nid = cfg->speaker_pins[0];
9938	if (nid) {
9939		if (nid == 0x16) {
9940			err = add_control(spec, ALC_CTL_WIDGET_VOL,
9941					  "Speaker Playback Volume",
9942					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9943							      HDA_OUTPUT));
9944			if (err < 0)
9945				return err;
9946			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9947					  "Speaker Playback Switch",
9948					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9949							      HDA_OUTPUT));
9950			if (err < 0)
9951				return err;
9952		} else {
9953			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9954					  "Speaker Playback Switch",
9955					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9956							      HDA_OUTPUT));
9957			if (err < 0)
9958				return err;
9959		}
9960	}
9961	nid = cfg->hp_pins[0];
9962	if (nid) {
9963		/* spec->multiout.hp_nid = 2; */
9964		if (nid == 0x16) {
9965			err = add_control(spec, ALC_CTL_WIDGET_VOL,
9966					  "Headphone Playback Volume",
9967					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9968							      HDA_OUTPUT));
9969			if (err < 0)
9970				return err;
9971			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9972					  "Headphone Playback Switch",
9973					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9974							      HDA_OUTPUT));
9975			if (err < 0)
9976				return err;
9977		} else {
9978			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9979					  "Headphone Playback Switch",
9980					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9981							      HDA_OUTPUT));
9982			if (err < 0)
9983				return err;
9984		}
9985	}
9986	return 0;
9987}
9988
9989/* identical with ALC880 */
9990#define alc262_auto_create_analog_input_ctls \
9991	alc880_auto_create_analog_input_ctls
9992
9993/*
9994 * generic initialization of ADC, input mixers and output mixers
9995 */
9996static struct hda_verb alc262_volume_init_verbs[] = {
9997	/*
9998	 * Unmute ADC0-2 and set the default input to mic-in
9999	 */
10000	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10001	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10002	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10003	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10004	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10005	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10006
10007	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10008	 * mixer widget
10009	 * Note: PASD motherboards uses the Line In 2 as the input for
10010	 * front panel mic (mic 2)
10011	 */
10012	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10013	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10014	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10015	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10016	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10017	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10018
10019	/*
10020	 * Set up output mixers (0x0c - 0x0f)
10021	 */
10022	/* set vol=0 to output mixers */
10023	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10024	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10025	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10026
10027	/* set up input amps for analog loopback */
10028	/* Amp Indices: DAC = 0, mixer = 1 */
10029	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10030	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10031	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10032	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10033	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10034	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10035
10036	/* FIXME: use matrix-type input source selection */
10037	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10038	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10039	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10040	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10041	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10042	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10043	/* Input mixer2 */
10044	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10045	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10046	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10047	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10048	/* Input mixer3 */
10049	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10050	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10051	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10052	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10053
10054	{ }
10055};
10056
10057static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10058	/*
10059	 * Unmute ADC0-2 and set the default input to mic-in
10060	 */
10061	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10062	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10063	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10064	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10065	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10066	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10067
10068	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10069	 * mixer widget
10070	 * Note: PASD motherboards uses the Line In 2 as the input for
10071	 * front panel mic (mic 2)
10072	 */
10073	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10074	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10075	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10076	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10077	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10078	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10079	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10080        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10081
10082	/*
10083	 * Set up output mixers (0x0c - 0x0e)
10084	 */
10085	/* set vol=0 to output mixers */
10086	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10087	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10088	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10089
10090	/* set up input amps for analog loopback */
10091	/* Amp Indices: DAC = 0, mixer = 1 */
10092	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10093	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10094	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10095	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10096	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10097	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10098
10099	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10100	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10101	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10102
10103	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10104	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10105
10106	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10107	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10108
10109	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10110	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10111        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10112	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10113	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10114
10115	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10116	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10117        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10118	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10119	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10120	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10121
10122
10123	/* FIXME: use matrix-type input source selection */
10124	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10125	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10126	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10127	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10128	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10129	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10130	/* Input mixer2 */
10131	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10132	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10133	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10134	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10135	/* Input mixer3 */
10136	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10137	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10138	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10139	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10140
10141	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10142
10143	{ }
10144};
10145
10146static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10147	/*
10148	 * Unmute ADC0-2 and set the default input to mic-in
10149	 */
10150	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10151	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10152	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10153	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10154	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10155	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10156
10157	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10158	 * mixer widget
10159	 * Note: PASD motherboards uses the Line In 2 as the input for front
10160	 * panel mic (mic 2)
10161	 */
10162	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10163	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10164	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10165	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10166	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10167	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10168	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10169	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10170	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10171	/*
10172	 * Set up output mixers (0x0c - 0x0e)
10173	 */
10174	/* set vol=0 to output mixers */
10175	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10176	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10177	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10178
10179	/* set up input amps for analog loopback */
10180	/* Amp Indices: DAC = 0, mixer = 1 */
10181	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10182	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10183	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10184	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10185	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10186	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10187
10188
10189	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },	/* HP */
10190	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Mono */
10191	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* rear MIC */
10192	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* Line in */
10193	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* Front MIC */
10194	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Line out */
10195	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* CD in */
10196
10197	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10198	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10199
10200	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10201	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10202
10203	/* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10204	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10205	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10206	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10207	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10208	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10209
10210	/* FIXME: use matrix-type input source selection */
10211	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10212	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10213	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10214	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10215	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10216	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10217	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10218        /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
10219	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10220	/* Input mixer2 */
10221	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10222	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10223	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10224	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10225	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10226        /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10227	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10228	/* Input mixer3 */
10229	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10230	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10231	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10232	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10233	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10234        /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10235	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10236
10237	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10238
10239	{ }
10240};
10241
10242static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10243
10244	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Front Speaker */
10245	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10246	{0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10247
10248	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* MIC jack */
10249	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* Front MIC */
10250	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10251	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10252
10253	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },	/* HP  jack */
10254	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10255	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10256	{}
10257};
10258
10259
10260#ifdef CONFIG_SND_HDA_POWER_SAVE
10261#define alc262_loopbacks	alc880_loopbacks
10262#endif
10263
10264/* pcm configuration: identiacal with ALC880 */
10265#define alc262_pcm_analog_playback	alc880_pcm_analog_playback
10266#define alc262_pcm_analog_capture	alc880_pcm_analog_capture
10267#define alc262_pcm_digital_playback	alc880_pcm_digital_playback
10268#define alc262_pcm_digital_capture	alc880_pcm_digital_capture
10269
10270/*
10271 * BIOS auto configuration
10272 */
10273static int alc262_parse_auto_config(struct hda_codec *codec)
10274{
10275	struct alc_spec *spec = codec->spec;
10276	int err;
10277	static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10278
10279	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10280					   alc262_ignore);
10281	if (err < 0)
10282		return err;
10283	if (!spec->autocfg.line_outs)
10284		return 0; /* can't find valid BIOS pin config */
10285	err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10286	if (err < 0)
10287		return err;
10288	err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10289	if (err < 0)
10290		return err;
10291
10292	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10293
10294	if (spec->autocfg.dig_out_pin)
10295		spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10296	if (spec->autocfg.dig_in_pin)
10297		spec->dig_in_nid = ALC262_DIGIN_NID;
10298
10299	if (spec->kctl_alloc)
10300		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10301
10302	spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
10303	spec->num_mux_defs = 1;
10304	spec->input_mux = &spec->private_imux;
10305
10306	err = alc_auto_add_mic_boost(codec);
10307	if (err < 0)
10308		return err;
10309
10310	return 1;
10311}
10312
10313#define alc262_auto_init_multi_out	alc882_auto_init_multi_out
10314#define alc262_auto_init_hp_out		alc882_auto_init_hp_out
10315#define alc262_auto_init_analog_input	alc882_auto_init_analog_input
10316#define alc262_auto_init_input_src	alc882_auto_init_input_src
10317
10318
10319/* init callback for auto-configuration model -- overriding the default init */
10320static void alc262_auto_init(struct hda_codec *codec)
10321{
10322	struct alc_spec *spec = codec->spec;
10323	alc262_auto_init_multi_out(codec);
10324	alc262_auto_init_hp_out(codec);
10325	alc262_auto_init_analog_input(codec);
10326	alc262_auto_init_input_src(codec);
10327	if (spec->unsol_event)
10328		alc_inithook(codec);
10329}
10330
10331/*
10332 * configuration and preset
10333 */
10334static const char *alc262_models[ALC262_MODEL_LAST] = {
10335	[ALC262_BASIC]		= "basic",
10336	[ALC262_HIPPO]		= "hippo",
10337	[ALC262_HIPPO_1]	= "hippo_1",
10338	[ALC262_FUJITSU]	= "fujitsu",
10339	[ALC262_HP_BPC]		= "hp-bpc",
10340	[ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
10341	[ALC262_HP_TC_T5735]	= "hp-tc-t5735",
10342	[ALC262_HP_RP5700]	= "hp-rp5700",
10343	[ALC262_BENQ_ED8]	= "benq",
10344	[ALC262_BENQ_T31]	= "benq-t31",
10345	[ALC262_SONY_ASSAMD]	= "sony-assamd",
10346	[ALC262_TOSHIBA_S06]	= "toshiba-s06",
10347	[ALC262_TOSHIBA_RX1]	= "toshiba-rx1",
10348	[ALC262_ULTRA]		= "ultra",
10349	[ALC262_LENOVO_3000]	= "lenovo-3000",
10350	[ALC262_NEC]		= "nec",
10351	[ALC262_AUTO]		= "auto",
10352};
10353
10354static struct snd_pci_quirk alc262_cfg_tbl[] = {
10355	SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10356	SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
10357	SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
10358	SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
10359	SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
10360	SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
10361	SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
10362	SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
10363	SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
10364	SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
10365	SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
10366	SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
10367	SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
10368	SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
10369	SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
10370	SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
10371	SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
10372	SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
10373	SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10374	SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10375	SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
10376	SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10377		      ALC262_HP_TC_T5735),
10378	SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
10379	SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10380	SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
10381	SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10382	SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10383	SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
10384	SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10385		      ALC262_TOSHIBA_RX1),
10386	SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
10387	SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
10388	SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
10389	SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
10390	SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA),
10391	SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
10392	SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10393	SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10394	SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
10395	{}
10396};
10397
10398static struct alc_config_preset alc262_presets[] = {
10399	[ALC262_BASIC] = {
10400		.mixers = { alc262_base_mixer },
10401		.init_verbs = { alc262_init_verbs },
10402		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10403		.dac_nids = alc262_dac_nids,
10404		.hp_nid = 0x03,
10405		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10406		.channel_mode = alc262_modes,
10407		.input_mux = &alc262_capture_source,
10408	},
10409	[ALC262_HIPPO] = {
10410		.mixers = { alc262_base_mixer },
10411		.init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10412		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10413		.dac_nids = alc262_dac_nids,
10414		.hp_nid = 0x03,
10415		.dig_out_nid = ALC262_DIGOUT_NID,
10416		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10417		.channel_mode = alc262_modes,
10418		.input_mux = &alc262_capture_source,
10419		.unsol_event = alc262_hippo_unsol_event,
10420		.init_hook = alc262_hippo_automute,
10421	},
10422	[ALC262_HIPPO_1] = {
10423		.mixers = { alc262_hippo1_mixer },
10424		.init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10425		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10426		.dac_nids = alc262_dac_nids,
10427		.hp_nid = 0x02,
10428		.dig_out_nid = ALC262_DIGOUT_NID,
10429		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10430		.channel_mode = alc262_modes,
10431		.input_mux = &alc262_capture_source,
10432		.unsol_event = alc262_hippo1_unsol_event,
10433		.init_hook = alc262_hippo1_automute,
10434	},
10435	[ALC262_FUJITSU] = {
10436		.mixers = { alc262_fujitsu_mixer },
10437		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10438				alc262_fujitsu_unsol_verbs },
10439		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10440		.dac_nids = alc262_dac_nids,
10441		.hp_nid = 0x03,
10442		.dig_out_nid = ALC262_DIGOUT_NID,
10443		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10444		.channel_mode = alc262_modes,
10445		.input_mux = &alc262_fujitsu_capture_source,
10446		.unsol_event = alc262_fujitsu_unsol_event,
10447		.init_hook = alc262_fujitsu_init_hook,
10448	},
10449	[ALC262_HP_BPC] = {
10450		.mixers = { alc262_HP_BPC_mixer },
10451		.init_verbs = { alc262_HP_BPC_init_verbs },
10452		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10453		.dac_nids = alc262_dac_nids,
10454		.hp_nid = 0x03,
10455		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10456		.channel_mode = alc262_modes,
10457		.input_mux = &alc262_HP_capture_source,
10458		.unsol_event = alc262_hp_bpc_unsol_event,
10459		.init_hook = alc262_hp_bpc_automute,
10460	},
10461	[ALC262_HP_BPC_D7000_WF] = {
10462		.mixers = { alc262_HP_BPC_WildWest_mixer },
10463		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10464		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10465		.dac_nids = alc262_dac_nids,
10466		.hp_nid = 0x03,
10467		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10468		.channel_mode = alc262_modes,
10469		.input_mux = &alc262_HP_D7000_capture_source,
10470		.unsol_event = alc262_hp_wildwest_unsol_event,
10471		.init_hook = alc262_hp_wildwest_automute,
10472	},
10473	[ALC262_HP_BPC_D7000_WL] = {
10474		.mixers = { alc262_HP_BPC_WildWest_mixer,
10475			    alc262_HP_BPC_WildWest_option_mixer },
10476		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10477		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10478		.dac_nids = alc262_dac_nids,
10479		.hp_nid = 0x03,
10480		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10481		.channel_mode = alc262_modes,
10482		.input_mux = &alc262_HP_D7000_capture_source,
10483		.unsol_event = alc262_hp_wildwest_unsol_event,
10484		.init_hook = alc262_hp_wildwest_automute,
10485	},
10486	[ALC262_HP_TC_T5735] = {
10487		.mixers = { alc262_hp_t5735_mixer },
10488		.init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
10489		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10490		.dac_nids = alc262_dac_nids,
10491		.hp_nid = 0x03,
10492		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10493		.channel_mode = alc262_modes,
10494		.input_mux = &alc262_capture_source,
10495		.unsol_event = alc262_hp_t5735_unsol_event,
10496		.init_hook = alc262_hp_t5735_init_hook,
10497	},
10498	[ALC262_HP_RP5700] = {
10499		.mixers = { alc262_hp_rp5700_mixer },
10500		.init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
10501		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10502		.dac_nids = alc262_dac_nids,
10503		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10504		.channel_mode = alc262_modes,
10505		.input_mux = &alc262_hp_rp5700_capture_source,
10506        },
10507	[ALC262_BENQ_ED8] = {
10508		.mixers = { alc262_base_mixer },
10509		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
10510		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10511		.dac_nids = alc262_dac_nids,
10512		.hp_nid = 0x03,
10513		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10514		.channel_mode = alc262_modes,
10515		.input_mux = &alc262_capture_source,
10516	},
10517	[ALC262_SONY_ASSAMD] = {
10518		.mixers = { alc262_sony_mixer },
10519		.init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
10520		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10521		.dac_nids = alc262_dac_nids,
10522		.hp_nid = 0x02,
10523		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10524		.channel_mode = alc262_modes,
10525		.input_mux = &alc262_capture_source,
10526		.unsol_event = alc262_hippo_unsol_event,
10527		.init_hook = alc262_hippo_automute,
10528	},
10529	[ALC262_BENQ_T31] = {
10530		.mixers = { alc262_benq_t31_mixer },
10531		.init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
10532		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10533		.dac_nids = alc262_dac_nids,
10534		.hp_nid = 0x03,
10535		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10536		.channel_mode = alc262_modes,
10537		.input_mux = &alc262_capture_source,
10538		.unsol_event = alc262_hippo_unsol_event,
10539		.init_hook = alc262_hippo_automute,
10540	},
10541	[ALC262_ULTRA] = {
10542		.mixers = { alc262_ultra_mixer, alc262_ultra_capture_mixer },
10543		.init_verbs = { alc262_ultra_verbs },
10544		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10545		.dac_nids = alc262_dac_nids,
10546		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10547		.channel_mode = alc262_modes,
10548		.input_mux = &alc262_ultra_capture_source,
10549		.adc_nids = alc262_adc_nids, /* ADC0 */
10550		.capsrc_nids = alc262_capsrc_nids,
10551		.num_adc_nids = 1, /* single ADC */
10552		.unsol_event = alc262_ultra_unsol_event,
10553		.init_hook = alc262_ultra_automute,
10554	},
10555	[ALC262_LENOVO_3000] = {
10556		.mixers = { alc262_lenovo_3000_mixer },
10557		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10558				alc262_lenovo_3000_unsol_verbs },
10559		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10560		.dac_nids = alc262_dac_nids,
10561		.hp_nid = 0x03,
10562		.dig_out_nid = ALC262_DIGOUT_NID,
10563		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10564		.channel_mode = alc262_modes,
10565		.input_mux = &alc262_fujitsu_capture_source,
10566		.unsol_event = alc262_lenovo_3000_unsol_event,
10567	},
10568	[ALC262_NEC] = {
10569		.mixers = { alc262_nec_mixer },
10570		.init_verbs = { alc262_nec_verbs },
10571		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10572		.dac_nids = alc262_dac_nids,
10573		.hp_nid = 0x03,
10574		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10575		.channel_mode = alc262_modes,
10576		.input_mux = &alc262_capture_source,
10577	},
10578	[ALC262_TOSHIBA_S06] = {
10579		.mixers = { alc262_toshiba_s06_mixer },
10580		.init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
10581							alc262_eapd_verbs },
10582		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10583		.capsrc_nids = alc262_dmic_capsrc_nids,
10584		.dac_nids = alc262_dac_nids,
10585		.adc_nids = alc262_dmic_adc_nids, /* ADC0 */
10586		.dig_out_nid = ALC262_DIGOUT_NID,
10587		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10588		.channel_mode = alc262_modes,
10589		.input_mux = &alc262_dmic_capture_source,
10590		.unsol_event = alc262_toshiba_s06_unsol_event,
10591		.init_hook = alc262_toshiba_s06_init_hook,
10592	},
10593	[ALC262_TOSHIBA_RX1] = {
10594		.mixers = { alc262_toshiba_rx1_mixer },
10595		.init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
10596		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10597		.dac_nids = alc262_dac_nids,
10598		.hp_nid = 0x03,
10599		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10600		.channel_mode = alc262_modes,
10601		.input_mux = &alc262_capture_source,
10602		.unsol_event = alc262_hippo_unsol_event,
10603		.init_hook = alc262_hippo_automute,
10604	},
10605};
10606
10607static int patch_alc262(struct hda_codec *codec)
10608{
10609	struct alc_spec *spec;
10610	int board_config;
10611	int err;
10612
10613	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10614	if (spec == NULL)
10615		return -ENOMEM;
10616
10617	codec->spec = spec;
10618#if 0
10619	/* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
10620	 * under-run
10621	 */
10622	{
10623	int tmp;
10624	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10625	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
10626	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10627	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
10628	}
10629#endif
10630
10631	alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10632
10633	board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
10634						  alc262_models,
10635						  alc262_cfg_tbl);
10636
10637	if (board_config < 0) {
10638		printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
10639		       "trying auto-probe from BIOS...\n");
10640		board_config = ALC262_AUTO;
10641	}
10642
10643	if (board_config == ALC262_AUTO) {
10644		/* automatic parse from the BIOS config */
10645		err = alc262_parse_auto_config(codec);
10646		if (err < 0) {
10647			alc_free(codec);
10648			return err;
10649		} else if (!err) {
10650			printk(KERN_INFO
10651			       "hda_codec: Cannot set up configuration "
10652			       "from BIOS.  Using base mode...\n");
10653			board_config = ALC262_BASIC;
10654		}
10655	}
10656
10657	if (board_config != ALC262_AUTO)
10658		setup_preset(spec, &alc262_presets[board_config]);
10659
10660	spec->stream_name_analog = "ALC262 Analog";
10661	spec->stream_analog_playback = &alc262_pcm_analog_playback;
10662	spec->stream_analog_capture = &alc262_pcm_analog_capture;
10663
10664	spec->stream_name_digital = "ALC262 Digital";
10665	spec->stream_digital_playback = &alc262_pcm_digital_playback;
10666	spec->stream_digital_capture = &alc262_pcm_digital_capture;
10667
10668	if (!spec->adc_nids && spec->input_mux) {
10669		/* check whether NID 0x07 is valid */
10670		unsigned int wcap = get_wcaps(codec, 0x07);
10671
10672		/* get type */
10673		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
10674		if (wcap != AC_WID_AUD_IN) {
10675			spec->adc_nids = alc262_adc_nids_alt;
10676			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
10677			spec->capsrc_nids = alc262_capsrc_nids_alt;
10678			spec->mixers[spec->num_mixers] =
10679				alc262_capture_alt_mixer;
10680			spec->num_mixers++;
10681		} else {
10682			spec->adc_nids = alc262_adc_nids;
10683			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
10684			spec->capsrc_nids = alc262_capsrc_nids;
10685			spec->mixers[spec->num_mixers] = alc262_capture_mixer;
10686			spec->num_mixers++;
10687		}
10688	}
10689
10690	spec->vmaster_nid = 0x0c;
10691
10692	codec->patch_ops = alc_patch_ops;
10693	if (board_config == ALC262_AUTO)
10694		spec->init_hook = alc262_auto_init;
10695#ifdef CONFIG_SND_HDA_POWER_SAVE
10696	if (!spec->loopback.amplist)
10697		spec->loopback.amplist = alc262_loopbacks;
10698#endif
10699
10700	return 0;
10701}
10702
10703/*
10704 *  ALC268 channel source setting (2 channel)
10705 */
10706#define ALC268_DIGOUT_NID	ALC880_DIGOUT_NID
10707#define alc268_modes		alc260_modes
10708
10709static hda_nid_t alc268_dac_nids[2] = {
10710	/* front, hp */
10711	0x02, 0x03
10712};
10713
10714static hda_nid_t alc268_adc_nids[2] = {
10715	/* ADC0-1 */
10716	0x08, 0x07
10717};
10718
10719static hda_nid_t alc268_adc_nids_alt[1] = {
10720	/* ADC0 */
10721	0x08
10722};
10723
10724static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
10725
10726static struct snd_kcontrol_new alc268_base_mixer[] = {
10727	/* output mixer control */
10728	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10729	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10730	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10731	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10732	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10733	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10734	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10735	{ }
10736};
10737
10738/* bind Beep switches of both NID 0x0f and 0x10 */
10739static struct hda_bind_ctls alc268_bind_beep_sw = {
10740	.ops = &snd_hda_bind_sw,
10741	.values = {
10742		HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
10743		HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
10744		0
10745	},
10746};
10747
10748static struct snd_kcontrol_new alc268_beep_mixer[] = {
10749	HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
10750	HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
10751	{ }
10752};
10753
10754static struct hda_verb alc268_eapd_verbs[] = {
10755	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10756	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10757	{ }
10758};
10759
10760/* Toshiba specific */
10761#define alc268_toshiba_automute	alc262_hippo_automute
10762
10763static struct hda_verb alc268_toshiba_verbs[] = {
10764	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10765	{ } /* end */
10766};
10767
10768static struct hda_input_mux alc268_acer_lc_capture_source = {
10769	.num_items = 2,
10770	.items = {
10771		{ "i-Mic", 0x6 },
10772		{ "E-Mic", 0x0 },
10773	},
10774};
10775
10776/* Acer specific */
10777/* bind volumes of both NID 0x02 and 0x03 */
10778static struct hda_bind_ctls alc268_acer_bind_master_vol = {
10779	.ops = &snd_hda_bind_vol,
10780	.values = {
10781		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
10782		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
10783		0
10784	},
10785};
10786
10787/* mute/unmute internal speaker according to the hp jack and mute state */
10788static void alc268_acer_automute(struct hda_codec *codec, int force)
10789{
10790	struct alc_spec *spec = codec->spec;
10791	unsigned int mute;
10792
10793	if (force || !spec->sense_updated) {
10794		unsigned int present;
10795		present = snd_hda_codec_read(codec, 0x14, 0,
10796				    	 AC_VERB_GET_PIN_SENSE, 0);
10797		spec->jack_present = (present & 0x80000000) != 0;
10798		spec->sense_updated = 1;
10799	}
10800	if (spec->jack_present)
10801		mute = HDA_AMP_MUTE; /* mute internal speaker */
10802	else /* unmute internal speaker if necessary */
10803		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10804	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10805				 HDA_AMP_MUTE, mute);
10806}
10807
10808
10809/* bind hp and internal speaker mute (with plug check) */
10810static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
10811				     struct snd_ctl_elem_value *ucontrol)
10812{
10813	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10814	long *valp = ucontrol->value.integer.value;
10815	int change;
10816
10817	change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10818					  HDA_AMP_MUTE,
10819					  valp[0] ? 0 : HDA_AMP_MUTE);
10820	change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10821					   HDA_AMP_MUTE,
10822					   valp[1] ? 0 : HDA_AMP_MUTE);
10823	if (change)
10824		alc268_acer_automute(codec, 0);
10825	return change;
10826}
10827
10828static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
10829	/* output mixer control */
10830	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10831	{
10832		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10833		.name = "Master Playback Switch",
10834		.info = snd_hda_mixer_amp_switch_info,
10835		.get = snd_hda_mixer_amp_switch_get,
10836		.put = alc268_acer_master_sw_put,
10837		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10838	},
10839	HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
10840	{ }
10841};
10842
10843static struct snd_kcontrol_new alc268_acer_mixer[] = {
10844	/* output mixer control */
10845	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10846	{
10847		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10848		.name = "Master Playback Switch",
10849		.info = snd_hda_mixer_amp_switch_info,
10850		.get = snd_hda_mixer_amp_switch_get,
10851		.put = alc268_acer_master_sw_put,
10852		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10853	},
10854	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10855	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10856	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10857	{ }
10858};
10859
10860static struct hda_verb alc268_acer_aspire_one_verbs[] = {
10861	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10862	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10863	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10864	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10865	{0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
10866	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
10867	{ }
10868};
10869
10870static struct hda_verb alc268_acer_verbs[] = {
10871	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
10872	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10873	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10874	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10875	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10876	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10877	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10878	{ }
10879};
10880
10881/* unsolicited event for HP jack sensing */
10882static void alc268_toshiba_unsol_event(struct hda_codec *codec,
10883				       unsigned int res)
10884{
10885	if ((res >> 26) != ALC880_HP_EVENT)
10886		return;
10887	alc268_toshiba_automute(codec);
10888}
10889
10890static void alc268_acer_unsol_event(struct hda_codec *codec,
10891				       unsigned int res)
10892{
10893	if ((res >> 26) != ALC880_HP_EVENT)
10894		return;
10895	alc268_acer_automute(codec, 1);
10896}
10897
10898static void alc268_acer_init_hook(struct hda_codec *codec)
10899{
10900	alc268_acer_automute(codec, 1);
10901}
10902
10903/* toggle speaker-output according to the hp-jack state */
10904static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
10905{
10906	unsigned int present;
10907	unsigned char bits;
10908
10909	present = snd_hda_codec_read(codec, 0x15, 0,
10910				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10911	bits = present ? AMP_IN_MUTE(0) : 0;
10912	snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
10913				AMP_IN_MUTE(0), bits);
10914	snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
10915				AMP_IN_MUTE(0), bits);
10916}
10917
10918
10919static void alc268_acer_mic_automute(struct hda_codec *codec)
10920{
10921	unsigned int present;
10922
10923	present = snd_hda_codec_read(codec, 0x18, 0,
10924				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10925	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
10926			    present ? 0x0 : 0x6);
10927}
10928
10929static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
10930				    unsigned int res)
10931{
10932	if ((res >> 26) == ALC880_HP_EVENT)
10933		alc268_aspire_one_speaker_automute(codec);
10934	if ((res >> 26) == ALC880_MIC_EVENT)
10935		alc268_acer_mic_automute(codec);
10936}
10937
10938static void alc268_acer_lc_init_hook(struct hda_codec *codec)
10939{
10940	alc268_aspire_one_speaker_automute(codec);
10941	alc268_acer_mic_automute(codec);
10942}
10943
10944static struct snd_kcontrol_new alc268_dell_mixer[] = {
10945	/* output mixer control */
10946	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10947	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10948	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10949	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10950	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10951	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10952	{ }
10953};
10954
10955static struct hda_verb alc268_dell_verbs[] = {
10956	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10957	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10958	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10959	{ }
10960};
10961
10962/* mute/unmute internal speaker according to the hp jack and mute state */
10963static void alc268_dell_automute(struct hda_codec *codec)
10964{
10965	unsigned int present;
10966	unsigned int mute;
10967
10968	present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
10969	if (present & 0x80000000)
10970		mute = HDA_AMP_MUTE;
10971	else
10972		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
10973	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10974				 HDA_AMP_MUTE, mute);
10975}
10976
10977static void alc268_dell_unsol_event(struct hda_codec *codec,
10978				    unsigned int res)
10979{
10980	if ((res >> 26) != ALC880_HP_EVENT)
10981		return;
10982	alc268_dell_automute(codec);
10983}
10984
10985#define alc268_dell_init_hook	alc268_dell_automute
10986
10987static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
10988	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10989	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10990	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10991	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10992	HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10993	HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
10994	HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
10995	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10996	{ }
10997};
10998
10999static struct hda_verb alc267_quanta_il1_verbs[] = {
11000	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11001	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
11002	{ }
11003};
11004
11005static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
11006{
11007	unsigned int present;
11008
11009	present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
11010		& AC_PINSENSE_PRESENCE;
11011	snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
11012			    present ? 0 : PIN_OUT);
11013}
11014
11015static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11016{
11017	unsigned int present;
11018
11019	present = snd_hda_codec_read(codec, 0x18, 0,
11020				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11021	snd_hda_codec_write(codec, 0x23, 0,
11022			    AC_VERB_SET_CONNECT_SEL,
11023			    present ? 0x00 : 0x01);
11024}
11025
11026static void alc267_quanta_il1_automute(struct hda_codec *codec)
11027{
11028	alc267_quanta_il1_hp_automute(codec);
11029	alc267_quanta_il1_mic_automute(codec);
11030}
11031
11032static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
11033					   unsigned int res)
11034{
11035	switch (res >> 26) {
11036	case ALC880_HP_EVENT:
11037		alc267_quanta_il1_hp_automute(codec);
11038		break;
11039	case ALC880_MIC_EVENT:
11040		alc267_quanta_il1_mic_automute(codec);
11041		break;
11042	}
11043}
11044
11045/*
11046 * generic initialization of ADC, input mixers and output mixers
11047 */
11048static struct hda_verb alc268_base_init_verbs[] = {
11049	/* Unmute DAC0-1 and set vol = 0 */
11050	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11051	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11052	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11053	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11054	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11055	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11056
11057	/*
11058	 * Set up output mixers (0x0c - 0x0e)
11059	 */
11060	/* set vol=0 to output mixers */
11061	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11062	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11063	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11064        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
11065
11066	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11067	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11068
11069	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11070	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11071	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11072	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11073	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11074	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11075	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11076	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11077
11078	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11079	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11080	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11081	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11082	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11083	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11084	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11085
11086	/* set PCBEEP vol = 0, mute connections */
11087	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11088	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11089	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11090
11091	/* Unmute Selector 23h,24h and set the default input to mic-in */
11092
11093	{0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11094	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11095	{0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11096	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11097
11098	{ }
11099};
11100
11101/*
11102 * generic initialization of ADC, input mixers and output mixers
11103 */
11104static struct hda_verb alc268_volume_init_verbs[] = {
11105	/* set output DAC */
11106	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11107	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11108	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11109	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11110
11111	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11112	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11113	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11114	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11115	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11116
11117	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11118	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11119	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11120	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11121	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11122
11123	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11124	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11125	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11126	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11127
11128	/* set PCBEEP vol = 0, mute connections */
11129	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11130	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11131	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11132
11133	{ }
11134};
11135
11136#define alc268_mux_enum_info alc_mux_enum_info
11137#define alc268_mux_enum_get alc_mux_enum_get
11138#define alc268_mux_enum_put alc_mux_enum_put
11139
11140static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11141	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11142	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11143	{
11144		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11145		/* The multiple "Capture Source" controls confuse alsamixer
11146		 * So call somewhat different..
11147		 */
11148		/* .name = "Capture Source", */
11149		.name = "Input Source",
11150		.count = 1,
11151		.info = alc268_mux_enum_info,
11152		.get = alc268_mux_enum_get,
11153		.put = alc268_mux_enum_put,
11154	},
11155	{ } /* end */
11156};
11157
11158static struct snd_kcontrol_new alc268_capture_mixer[] = {
11159	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11160	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11161	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11162	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11163	{
11164		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11165		/* The multiple "Capture Source" controls confuse alsamixer
11166		 * So call somewhat different..
11167		 */
11168		/* .name = "Capture Source", */
11169		.name = "Input Source",
11170		.count = 2,
11171		.info = alc268_mux_enum_info,
11172		.get = alc268_mux_enum_get,
11173		.put = alc268_mux_enum_put,
11174	},
11175	{ } /* end */
11176};
11177
11178static struct hda_input_mux alc268_capture_source = {
11179	.num_items = 4,
11180	.items = {
11181		{ "Mic", 0x0 },
11182		{ "Front Mic", 0x1 },
11183		{ "Line", 0x2 },
11184		{ "CD", 0x3 },
11185	},
11186};
11187
11188static struct hda_input_mux alc268_acer_capture_source = {
11189	.num_items = 3,
11190	.items = {
11191		{ "Mic", 0x0 },
11192		{ "Internal Mic", 0x6 },
11193		{ "Line", 0x2 },
11194	},
11195};
11196
11197#ifdef CONFIG_SND_DEBUG
11198static struct snd_kcontrol_new alc268_test_mixer[] = {
11199	/* Volume widgets */
11200	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11201	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11202	HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11203	HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11204	HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11205	HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11206	HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11207	HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11208	HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11209	HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11210	HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11211	HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11212	HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11213	/* The below appears problematic on some hardwares */
11214	/*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11215	HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11216	HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11217	HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11218	HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11219
11220	/* Modes for retasking pin widgets */
11221	ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11222	ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11223	ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11224	ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11225
11226	/* Controls for GPIO pins, assuming they are configured as outputs */
11227	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11228	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11229	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11230	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11231
11232	/* Switches to allow the digital SPDIF output pin to be enabled.
11233	 * The ALC268 does not have an SPDIF input.
11234	 */
11235	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11236
11237	/* A switch allowing EAPD to be enabled.  Some laptops seem to use
11238	 * this output to turn on an external amplifier.
11239	 */
11240	ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11241	ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11242
11243	{ } /* end */
11244};
11245#endif
11246
11247/* create input playback/capture controls for the given pin */
11248static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11249				    const char *ctlname, int idx)
11250{
11251	char name[32];
11252	int err;
11253
11254	sprintf(name, "%s Playback Volume", ctlname);
11255	if (nid == 0x14) {
11256		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11257				  HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11258						      HDA_OUTPUT));
11259		if (err < 0)
11260			return err;
11261	} else if (nid == 0x15) {
11262		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11263				  HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11264						      HDA_OUTPUT));
11265		if (err < 0)
11266			return err;
11267	} else
11268		return -1;
11269	sprintf(name, "%s Playback Switch", ctlname);
11270	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11271			  HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11272	if (err < 0)
11273		return err;
11274	return 0;
11275}
11276
11277/* add playback controls from the parsed DAC table */
11278static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11279					     const struct auto_pin_cfg *cfg)
11280{
11281	hda_nid_t nid;
11282	int err;
11283
11284	spec->multiout.num_dacs = 2;	/* only use one dac */
11285	spec->multiout.dac_nids = spec->private_dac_nids;
11286	spec->multiout.dac_nids[0] = 2;
11287	spec->multiout.dac_nids[1] = 3;
11288
11289	nid = cfg->line_out_pins[0];
11290	if (nid)
11291		alc268_new_analog_output(spec, nid, "Front", 0);
11292
11293	nid = cfg->speaker_pins[0];
11294	if (nid == 0x1d) {
11295		err = add_control(spec, ALC_CTL_WIDGET_VOL,
11296				  "Speaker Playback Volume",
11297				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11298		if (err < 0)
11299			return err;
11300	}
11301	nid = cfg->hp_pins[0];
11302	if (nid)
11303		alc268_new_analog_output(spec, nid, "Headphone", 0);
11304
11305	nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11306	if (nid == 0x16) {
11307		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11308				  "Mono Playback Switch",
11309				  HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11310		if (err < 0)
11311			return err;
11312	}
11313	return 0;
11314}
11315
11316/* create playback/capture controls for input pins */
11317static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11318						const struct auto_pin_cfg *cfg)
11319{
11320	struct hda_input_mux *imux = &spec->private_imux;
11321	int i, idx1;
11322
11323	for (i = 0; i < AUTO_PIN_LAST; i++) {
11324		switch(cfg->input_pins[i]) {
11325		case 0x18:
11326			idx1 = 0;	/* Mic 1 */
11327			break;
11328		case 0x19:
11329			idx1 = 1;	/* Mic 2 */
11330			break;
11331		case 0x1a:
11332			idx1 = 2;	/* Line In */
11333			break;
11334		case 0x1c:
11335			idx1 = 3;	/* CD */
11336			break;
11337		case 0x12:
11338		case 0x13:
11339			idx1 = 6;	/* digital mics */
11340			break;
11341		default:
11342			continue;
11343		}
11344		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11345		imux->items[imux->num_items].index = idx1;
11346		imux->num_items++;
11347	}
11348	return 0;
11349}
11350
11351static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11352{
11353	struct alc_spec *spec = codec->spec;
11354	hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11355	hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11356	hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11357	unsigned int	dac_vol1, dac_vol2;
11358
11359	if (speaker_nid) {
11360		snd_hda_codec_write(codec, speaker_nid, 0,
11361				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11362		snd_hda_codec_write(codec, 0x0f, 0,
11363				    AC_VERB_SET_AMP_GAIN_MUTE,
11364				    AMP_IN_UNMUTE(1));
11365		snd_hda_codec_write(codec, 0x10, 0,
11366				    AC_VERB_SET_AMP_GAIN_MUTE,
11367				    AMP_IN_UNMUTE(1));
11368	} else {
11369		snd_hda_codec_write(codec, 0x0f, 0,
11370				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11371		snd_hda_codec_write(codec, 0x10, 0,
11372				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11373	}
11374
11375	dac_vol1 = dac_vol2 = 0xb000 | 0x40;	/* set max volume  */
11376	if (line_nid == 0x14)
11377		dac_vol2 = AMP_OUT_ZERO;
11378	else if (line_nid == 0x15)
11379		dac_vol1 = AMP_OUT_ZERO;
11380	if (hp_nid == 0x14)
11381		dac_vol2 = AMP_OUT_ZERO;
11382	else if (hp_nid == 0x15)
11383		dac_vol1 = AMP_OUT_ZERO;
11384	if (line_nid != 0x16 || hp_nid != 0x16 ||
11385	    spec->autocfg.line_out_pins[1] != 0x16 ||
11386	    spec->autocfg.line_out_pins[2] != 0x16)
11387		dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11388
11389	snd_hda_codec_write(codec, 0x02, 0,
11390			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11391	snd_hda_codec_write(codec, 0x03, 0,
11392			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11393}
11394
11395/* pcm configuration: identiacal with ALC880 */
11396#define alc268_pcm_analog_playback	alc880_pcm_analog_playback
11397#define alc268_pcm_analog_capture	alc880_pcm_analog_capture
11398#define alc268_pcm_analog_alt_capture	alc880_pcm_analog_alt_capture
11399#define alc268_pcm_digital_playback	alc880_pcm_digital_playback
11400
11401/*
11402 * BIOS auto configuration
11403 */
11404static int alc268_parse_auto_config(struct hda_codec *codec)
11405{
11406	struct alc_spec *spec = codec->spec;
11407	int err;
11408	static hda_nid_t alc268_ignore[] = { 0 };
11409
11410	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11411					   alc268_ignore);
11412	if (err < 0)
11413		return err;
11414	if (!spec->autocfg.line_outs)
11415		return 0; /* can't find valid BIOS pin config */
11416
11417	err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11418	if (err < 0)
11419		return err;
11420	err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11421	if (err < 0)
11422		return err;
11423
11424	spec->multiout.max_channels = 2;
11425
11426	/* digital only support output */
11427	if (spec->autocfg.dig_out_pin)
11428		spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
11429
11430	if (spec->kctl_alloc)
11431		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11432
11433	if (spec->autocfg.speaker_pins[0] != 0x1d)
11434		spec->mixers[spec->num_mixers++] = alc268_beep_mixer;
11435
11436	spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
11437	spec->num_mux_defs = 1;
11438	spec->input_mux = &spec->private_imux;
11439
11440	err = alc_auto_add_mic_boost(codec);
11441	if (err < 0)
11442		return err;
11443
11444	return 1;
11445}
11446
11447#define alc268_auto_init_multi_out	alc882_auto_init_multi_out
11448#define alc268_auto_init_hp_out		alc882_auto_init_hp_out
11449#define alc268_auto_init_analog_input	alc882_auto_init_analog_input
11450
11451/* init callback for auto-configuration model -- overriding the default init */
11452static void alc268_auto_init(struct hda_codec *codec)
11453{
11454	struct alc_spec *spec = codec->spec;
11455	alc268_auto_init_multi_out(codec);
11456	alc268_auto_init_hp_out(codec);
11457	alc268_auto_init_mono_speaker_out(codec);
11458	alc268_auto_init_analog_input(codec);
11459	if (spec->unsol_event)
11460		alc_inithook(codec);
11461}
11462
11463/*
11464 * configuration and preset
11465 */
11466static const char *alc268_models[ALC268_MODEL_LAST] = {
11467	[ALC267_QUANTA_IL1]	= "quanta-il1",
11468	[ALC268_3ST]		= "3stack",
11469	[ALC268_TOSHIBA]	= "toshiba",
11470	[ALC268_ACER]		= "acer",
11471	[ALC268_ACER_ASPIRE_ONE]	= "acer-aspire",
11472	[ALC268_DELL]		= "dell",
11473	[ALC268_ZEPTO]		= "zepto",
11474#ifdef CONFIG_SND_DEBUG
11475	[ALC268_TEST]		= "test",
11476#endif
11477	[ALC268_AUTO]		= "auto",
11478};
11479
11480static struct snd_pci_quirk alc268_cfg_tbl[] = {
11481	SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
11482	SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
11483	SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
11484	SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
11485	SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
11486	SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
11487						ALC268_ACER_ASPIRE_ONE),
11488	SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
11489	SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
11490	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
11491	SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
11492	SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
11493	SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
11494	SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
11495	SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
11496	SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
11497	SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
11498	{}
11499};
11500
11501static struct alc_config_preset alc268_presets[] = {
11502	[ALC267_QUANTA_IL1] = {
11503		.mixers = { alc267_quanta_il1_mixer },
11504		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11505				alc267_quanta_il1_verbs },
11506		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11507		.dac_nids = alc268_dac_nids,
11508		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11509		.adc_nids = alc268_adc_nids_alt,
11510		.hp_nid = 0x03,
11511		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11512		.channel_mode = alc268_modes,
11513		.input_mux = &alc268_capture_source,
11514		.unsol_event = alc267_quanta_il1_unsol_event,
11515		.init_hook = alc267_quanta_il1_automute,
11516	},
11517	[ALC268_3ST] = {
11518		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11519			    alc268_beep_mixer },
11520		.init_verbs = { alc268_base_init_verbs },
11521		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11522		.dac_nids = alc268_dac_nids,
11523                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11524                .adc_nids = alc268_adc_nids_alt,
11525		.capsrc_nids = alc268_capsrc_nids,
11526		.hp_nid = 0x03,
11527		.dig_out_nid = ALC268_DIGOUT_NID,
11528		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11529		.channel_mode = alc268_modes,
11530		.input_mux = &alc268_capture_source,
11531	},
11532	[ALC268_TOSHIBA] = {
11533		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11534			    alc268_beep_mixer },
11535		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11536				alc268_toshiba_verbs },
11537		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11538		.dac_nids = alc268_dac_nids,
11539		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11540		.adc_nids = alc268_adc_nids_alt,
11541		.capsrc_nids = alc268_capsrc_nids,
11542		.hp_nid = 0x03,
11543		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11544		.channel_mode = alc268_modes,
11545		.input_mux = &alc268_capture_source,
11546		.unsol_event = alc268_toshiba_unsol_event,
11547		.init_hook = alc268_toshiba_automute,
11548	},
11549	[ALC268_ACER] = {
11550		.mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
11551			    alc268_beep_mixer },
11552		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11553				alc268_acer_verbs },
11554		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11555		.dac_nids = alc268_dac_nids,
11556		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11557		.adc_nids = alc268_adc_nids_alt,
11558		.capsrc_nids = alc268_capsrc_nids,
11559		.hp_nid = 0x02,
11560		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11561		.channel_mode = alc268_modes,
11562		.input_mux = &alc268_acer_capture_source,
11563		.unsol_event = alc268_acer_unsol_event,
11564		.init_hook = alc268_acer_init_hook,
11565	},
11566	[ALC268_ACER_ASPIRE_ONE] = {
11567		.mixers = { alc268_acer_aspire_one_mixer,
11568				alc268_capture_alt_mixer },
11569		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11570				alc268_acer_aspire_one_verbs },
11571		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11572		.dac_nids = alc268_dac_nids,
11573		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11574		.adc_nids = alc268_adc_nids_alt,
11575		.capsrc_nids = alc268_capsrc_nids,
11576		.hp_nid = 0x03,
11577		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11578		.channel_mode = alc268_modes,
11579		.input_mux = &alc268_acer_lc_capture_source,
11580		.unsol_event = alc268_acer_lc_unsol_event,
11581		.init_hook = alc268_acer_lc_init_hook,
11582	},
11583	[ALC268_DELL] = {
11584		.mixers = { alc268_dell_mixer, alc268_beep_mixer },
11585		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11586				alc268_dell_verbs },
11587		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11588		.dac_nids = alc268_dac_nids,
11589		.hp_nid = 0x02,
11590		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11591		.channel_mode = alc268_modes,
11592		.unsol_event = alc268_dell_unsol_event,
11593		.init_hook = alc268_dell_init_hook,
11594		.input_mux = &alc268_capture_source,
11595	},
11596	[ALC268_ZEPTO] = {
11597		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11598			    alc268_beep_mixer },
11599		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11600				alc268_toshiba_verbs },
11601		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11602		.dac_nids = alc268_dac_nids,
11603		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11604		.adc_nids = alc268_adc_nids_alt,
11605		.capsrc_nids = alc268_capsrc_nids,
11606		.hp_nid = 0x03,
11607		.dig_out_nid = ALC268_DIGOUT_NID,
11608		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11609		.channel_mode = alc268_modes,
11610		.input_mux = &alc268_capture_source,
11611		.unsol_event = alc268_toshiba_unsol_event,
11612		.init_hook = alc268_toshiba_automute
11613	},
11614#ifdef CONFIG_SND_DEBUG
11615	[ALC268_TEST] = {
11616		.mixers = { alc268_test_mixer, alc268_capture_mixer },
11617		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11618				alc268_volume_init_verbs },
11619		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
11620		.dac_nids = alc268_dac_nids,
11621		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11622		.adc_nids = alc268_adc_nids_alt,
11623		.capsrc_nids = alc268_capsrc_nids,
11624		.hp_nid = 0x03,
11625		.dig_out_nid = ALC268_DIGOUT_NID,
11626		.num_channel_mode = ARRAY_SIZE(alc268_modes),
11627		.channel_mode = alc268_modes,
11628		.input_mux = &alc268_capture_source,
11629	},
11630#endif
11631};
11632
11633static int patch_alc268(struct hda_codec *codec)
11634{
11635	struct alc_spec *spec;
11636	int board_config;
11637	int err;
11638
11639	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
11640	if (spec == NULL)
11641		return -ENOMEM;
11642
11643	codec->spec = spec;
11644
11645	board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
11646						  alc268_models,
11647						  alc268_cfg_tbl);
11648
11649	if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
11650		printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
11651		       "trying auto-probe from BIOS...\n");
11652		board_config = ALC268_AUTO;
11653	}
11654
11655	if (board_config == ALC268_AUTO) {
11656		/* automatic parse from the BIOS config */
11657		err = alc268_parse_auto_config(codec);
11658		if (err < 0) {
11659			alc_free(codec);
11660			return err;
11661		} else if (!err) {
11662			printk(KERN_INFO
11663			       "hda_codec: Cannot set up configuration "
11664			       "from BIOS.  Using base mode...\n");
11665			board_config = ALC268_3ST;
11666		}
11667	}
11668
11669	if (board_config != ALC268_AUTO)
11670		setup_preset(spec, &alc268_presets[board_config]);
11671
11672	if (codec->vendor_id == 0x10ec0267) {
11673		spec->stream_name_analog = "ALC267 Analog";
11674		spec->stream_name_digital = "ALC267 Digital";
11675	} else {
11676		spec->stream_name_analog = "ALC268 Analog";
11677		spec->stream_name_digital = "ALC268 Digital";
11678	}
11679
11680	spec->stream_analog_playback = &alc268_pcm_analog_playback;
11681	spec->stream_analog_capture = &alc268_pcm_analog_capture;
11682	spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
11683
11684	spec->stream_digital_playback = &alc268_pcm_digital_playback;
11685
11686	if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
11687		/* override the amp caps for beep generator */
11688		snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
11689					  (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
11690					  (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
11691					  (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
11692					  (0 << AC_AMPCAP_MUTE_SHIFT));
11693
11694	if (!spec->adc_nids && spec->input_mux) {
11695		/* check whether NID 0x07 is valid */
11696		unsigned int wcap = get_wcaps(codec, 0x07);
11697		int i;
11698
11699		/* get type */
11700		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11701		if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
11702			spec->adc_nids = alc268_adc_nids_alt;
11703			spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
11704			spec->mixers[spec->num_mixers] =
11705					alc268_capture_alt_mixer;
11706			spec->num_mixers++;
11707		} else {
11708			spec->adc_nids = alc268_adc_nids;
11709			spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
11710			spec->mixers[spec->num_mixers] =
11711				alc268_capture_mixer;
11712			spec->num_mixers++;
11713		}
11714		spec->capsrc_nids = alc268_capsrc_nids;
11715		/* set default input source */
11716		for (i = 0; i < spec->num_adc_nids; i++)
11717			snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
11718				0, AC_VERB_SET_CONNECT_SEL,
11719				spec->input_mux->items[0].index);
11720	}
11721
11722	spec->vmaster_nid = 0x02;
11723
11724	codec->patch_ops = alc_patch_ops;
11725	if (board_config == ALC268_AUTO)
11726		spec->init_hook = alc268_auto_init;
11727
11728	return 0;
11729}
11730
11731/*
11732 *  ALC269 channel source setting (2 channel)
11733 */
11734#define ALC269_DIGOUT_NID	ALC880_DIGOUT_NID
11735
11736#define alc269_dac_nids		alc260_dac_nids
11737
11738static hda_nid_t alc269_adc_nids[1] = {
11739	/* ADC1 */
11740	0x08,
11741};
11742
11743static hda_nid_t alc269_capsrc_nids[1] = {
11744	0x23,
11745};
11746
11747/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
11748 *       not a mux!
11749 */
11750
11751static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
11752	.num_items = 2,
11753	.items = {
11754		{ "i-Mic", 0x5 },
11755		{ "e-Mic", 0x0 },
11756	},
11757};
11758
11759static struct hda_input_mux alc269_eeepc_amic_capture_source = {
11760	.num_items = 2,
11761	.items = {
11762		{ "i-Mic", 0x1 },
11763		{ "e-Mic", 0x0 },
11764	},
11765};
11766
11767#define alc269_modes		alc260_modes
11768#define alc269_capture_source	alc880_lg_lw_capture_source
11769
11770static struct snd_kcontrol_new alc269_base_mixer[] = {
11771	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11772	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11773	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11774	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11775	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11776	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11777	HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11778	HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11779	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11780	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11781	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11782	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11783	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11784	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11785	{ } /* end */
11786};
11787
11788static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
11789	/* output mixer control */
11790	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11791	{
11792		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11793		.name = "Master Playback Switch",
11794		.info = snd_hda_mixer_amp_switch_info,
11795		.get = snd_hda_mixer_amp_switch_get,
11796		.put = alc268_acer_master_sw_put,
11797		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11798	},
11799	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11800	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11801	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11802	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11803	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11804	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11805	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
11806	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
11807	{ }
11808};
11809
11810/* bind volumes of both NID 0x0c and 0x0d */
11811static struct hda_bind_ctls alc269_epc_bind_vol = {
11812	.ops = &snd_hda_bind_vol,
11813	.values = {
11814		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11815		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11816		0
11817	},
11818};
11819
11820static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
11821	HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11822	HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
11823	HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11824	{ } /* end */
11825};
11826
11827/* capture mixer elements */
11828static struct snd_kcontrol_new alc269_capture_mixer[] = {
11829	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11830	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11831	{
11832		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11833		/* The multiple "Capture Source" controls confuse alsamixer
11834		 * So call somewhat different..
11835		 */
11836		/* .name = "Capture Source", */
11837		.name = "Input Source",
11838		.count = 1,
11839		.info = alc_mux_enum_info,
11840		.get = alc_mux_enum_get,
11841		.put = alc_mux_enum_put,
11842	},
11843	{ } /* end */
11844};
11845
11846/* capture mixer elements */
11847static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
11848	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11849	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11850	{ } /* end */
11851};
11852
11853/* beep control */
11854static struct snd_kcontrol_new alc269_beep_mixer[] = {
11855	HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11856	HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11857	{ } /* end */
11858};
11859
11860static struct hda_verb alc269_quanta_fl1_verbs[] = {
11861	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11862	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11863	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11864	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11865	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11866	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11867	{ }
11868};
11869
11870/* toggle speaker-output according to the hp-jack state */
11871static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
11872{
11873	unsigned int present;
11874	unsigned char bits;
11875
11876	present = snd_hda_codec_read(codec, 0x15, 0,
11877			AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11878	bits = present ? AMP_IN_MUTE(0) : 0;
11879	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11880			AMP_IN_MUTE(0), bits);
11881	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11882			AMP_IN_MUTE(0), bits);
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, 0x680);
11888
11889	snd_hda_codec_write(codec, 0x20, 0,
11890			AC_VERB_SET_COEF_INDEX, 0x0c);
11891	snd_hda_codec_write(codec, 0x20, 0,
11892			AC_VERB_SET_PROC_COEF, 0x480);
11893}
11894
11895static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
11896{
11897	unsigned int present;
11898
11899	present = snd_hda_codec_read(codec, 0x18, 0,
11900				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11901	snd_hda_codec_write(codec, 0x23, 0,
11902			    AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
11903}
11904
11905static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
11906				    unsigned int res)
11907{
11908	if ((res >> 26) == ALC880_HP_EVENT)
11909		alc269_quanta_fl1_speaker_automute(codec);
11910	if ((res >> 26) == ALC880_MIC_EVENT)
11911		alc269_quanta_fl1_mic_automute(codec);
11912}
11913
11914static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
11915{
11916	alc269_quanta_fl1_speaker_automute(codec);
11917	alc269_quanta_fl1_mic_automute(codec);
11918}
11919
11920static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
11921	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11922	{0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
11923	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11924	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
11925	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11926	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11927	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11928	{}
11929};
11930
11931static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
11932	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11933	{0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
11934	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11935	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
11936	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11937	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11938	{}
11939};
11940
11941/* toggle speaker-output according to the hp-jack state */
11942static void alc269_speaker_automute(struct hda_codec *codec)
11943{
11944	unsigned int present;
11945	unsigned char bits;
11946
11947	present = snd_hda_codec_read(codec, 0x15, 0,
11948				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11949	bits = present ? AMP_IN_MUTE(0) : 0;
11950	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11951				AMP_IN_MUTE(0), bits);
11952	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11953				AMP_IN_MUTE(0), bits);
11954}
11955
11956static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
11957{
11958	unsigned int present;
11959
11960	present = snd_hda_codec_read(codec, 0x18, 0,
11961				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11962	snd_hda_codec_write(codec, 0x23, 0,
11963				AC_VERB_SET_CONNECT_SEL,  (present ? 0 : 5));
11964}
11965
11966static void alc269_eeepc_amic_automute(struct hda_codec *codec)
11967{
11968	unsigned int present;
11969
11970	present = snd_hda_codec_read(codec, 0x18, 0,
11971				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11972	snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11973				0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
11974	snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11975				0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
11976}
11977
11978/* unsolicited event for HP jack sensing */
11979static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
11980				     unsigned int res)
11981{
11982	if ((res >> 26) == ALC880_HP_EVENT)
11983		alc269_speaker_automute(codec);
11984
11985	if ((res >> 26) == ALC880_MIC_EVENT)
11986		alc269_eeepc_dmic_automute(codec);
11987}
11988
11989static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
11990{
11991	alc269_speaker_automute(codec);
11992	alc269_eeepc_dmic_automute(codec);
11993}
11994
11995/* unsolicited event for HP jack sensing */
11996static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
11997				     unsigned int res)
11998{
11999	if ((res >> 26) == ALC880_HP_EVENT)
12000		alc269_speaker_automute(codec);
12001
12002	if ((res >> 26) == ALC880_MIC_EVENT)
12003		alc269_eeepc_amic_automute(codec);
12004}
12005
12006static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
12007{
12008	alc269_speaker_automute(codec);
12009	alc269_eeepc_amic_automute(codec);
12010}
12011
12012/*
12013 * generic initialization of ADC, input mixers and output mixers
12014 */
12015static struct hda_verb alc269_init_verbs[] = {
12016	/*
12017	 * Unmute ADC0 and set the default input to mic-in
12018	 */
12019	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12020
12021	/* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12022	 * analog-loopback mixer widget
12023	 * Note: PASD motherboards uses the Line In 2 as the input for
12024	 * front panel mic (mic 2)
12025	 */
12026	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12027	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12028	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12029	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12030	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12031	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12032
12033	/*
12034	 * Set up output mixers (0x0c - 0x0e)
12035	 */
12036	/* set vol=0 to output mixers */
12037	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12038	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12039
12040	/* set up input amps for analog loopback */
12041	/* Amp Indices: DAC = 0, mixer = 1 */
12042	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12043	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12044	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12045	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12046	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12047	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12048
12049	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12050	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12051	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12052	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12053	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12054	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12055	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12056
12057	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12058	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12059	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12060	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12061	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12062	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12063	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12064
12065	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12066	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12067
12068	/* FIXME: use matrix-type input source selection */
12069	/* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12070	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12071	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12072	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12073	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12074	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12075
12076	/* set EAPD */
12077	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12078	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12079	{ }
12080};
12081
12082/* add playback controls from the parsed DAC table */
12083static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12084					     const struct auto_pin_cfg *cfg)
12085{
12086	hda_nid_t nid;
12087	int err;
12088
12089	spec->multiout.num_dacs = 1;	/* only use one dac */
12090	spec->multiout.dac_nids = spec->private_dac_nids;
12091	spec->multiout.dac_nids[0] = 2;
12092
12093	nid = cfg->line_out_pins[0];
12094	if (nid) {
12095		err = add_control(spec, ALC_CTL_WIDGET_VOL,
12096				  "Front Playback Volume",
12097				  HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12098		if (err < 0)
12099			return err;
12100		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12101				  "Front Playback Switch",
12102				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12103		if (err < 0)
12104			return err;
12105	}
12106
12107	nid = cfg->speaker_pins[0];
12108	if (nid) {
12109		if (!cfg->line_out_pins[0]) {
12110			err = add_control(spec, ALC_CTL_WIDGET_VOL,
12111					  "Speaker Playback Volume",
12112					  HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12113							      HDA_OUTPUT));
12114			if (err < 0)
12115				return err;
12116		}
12117		if (nid == 0x16) {
12118			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12119					  "Speaker Playback Switch",
12120					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12121							      HDA_OUTPUT));
12122			if (err < 0)
12123				return err;
12124		} else {
12125			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12126					  "Speaker Playback Switch",
12127					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12128							      HDA_OUTPUT));
12129			if (err < 0)
12130				return err;
12131		}
12132	}
12133	nid = cfg->hp_pins[0];
12134	if (nid) {
12135		/* spec->multiout.hp_nid = 2; */
12136		if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12137			err = add_control(spec, ALC_CTL_WIDGET_VOL,
12138					  "Headphone Playback Volume",
12139					  HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12140							      HDA_OUTPUT));
12141			if (err < 0)
12142				return err;
12143		}
12144		if (nid == 0x16) {
12145			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12146					  "Headphone Playback Switch",
12147					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12148							      HDA_OUTPUT));
12149			if (err < 0)
12150				return err;
12151		} else {
12152			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12153					  "Headphone Playback Switch",
12154					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12155							      HDA_OUTPUT));
12156			if (err < 0)
12157				return err;
12158		}
12159	}
12160	return 0;
12161}
12162
12163#define alc269_auto_create_analog_input_ctls \
12164	alc880_auto_create_analog_input_ctls
12165
12166#ifdef CONFIG_SND_HDA_POWER_SAVE
12167#define alc269_loopbacks	alc880_loopbacks
12168#endif
12169
12170/* pcm configuration: identiacal with ALC880 */
12171#define alc269_pcm_analog_playback	alc880_pcm_analog_playback
12172#define alc269_pcm_analog_capture	alc880_pcm_analog_capture
12173#define alc269_pcm_digital_playback	alc880_pcm_digital_playback
12174#define alc269_pcm_digital_capture	alc880_pcm_digital_capture
12175
12176/*
12177 * BIOS auto configuration
12178 */
12179static int alc269_parse_auto_config(struct hda_codec *codec)
12180{
12181	struct alc_spec *spec = codec->spec;
12182	int i, err;
12183	static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12184
12185	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12186					   alc269_ignore);
12187	if (err < 0)
12188		return err;
12189
12190	err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12191	if (err < 0)
12192		return err;
12193	err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12194	if (err < 0)
12195		return err;
12196
12197	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12198
12199	if (spec->autocfg.dig_out_pin)
12200		spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12201
12202	if (spec->kctl_alloc)
12203		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
12204
12205	/* create a beep mixer control if the pin 0x1d isn't assigned */
12206	for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++)
12207		if (spec->autocfg.input_pins[i] == 0x1d)
12208			break;
12209	if (i >= ARRAY_SIZE(spec->autocfg.input_pins))
12210		spec->mixers[spec->num_mixers++] = alc269_beep_mixer;
12211
12212	spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
12213	spec->num_mux_defs = 1;
12214	spec->input_mux = &spec->private_imux;
12215	/* set default input source */
12216	snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12217				  0, AC_VERB_SET_CONNECT_SEL,
12218				  spec->input_mux->items[0].index);
12219
12220	err = alc_auto_add_mic_boost(codec);
12221	if (err < 0)
12222		return err;
12223
12224	spec->mixers[spec->num_mixers] = alc269_capture_mixer;
12225	spec->num_mixers++;
12226
12227	return 1;
12228}
12229
12230#define alc269_auto_init_multi_out	alc882_auto_init_multi_out
12231#define alc269_auto_init_hp_out		alc882_auto_init_hp_out
12232#define alc269_auto_init_analog_input	alc882_auto_init_analog_input
12233
12234
12235/* init callback for auto-configuration model -- overriding the default init */
12236static void alc269_auto_init(struct hda_codec *codec)
12237{
12238	struct alc_spec *spec = codec->spec;
12239	alc269_auto_init_multi_out(codec);
12240	alc269_auto_init_hp_out(codec);
12241	alc269_auto_init_analog_input(codec);
12242	if (spec->unsol_event)
12243		alc_inithook(codec);
12244}
12245
12246/*
12247 * configuration and preset
12248 */
12249static const char *alc269_models[ALC269_MODEL_LAST] = {
12250	[ALC269_BASIC]			= "basic",
12251	[ALC269_QUANTA_FL1]		= "quanta",
12252	[ALC269_ASUS_EEEPC_P703]	= "eeepc-p703",
12253	[ALC269_ASUS_EEEPC_P901]	= "eeepc-p901"
12254};
12255
12256static struct snd_pci_quirk alc269_cfg_tbl[] = {
12257	SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
12258	SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12259		      ALC269_ASUS_EEEPC_P703),
12260	SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12261		      ALC269_ASUS_EEEPC_P901),
12262	SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12263		      ALC269_ASUS_EEEPC_P901),
12264	{}
12265};
12266
12267static struct alc_config_preset alc269_presets[] = {
12268	[ALC269_BASIC] = {
12269		.mixers = { alc269_base_mixer, alc269_capture_mixer },
12270		.init_verbs = { alc269_init_verbs },
12271		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
12272		.dac_nids = alc269_dac_nids,
12273		.hp_nid = 0x03,
12274		.num_channel_mode = ARRAY_SIZE(alc269_modes),
12275		.channel_mode = alc269_modes,
12276		.input_mux = &alc269_capture_source,
12277	},
12278	[ALC269_QUANTA_FL1] = {
12279		.mixers = { alc269_quanta_fl1_mixer },
12280		.init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
12281		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
12282		.dac_nids = alc269_dac_nids,
12283		.hp_nid = 0x03,
12284		.num_channel_mode = ARRAY_SIZE(alc269_modes),
12285		.channel_mode = alc269_modes,
12286		.input_mux = &alc269_capture_source,
12287		.unsol_event = alc269_quanta_fl1_unsol_event,
12288		.init_hook = alc269_quanta_fl1_init_hook,
12289	},
12290	[ALC269_ASUS_EEEPC_P703] = {
12291		.mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer },
12292		.init_verbs = { alc269_init_verbs,
12293				alc269_eeepc_amic_init_verbs },
12294		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
12295		.dac_nids = alc269_dac_nids,
12296		.hp_nid = 0x03,
12297		.num_channel_mode = ARRAY_SIZE(alc269_modes),
12298		.channel_mode = alc269_modes,
12299		.input_mux = &alc269_eeepc_amic_capture_source,
12300		.unsol_event = alc269_eeepc_amic_unsol_event,
12301		.init_hook = alc269_eeepc_amic_inithook,
12302	},
12303	[ALC269_ASUS_EEEPC_P901] = {
12304		.mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer},
12305		.init_verbs = { alc269_init_verbs,
12306				alc269_eeepc_dmic_init_verbs },
12307		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
12308		.dac_nids = alc269_dac_nids,
12309		.hp_nid = 0x03,
12310		.num_channel_mode = ARRAY_SIZE(alc269_modes),
12311		.channel_mode = alc269_modes,
12312		.input_mux = &alc269_eeepc_dmic_capture_source,
12313		.unsol_event = alc269_eeepc_dmic_unsol_event,
12314		.init_hook = alc269_eeepc_dmic_inithook,
12315	},
12316};
12317
12318static int patch_alc269(struct hda_codec *codec)
12319{
12320	struct alc_spec *spec;
12321	int board_config;
12322	int err;
12323
12324	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12325	if (spec == NULL)
12326		return -ENOMEM;
12327
12328	codec->spec = spec;
12329
12330	alc_fix_pll_init(codec, 0x20, 0x04, 15);
12331
12332	board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
12333						  alc269_models,
12334						  alc269_cfg_tbl);
12335
12336	if (board_config < 0) {
12337		printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
12338		       "trying auto-probe from BIOS...\n");
12339		board_config = ALC269_AUTO;
12340	}
12341
12342	if (board_config == ALC269_AUTO) {
12343		/* automatic parse from the BIOS config */
12344		err = alc269_parse_auto_config(codec);
12345		if (err < 0) {
12346			alc_free(codec);
12347			return err;
12348		} else if (!err) {
12349			printk(KERN_INFO
12350			       "hda_codec: Cannot set up configuration "
12351			       "from BIOS.  Using base mode...\n");
12352			board_config = ALC269_BASIC;
12353		}
12354	}
12355
12356	if (board_config != ALC269_AUTO)
12357		setup_preset(spec, &alc269_presets[board_config]);
12358
12359	spec->stream_name_analog = "ALC269 Analog";
12360	spec->stream_analog_playback = &alc269_pcm_analog_playback;
12361	spec->stream_analog_capture = &alc269_pcm_analog_capture;
12362
12363	spec->stream_name_digital = "ALC269 Digital";
12364	spec->stream_digital_playback = &alc269_pcm_digital_playback;
12365	spec->stream_digital_capture = &alc269_pcm_digital_capture;
12366
12367	spec->adc_nids = alc269_adc_nids;
12368	spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
12369	spec->capsrc_nids = alc269_capsrc_nids;
12370
12371	codec->patch_ops = alc_patch_ops;
12372	if (board_config == ALC269_AUTO)
12373		spec->init_hook = alc269_auto_init;
12374#ifdef CONFIG_SND_HDA_POWER_SAVE
12375	if (!spec->loopback.amplist)
12376		spec->loopback.amplist = alc269_loopbacks;
12377#endif
12378
12379	return 0;
12380}
12381
12382/*
12383 *  ALC861 channel source setting (2/6 channel selection for 3-stack)
12384 */
12385
12386/*
12387 * set the path ways for 2 channel output
12388 * need to set the codec line out and mic 1 pin widgets to inputs
12389 */
12390static struct hda_verb alc861_threestack_ch2_init[] = {
12391	/* set pin widget 1Ah (line in) for input */
12392	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12393	/* set pin widget 18h (mic1/2) for input, for mic also enable
12394	 * the vref
12395	 */
12396	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12397
12398	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12399#if 0
12400	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12401	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12402#endif
12403	{ } /* end */
12404};
12405/*
12406 * 6ch mode
12407 * need to set the codec line out and mic 1 pin widgets to outputs
12408 */
12409static struct hda_verb alc861_threestack_ch6_init[] = {
12410	/* set pin widget 1Ah (line in) for output (Back Surround)*/
12411	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12412	/* set pin widget 18h (mic1) for output (CLFE)*/
12413	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12414
12415	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12416	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12417
12418	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12419#if 0
12420	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12421	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12422#endif
12423	{ } /* end */
12424};
12425
12426static struct hda_channel_mode alc861_threestack_modes[2] = {
12427	{ 2, alc861_threestack_ch2_init },
12428	{ 6, alc861_threestack_ch6_init },
12429};
12430/* Set mic1 as input and unmute the mixer */
12431static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
12432	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12433	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12434	{ } /* end */
12435};
12436/* Set mic1 as output and mute mixer */
12437static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
12438	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12439	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12440	{ } /* end */
12441};
12442
12443static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
12444	{ 2, alc861_uniwill_m31_ch2_init },
12445	{ 4, alc861_uniwill_m31_ch4_init },
12446};
12447
12448/* Set mic1 and line-in as input and unmute the mixer */
12449static struct hda_verb alc861_asus_ch2_init[] = {
12450	/* set pin widget 1Ah (line in) for input */
12451	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12452	/* set pin widget 18h (mic1/2) for input, for mic also enable
12453	 * the vref
12454	 */
12455	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12456
12457	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12458#if 0
12459	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12460	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12461#endif
12462	{ } /* end */
12463};
12464/* Set mic1 nad line-in as output and mute mixer */
12465static struct hda_verb alc861_asus_ch6_init[] = {
12466	/* set pin widget 1Ah (line in) for output (Back Surround)*/
12467	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12468	/* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12469	/* set pin widget 18h (mic1) for output (CLFE)*/
12470	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12471	/* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12472	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12473	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12474
12475	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12476#if 0
12477	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12478	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12479#endif
12480	{ } /* end */
12481};
12482
12483static struct hda_channel_mode alc861_asus_modes[2] = {
12484	{ 2, alc861_asus_ch2_init },
12485	{ 6, alc861_asus_ch6_init },
12486};
12487
12488/* patch-ALC861 */
12489
12490static struct snd_kcontrol_new alc861_base_mixer[] = {
12491        /* output mixer control */
12492	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12493	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12494	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12495	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12496	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12497
12498        /*Input mixer control */
12499	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12500	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12501	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12502	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12503	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12504	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12505	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12506	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12507	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12508	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12509
12510        /* Capture mixer control */
12511	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12512	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12513	{
12514		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12515		.name = "Capture Source",
12516		.count = 1,
12517		.info = alc_mux_enum_info,
12518		.get = alc_mux_enum_get,
12519		.put = alc_mux_enum_put,
12520	},
12521	{ } /* end */
12522};
12523
12524static struct snd_kcontrol_new alc861_3ST_mixer[] = {
12525        /* output mixer control */
12526	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12527	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12528	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12529	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12530	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12531
12532	/* Input mixer control */
12533	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12534	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12535	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12536	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12537	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12538	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12539	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12540	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12541	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12542	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12543
12544	/* Capture mixer control */
12545	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12546	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12547	{
12548		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12549		.name = "Capture Source",
12550		.count = 1,
12551		.info = alc_mux_enum_info,
12552		.get = alc_mux_enum_get,
12553		.put = alc_mux_enum_put,
12554	},
12555	{
12556		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12557		.name = "Channel Mode",
12558		.info = alc_ch_mode_info,
12559		.get = alc_ch_mode_get,
12560		.put = alc_ch_mode_put,
12561                .private_value = ARRAY_SIZE(alc861_threestack_modes),
12562	},
12563	{ } /* end */
12564};
12565
12566static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
12567        /* output mixer control */
12568	HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12569	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12570	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12571
12572        /*Capture mixer control */
12573	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12574	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12575	{
12576		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12577		.name = "Capture Source",
12578		.count = 1,
12579		.info = alc_mux_enum_info,
12580		.get = alc_mux_enum_get,
12581		.put = alc_mux_enum_put,
12582	},
12583
12584	{ } /* end */
12585};
12586
12587static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
12588        /* output mixer control */
12589	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12590	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12591	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12592	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12593	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12594
12595	/* Input mixer control */
12596	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12597	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12598	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12599	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12600	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12601	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12602	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12603	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12604	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12605	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12606
12607	/* Capture mixer control */
12608	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12609	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12610	{
12611		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12612		.name = "Capture Source",
12613		.count = 1,
12614		.info = alc_mux_enum_info,
12615		.get = alc_mux_enum_get,
12616		.put = alc_mux_enum_put,
12617	},
12618	{
12619		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12620		.name = "Channel Mode",
12621		.info = alc_ch_mode_info,
12622		.get = alc_ch_mode_get,
12623		.put = alc_ch_mode_put,
12624                .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
12625	},
12626	{ } /* end */
12627};
12628
12629static struct snd_kcontrol_new alc861_asus_mixer[] = {
12630        /* output mixer control */
12631	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12632	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12633	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12634	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12635	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12636
12637	/* Input mixer control */
12638	HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12639	HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12640	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12641	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12642	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12643	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12644	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12645	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12646	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12647	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
12648
12649	/* Capture mixer control */
12650	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12651	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12652	{
12653		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12654		.name = "Capture Source",
12655		.count = 1,
12656		.info = alc_mux_enum_info,
12657		.get = alc_mux_enum_get,
12658		.put = alc_mux_enum_put,
12659	},
12660	{
12661		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12662		.name = "Channel Mode",
12663		.info = alc_ch_mode_info,
12664		.get = alc_ch_mode_get,
12665		.put = alc_ch_mode_put,
12666                .private_value = ARRAY_SIZE(alc861_asus_modes),
12667	},
12668	{ }
12669};
12670
12671/* additional mixer */
12672static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
12673	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12674	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12675	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
12676	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
12677	{ }
12678};
12679
12680/*
12681 * generic initialization of ADC, input mixers and output mixers
12682 */
12683static struct hda_verb alc861_base_init_verbs[] = {
12684	/*
12685	 * Unmute ADC0 and set the default input to mic-in
12686	 */
12687	/* port-A for surround (rear panel) */
12688	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12689	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
12690	/* port-B for mic-in (rear panel) with vref */
12691	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12692	/* port-C for line-in (rear panel) */
12693	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12694	/* port-D for Front */
12695	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12696	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12697	/* port-E for HP out (front panel) */
12698	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12699	/* route front PCM to HP */
12700	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12701	/* port-F for mic-in (front panel) with vref */
12702	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12703	/* port-G for CLFE (rear panel) */
12704	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12705	{ 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12706	/* port-H for side (rear panel) */
12707	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12708	{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
12709	/* CD-in */
12710	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12711	/* route front mic to ADC1*/
12712	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12713	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12714
12715	/* Unmute DAC0~3 & spdif out*/
12716	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12717	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12718	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12719	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12720	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12721
12722	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12723	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12724        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12725	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12726        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12727
12728	/* Unmute Stereo Mixer 15 */
12729	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12730	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12731	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12732	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12733
12734	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12735	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12736	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12737	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12738	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12739	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12740	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12741	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12742	/* hp used DAC 3 (Front) */
12743	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12744        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12745
12746	{ }
12747};
12748
12749static struct hda_verb alc861_threestack_init_verbs[] = {
12750	/*
12751	 * Unmute ADC0 and set the default input to mic-in
12752	 */
12753	/* port-A for surround (rear panel) */
12754	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12755	/* port-B for mic-in (rear panel) with vref */
12756	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12757	/* port-C for line-in (rear panel) */
12758	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12759	/* port-D for Front */
12760	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12761	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12762	/* port-E for HP out (front panel) */
12763	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12764	/* route front PCM to HP */
12765	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12766	/* port-F for mic-in (front panel) with vref */
12767	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12768	/* port-G for CLFE (rear panel) */
12769	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12770	/* port-H for side (rear panel) */
12771	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12772	/* CD-in */
12773	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12774	/* route front mic to ADC1*/
12775	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12776	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12777	/* Unmute DAC0~3 & spdif out*/
12778	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12779	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12780	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12781	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12782	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12783
12784	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12785	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12786        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12787	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12788        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12789
12790	/* Unmute Stereo Mixer 15 */
12791	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12792	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12793	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12794	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12795
12796	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12797	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12798	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12799	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12800	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12801	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12802	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12803	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12804	/* hp used DAC 3 (Front) */
12805	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12806        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12807	{ }
12808};
12809
12810static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
12811	/*
12812	 * Unmute ADC0 and set the default input to mic-in
12813	 */
12814	/* port-A for surround (rear panel) */
12815	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12816	/* port-B for mic-in (rear panel) with vref */
12817	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12818	/* port-C for line-in (rear panel) */
12819	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12820	/* port-D for Front */
12821	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12822	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12823	/* port-E for HP out (front panel) */
12824	/* this has to be set to VREF80 */
12825	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12826	/* route front PCM to HP */
12827	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12828	/* port-F for mic-in (front panel) with vref */
12829	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12830	/* port-G for CLFE (rear panel) */
12831	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12832	/* port-H for side (rear panel) */
12833	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12834	/* CD-in */
12835	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12836	/* route front mic to ADC1*/
12837	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12838	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12839	/* Unmute DAC0~3 & spdif out*/
12840	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12841	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12842	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12843	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12844	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12845
12846	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12847	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12848        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12849	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12850        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12851
12852	/* Unmute Stereo Mixer 15 */
12853	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12854	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12855	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12856	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12857
12858	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12859	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12860	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12861	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12862	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12863	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12864	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12865	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12866	/* hp used DAC 3 (Front) */
12867	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12868        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12869	{ }
12870};
12871
12872static struct hda_verb alc861_asus_init_verbs[] = {
12873	/*
12874	 * Unmute ADC0 and set the default input to mic-in
12875	 */
12876	/* port-A for surround (rear panel)
12877	 * according to codec#0 this is the HP jack
12878	 */
12879	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
12880	/* route front PCM to HP */
12881	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
12882	/* port-B for mic-in (rear panel) with vref */
12883	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12884	/* port-C for line-in (rear panel) */
12885	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12886	/* port-D for Front */
12887	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12888	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12889	/* port-E for HP out (front panel) */
12890	/* this has to be set to VREF80 */
12891	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12892	/* route front PCM to HP */
12893	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12894	/* port-F for mic-in (front panel) with vref */
12895	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12896	/* port-G for CLFE (rear panel) */
12897	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12898	/* port-H for side (rear panel) */
12899	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12900	/* CD-in */
12901	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12902	/* route front mic to ADC1*/
12903	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12904	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12905	/* Unmute DAC0~3 & spdif out*/
12906	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12907	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12908	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12909	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12910	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12911	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12912	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12913        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12914	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12915        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12916
12917	/* Unmute Stereo Mixer 15 */
12918	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12919	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12920	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12921	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12922
12923	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12924	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12925	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12926	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12927	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12928	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12929	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12930	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12931	/* hp used DAC 3 (Front) */
12932	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12933	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12934	{ }
12935};
12936
12937/* additional init verbs for ASUS laptops */
12938static struct hda_verb alc861_asus_laptop_init_verbs[] = {
12939	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
12940	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
12941	{ }
12942};
12943
12944/*
12945 * generic initialization of ADC, input mixers and output mixers
12946 */
12947static struct hda_verb alc861_auto_init_verbs[] = {
12948	/*
12949	 * Unmute ADC0 and set the default input to mic-in
12950	 */
12951	/* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
12952	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12953
12954	/* Unmute DAC0~3 & spdif out*/
12955	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12956	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12957	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12958	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12959	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12960
12961	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12962	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12963	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12964	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12965	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12966
12967	/* Unmute Stereo Mixer 15 */
12968	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12969	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12970	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12971	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
12972
12973	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12974	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12975	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12976	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12977	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12978	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12979	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12980	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12981
12982	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12983	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12984	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12985	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12986	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12987	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12988	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12989	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12990
12991	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},	/* set Mic 1 */
12992
12993	{ }
12994};
12995
12996static struct hda_verb alc861_toshiba_init_verbs[] = {
12997	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12998
12999	{ }
13000};
13001
13002/* toggle speaker-output according to the hp-jack state */
13003static void alc861_toshiba_automute(struct hda_codec *codec)
13004{
13005	unsigned int present;
13006
13007	present = snd_hda_codec_read(codec, 0x0f, 0,
13008				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13009	snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
13010				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13011	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
13012				 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
13013}
13014
13015static void alc861_toshiba_unsol_event(struct hda_codec *codec,
13016				       unsigned int res)
13017{
13018	if ((res >> 26) == ALC880_HP_EVENT)
13019		alc861_toshiba_automute(codec);
13020}
13021
13022/* pcm configuration: identiacal with ALC880 */
13023#define alc861_pcm_analog_playback	alc880_pcm_analog_playback
13024#define alc861_pcm_analog_capture	alc880_pcm_analog_capture
13025#define alc861_pcm_digital_playback	alc880_pcm_digital_playback
13026#define alc861_pcm_digital_capture	alc880_pcm_digital_capture
13027
13028
13029#define ALC861_DIGOUT_NID	0x07
13030
13031static struct hda_channel_mode alc861_8ch_modes[1] = {
13032	{ 8, NULL }
13033};
13034
13035static hda_nid_t alc861_dac_nids[4] = {
13036	/* front, surround, clfe, side */
13037	0x03, 0x06, 0x05, 0x04
13038};
13039
13040static hda_nid_t alc660_dac_nids[3] = {
13041	/* front, clfe, surround */
13042	0x03, 0x05, 0x06
13043};
13044
13045static hda_nid_t alc861_adc_nids[1] = {
13046	/* ADC0-2 */
13047	0x08,
13048};
13049
13050static struct hda_input_mux alc861_capture_source = {
13051	.num_items = 5,
13052	.items = {
13053		{ "Mic", 0x0 },
13054		{ "Front Mic", 0x3 },
13055		{ "Line", 0x1 },
13056		{ "CD", 0x4 },
13057		{ "Mixer", 0x5 },
13058	},
13059};
13060
13061/* fill in the dac_nids table from the parsed pin configuration */
13062static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
13063				     const struct auto_pin_cfg *cfg)
13064{
13065	int i;
13066	hda_nid_t nid;
13067
13068	spec->multiout.dac_nids = spec->private_dac_nids;
13069	for (i = 0; i < cfg->line_outs; i++) {
13070		nid = cfg->line_out_pins[i];
13071		if (nid) {
13072			if (i >= ARRAY_SIZE(alc861_dac_nids))
13073				continue;
13074			spec->multiout.dac_nids[i] = alc861_dac_nids[i];
13075		}
13076	}
13077	spec->multiout.num_dacs = cfg->line_outs;
13078	return 0;
13079}
13080
13081/* add playback controls from the parsed DAC table */
13082static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
13083					     const struct auto_pin_cfg *cfg)
13084{
13085	char name[32];
13086	static const char *chname[4] = {
13087		"Front", "Surround", NULL /*CLFE*/, "Side"
13088	};
13089	hda_nid_t nid;
13090	int i, idx, err;
13091
13092	for (i = 0; i < cfg->line_outs; i++) {
13093		nid = spec->multiout.dac_nids[i];
13094		if (!nid)
13095			continue;
13096		if (nid == 0x05) {
13097			/* Center/LFE */
13098			err = add_control(spec, ALC_CTL_BIND_MUTE,
13099					  "Center Playback Switch",
13100					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13101							      HDA_OUTPUT));
13102			if (err < 0)
13103				return err;
13104			err = add_control(spec, ALC_CTL_BIND_MUTE,
13105					  "LFE Playback Switch",
13106					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13107							      HDA_OUTPUT));
13108			if (err < 0)
13109				return err;
13110		} else {
13111			for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13112			     idx++)
13113				if (nid == alc861_dac_nids[idx])
13114					break;
13115			sprintf(name, "%s Playback Switch", chname[idx]);
13116			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13117					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13118							      HDA_OUTPUT));
13119			if (err < 0)
13120				return err;
13121		}
13122	}
13123	return 0;
13124}
13125
13126static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13127{
13128	int err;
13129	hda_nid_t nid;
13130
13131	if (!pin)
13132		return 0;
13133
13134	if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13135		nid = 0x03;
13136		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13137				  "Headphone Playback Switch",
13138				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13139		if (err < 0)
13140			return err;
13141		spec->multiout.hp_nid = nid;
13142	}
13143	return 0;
13144}
13145
13146/* create playback/capture controls for input pins */
13147static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13148						const struct auto_pin_cfg *cfg)
13149{
13150	struct hda_input_mux *imux = &spec->private_imux;
13151	int i, err, idx, idx1;
13152
13153	for (i = 0; i < AUTO_PIN_LAST; i++) {
13154		switch (cfg->input_pins[i]) {
13155		case 0x0c:
13156			idx1 = 1;
13157			idx = 2;	/* Line In */
13158			break;
13159		case 0x0f:
13160			idx1 = 2;
13161			idx = 2;	/* Line In */
13162			break;
13163		case 0x0d:
13164			idx1 = 0;
13165			idx = 1;	/* Mic In */
13166			break;
13167		case 0x10:
13168			idx1 = 3;
13169			idx = 1;	/* Mic In */
13170			break;
13171		case 0x11:
13172			idx1 = 4;
13173			idx = 0;	/* CD */
13174			break;
13175		default:
13176			continue;
13177		}
13178
13179		err = new_analog_input(spec, cfg->input_pins[i],
13180				       auto_pin_cfg_labels[i], idx, 0x15);
13181		if (err < 0)
13182			return err;
13183
13184		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
13185		imux->items[imux->num_items].index = idx1;
13186		imux->num_items++;
13187	}
13188	return 0;
13189}
13190
13191static struct snd_kcontrol_new alc861_capture_mixer[] = {
13192	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13193	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13194
13195	{
13196		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13197		/* The multiple "Capture Source" controls confuse alsamixer
13198		 * So call somewhat different..
13199		 */
13200		/* .name = "Capture Source", */
13201		.name = "Input Source",
13202		.count = 1,
13203		.info = alc_mux_enum_info,
13204		.get = alc_mux_enum_get,
13205		.put = alc_mux_enum_put,
13206	},
13207	{ } /* end */
13208};
13209
13210static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13211					      hda_nid_t nid,
13212					      int pin_type, int dac_idx)
13213{
13214	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13215			    pin_type);
13216	snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13217			    AMP_OUT_UNMUTE);
13218}
13219
13220static void alc861_auto_init_multi_out(struct hda_codec *codec)
13221{
13222	struct alc_spec *spec = codec->spec;
13223	int i;
13224
13225	alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
13226	for (i = 0; i < spec->autocfg.line_outs; i++) {
13227		hda_nid_t nid = spec->autocfg.line_out_pins[i];
13228		int pin_type = get_pin_type(spec->autocfg.line_out_type);
13229		if (nid)
13230			alc861_auto_set_output_and_unmute(codec, nid, pin_type,
13231							  spec->multiout.dac_nids[i]);
13232	}
13233}
13234
13235static void alc861_auto_init_hp_out(struct hda_codec *codec)
13236{
13237	struct alc_spec *spec = codec->spec;
13238	hda_nid_t pin;
13239
13240	pin = spec->autocfg.hp_pins[0];
13241	if (pin) /* connect to front */
13242		alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13243						  spec->multiout.dac_nids[0]);
13244	pin = spec->autocfg.speaker_pins[0];
13245	if (pin)
13246		alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13247}
13248
13249static void alc861_auto_init_analog_input(struct hda_codec *codec)
13250{
13251	struct alc_spec *spec = codec->spec;
13252	int i;
13253
13254	for (i = 0; i < AUTO_PIN_LAST; i++) {
13255		hda_nid_t nid = spec->autocfg.input_pins[i];
13256		if (nid >= 0x0c && nid <= 0x11) {
13257			snd_hda_codec_write(codec, nid, 0,
13258					    AC_VERB_SET_PIN_WIDGET_CONTROL,
13259					    i <= AUTO_PIN_FRONT_MIC ?
13260					    PIN_VREF80 : PIN_IN);
13261		}
13262	}
13263}
13264
13265/* parse the BIOS configuration and set up the alc_spec */
13266/* return 1 if successful, 0 if the proper config is not found,
13267 * or a negative error code
13268 */
13269static int alc861_parse_auto_config(struct hda_codec *codec)
13270{
13271	struct alc_spec *spec = codec->spec;
13272	int err;
13273	static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13274
13275	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13276					   alc861_ignore);
13277	if (err < 0)
13278		return err;
13279	if (!spec->autocfg.line_outs)
13280		return 0; /* can't find valid BIOS pin config */
13281
13282	err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13283	if (err < 0)
13284		return err;
13285	err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13286	if (err < 0)
13287		return err;
13288	err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13289	if (err < 0)
13290		return err;
13291	err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13292	if (err < 0)
13293		return err;
13294
13295	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13296
13297	if (spec->autocfg.dig_out_pin)
13298		spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13299
13300	if (spec->kctl_alloc)
13301		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
13302
13303	spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
13304
13305	spec->num_mux_defs = 1;
13306	spec->input_mux = &spec->private_imux;
13307
13308	spec->adc_nids = alc861_adc_nids;
13309	spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
13310	spec->mixers[spec->num_mixers] = alc861_capture_mixer;
13311	spec->num_mixers++;
13312
13313	return 1;
13314}
13315
13316/* additional initialization for auto-configuration model */
13317static void alc861_auto_init(struct hda_codec *codec)
13318{
13319	struct alc_spec *spec = codec->spec;
13320	alc861_auto_init_multi_out(codec);
13321	alc861_auto_init_hp_out(codec);
13322	alc861_auto_init_analog_input(codec);
13323	if (spec->unsol_event)
13324		alc_inithook(codec);
13325}
13326
13327#ifdef CONFIG_SND_HDA_POWER_SAVE
13328static struct hda_amp_list alc861_loopbacks[] = {
13329	{ 0x15, HDA_INPUT, 0 },
13330	{ 0x15, HDA_INPUT, 1 },
13331	{ 0x15, HDA_INPUT, 2 },
13332	{ 0x15, HDA_INPUT, 3 },
13333	{ } /* end */
13334};
13335#endif
13336
13337
13338/*
13339 * configuration and preset
13340 */
13341static const char *alc861_models[ALC861_MODEL_LAST] = {
13342	[ALC861_3ST]		= "3stack",
13343	[ALC660_3ST]		= "3stack-660",
13344	[ALC861_3ST_DIG]	= "3stack-dig",
13345	[ALC861_6ST_DIG]	= "6stack-dig",
13346	[ALC861_UNIWILL_M31]	= "uniwill-m31",
13347	[ALC861_TOSHIBA]	= "toshiba",
13348	[ALC861_ASUS]		= "asus",
13349	[ALC861_ASUS_LAPTOP]	= "asus-laptop",
13350	[ALC861_AUTO]		= "auto",
13351};
13352
13353static struct snd_pci_quirk alc861_cfg_tbl[] = {
13354	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
13355	SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13356	SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13357	SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
13358	SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
13359	SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
13360	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
13361	/* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
13362	 *        Any other models that need this preset?
13363	 */
13364	/* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
13365	SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
13366	SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
13367	SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
13368	SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
13369	SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
13370	/* FIXME: the below seems conflict */
13371	/* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
13372	SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
13373	SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
13374	{}
13375};
13376
13377static struct alc_config_preset alc861_presets[] = {
13378	[ALC861_3ST] = {
13379		.mixers = { alc861_3ST_mixer },
13380		.init_verbs = { alc861_threestack_init_verbs },
13381		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13382		.dac_nids = alc861_dac_nids,
13383		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13384		.channel_mode = alc861_threestack_modes,
13385		.need_dac_fix = 1,
13386		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13387		.adc_nids = alc861_adc_nids,
13388		.input_mux = &alc861_capture_source,
13389	},
13390	[ALC861_3ST_DIG] = {
13391		.mixers = { alc861_base_mixer },
13392		.init_verbs = { alc861_threestack_init_verbs },
13393		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13394		.dac_nids = alc861_dac_nids,
13395		.dig_out_nid = ALC861_DIGOUT_NID,
13396		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13397		.channel_mode = alc861_threestack_modes,
13398		.need_dac_fix = 1,
13399		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13400		.adc_nids = alc861_adc_nids,
13401		.input_mux = &alc861_capture_source,
13402	},
13403	[ALC861_6ST_DIG] = {
13404		.mixers = { alc861_base_mixer },
13405		.init_verbs = { alc861_base_init_verbs },
13406		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13407		.dac_nids = alc861_dac_nids,
13408		.dig_out_nid = ALC861_DIGOUT_NID,
13409		.num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
13410		.channel_mode = alc861_8ch_modes,
13411		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13412		.adc_nids = alc861_adc_nids,
13413		.input_mux = &alc861_capture_source,
13414	},
13415	[ALC660_3ST] = {
13416		.mixers = { alc861_3ST_mixer },
13417		.init_verbs = { alc861_threestack_init_verbs },
13418		.num_dacs = ARRAY_SIZE(alc660_dac_nids),
13419		.dac_nids = alc660_dac_nids,
13420		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13421		.channel_mode = alc861_threestack_modes,
13422		.need_dac_fix = 1,
13423		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13424		.adc_nids = alc861_adc_nids,
13425		.input_mux = &alc861_capture_source,
13426	},
13427	[ALC861_UNIWILL_M31] = {
13428		.mixers = { alc861_uniwill_m31_mixer },
13429		.init_verbs = { alc861_uniwill_m31_init_verbs },
13430		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13431		.dac_nids = alc861_dac_nids,
13432		.dig_out_nid = ALC861_DIGOUT_NID,
13433		.num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
13434		.channel_mode = alc861_uniwill_m31_modes,
13435		.need_dac_fix = 1,
13436		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13437		.adc_nids = alc861_adc_nids,
13438		.input_mux = &alc861_capture_source,
13439	},
13440	[ALC861_TOSHIBA] = {
13441		.mixers = { alc861_toshiba_mixer },
13442		.init_verbs = { alc861_base_init_verbs,
13443				alc861_toshiba_init_verbs },
13444		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13445		.dac_nids = alc861_dac_nids,
13446		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13447		.channel_mode = alc883_3ST_2ch_modes,
13448		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13449		.adc_nids = alc861_adc_nids,
13450		.input_mux = &alc861_capture_source,
13451		.unsol_event = alc861_toshiba_unsol_event,
13452		.init_hook = alc861_toshiba_automute,
13453	},
13454	[ALC861_ASUS] = {
13455		.mixers = { alc861_asus_mixer },
13456		.init_verbs = { alc861_asus_init_verbs },
13457		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13458		.dac_nids = alc861_dac_nids,
13459		.dig_out_nid = ALC861_DIGOUT_NID,
13460		.num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
13461		.channel_mode = alc861_asus_modes,
13462		.need_dac_fix = 1,
13463		.hp_nid = 0x06,
13464		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13465		.adc_nids = alc861_adc_nids,
13466		.input_mux = &alc861_capture_source,
13467	},
13468	[ALC861_ASUS_LAPTOP] = {
13469		.mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
13470		.init_verbs = { alc861_asus_init_verbs,
13471				alc861_asus_laptop_init_verbs },
13472		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
13473		.dac_nids = alc861_dac_nids,
13474		.dig_out_nid = ALC861_DIGOUT_NID,
13475		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13476		.channel_mode = alc883_3ST_2ch_modes,
13477		.need_dac_fix = 1,
13478		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13479		.adc_nids = alc861_adc_nids,
13480		.input_mux = &alc861_capture_source,
13481	},
13482};
13483
13484
13485static int patch_alc861(struct hda_codec *codec)
13486{
13487	struct alc_spec *spec;
13488	int board_config;
13489	int err;
13490
13491	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13492	if (spec == NULL)
13493		return -ENOMEM;
13494
13495	codec->spec = spec;
13496
13497        board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
13498						  alc861_models,
13499						  alc861_cfg_tbl);
13500
13501	if (board_config < 0) {
13502		printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
13503		       "trying auto-probe from BIOS...\n");
13504		board_config = ALC861_AUTO;
13505	}
13506
13507	if (board_config == ALC861_AUTO) {
13508		/* automatic parse from the BIOS config */
13509		err = alc861_parse_auto_config(codec);
13510		if (err < 0) {
13511			alc_free(codec);
13512			return err;
13513		} else if (!err) {
13514			printk(KERN_INFO
13515			       "hda_codec: Cannot set up configuration "
13516			       "from BIOS.  Using base mode...\n");
13517		   board_config = ALC861_3ST_DIG;
13518		}
13519	}
13520
13521	if (board_config != ALC861_AUTO)
13522		setup_preset(spec, &alc861_presets[board_config]);
13523
13524	spec->stream_name_analog = "ALC861 Analog";
13525	spec->stream_analog_playback = &alc861_pcm_analog_playback;
13526	spec->stream_analog_capture = &alc861_pcm_analog_capture;
13527
13528	spec->stream_name_digital = "ALC861 Digital";
13529	spec->stream_digital_playback = &alc861_pcm_digital_playback;
13530	spec->stream_digital_capture = &alc861_pcm_digital_capture;
13531
13532	spec->vmaster_nid = 0x03;
13533
13534	codec->patch_ops = alc_patch_ops;
13535	if (board_config == ALC861_AUTO)
13536		spec->init_hook = alc861_auto_init;
13537#ifdef CONFIG_SND_HDA_POWER_SAVE
13538	if (!spec->loopback.amplist)
13539		spec->loopback.amplist = alc861_loopbacks;
13540#endif
13541
13542	return 0;
13543}
13544
13545/*
13546 * ALC861-VD support
13547 *
13548 * Based on ALC882
13549 *
13550 * In addition, an independent DAC
13551 */
13552#define ALC861VD_DIGOUT_NID	0x06
13553
13554static hda_nid_t alc861vd_dac_nids[4] = {
13555	/* front, surr, clfe, side surr */
13556	0x02, 0x03, 0x04, 0x05
13557};
13558
13559/* dac_nids for ALC660vd are in a different order - according to
13560 * Realtek's driver.
13561 * This should probably tesult in a different mixer for 6stack models
13562 * of ALC660vd codecs, but for now there is only 3stack mixer
13563 * - and it is the same as in 861vd.
13564 * adc_nids in ALC660vd are (is) the same as in 861vd
13565 */
13566static hda_nid_t alc660vd_dac_nids[3] = {
13567	/* front, rear, clfe, rear_surr */
13568	0x02, 0x04, 0x03
13569};
13570
13571static hda_nid_t alc861vd_adc_nids[1] = {
13572	/* ADC0 */
13573	0x09,
13574};
13575
13576static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
13577
13578/* input MUX */
13579/* FIXME: should be a matrix-type input source selection */
13580static struct hda_input_mux alc861vd_capture_source = {
13581	.num_items = 4,
13582	.items = {
13583		{ "Mic", 0x0 },
13584		{ "Front Mic", 0x1 },
13585		{ "Line", 0x2 },
13586		{ "CD", 0x4 },
13587	},
13588};
13589
13590static struct hda_input_mux alc861vd_dallas_capture_source = {
13591	.num_items = 2,
13592	.items = {
13593		{ "Ext Mic", 0x0 },
13594		{ "Int Mic", 0x1 },
13595	},
13596};
13597
13598static struct hda_input_mux alc861vd_hp_capture_source = {
13599	.num_items = 2,
13600	.items = {
13601		{ "Front Mic", 0x0 },
13602		{ "ATAPI Mic", 0x1 },
13603	},
13604};
13605
13606#define alc861vd_mux_enum_info alc_mux_enum_info
13607#define alc861vd_mux_enum_get alc_mux_enum_get
13608/* ALC861VD has the ALC882-type input selection (but has only one ADC) */
13609#define alc861vd_mux_enum_put alc882_mux_enum_put
13610
13611/*
13612 * 2ch mode
13613 */
13614static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
13615	{ 2, NULL }
13616};
13617
13618/*
13619 * 6ch mode
13620 */
13621static struct hda_verb alc861vd_6stack_ch6_init[] = {
13622	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13623	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13624	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13625	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13626	{ } /* end */
13627};
13628
13629/*
13630 * 8ch mode
13631 */
13632static struct hda_verb alc861vd_6stack_ch8_init[] = {
13633	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13634	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13635	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13636	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13637	{ } /* end */
13638};
13639
13640static struct hda_channel_mode alc861vd_6stack_modes[2] = {
13641	{ 6, alc861vd_6stack_ch6_init },
13642	{ 8, alc861vd_6stack_ch8_init },
13643};
13644
13645static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
13646	{
13647		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13648		.name = "Channel Mode",
13649		.info = alc_ch_mode_info,
13650		.get = alc_ch_mode_get,
13651		.put = alc_ch_mode_put,
13652	},
13653	{ } /* end */
13654};
13655
13656static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
13657	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13658	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13659
13660	{
13661		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13662		/* The multiple "Capture Source" controls confuse alsamixer
13663		 * So call somewhat different..
13664		 */
13665		/* .name = "Capture Source", */
13666		.name = "Input Source",
13667		.count = 1,
13668		.info = alc861vd_mux_enum_info,
13669		.get = alc861vd_mux_enum_get,
13670		.put = alc861vd_mux_enum_put,
13671	},
13672	{ } /* end */
13673};
13674
13675/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
13676 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
13677 */
13678static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
13679	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13680	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13681
13682	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13683	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
13684
13685	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
13686				HDA_OUTPUT),
13687	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
13688				HDA_OUTPUT),
13689	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13690	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
13691
13692	HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
13693	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
13694
13695	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13696
13697	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13698	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13699	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13700
13701	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13702	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13703	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13704
13705	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13706	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13707
13708	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13709	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13710
13711	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13712	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13713
13714	{ } /* end */
13715};
13716
13717static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
13718	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13719	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13720
13721	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13722
13723	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13724	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13725	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13726
13727	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13728	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13729	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13730
13731	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13732	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13733
13734	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13735	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13736
13737	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13738	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13739
13740	{ } /* end */
13741};
13742
13743static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
13744	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13745	/*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
13746	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13747
13748	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13749
13750	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13751	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13752	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13753
13754	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13755	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13756	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13757
13758	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13759	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13760
13761	{ } /* end */
13762};
13763
13764/* Pin assignment: Speaker=0x14, HP = 0x15,
13765 *                 Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
13766 */
13767static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
13768	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13769	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
13770	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13771	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13772	HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
13773	HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13774	HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13775	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
13776	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13777	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13778	HDA_CODEC_VOLUME("PC Beep Volume", 0x0b, 0x05, HDA_INPUT),
13779	HDA_CODEC_MUTE("PC Beep Switch", 0x0b, 0x05, HDA_INPUT),
13780	{ } /* end */
13781};
13782
13783/* Pin assignment: Speaker=0x14, Line-out = 0x15,
13784 *                 Front Mic=0x18, ATAPI Mic = 0x19,
13785 */
13786static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
13787	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13788	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13789	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13790	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13791	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13792	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13793	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13794	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13795
13796	{ } /* end */
13797};
13798
13799/*
13800 * generic initialization of ADC, input mixers and output mixers
13801 */
13802static struct hda_verb alc861vd_volume_init_verbs[] = {
13803	/*
13804	 * Unmute ADC0 and set the default input to mic-in
13805	 */
13806	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13807	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13808
13809	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
13810	 * the analog-loopback mixer widget
13811	 */
13812	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13813	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13814	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13815	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13816	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13817	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13818
13819	/* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
13820	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13821	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13822	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13823	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
13824
13825	/*
13826	 * Set up output mixers (0x02 - 0x05)
13827	 */
13828	/* set vol=0 to output mixers */
13829	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13830	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13831	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13832	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13833
13834	/* set up input amps for analog loopback */
13835	/* Amp Indices: DAC = 0, mixer = 1 */
13836	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13837	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13838	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13839	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13840	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13841	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13842	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13843	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13844
13845	{ }
13846};
13847
13848/*
13849 * 3-stack pin configuration:
13850 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
13851 */
13852static struct hda_verb alc861vd_3stack_init_verbs[] = {
13853	/*
13854	 * Set pin mode and muting
13855	 */
13856	/* set front pin widgets 0x14 for output */
13857	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13858	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13859	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13860
13861	/* Mic (rear) pin: input vref at 80% */
13862	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13863	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13864	/* Front Mic pin: input vref at 80% */
13865	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13866	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13867	/* Line In pin: input */
13868	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13869	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13870	/* Line-2 In: Headphone output (output 0 - 0x0c) */
13871	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13872	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13873	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13874	/* CD pin widget for input */
13875	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13876
13877	{ }
13878};
13879
13880/*
13881 * 6-stack pin configuration:
13882 */
13883static struct hda_verb alc861vd_6stack_init_verbs[] = {
13884	/*
13885	 * Set pin mode and muting
13886	 */
13887	/* set front pin widgets 0x14 for output */
13888	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13889	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13890	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13891
13892	/* Rear Pin: output 1 (0x0d) */
13893	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13894	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13895	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13896	/* CLFE Pin: output 2 (0x0e) */
13897	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13898	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13899	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
13900	/* Side Pin: output 3 (0x0f) */
13901	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13902	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13903	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
13904
13905	/* Mic (rear) pin: input vref at 80% */
13906	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13907	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13908	/* Front Mic pin: input vref at 80% */
13909	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13910	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13911	/* Line In pin: input */
13912	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13913	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13914	/* Line-2 In: Headphone output (output 0 - 0x0c) */
13915	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13916	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13917	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13918	/* CD pin widget for input */
13919	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13920
13921	{ }
13922};
13923
13924static struct hda_verb alc861vd_eapd_verbs[] = {
13925	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13926	{ }
13927};
13928
13929static struct hda_verb alc660vd_eapd_verbs[] = {
13930	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13931	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13932	{ }
13933};
13934
13935static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
13936	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13937	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13938	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
13939	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13940	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13941	{}
13942};
13943
13944/* toggle speaker-output according to the hp-jack state */
13945static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
13946{
13947	unsigned int present;
13948	unsigned char bits;
13949
13950	present = snd_hda_codec_read(codec, 0x1b, 0,
13951				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13952	bits = present ? HDA_AMP_MUTE : 0;
13953	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13954				 HDA_AMP_MUTE, bits);
13955}
13956
13957static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
13958{
13959	unsigned int present;
13960	unsigned char bits;
13961
13962	present = snd_hda_codec_read(codec, 0x18, 0,
13963				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13964	bits = present ? HDA_AMP_MUTE : 0;
13965	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
13966				 HDA_AMP_MUTE, bits);
13967}
13968
13969static void alc861vd_lenovo_automute(struct hda_codec *codec)
13970{
13971	alc861vd_lenovo_hp_automute(codec);
13972	alc861vd_lenovo_mic_automute(codec);
13973}
13974
13975static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
13976					unsigned int res)
13977{
13978	switch (res >> 26) {
13979	case ALC880_HP_EVENT:
13980		alc861vd_lenovo_hp_automute(codec);
13981		break;
13982	case ALC880_MIC_EVENT:
13983		alc861vd_lenovo_mic_automute(codec);
13984		break;
13985	}
13986}
13987
13988static struct hda_verb alc861vd_dallas_verbs[] = {
13989	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13990	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13991	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13992	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13993
13994	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13995	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13996	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13997	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13998	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13999	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14000	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14001	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14002
14003	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14004	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14005	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14006	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14007	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14008	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14009	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14010	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14011
14012	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14013	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14014	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14015	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14016	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14017	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14018	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14019	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14020
14021	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14022	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14023	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14024	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14025
14026	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14027	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14028	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14029
14030	{ } /* end */
14031};
14032
14033/* toggle speaker-output according to the hp-jack state */
14034static void alc861vd_dallas_automute(struct hda_codec *codec)
14035{
14036	unsigned int present;
14037
14038	present = snd_hda_codec_read(codec, 0x15, 0,
14039				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14040	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14041				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
14042}
14043
14044static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
14045{
14046	if ((res >> 26) == ALC880_HP_EVENT)
14047		alc861vd_dallas_automute(codec);
14048}
14049
14050#ifdef CONFIG_SND_HDA_POWER_SAVE
14051#define alc861vd_loopbacks	alc880_loopbacks
14052#endif
14053
14054/* pcm configuration: identiacal with ALC880 */
14055#define alc861vd_pcm_analog_playback	alc880_pcm_analog_playback
14056#define alc861vd_pcm_analog_capture	alc880_pcm_analog_capture
14057#define alc861vd_pcm_digital_playback	alc880_pcm_digital_playback
14058#define alc861vd_pcm_digital_capture	alc880_pcm_digital_capture
14059
14060/*
14061 * configuration and preset
14062 */
14063static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14064	[ALC660VD_3ST]		= "3stack-660",
14065	[ALC660VD_3ST_DIG]	= "3stack-660-digout",
14066	[ALC861VD_3ST]		= "3stack",
14067	[ALC861VD_3ST_DIG]	= "3stack-digout",
14068	[ALC861VD_6ST_DIG]	= "6stack-digout",
14069	[ALC861VD_LENOVO]	= "lenovo",
14070	[ALC861VD_DALLAS]	= "dallas",
14071	[ALC861VD_HP]		= "hp",
14072	[ALC861VD_AUTO]		= "auto",
14073};
14074
14075static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
14076	SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14077	SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
14078	SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
14079	SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
14080	SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC861VD_LENOVO),
14081	SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
14082	SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
14083	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
14084	/*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
14085	SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
14086	SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
14087	SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
14088	SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
14089	SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
14090	SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
14091	SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO),
14092	SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
14093	{}
14094};
14095
14096static struct alc_config_preset alc861vd_presets[] = {
14097	[ALC660VD_3ST] = {
14098		.mixers = { alc861vd_3st_mixer },
14099		.init_verbs = { alc861vd_volume_init_verbs,
14100				 alc861vd_3stack_init_verbs },
14101		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14102		.dac_nids = alc660vd_dac_nids,
14103		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14104		.channel_mode = alc861vd_3stack_2ch_modes,
14105		.input_mux = &alc861vd_capture_source,
14106	},
14107	[ALC660VD_3ST_DIG] = {
14108		.mixers = { alc861vd_3st_mixer },
14109		.init_verbs = { alc861vd_volume_init_verbs,
14110				 alc861vd_3stack_init_verbs },
14111		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14112		.dac_nids = alc660vd_dac_nids,
14113		.dig_out_nid = ALC861VD_DIGOUT_NID,
14114		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14115		.channel_mode = alc861vd_3stack_2ch_modes,
14116		.input_mux = &alc861vd_capture_source,
14117	},
14118	[ALC861VD_3ST] = {
14119		.mixers = { alc861vd_3st_mixer },
14120		.init_verbs = { alc861vd_volume_init_verbs,
14121				 alc861vd_3stack_init_verbs },
14122		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14123		.dac_nids = alc861vd_dac_nids,
14124		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14125		.channel_mode = alc861vd_3stack_2ch_modes,
14126		.input_mux = &alc861vd_capture_source,
14127	},
14128	[ALC861VD_3ST_DIG] = {
14129		.mixers = { alc861vd_3st_mixer },
14130		.init_verbs = { alc861vd_volume_init_verbs,
14131		 		 alc861vd_3stack_init_verbs },
14132		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14133		.dac_nids = alc861vd_dac_nids,
14134		.dig_out_nid = ALC861VD_DIGOUT_NID,
14135		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14136		.channel_mode = alc861vd_3stack_2ch_modes,
14137		.input_mux = &alc861vd_capture_source,
14138	},
14139	[ALC861VD_6ST_DIG] = {
14140		.mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14141		.init_verbs = { alc861vd_volume_init_verbs,
14142				alc861vd_6stack_init_verbs },
14143		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14144		.dac_nids = alc861vd_dac_nids,
14145		.dig_out_nid = ALC861VD_DIGOUT_NID,
14146		.num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14147		.channel_mode = alc861vd_6stack_modes,
14148		.input_mux = &alc861vd_capture_source,
14149	},
14150	[ALC861VD_LENOVO] = {
14151		.mixers = { alc861vd_lenovo_mixer },
14152		.init_verbs = { alc861vd_volume_init_verbs,
14153				alc861vd_3stack_init_verbs,
14154				alc861vd_eapd_verbs,
14155				alc861vd_lenovo_unsol_verbs },
14156		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14157		.dac_nids = alc660vd_dac_nids,
14158		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14159		.channel_mode = alc861vd_3stack_2ch_modes,
14160		.input_mux = &alc861vd_capture_source,
14161		.unsol_event = alc861vd_lenovo_unsol_event,
14162		.init_hook = alc861vd_lenovo_automute,
14163	},
14164	[ALC861VD_DALLAS] = {
14165		.mixers = { alc861vd_dallas_mixer },
14166		.init_verbs = { alc861vd_dallas_verbs },
14167		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14168		.dac_nids = alc861vd_dac_nids,
14169		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14170		.channel_mode = alc861vd_3stack_2ch_modes,
14171		.input_mux = &alc861vd_dallas_capture_source,
14172		.unsol_event = alc861vd_dallas_unsol_event,
14173		.init_hook = alc861vd_dallas_automute,
14174	},
14175	[ALC861VD_HP] = {
14176		.mixers = { alc861vd_hp_mixer },
14177		.init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14178		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14179		.dac_nids = alc861vd_dac_nids,
14180		.dig_out_nid = ALC861VD_DIGOUT_NID,
14181		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14182		.channel_mode = alc861vd_3stack_2ch_modes,
14183		.input_mux = &alc861vd_hp_capture_source,
14184		.unsol_event = alc861vd_dallas_unsol_event,
14185		.init_hook = alc861vd_dallas_automute,
14186	},
14187};
14188
14189/*
14190 * BIOS auto configuration
14191 */
14192static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14193				hda_nid_t nid, int pin_type, int dac_idx)
14194{
14195	alc_set_pin_output(codec, nid, pin_type);
14196}
14197
14198static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14199{
14200	struct alc_spec *spec = codec->spec;
14201	int i;
14202
14203	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
14204	for (i = 0; i <= HDA_SIDE; i++) {
14205		hda_nid_t nid = spec->autocfg.line_out_pins[i];
14206		int pin_type = get_pin_type(spec->autocfg.line_out_type);
14207		if (nid)
14208			alc861vd_auto_set_output_and_unmute(codec, nid,
14209							    pin_type, i);
14210	}
14211}
14212
14213
14214static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14215{
14216	struct alc_spec *spec = codec->spec;
14217	hda_nid_t pin;
14218
14219	pin = spec->autocfg.hp_pins[0];
14220	if (pin) /* connect to front and  use dac 0 */
14221		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
14222	pin = spec->autocfg.speaker_pins[0];
14223	if (pin)
14224		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14225}
14226
14227#define alc861vd_is_input_pin(nid)	alc880_is_input_pin(nid)
14228#define ALC861VD_PIN_CD_NID		ALC880_PIN_CD_NID
14229
14230static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14231{
14232	struct alc_spec *spec = codec->spec;
14233	int i;
14234
14235	for (i = 0; i < AUTO_PIN_LAST; i++) {
14236		hda_nid_t nid = spec->autocfg.input_pins[i];
14237		if (alc861vd_is_input_pin(nid)) {
14238			snd_hda_codec_write(codec, nid, 0,
14239					AC_VERB_SET_PIN_WIDGET_CONTROL,
14240					i <= AUTO_PIN_FRONT_MIC ?
14241							PIN_VREF80 : PIN_IN);
14242			if (nid != ALC861VD_PIN_CD_NID)
14243				snd_hda_codec_write(codec, nid, 0,
14244						AC_VERB_SET_AMP_GAIN_MUTE,
14245						AMP_OUT_MUTE);
14246		}
14247	}
14248}
14249
14250#define alc861vd_auto_init_input_src	alc882_auto_init_input_src
14251
14252#define alc861vd_idx_to_mixer_vol(nid)		((nid) + 0x02)
14253#define alc861vd_idx_to_mixer_switch(nid)	((nid) + 0x0c)
14254
14255/* add playback controls from the parsed DAC table */
14256/* Based on ALC880 version. But ALC861VD has separate,
14257 * different NIDs for mute/unmute switch and volume control */
14258static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14259					     const struct auto_pin_cfg *cfg)
14260{
14261	char name[32];
14262	static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14263	hda_nid_t nid_v, nid_s;
14264	int i, err;
14265
14266	for (i = 0; i < cfg->line_outs; i++) {
14267		if (!spec->multiout.dac_nids[i])
14268			continue;
14269		nid_v = alc861vd_idx_to_mixer_vol(
14270				alc880_dac_to_idx(
14271					spec->multiout.dac_nids[i]));
14272		nid_s = alc861vd_idx_to_mixer_switch(
14273				alc880_dac_to_idx(
14274					spec->multiout.dac_nids[i]));
14275
14276		if (i == 2) {
14277			/* Center/LFE */
14278			err = add_control(spec, ALC_CTL_WIDGET_VOL,
14279					  "Center Playback Volume",
14280					  HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14281							      HDA_OUTPUT));
14282			if (err < 0)
14283				return err;
14284			err = add_control(spec, ALC_CTL_WIDGET_VOL,
14285					  "LFE Playback Volume",
14286					  HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14287							      HDA_OUTPUT));
14288			if (err < 0)
14289				return err;
14290			err = add_control(spec, ALC_CTL_BIND_MUTE,
14291					  "Center Playback Switch",
14292					  HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14293							      HDA_INPUT));
14294			if (err < 0)
14295				return err;
14296			err = add_control(spec, ALC_CTL_BIND_MUTE,
14297					  "LFE Playback Switch",
14298					  HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14299							      HDA_INPUT));
14300			if (err < 0)
14301				return err;
14302		} else {
14303			sprintf(name, "%s Playback Volume", chname[i]);
14304			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14305					  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14306							      HDA_OUTPUT));
14307			if (err < 0)
14308				return err;
14309			sprintf(name, "%s Playback Switch", chname[i]);
14310			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14311					  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
14312							      HDA_INPUT));
14313			if (err < 0)
14314				return err;
14315		}
14316	}
14317	return 0;
14318}
14319
14320/* add playback controls for speaker and HP outputs */
14321/* Based on ALC880 version. But ALC861VD has separate,
14322 * different NIDs for mute/unmute switch and volume control */
14323static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
14324					hda_nid_t pin, const char *pfx)
14325{
14326	hda_nid_t nid_v, nid_s;
14327	int err;
14328	char name[32];
14329
14330	if (!pin)
14331		return 0;
14332
14333	if (alc880_is_fixed_pin(pin)) {
14334		nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14335		/* specify the DAC as the extra output */
14336		if (!spec->multiout.hp_nid)
14337			spec->multiout.hp_nid = nid_v;
14338		else
14339			spec->multiout.extra_out_nid[0] = nid_v;
14340		/* control HP volume/switch on the output mixer amp */
14341		nid_v = alc861vd_idx_to_mixer_vol(
14342				alc880_fixed_pin_idx(pin));
14343		nid_s = alc861vd_idx_to_mixer_switch(
14344				alc880_fixed_pin_idx(pin));
14345
14346		sprintf(name, "%s Playback Volume", pfx);
14347		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14348				  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
14349		if (err < 0)
14350			return err;
14351		sprintf(name, "%s Playback Switch", pfx);
14352		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14353				  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
14354		if (err < 0)
14355			return err;
14356	} else if (alc880_is_multi_pin(pin)) {
14357		/* set manual connection */
14358		/* we have only a switch on HP-out PIN */
14359		sprintf(name, "%s Playback Switch", pfx);
14360		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14361				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
14362		if (err < 0)
14363			return err;
14364	}
14365	return 0;
14366}
14367
14368/* parse the BIOS configuration and set up the alc_spec
14369 * return 1 if successful, 0 if the proper config is not found,
14370 * or a negative error code
14371 * Based on ALC880 version - had to change it to override
14372 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
14373static int alc861vd_parse_auto_config(struct hda_codec *codec)
14374{
14375	struct alc_spec *spec = codec->spec;
14376	int err;
14377	static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
14378
14379	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14380					   alc861vd_ignore);
14381	if (err < 0)
14382		return err;
14383	if (!spec->autocfg.line_outs)
14384		return 0; /* can't find valid BIOS pin config */
14385
14386	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
14387	if (err < 0)
14388		return err;
14389	err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
14390	if (err < 0)
14391		return err;
14392	err = alc861vd_auto_create_extra_out(spec,
14393					     spec->autocfg.speaker_pins[0],
14394					     "Speaker");
14395	if (err < 0)
14396		return err;
14397	err = alc861vd_auto_create_extra_out(spec,
14398					     spec->autocfg.hp_pins[0],
14399					     "Headphone");
14400	if (err < 0)
14401		return err;
14402	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
14403	if (err < 0)
14404		return err;
14405
14406	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14407
14408	if (spec->autocfg.dig_out_pin)
14409		spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
14410
14411	if (spec->kctl_alloc)
14412		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
14413
14414	spec->init_verbs[spec->num_init_verbs++]
14415		= alc861vd_volume_init_verbs;
14416
14417	spec->num_mux_defs = 1;
14418	spec->input_mux = &spec->private_imux;
14419
14420	err = alc_auto_add_mic_boost(codec);
14421	if (err < 0)
14422		return err;
14423
14424	return 1;
14425}
14426
14427/* additional initialization for auto-configuration model */
14428static void alc861vd_auto_init(struct hda_codec *codec)
14429{
14430	struct alc_spec *spec = codec->spec;
14431	alc861vd_auto_init_multi_out(codec);
14432	alc861vd_auto_init_hp_out(codec);
14433	alc861vd_auto_init_analog_input(codec);
14434	alc861vd_auto_init_input_src(codec);
14435	if (spec->unsol_event)
14436		alc_inithook(codec);
14437}
14438
14439static int patch_alc861vd(struct hda_codec *codec)
14440{
14441	struct alc_spec *spec;
14442	int err, board_config;
14443
14444	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14445	if (spec == NULL)
14446		return -ENOMEM;
14447
14448	codec->spec = spec;
14449
14450	board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
14451						  alc861vd_models,
14452						  alc861vd_cfg_tbl);
14453
14454	if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
14455		printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
14456			"ALC861VD, trying auto-probe from BIOS...\n");
14457		board_config = ALC861VD_AUTO;
14458	}
14459
14460	if (board_config == ALC861VD_AUTO) {
14461		/* automatic parse from the BIOS config */
14462		err = alc861vd_parse_auto_config(codec);
14463		if (err < 0) {
14464			alc_free(codec);
14465			return err;
14466		} else if (!err) {
14467			printk(KERN_INFO
14468			       "hda_codec: Cannot set up configuration "
14469			       "from BIOS.  Using base mode...\n");
14470			board_config = ALC861VD_3ST;
14471		}
14472	}
14473
14474	if (board_config != ALC861VD_AUTO)
14475		setup_preset(spec, &alc861vd_presets[board_config]);
14476
14477	if (codec->vendor_id == 0x10ec0660) {
14478		spec->stream_name_analog = "ALC660-VD Analog";
14479		spec->stream_name_digital = "ALC660-VD Digital";
14480		/* always turn on EAPD */
14481		spec->init_verbs[spec->num_init_verbs++] = alc660vd_eapd_verbs;
14482	} else {
14483		spec->stream_name_analog = "ALC861VD Analog";
14484		spec->stream_name_digital = "ALC861VD Digital";
14485	}
14486
14487	spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
14488	spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
14489
14490	spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
14491	spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
14492
14493	spec->adc_nids = alc861vd_adc_nids;
14494	spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
14495	spec->capsrc_nids = alc861vd_capsrc_nids;
14496
14497	spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
14498	spec->num_mixers++;
14499
14500	spec->vmaster_nid = 0x02;
14501
14502	codec->patch_ops = alc_patch_ops;
14503
14504	if (board_config == ALC861VD_AUTO)
14505		spec->init_hook = alc861vd_auto_init;
14506#ifdef CONFIG_SND_HDA_POWER_SAVE
14507	if (!spec->loopback.amplist)
14508		spec->loopback.amplist = alc861vd_loopbacks;
14509#endif
14510
14511	return 0;
14512}
14513
14514/*
14515 * ALC662 support
14516 *
14517 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
14518 * configuration.  Each pin widget can choose any input DACs and a mixer.
14519 * Each ADC is connected from a mixer of all inputs.  This makes possible
14520 * 6-channel independent captures.
14521 *
14522 * In addition, an independent DAC for the multi-playback (not used in this
14523 * driver yet).
14524 */
14525#define ALC662_DIGOUT_NID	0x06
14526#define ALC662_DIGIN_NID	0x0a
14527
14528static hda_nid_t alc662_dac_nids[4] = {
14529	/* front, rear, clfe, rear_surr */
14530	0x02, 0x03, 0x04
14531};
14532
14533static hda_nid_t alc662_adc_nids[1] = {
14534	/* ADC1-2 */
14535	0x09,
14536};
14537
14538static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
14539
14540/* input MUX */
14541/* FIXME: should be a matrix-type input source selection */
14542static struct hda_input_mux alc662_capture_source = {
14543	.num_items = 4,
14544	.items = {
14545		{ "Mic", 0x0 },
14546		{ "Front Mic", 0x1 },
14547		{ "Line", 0x2 },
14548		{ "CD", 0x4 },
14549	},
14550};
14551
14552static struct hda_input_mux alc662_lenovo_101e_capture_source = {
14553	.num_items = 2,
14554	.items = {
14555		{ "Mic", 0x1 },
14556		{ "Line", 0x2 },
14557	},
14558};
14559
14560static struct hda_input_mux alc662_eeepc_capture_source = {
14561	.num_items = 2,
14562	.items = {
14563		{ "i-Mic", 0x1 },
14564		{ "e-Mic", 0x0 },
14565	},
14566};
14567
14568static struct hda_input_mux alc663_capture_source = {
14569	.num_items = 3,
14570	.items = {
14571		{ "Mic", 0x0 },
14572		{ "Front Mic", 0x1 },
14573		{ "Line", 0x2 },
14574	},
14575};
14576
14577static struct hda_input_mux alc663_m51va_capture_source = {
14578	.num_items = 2,
14579	.items = {
14580		{ "Ext-Mic", 0x0 },
14581		{ "D-Mic", 0x9 },
14582	},
14583};
14584
14585#define alc662_mux_enum_info alc_mux_enum_info
14586#define alc662_mux_enum_get alc_mux_enum_get
14587#define alc662_mux_enum_put alc882_mux_enum_put
14588
14589/*
14590 * 2ch mode
14591 */
14592static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
14593	{ 2, NULL }
14594};
14595
14596/*
14597 * 2ch mode
14598 */
14599static struct hda_verb alc662_3ST_ch2_init[] = {
14600	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
14601	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14602	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
14603	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14604	{ } /* end */
14605};
14606
14607/*
14608 * 6ch mode
14609 */
14610static struct hda_verb alc662_3ST_ch6_init[] = {
14611	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14612	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14613	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
14614	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14615	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14616	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
14617	{ } /* end */
14618};
14619
14620static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
14621	{ 2, alc662_3ST_ch2_init },
14622	{ 6, alc662_3ST_ch6_init },
14623};
14624
14625/*
14626 * 2ch mode
14627 */
14628static struct hda_verb alc662_sixstack_ch6_init[] = {
14629	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14630	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14631	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14632	{ } /* end */
14633};
14634
14635/*
14636 * 6ch mode
14637 */
14638static struct hda_verb alc662_sixstack_ch8_init[] = {
14639	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14640	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14641	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14642	{ } /* end */
14643};
14644
14645static struct hda_channel_mode alc662_5stack_modes[2] = {
14646	{ 2, alc662_sixstack_ch6_init },
14647	{ 6, alc662_sixstack_ch8_init },
14648};
14649
14650/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14651 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14652 */
14653
14654static struct snd_kcontrol_new alc662_base_mixer[] = {
14655	/* output mixer control */
14656	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
14657	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14658	HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
14659	HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14660	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14661	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14662	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14663	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14664	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14665
14666	/*Input mixer control */
14667	HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
14668	HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
14669	HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
14670	HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
14671	HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
14672	HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
14673	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
14674	HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
14675	{ } /* end */
14676};
14677
14678static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
14679	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14680	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14681	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14682	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14683	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14684	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14685	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14686	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14687	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14688	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14689	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14690	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14691	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14692	{ } /* end */
14693};
14694
14695static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
14696	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14697	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14698	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14699	HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14700	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14701	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14702	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14703	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14704	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14705	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14706	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14707	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14708	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14709	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14710	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14711	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14712	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14713	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14714	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14715	{ } /* end */
14716};
14717
14718static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
14719	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14720	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
14721	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14722	HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
14723	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14724	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14725	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14726	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14727	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14728	{ } /* end */
14729};
14730
14731static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
14732	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14733
14734	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14735	HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14736
14737	HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
14738	HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14739	HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14740
14741	HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
14742	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14743	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14744	{ } /* end */
14745};
14746
14747static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
14748	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14749	HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14750	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14751	HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
14752	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14753	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14754	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
14755	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
14756	HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14757	HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
14758	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14759	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14760	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14761	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14762	{ } /* end */
14763};
14764
14765static struct hda_bind_ctls alc663_asus_bind_master_vol = {
14766	.ops = &snd_hda_bind_vol,
14767	.values = {
14768		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14769		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
14770		0
14771	},
14772};
14773
14774static struct hda_bind_ctls alc663_asus_one_bind_switch = {
14775	.ops = &snd_hda_bind_sw,
14776	.values = {
14777		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14778		HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14779		0
14780	},
14781};
14782
14783static struct snd_kcontrol_new alc663_m51va_mixer[] = {
14784	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14785	HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
14786	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14787	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14788	{ } /* end */
14789};
14790
14791static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
14792	.ops = &snd_hda_bind_sw,
14793	.values = {
14794		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14795		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14796		HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14797		0
14798	},
14799};
14800
14801static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
14802	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14803	HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
14804	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14805	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14806	HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14807	HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14808
14809	{ } /* end */
14810};
14811
14812static struct hda_bind_ctls alc663_asus_four_bind_switch = {
14813	.ops = &snd_hda_bind_sw,
14814	.values = {
14815		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14816		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14817		HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
14818		0
14819	},
14820};
14821
14822static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
14823	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14824	HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
14825	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14826	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14827	HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14828	HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14829	{ } /* end */
14830};
14831
14832static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
14833	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14834	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14835	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14836	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14837	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14838	HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14839	HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14840	{ } /* end */
14841};
14842
14843static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
14844	.ops = &snd_hda_bind_vol,
14845	.values = {
14846		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14847		HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
14848		0
14849	},
14850};
14851
14852static struct hda_bind_ctls alc663_asus_two_bind_switch = {
14853	.ops = &snd_hda_bind_sw,
14854	.values = {
14855		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14856		HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
14857		0
14858	},
14859};
14860
14861static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
14862	HDA_BIND_VOL("Master Playback Volume",
14863				&alc663_asus_two_bind_master_vol),
14864	HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14865	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14866	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14867	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14868	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14869	{ } /* end */
14870};
14871
14872static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
14873	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14874	HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14875	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14876	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14877	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14878	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14879	{ } /* end */
14880};
14881
14882static struct snd_kcontrol_new alc663_g71v_mixer[] = {
14883	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14884	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14885	HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14886	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14887	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14888
14889	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14890	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14891	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14892	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14893	{ } /* end */
14894};
14895
14896static struct snd_kcontrol_new alc663_g50v_mixer[] = {
14897	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14898	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14899	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14900
14901	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14902	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14903	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14904	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14905	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14906	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14907	{ } /* end */
14908};
14909
14910static struct snd_kcontrol_new alc662_chmode_mixer[] = {
14911	{
14912		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14913		.name = "Channel Mode",
14914		.info = alc_ch_mode_info,
14915		.get = alc_ch_mode_get,
14916		.put = alc_ch_mode_put,
14917	},
14918	{ } /* end */
14919};
14920
14921static struct hda_verb alc662_init_verbs[] = {
14922	/* ADC: mute amp left and right */
14923	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14924	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14925	/* Front mixer: unmute input/output amp left and right (volume = 0) */
14926
14927	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14928	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14929	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14930	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14931	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14932
14933	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14934	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14935	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14936	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14937	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14938	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14939
14940	/* Front Pin: output 0 (0x0c) */
14941	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14942	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14943
14944	/* Rear Pin: output 1 (0x0d) */
14945	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14946	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14947
14948	/* CLFE Pin: output 2 (0x0e) */
14949	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14950	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14951
14952	/* Mic (rear) pin: input vref at 80% */
14953	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14954	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14955	/* Front Mic pin: input vref at 80% */
14956	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14957	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14958	/* Line In pin: input */
14959	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14960	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14961	/* Line-2 In: Headphone output (output 0 - 0x0c) */
14962	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14963	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14964	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14965	/* CD pin widget for input */
14966	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14967
14968	/* FIXME: use matrix-type input source selection */
14969	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
14970	/* Input mixer */
14971	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14972	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14973	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14974	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14975
14976	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14977	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14978	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14979	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14980
14981	/* always trun on EAPD */
14982	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14983	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14984
14985	{ }
14986};
14987
14988static struct hda_verb alc662_sue_init_verbs[] = {
14989	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
14990	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
14991	{}
14992};
14993
14994static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
14995	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14996	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14997	{}
14998};
14999
15000/* Set Unsolicited Event*/
15001static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
15002	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15003	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15004	{}
15005};
15006
15007/*
15008 * generic initialization of ADC, input mixers and output mixers
15009 */
15010static struct hda_verb alc662_auto_init_verbs[] = {
15011	/*
15012	 * Unmute ADC and set the default input to mic-in
15013	 */
15014	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15015	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15016
15017	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
15018	 * mixer widget
15019	 * Note: PASD motherboards uses the Line In 2 as the input for front
15020	 * panel mic (mic 2)
15021	 */
15022	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
15023	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15024	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15025	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15026	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15027	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15028
15029	/*
15030	 * Set up output mixers (0x0c - 0x0f)
15031	 */
15032	/* set vol=0 to output mixers */
15033	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15034	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15035	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15036
15037	/* set up input amps for analog loopback */
15038	/* Amp Indices: DAC = 0, mixer = 1 */
15039	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15040	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15041	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15042	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15043	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15044	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15045
15046
15047	/* FIXME: use matrix-type input source selection */
15048	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15049	/* Input mixer */
15050	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15051	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15052	{ }
15053};
15054
15055/* additional verbs for ALC663 */
15056static struct hda_verb alc663_auto_init_verbs[] = {
15057	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15058	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15059	{ }
15060};
15061
15062static struct hda_verb alc663_m51va_init_verbs[] = {
15063	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15064	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15065	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15066	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15067	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
15068	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15069	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15070	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15071	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15072	{}
15073};
15074
15075static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15076	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15077	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15078	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
15079	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15080	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15081	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15082	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15083	{}
15084};
15085
15086static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15087	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15088	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15089	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15090	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
15091	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15092	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15093	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15094	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15095	{}
15096};
15097
15098static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15099	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15100	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15101	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
15102	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15103	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15104	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15105	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15106	{}
15107};
15108
15109static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15110	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15111	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15112	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15113	{0x21, AC_VERB_SET_CONNECT_SEL, 0x0},	/* Headphone */
15114	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15115	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15116	{0x15, AC_VERB_SET_CONNECT_SEL, 0x0},	/* Headphone */
15117	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15118	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15119	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15120	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15121	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15122	{}
15123};
15124
15125static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15126	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15127	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15128	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15129	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
15130	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15131	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15132	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
15133	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15134	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15135	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15136	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15137	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15138	{}
15139};
15140
15141static struct hda_verb alc663_g71v_init_verbs[] = {
15142	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15143	/* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15144	/* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15145
15146	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15147	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15148	{0x21, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
15149
15150	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15151	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15152	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15153	{}
15154};
15155
15156static struct hda_verb alc663_g50v_init_verbs[] = {
15157	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15158	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15159	{0x21, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
15160
15161	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15162	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15163	{}
15164};
15165
15166static struct hda_verb alc662_ecs_init_verbs[] = {
15167	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15168	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15169	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15170	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15171	{}
15172};
15173
15174/* capture mixer elements */
15175static struct snd_kcontrol_new alc662_capture_mixer[] = {
15176	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15177	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15178	{
15179		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15180		/* The multiple "Capture Source" controls confuse alsamixer
15181		 * So call somewhat different..
15182		 */
15183		/* .name = "Capture Source", */
15184		.name = "Input Source",
15185		.count = 1,
15186		.info = alc662_mux_enum_info,
15187		.get = alc662_mux_enum_get,
15188		.put = alc662_mux_enum_put,
15189	},
15190	{ } /* end */
15191};
15192
15193static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15194	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15195	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15196	{ } /* end */
15197};
15198
15199static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15200{
15201	unsigned int present;
15202	unsigned char bits;
15203
15204	present = snd_hda_codec_read(codec, 0x14, 0,
15205				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15206	bits = present ? HDA_AMP_MUTE : 0;
15207	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15208				 HDA_AMP_MUTE, bits);
15209}
15210
15211static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15212{
15213	unsigned int present;
15214	unsigned char bits;
15215
15216 	present = snd_hda_codec_read(codec, 0x1b, 0,
15217				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15218	bits = present ? HDA_AMP_MUTE : 0;
15219	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15220				 HDA_AMP_MUTE, bits);
15221	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15222				 HDA_AMP_MUTE, bits);
15223}
15224
15225static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15226					   unsigned int res)
15227{
15228	if ((res >> 26) == ALC880_HP_EVENT)
15229		alc662_lenovo_101e_all_automute(codec);
15230	if ((res >> 26) == ALC880_FRONT_EVENT)
15231		alc662_lenovo_101e_ispeaker_automute(codec);
15232}
15233
15234static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15235{
15236	unsigned int present;
15237
15238	present = snd_hda_codec_read(codec, 0x18, 0,
15239				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15240	snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15241			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15242	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15243			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15244	snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15245			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15246	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15247			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15248}
15249
15250/* unsolicited event for HP jack sensing */
15251static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15252				     unsigned int res)
15253{
15254	if ((res >> 26) == ALC880_HP_EVENT)
15255		alc262_hippo1_automute( codec );
15256
15257	if ((res >> 26) == ALC880_MIC_EVENT)
15258		alc662_eeepc_mic_automute(codec);
15259}
15260
15261static void alc662_eeepc_inithook(struct hda_codec *codec)
15262{
15263	alc262_hippo1_automute( codec );
15264	alc662_eeepc_mic_automute(codec);
15265}
15266
15267static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
15268{
15269	unsigned int mute;
15270	unsigned int present;
15271
15272	snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
15273	present = snd_hda_codec_read(codec, 0x14, 0,
15274				     AC_VERB_GET_PIN_SENSE, 0);
15275	present = (present & 0x80000000) != 0;
15276	if (present) {
15277		/* mute internal speaker */
15278		snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15279					HDA_AMP_MUTE, HDA_AMP_MUTE);
15280	} else {
15281		/* unmute internal speaker if necessary */
15282		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
15283		snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15284					HDA_AMP_MUTE, mute);
15285	}
15286}
15287
15288/* unsolicited event for HP jack sensing */
15289static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
15290					  unsigned int res)
15291{
15292	if ((res >> 26) == ALC880_HP_EVENT)
15293		alc662_eeepc_ep20_automute(codec);
15294}
15295
15296static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
15297{
15298	alc662_eeepc_ep20_automute(codec);
15299}
15300
15301static void alc663_m51va_speaker_automute(struct hda_codec *codec)
15302{
15303	unsigned int present;
15304	unsigned char bits;
15305
15306	present = snd_hda_codec_read(codec, 0x21, 0,
15307			AC_VERB_GET_PIN_SENSE, 0)
15308			& AC_PINSENSE_PRESENCE;
15309	bits = present ? HDA_AMP_MUTE : 0;
15310	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15311				AMP_IN_MUTE(0), bits);
15312	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15313				AMP_IN_MUTE(0), bits);
15314}
15315
15316static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
15317{
15318	unsigned int present;
15319	unsigned char bits;
15320
15321	present = snd_hda_codec_read(codec, 0x21, 0,
15322			AC_VERB_GET_PIN_SENSE, 0)
15323			& AC_PINSENSE_PRESENCE;
15324	bits = present ? HDA_AMP_MUTE : 0;
15325	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15326				AMP_IN_MUTE(0), bits);
15327	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15328				AMP_IN_MUTE(0), bits);
15329	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15330				AMP_IN_MUTE(0), bits);
15331	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15332				AMP_IN_MUTE(0), bits);
15333}
15334
15335static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
15336{
15337	unsigned int present;
15338	unsigned char bits;
15339
15340	present = snd_hda_codec_read(codec, 0x15, 0,
15341			AC_VERB_GET_PIN_SENSE, 0)
15342			& AC_PINSENSE_PRESENCE;
15343	bits = present ? HDA_AMP_MUTE : 0;
15344	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15345				AMP_IN_MUTE(0), bits);
15346	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15347				AMP_IN_MUTE(0), bits);
15348	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15349				AMP_IN_MUTE(0), bits);
15350	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15351				AMP_IN_MUTE(0), bits);
15352}
15353
15354static void alc662_f5z_speaker_automute(struct hda_codec *codec)
15355{
15356	unsigned int present;
15357	unsigned char bits;
15358
15359	present = snd_hda_codec_read(codec, 0x1b, 0,
15360			AC_VERB_GET_PIN_SENSE, 0)
15361			& AC_PINSENSE_PRESENCE;
15362	bits = present ? 0 : PIN_OUT;
15363	snd_hda_codec_write(codec, 0x14, 0,
15364			 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
15365}
15366
15367static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
15368{
15369	unsigned int present1, present2;
15370
15371	present1 = snd_hda_codec_read(codec, 0x21, 0,
15372			AC_VERB_GET_PIN_SENSE, 0)
15373			& AC_PINSENSE_PRESENCE;
15374	present2 = snd_hda_codec_read(codec, 0x15, 0,
15375			AC_VERB_GET_PIN_SENSE, 0)
15376			& AC_PINSENSE_PRESENCE;
15377
15378	if (present1 || present2) {
15379		snd_hda_codec_write_cache(codec, 0x14, 0,
15380			AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
15381	} else {
15382		snd_hda_codec_write_cache(codec, 0x14, 0,
15383			AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
15384	}
15385}
15386
15387static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
15388{
15389	unsigned int present1, present2;
15390
15391	present1 = snd_hda_codec_read(codec, 0x1b, 0,
15392				AC_VERB_GET_PIN_SENSE, 0)
15393				& AC_PINSENSE_PRESENCE;
15394	present2 = snd_hda_codec_read(codec, 0x15, 0,
15395				AC_VERB_GET_PIN_SENSE, 0)
15396				& AC_PINSENSE_PRESENCE;
15397
15398	if (present1 || present2) {
15399		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15400				AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15401		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15402				AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15403	} else {
15404		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15405				AMP_IN_MUTE(0), 0);
15406		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15407				AMP_IN_MUTE(0), 0);
15408	}
15409}
15410
15411static void alc663_m51va_mic_automute(struct hda_codec *codec)
15412{
15413	unsigned int present;
15414
15415	present = snd_hda_codec_read(codec, 0x18, 0,
15416			AC_VERB_GET_PIN_SENSE, 0)
15417			& AC_PINSENSE_PRESENCE;
15418	snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15419			0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15420	snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15421			0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15422	snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15423			0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15424	snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15425			0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15426}
15427
15428static void alc663_m51va_unsol_event(struct hda_codec *codec,
15429					   unsigned int res)
15430{
15431	switch (res >> 26) {
15432	case ALC880_HP_EVENT:
15433		alc663_m51va_speaker_automute(codec);
15434		break;
15435	case ALC880_MIC_EVENT:
15436		alc663_m51va_mic_automute(codec);
15437		break;
15438	}
15439}
15440
15441static void alc663_m51va_inithook(struct hda_codec *codec)
15442{
15443	alc663_m51va_speaker_automute(codec);
15444	alc663_m51va_mic_automute(codec);
15445}
15446
15447/* ***************** Mode1 ******************************/
15448static void alc663_mode1_unsol_event(struct hda_codec *codec,
15449					   unsigned int res)
15450{
15451	switch (res >> 26) {
15452	case ALC880_HP_EVENT:
15453		alc663_m51va_speaker_automute(codec);
15454		break;
15455	case ALC880_MIC_EVENT:
15456		alc662_eeepc_mic_automute(codec);
15457		break;
15458	}
15459}
15460
15461static void alc663_mode1_inithook(struct hda_codec *codec)
15462{
15463	alc663_m51va_speaker_automute(codec);
15464	alc662_eeepc_mic_automute(codec);
15465}
15466/* ***************** Mode2 ******************************/
15467static void alc662_mode2_unsol_event(struct hda_codec *codec,
15468					   unsigned int res)
15469{
15470	switch (res >> 26) {
15471	case ALC880_HP_EVENT:
15472		alc662_f5z_speaker_automute(codec);
15473		break;
15474	case ALC880_MIC_EVENT:
15475		alc662_eeepc_mic_automute(codec);
15476		break;
15477	}
15478}
15479
15480static void alc662_mode2_inithook(struct hda_codec *codec)
15481{
15482	alc662_f5z_speaker_automute(codec);
15483	alc662_eeepc_mic_automute(codec);
15484}
15485/* ***************** Mode3 ******************************/
15486static void alc663_mode3_unsol_event(struct hda_codec *codec,
15487					   unsigned int res)
15488{
15489	switch (res >> 26) {
15490	case ALC880_HP_EVENT:
15491		alc663_two_hp_m1_speaker_automute(codec);
15492		break;
15493	case ALC880_MIC_EVENT:
15494		alc662_eeepc_mic_automute(codec);
15495		break;
15496	}
15497}
15498
15499static void alc663_mode3_inithook(struct hda_codec *codec)
15500{
15501	alc663_two_hp_m1_speaker_automute(codec);
15502	alc662_eeepc_mic_automute(codec);
15503}
15504/* ***************** Mode4 ******************************/
15505static void alc663_mode4_unsol_event(struct hda_codec *codec,
15506					   unsigned int res)
15507{
15508	switch (res >> 26) {
15509	case ALC880_HP_EVENT:
15510		alc663_21jd_two_speaker_automute(codec);
15511		break;
15512	case ALC880_MIC_EVENT:
15513		alc662_eeepc_mic_automute(codec);
15514		break;
15515	}
15516}
15517
15518static void alc663_mode4_inithook(struct hda_codec *codec)
15519{
15520	alc663_21jd_two_speaker_automute(codec);
15521	alc662_eeepc_mic_automute(codec);
15522}
15523/* ***************** Mode5 ******************************/
15524static void alc663_mode5_unsol_event(struct hda_codec *codec,
15525					   unsigned int res)
15526{
15527	switch (res >> 26) {
15528	case ALC880_HP_EVENT:
15529		alc663_15jd_two_speaker_automute(codec);
15530		break;
15531	case ALC880_MIC_EVENT:
15532		alc662_eeepc_mic_automute(codec);
15533		break;
15534	}
15535}
15536
15537static void alc663_mode5_inithook(struct hda_codec *codec)
15538{
15539	alc663_15jd_two_speaker_automute(codec);
15540	alc662_eeepc_mic_automute(codec);
15541}
15542/* ***************** Mode6 ******************************/
15543static void alc663_mode6_unsol_event(struct hda_codec *codec,
15544					   unsigned int res)
15545{
15546	switch (res >> 26) {
15547	case ALC880_HP_EVENT:
15548		alc663_two_hp_m2_speaker_automute(codec);
15549		break;
15550	case ALC880_MIC_EVENT:
15551		alc662_eeepc_mic_automute(codec);
15552		break;
15553	}
15554}
15555
15556static void alc663_mode6_inithook(struct hda_codec *codec)
15557{
15558	alc663_two_hp_m2_speaker_automute(codec);
15559	alc662_eeepc_mic_automute(codec);
15560}
15561
15562static void alc663_g71v_hp_automute(struct hda_codec *codec)
15563{
15564	unsigned int present;
15565	unsigned char bits;
15566
15567	present = snd_hda_codec_read(codec, 0x21, 0,
15568				     AC_VERB_GET_PIN_SENSE, 0)
15569		& AC_PINSENSE_PRESENCE;
15570	bits = present ? HDA_AMP_MUTE : 0;
15571	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15572				 HDA_AMP_MUTE, bits);
15573	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15574				 HDA_AMP_MUTE, bits);
15575}
15576
15577static void alc663_g71v_front_automute(struct hda_codec *codec)
15578{
15579	unsigned int present;
15580	unsigned char bits;
15581
15582	present = snd_hda_codec_read(codec, 0x15, 0,
15583				     AC_VERB_GET_PIN_SENSE, 0)
15584		& AC_PINSENSE_PRESENCE;
15585	bits = present ? HDA_AMP_MUTE : 0;
15586	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15587				 HDA_AMP_MUTE, bits);
15588}
15589
15590static void alc663_g71v_unsol_event(struct hda_codec *codec,
15591					   unsigned int res)
15592{
15593	switch (res >> 26) {
15594	case ALC880_HP_EVENT:
15595		alc663_g71v_hp_automute(codec);
15596		break;
15597	case ALC880_FRONT_EVENT:
15598		alc663_g71v_front_automute(codec);
15599		break;
15600	case ALC880_MIC_EVENT:
15601		alc662_eeepc_mic_automute(codec);
15602		break;
15603	}
15604}
15605
15606static void alc663_g71v_inithook(struct hda_codec *codec)
15607{
15608	alc663_g71v_front_automute(codec);
15609	alc663_g71v_hp_automute(codec);
15610	alc662_eeepc_mic_automute(codec);
15611}
15612
15613static void alc663_g50v_unsol_event(struct hda_codec *codec,
15614					   unsigned int res)
15615{
15616	switch (res >> 26) {
15617	case ALC880_HP_EVENT:
15618		alc663_m51va_speaker_automute(codec);
15619		break;
15620	case ALC880_MIC_EVENT:
15621		alc662_eeepc_mic_automute(codec);
15622		break;
15623	}
15624}
15625
15626static void alc663_g50v_inithook(struct hda_codec *codec)
15627{
15628	alc663_m51va_speaker_automute(codec);
15629	alc662_eeepc_mic_automute(codec);
15630}
15631
15632/* bind hp and internal speaker mute (with plug check) */
15633static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol,
15634				     struct snd_ctl_elem_value *ucontrol)
15635{
15636	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
15637	long *valp = ucontrol->value.integer.value;
15638	int change;
15639
15640	change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
15641					  HDA_AMP_MUTE,
15642					  valp[0] ? 0 : HDA_AMP_MUTE);
15643	change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
15644					   HDA_AMP_MUTE,
15645					   valp[1] ? 0 : HDA_AMP_MUTE);
15646	if (change)
15647		alc262_hippo1_automute(codec);
15648	return change;
15649}
15650
15651static struct snd_kcontrol_new alc662_ecs_mixer[] = {
15652	HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15653	{
15654		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15655		.name = "Master Playback Switch",
15656		.info = snd_hda_mixer_amp_switch_info,
15657		.get = snd_hda_mixer_amp_switch_get,
15658		.put = alc662_ecs_master_sw_put,
15659		.private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15660	},
15661
15662	HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
15663	HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
15664	HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
15665
15666	HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15667	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15668	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15669	{ } /* end */
15670};
15671
15672#ifdef CONFIG_SND_HDA_POWER_SAVE
15673#define alc662_loopbacks	alc880_loopbacks
15674#endif
15675
15676
15677/* pcm configuration: identiacal with ALC880 */
15678#define alc662_pcm_analog_playback	alc880_pcm_analog_playback
15679#define alc662_pcm_analog_capture	alc880_pcm_analog_capture
15680#define alc662_pcm_digital_playback	alc880_pcm_digital_playback
15681#define alc662_pcm_digital_capture	alc880_pcm_digital_capture
15682
15683/*
15684 * configuration and preset
15685 */
15686static const char *alc662_models[ALC662_MODEL_LAST] = {
15687	[ALC662_3ST_2ch_DIG]	= "3stack-dig",
15688	[ALC662_3ST_6ch_DIG]	= "3stack-6ch-dig",
15689	[ALC662_3ST_6ch]	= "3stack-6ch",
15690	[ALC662_5ST_DIG]	= "6stack-dig",
15691	[ALC662_LENOVO_101E]	= "lenovo-101e",
15692	[ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
15693	[ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
15694	[ALC662_ECS] = "ecs",
15695	[ALC663_ASUS_M51VA] = "m51va",
15696	[ALC663_ASUS_G71V] = "g71v",
15697	[ALC663_ASUS_H13] = "h13",
15698	[ALC663_ASUS_G50V] = "g50v",
15699	[ALC663_ASUS_MODE1] = "asus-mode1",
15700	[ALC662_ASUS_MODE2] = "asus-mode2",
15701	[ALC663_ASUS_MODE3] = "asus-mode3",
15702	[ALC663_ASUS_MODE4] = "asus-mode4",
15703	[ALC663_ASUS_MODE5] = "asus-mode5",
15704	[ALC663_ASUS_MODE6] = "asus-mode6",
15705	[ALC662_AUTO]		= "auto",
15706};
15707
15708static struct snd_pci_quirk alc662_cfg_tbl[] = {
15709	SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
15710	SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
15711	SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
15712	SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
15713	SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
15714	SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
15715	SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),
15716	SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
15717	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
15718	SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
15719	SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),
15720	SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
15721	SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
15722	SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
15723	SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
15724	SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
15725	SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
15726	SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
15727	SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
15728	SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
15729	SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
15730	SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
15731	SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
15732	SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
15733	SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
15734	SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
15735	SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
15736	SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
15737	SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
15738	SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
15739	SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
15740	SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
15741	SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
15742	SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
15743	SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
15744	SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
15745	SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
15746	SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
15747		      ALC662_3ST_6ch_DIG),
15748	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
15749	SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
15750	SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
15751	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
15752		      ALC662_3ST_6ch_DIG),
15753	SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
15754	SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
15755					ALC662_3ST_6ch_DIG),
15756	SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13),
15757	SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13),
15758	SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13),
15759	{}
15760};
15761
15762static struct alc_config_preset alc662_presets[] = {
15763	[ALC662_3ST_2ch_DIG] = {
15764		.mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
15765		.init_verbs = { alc662_init_verbs },
15766		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15767		.dac_nids = alc662_dac_nids,
15768		.dig_out_nid = ALC662_DIGOUT_NID,
15769		.dig_in_nid = ALC662_DIGIN_NID,
15770		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15771		.channel_mode = alc662_3ST_2ch_modes,
15772		.input_mux = &alc662_capture_source,
15773	},
15774	[ALC662_3ST_6ch_DIG] = {
15775		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
15776			    alc662_capture_mixer },
15777		.init_verbs = { alc662_init_verbs },
15778		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15779		.dac_nids = alc662_dac_nids,
15780		.dig_out_nid = ALC662_DIGOUT_NID,
15781		.dig_in_nid = ALC662_DIGIN_NID,
15782		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15783		.channel_mode = alc662_3ST_6ch_modes,
15784		.need_dac_fix = 1,
15785		.input_mux = &alc662_capture_source,
15786	},
15787	[ALC662_3ST_6ch] = {
15788		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
15789			    alc662_capture_mixer },
15790		.init_verbs = { alc662_init_verbs },
15791		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15792		.dac_nids = alc662_dac_nids,
15793		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15794		.channel_mode = alc662_3ST_6ch_modes,
15795		.need_dac_fix = 1,
15796		.input_mux = &alc662_capture_source,
15797	},
15798	[ALC662_5ST_DIG] = {
15799		.mixers = { alc662_base_mixer, alc662_chmode_mixer,
15800			    alc662_capture_mixer },
15801		.init_verbs = { alc662_init_verbs },
15802		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15803		.dac_nids = alc662_dac_nids,
15804		.dig_out_nid = ALC662_DIGOUT_NID,
15805		.dig_in_nid = ALC662_DIGIN_NID,
15806		.num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
15807		.channel_mode = alc662_5stack_modes,
15808		.input_mux = &alc662_capture_source,
15809	},
15810	[ALC662_LENOVO_101E] = {
15811		.mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
15812		.init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
15813		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15814		.dac_nids = alc662_dac_nids,
15815		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15816		.channel_mode = alc662_3ST_2ch_modes,
15817		.input_mux = &alc662_lenovo_101e_capture_source,
15818		.unsol_event = alc662_lenovo_101e_unsol_event,
15819		.init_hook = alc662_lenovo_101e_all_automute,
15820	},
15821	[ALC662_ASUS_EEEPC_P701] = {
15822		.mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
15823		.init_verbs = { alc662_init_verbs,
15824				alc662_eeepc_sue_init_verbs },
15825		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15826		.dac_nids = alc662_dac_nids,
15827		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15828		.channel_mode = alc662_3ST_2ch_modes,
15829		.input_mux = &alc662_eeepc_capture_source,
15830		.unsol_event = alc662_eeepc_unsol_event,
15831		.init_hook = alc662_eeepc_inithook,
15832	},
15833	[ALC662_ASUS_EEEPC_EP20] = {
15834		.mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer,
15835			    alc662_chmode_mixer },
15836		.init_verbs = { alc662_init_verbs,
15837				alc662_eeepc_ep20_sue_init_verbs },
15838		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15839		.dac_nids = alc662_dac_nids,
15840		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15841		.channel_mode = alc662_3ST_6ch_modes,
15842		.input_mux = &alc662_lenovo_101e_capture_source,
15843		.unsol_event = alc662_eeepc_ep20_unsol_event,
15844		.init_hook = alc662_eeepc_ep20_inithook,
15845	},
15846	[ALC662_ECS] = {
15847		.mixers = { alc662_ecs_mixer, alc662_capture_mixer },
15848		.init_verbs = { alc662_init_verbs,
15849				alc662_ecs_init_verbs },
15850		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15851		.dac_nids = alc662_dac_nids,
15852		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15853		.channel_mode = alc662_3ST_2ch_modes,
15854		.input_mux = &alc662_eeepc_capture_source,
15855		.unsol_event = alc662_eeepc_unsol_event,
15856		.init_hook = alc662_eeepc_inithook,
15857	},
15858	[ALC663_ASUS_M51VA] = {
15859		.mixers = { alc663_m51va_mixer, alc662_capture_mixer},
15860		.init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15861		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15862		.dac_nids = alc662_dac_nids,
15863		.dig_out_nid = ALC662_DIGOUT_NID,
15864		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15865		.channel_mode = alc662_3ST_2ch_modes,
15866		.input_mux = &alc663_m51va_capture_source,
15867		.unsol_event = alc663_m51va_unsol_event,
15868		.init_hook = alc663_m51va_inithook,
15869	},
15870	[ALC663_ASUS_G71V] = {
15871		.mixers = { alc663_g71v_mixer, alc662_capture_mixer},
15872		.init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
15873		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15874		.dac_nids = alc662_dac_nids,
15875		.dig_out_nid = ALC662_DIGOUT_NID,
15876		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15877		.channel_mode = alc662_3ST_2ch_modes,
15878		.input_mux = &alc662_eeepc_capture_source,
15879		.unsol_event = alc663_g71v_unsol_event,
15880		.init_hook = alc663_g71v_inithook,
15881	},
15882	[ALC663_ASUS_H13] = {
15883		.mixers = { alc663_m51va_mixer, alc662_capture_mixer},
15884		.init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15885		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15886		.dac_nids = alc662_dac_nids,
15887		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15888		.channel_mode = alc662_3ST_2ch_modes,
15889		.input_mux = &alc663_m51va_capture_source,
15890		.unsol_event = alc663_m51va_unsol_event,
15891		.init_hook = alc663_m51va_inithook,
15892	},
15893	[ALC663_ASUS_G50V] = {
15894		.mixers = { alc663_g50v_mixer, alc662_capture_mixer},
15895		.init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
15896		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15897		.dac_nids = alc662_dac_nids,
15898		.dig_out_nid = ALC662_DIGOUT_NID,
15899		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15900		.channel_mode = alc662_3ST_6ch_modes,
15901		.input_mux = &alc663_capture_source,
15902		.unsol_event = alc663_g50v_unsol_event,
15903		.init_hook = alc663_g50v_inithook,
15904	},
15905	[ALC663_ASUS_MODE1] = {
15906		.mixers = { alc663_m51va_mixer, alc662_auto_capture_mixer },
15907		.init_verbs = { alc662_init_verbs,
15908				alc663_21jd_amic_init_verbs },
15909		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15910		.hp_nid = 0x03,
15911		.dac_nids = alc662_dac_nids,
15912		.dig_out_nid = ALC662_DIGOUT_NID,
15913		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15914		.channel_mode = alc662_3ST_2ch_modes,
15915		.input_mux = &alc662_eeepc_capture_source,
15916		.unsol_event = alc663_mode1_unsol_event,
15917		.init_hook = alc663_mode1_inithook,
15918	},
15919	[ALC662_ASUS_MODE2] = {
15920		.mixers = { alc662_1bjd_mixer, alc662_auto_capture_mixer },
15921		.init_verbs = { alc662_init_verbs,
15922				alc662_1bjd_amic_init_verbs },
15923		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15924		.dac_nids = alc662_dac_nids,
15925		.dig_out_nid = ALC662_DIGOUT_NID,
15926		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15927		.channel_mode = alc662_3ST_2ch_modes,
15928		.input_mux = &alc662_eeepc_capture_source,
15929		.unsol_event = alc662_mode2_unsol_event,
15930		.init_hook = alc662_mode2_inithook,
15931	},
15932	[ALC663_ASUS_MODE3] = {
15933		.mixers = { alc663_two_hp_m1_mixer, alc662_auto_capture_mixer },
15934		.init_verbs = { alc662_init_verbs,
15935				alc663_two_hp_amic_m1_init_verbs },
15936		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15937		.hp_nid = 0x03,
15938		.dac_nids = alc662_dac_nids,
15939		.dig_out_nid = ALC662_DIGOUT_NID,
15940		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15941		.channel_mode = alc662_3ST_2ch_modes,
15942		.input_mux = &alc662_eeepc_capture_source,
15943		.unsol_event = alc663_mode3_unsol_event,
15944		.init_hook = alc663_mode3_inithook,
15945	},
15946	[ALC663_ASUS_MODE4] = {
15947		.mixers = { alc663_asus_21jd_clfe_mixer,
15948				alc662_auto_capture_mixer},
15949		.init_verbs = { alc662_init_verbs,
15950				alc663_21jd_amic_init_verbs},
15951		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15952		.hp_nid = 0x03,
15953		.dac_nids = alc662_dac_nids,
15954		.dig_out_nid = ALC662_DIGOUT_NID,
15955		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15956		.channel_mode = alc662_3ST_2ch_modes,
15957		.input_mux = &alc662_eeepc_capture_source,
15958		.unsol_event = alc663_mode4_unsol_event,
15959		.init_hook = alc663_mode4_inithook,
15960	},
15961	[ALC663_ASUS_MODE5] = {
15962		.mixers = { alc663_asus_15jd_clfe_mixer,
15963				alc662_auto_capture_mixer },
15964		.init_verbs = { alc662_init_verbs,
15965				alc663_15jd_amic_init_verbs },
15966		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15967		.hp_nid = 0x03,
15968		.dac_nids = alc662_dac_nids,
15969		.dig_out_nid = ALC662_DIGOUT_NID,
15970		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15971		.channel_mode = alc662_3ST_2ch_modes,
15972		.input_mux = &alc662_eeepc_capture_source,
15973		.unsol_event = alc663_mode5_unsol_event,
15974		.init_hook = alc663_mode5_inithook,
15975	},
15976	[ALC663_ASUS_MODE6] = {
15977		.mixers = { alc663_two_hp_m2_mixer, alc662_auto_capture_mixer },
15978		.init_verbs = { alc662_init_verbs,
15979				alc663_two_hp_amic_m2_init_verbs },
15980		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
15981		.hp_nid = 0x03,
15982		.dac_nids = alc662_dac_nids,
15983		.dig_out_nid = ALC662_DIGOUT_NID,
15984		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15985		.channel_mode = alc662_3ST_2ch_modes,
15986		.input_mux = &alc662_eeepc_capture_source,
15987		.unsol_event = alc663_mode6_unsol_event,
15988		.init_hook = alc663_mode6_inithook,
15989	},
15990};
15991
15992
15993/*
15994 * BIOS auto configuration
15995 */
15996
15997/* add playback controls from the parsed DAC table */
15998static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
15999					     const struct auto_pin_cfg *cfg)
16000{
16001	char name[32];
16002	static const char *chname[4] = {
16003		"Front", "Surround", NULL /*CLFE*/, "Side"
16004	};
16005	hda_nid_t nid;
16006	int i, err;
16007
16008	for (i = 0; i < cfg->line_outs; i++) {
16009		if (!spec->multiout.dac_nids[i])
16010			continue;
16011		nid = alc880_idx_to_dac(i);
16012		if (i == 2) {
16013			/* Center/LFE */
16014			err = add_control(spec, ALC_CTL_WIDGET_VOL,
16015					  "Center Playback Volume",
16016					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
16017							      HDA_OUTPUT));
16018			if (err < 0)
16019				return err;
16020			err = add_control(spec, ALC_CTL_WIDGET_VOL,
16021					  "LFE Playback Volume",
16022					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
16023							      HDA_OUTPUT));
16024			if (err < 0)
16025				return err;
16026			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16027					  "Center Playback Switch",
16028					  HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
16029							      HDA_INPUT));
16030			if (err < 0)
16031				return err;
16032			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16033					  "LFE Playback Switch",
16034					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
16035							      HDA_INPUT));
16036			if (err < 0)
16037				return err;
16038		} else {
16039			sprintf(name, "%s Playback Volume", chname[i]);
16040			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16041					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
16042							      HDA_OUTPUT));
16043			if (err < 0)
16044				return err;
16045			sprintf(name, "%s Playback Switch", chname[i]);
16046			err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16047				HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16048						    3, 0, HDA_INPUT));
16049			if (err < 0)
16050				return err;
16051		}
16052	}
16053	return 0;
16054}
16055
16056/* add playback controls for speaker and HP outputs */
16057static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16058					const char *pfx)
16059{
16060	hda_nid_t nid;
16061	int err;
16062	char name[32];
16063
16064	if (!pin)
16065		return 0;
16066
16067	if (pin == 0x17) {
16068		/* ALC663 has a mono output pin on 0x17 */
16069		sprintf(name, "%s Playback Switch", pfx);
16070		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16071				  HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16072		return err;
16073	}
16074
16075	if (alc880_is_fixed_pin(pin)) {
16076		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16077                /* printk("DAC nid=%x\n",nid); */
16078		/* specify the DAC as the extra output */
16079		if (!spec->multiout.hp_nid)
16080			spec->multiout.hp_nid = nid;
16081		else
16082			spec->multiout.extra_out_nid[0] = nid;
16083		/* control HP volume/switch on the output mixer amp */
16084		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16085		sprintf(name, "%s Playback Volume", pfx);
16086		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16087				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16088		if (err < 0)
16089			return err;
16090		sprintf(name, "%s Playback Switch", pfx);
16091		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
16092				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
16093		if (err < 0)
16094			return err;
16095	} else if (alc880_is_multi_pin(pin)) {
16096		/* set manual connection */
16097		/* we have only a switch on HP-out PIN */
16098		sprintf(name, "%s Playback Switch", pfx);
16099		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16100				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16101		if (err < 0)
16102			return err;
16103	}
16104	return 0;
16105}
16106
16107/* create playback/capture controls for input pins */
16108static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
16109						const struct auto_pin_cfg *cfg)
16110{
16111	struct hda_input_mux *imux = &spec->private_imux;
16112	int i, err, idx;
16113
16114	for (i = 0; i < AUTO_PIN_LAST; i++) {
16115		if (alc880_is_input_pin(cfg->input_pins[i])) {
16116			idx = alc880_input_pin_idx(cfg->input_pins[i]);
16117			err = new_analog_input(spec, cfg->input_pins[i],
16118					       auto_pin_cfg_labels[i],
16119					       idx, 0x0b);
16120			if (err < 0)
16121				return err;
16122			imux->items[imux->num_items].label =
16123				auto_pin_cfg_labels[i];
16124			imux->items[imux->num_items].index =
16125				alc880_input_pin_idx(cfg->input_pins[i]);
16126			imux->num_items++;
16127		}
16128	}
16129	return 0;
16130}
16131
16132static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16133					      hda_nid_t nid, int pin_type,
16134					      int dac_idx)
16135{
16136	alc_set_pin_output(codec, nid, pin_type);
16137	/* need the manual connection? */
16138	if (alc880_is_multi_pin(nid)) {
16139		struct alc_spec *spec = codec->spec;
16140		int idx = alc880_multi_pin_idx(nid);
16141		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16142				    AC_VERB_SET_CONNECT_SEL,
16143				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16144	}
16145}
16146
16147static void alc662_auto_init_multi_out(struct hda_codec *codec)
16148{
16149	struct alc_spec *spec = codec->spec;
16150	int i;
16151
16152	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
16153	for (i = 0; i <= HDA_SIDE; i++) {
16154		hda_nid_t nid = spec->autocfg.line_out_pins[i];
16155		int pin_type = get_pin_type(spec->autocfg.line_out_type);
16156		if (nid)
16157			alc662_auto_set_output_and_unmute(codec, nid, pin_type,
16158							  i);
16159	}
16160}
16161
16162static void alc662_auto_init_hp_out(struct hda_codec *codec)
16163{
16164	struct alc_spec *spec = codec->spec;
16165	hda_nid_t pin;
16166
16167	pin = spec->autocfg.hp_pins[0];
16168	if (pin) /* connect to front */
16169		/* use dac 0 */
16170		alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
16171	pin = spec->autocfg.speaker_pins[0];
16172	if (pin)
16173		alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
16174}
16175
16176#define alc662_is_input_pin(nid)	alc880_is_input_pin(nid)
16177#define ALC662_PIN_CD_NID		ALC880_PIN_CD_NID
16178
16179static void alc662_auto_init_analog_input(struct hda_codec *codec)
16180{
16181	struct alc_spec *spec = codec->spec;
16182	int i;
16183
16184	for (i = 0; i < AUTO_PIN_LAST; i++) {
16185		hda_nid_t nid = spec->autocfg.input_pins[i];
16186		if (alc662_is_input_pin(nid)) {
16187			snd_hda_codec_write(codec, nid, 0,
16188					    AC_VERB_SET_PIN_WIDGET_CONTROL,
16189					    (i <= AUTO_PIN_FRONT_MIC ?
16190					     PIN_VREF80 : PIN_IN));
16191			if (nid != ALC662_PIN_CD_NID)
16192				snd_hda_codec_write(codec, nid, 0,
16193						    AC_VERB_SET_AMP_GAIN_MUTE,
16194						    AMP_OUT_MUTE);
16195		}
16196	}
16197}
16198
16199#define alc662_auto_init_input_src	alc882_auto_init_input_src
16200
16201static int alc662_parse_auto_config(struct hda_codec *codec)
16202{
16203	struct alc_spec *spec = codec->spec;
16204	int err;
16205	static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
16206
16207	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16208					   alc662_ignore);
16209	if (err < 0)
16210		return err;
16211	if (!spec->autocfg.line_outs)
16212		return 0; /* can't find valid BIOS pin config */
16213
16214	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16215	if (err < 0)
16216		return err;
16217	err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
16218	if (err < 0)
16219		return err;
16220	err = alc662_auto_create_extra_out(spec,
16221					   spec->autocfg.speaker_pins[0],
16222					   "Speaker");
16223	if (err < 0)
16224		return err;
16225	err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
16226					   "Headphone");
16227	if (err < 0)
16228		return err;
16229	err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
16230	if (err < 0)
16231		return err;
16232
16233	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16234
16235	if (spec->autocfg.dig_out_pin)
16236		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
16237
16238	if (spec->kctl_alloc)
16239		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
16240
16241	spec->num_mux_defs = 1;
16242	spec->input_mux = &spec->private_imux;
16243
16244	spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
16245	if (codec->vendor_id == 0x10ec0663)
16246		spec->init_verbs[spec->num_init_verbs++] =
16247			alc663_auto_init_verbs;
16248
16249	err = alc_auto_add_mic_boost(codec);
16250	if (err < 0)
16251		return err;
16252
16253	spec->mixers[spec->num_mixers] = alc662_capture_mixer;
16254	spec->num_mixers++;
16255	return 1;
16256}
16257
16258/* additional initialization for auto-configuration model */
16259static void alc662_auto_init(struct hda_codec *codec)
16260{
16261	struct alc_spec *spec = codec->spec;
16262	alc662_auto_init_multi_out(codec);
16263	alc662_auto_init_hp_out(codec);
16264	alc662_auto_init_analog_input(codec);
16265	alc662_auto_init_input_src(codec);
16266	if (spec->unsol_event)
16267		alc_inithook(codec);
16268}
16269
16270static int patch_alc662(struct hda_codec *codec)
16271{
16272	struct alc_spec *spec;
16273	int err, board_config;
16274
16275	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16276	if (!spec)
16277		return -ENOMEM;
16278
16279	codec->spec = spec;
16280
16281	alc_fix_pll_init(codec, 0x20, 0x04, 15);
16282
16283	board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
16284						  alc662_models,
16285			  	                  alc662_cfg_tbl);
16286	if (board_config < 0) {
16287		printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
16288		       "trying auto-probe from BIOS...\n");
16289		board_config = ALC662_AUTO;
16290	}
16291
16292	if (board_config == ALC662_AUTO) {
16293		/* automatic parse from the BIOS config */
16294		err = alc662_parse_auto_config(codec);
16295		if (err < 0) {
16296			alc_free(codec);
16297			return err;
16298		} else if (!err) {
16299			printk(KERN_INFO
16300			       "hda_codec: Cannot set up configuration "
16301			       "from BIOS.  Using base mode...\n");
16302			board_config = ALC662_3ST_2ch_DIG;
16303		}
16304	}
16305
16306	if (board_config != ALC662_AUTO)
16307		setup_preset(spec, &alc662_presets[board_config]);
16308
16309	if (codec->vendor_id == 0x10ec0663) {
16310		spec->stream_name_analog = "ALC663 Analog";
16311		spec->stream_name_digital = "ALC663 Digital";
16312	} else if (codec->vendor_id == 0x10ec0272) {
16313		spec->stream_name_analog = "ALC272 Analog";
16314		spec->stream_name_digital = "ALC272 Digital";
16315	} else {
16316		spec->stream_name_analog = "ALC662 Analog";
16317		spec->stream_name_digital = "ALC662 Digital";
16318	}
16319
16320	spec->stream_analog_playback = &alc662_pcm_analog_playback;
16321	spec->stream_analog_capture = &alc662_pcm_analog_capture;
16322
16323	spec->stream_digital_playback = &alc662_pcm_digital_playback;
16324	spec->stream_digital_capture = &alc662_pcm_digital_capture;
16325
16326	spec->adc_nids = alc662_adc_nids;
16327	spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
16328	spec->capsrc_nids = alc662_capsrc_nids;
16329
16330	spec->vmaster_nid = 0x02;
16331
16332	codec->patch_ops = alc_patch_ops;
16333	if (board_config == ALC662_AUTO)
16334		spec->init_hook = alc662_auto_init;
16335#ifdef CONFIG_SND_HDA_POWER_SAVE
16336	if (!spec->loopback.amplist)
16337		spec->loopback.amplist = alc662_loopbacks;
16338#endif
16339
16340	return 0;
16341}
16342
16343/*
16344 * patch entries
16345 */
16346struct hda_codec_preset snd_hda_preset_realtek[] = {
16347	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
16348	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
16349	{ .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
16350	{ .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
16351	{ .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
16352	{ .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
16353	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
16354	  .patch = patch_alc861 },
16355	{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
16356	{ .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
16357	{ .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
16358	{ .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
16359	  .patch = patch_alc883 },
16360	{ .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
16361	  .patch = patch_alc662 },
16362	{ .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
16363	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
16364	{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
16365	{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
16366	{ .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
16367	  .patch = patch_alc882 }, /* should be patch_alc883() in future */
16368	{ .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
16369	  .patch = patch_alc882 }, /* should be patch_alc883() in future */
16370	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
16371	{ .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
16372	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
16373	{ .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
16374	  .patch = patch_alc883 },
16375	{ .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
16376	{} /* terminator */
16377};
16378