patch_realtek.c revision 38baf5ad8b7d24be16a2cf0e4c1d7429aeb4aa45
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 <sound/driver.h>
27#include <linux/init.h>
28#include <linux/delay.h>
29#include <linux/slab.h>
30#include <linux/pci.h>
31#include <sound/core.h>
32#include "hda_codec.h"
33#include "hda_local.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#ifdef CONFIG_SND_DEBUG
64	ALC880_TEST,
65#endif
66	ALC880_AUTO,
67	ALC880_MODEL_LAST /* last tag */
68};
69
70/* ALC260 models */
71enum {
72	ALC260_BASIC,
73	ALC260_HP,
74	ALC260_HP_3013,
75	ALC260_FUJITSU_S702X,
76	ALC260_ACER,
77	ALC260_WILL,
78	ALC260_REPLACER_672V,
79#ifdef CONFIG_SND_DEBUG
80	ALC260_TEST,
81#endif
82	ALC260_AUTO,
83	ALC260_MODEL_LAST /* last tag */
84};
85
86/* ALC262 models */
87enum {
88	ALC262_BASIC,
89	ALC262_HIPPO,
90	ALC262_HIPPO_1,
91	ALC262_FUJITSU,
92	ALC262_HP_BPC,
93	ALC262_HP_BPC_D7000_WL,
94	ALC262_HP_BPC_D7000_WF,
95	ALC262_BENQ_ED8,
96	ALC262_SONY_ASSAMD,
97	ALC262_BENQ_T31,
98	ALC262_AUTO,
99	ALC262_MODEL_LAST /* last tag */
100};
101
102/* ALC268 models */
103enum {
104	ALC268_3ST,
105	ALC268_TOSHIBA,
106	ALC268_ACER,
107	ALC268_AUTO,
108	ALC268_MODEL_LAST /* last tag */
109};
110
111/* ALC861 models */
112enum {
113	ALC861_3ST,
114	ALC660_3ST,
115	ALC861_3ST_DIG,
116	ALC861_6ST_DIG,
117	ALC861_UNIWILL_M31,
118	ALC861_TOSHIBA,
119	ALC861_ASUS,
120	ALC861_ASUS_LAPTOP,
121	ALC861_AUTO,
122	ALC861_MODEL_LAST,
123};
124
125/* ALC861-VD models */
126enum {
127	ALC660VD_3ST,
128	ALC660VD_3ST_DIG,
129	ALC861VD_3ST,
130	ALC861VD_3ST_DIG,
131	ALC861VD_6ST_DIG,
132	ALC861VD_LENOVO,
133	ALC861VD_DALLAS,
134	ALC861VD_HP,
135	ALC861VD_AUTO,
136	ALC861VD_MODEL_LAST,
137};
138
139/* ALC662 models */
140enum {
141	ALC662_3ST_2ch_DIG,
142	ALC662_3ST_6ch_DIG,
143	ALC662_3ST_6ch,
144	ALC662_5ST_DIG,
145	ALC662_LENOVO_101E,
146	ALC662_AUTO,
147	ALC662_MODEL_LAST,
148};
149
150/* ALC882 models */
151enum {
152	ALC882_3ST_DIG,
153	ALC882_6ST_DIG,
154	ALC882_ARIMA,
155	ALC882_W2JC,
156	ALC882_TARGA,
157	ALC882_ASUS_A7J,
158	ALC885_MACPRO,
159	ALC885_IMAC24,
160	ALC882_AUTO,
161	ALC882_MODEL_LAST,
162};
163
164/* ALC883 models */
165enum {
166	ALC883_3ST_2ch_DIG,
167	ALC883_3ST_6ch_DIG,
168	ALC883_3ST_6ch,
169	ALC883_6ST_DIG,
170	ALC883_TARGA_DIG,
171	ALC883_TARGA_2ch_DIG,
172	ALC883_ACER,
173	ALC883_ACER_ASPIRE,
174	ALC883_MEDION,
175	ALC883_MEDION_MD2,
176	ALC883_LAPTOP_EAPD,
177	ALC883_LENOVO_101E_2ch,
178	ALC883_LENOVO_NB0763,
179	ALC888_LENOVO_MS7195_DIG,
180	ALC888_6ST_HP,
181	ALC888_3ST_HP,
182	ALC883_AUTO,
183	ALC883_MODEL_LAST,
184};
185
186/* for GPIO Poll */
187#define GPIO_MASK	0x03
188
189struct alc_spec {
190	/* codec parameterization */
191	struct snd_kcontrol_new *mixers[5];	/* mixer arrays */
192	unsigned int num_mixers;
193
194	const struct hda_verb *init_verbs[5];	/* initialization verbs
195						 * don't forget NULL
196						 * termination!
197						 */
198	unsigned int num_init_verbs;
199
200	char *stream_name_analog;	/* analog PCM stream */
201	struct hda_pcm_stream *stream_analog_playback;
202	struct hda_pcm_stream *stream_analog_capture;
203
204	char *stream_name_digital;	/* digital PCM stream */
205	struct hda_pcm_stream *stream_digital_playback;
206	struct hda_pcm_stream *stream_digital_capture;
207
208	/* playback */
209	struct hda_multi_out multiout;	/* playback set-up
210					 * max_channels, dacs must be set
211					 * dig_out_nid and hp_nid are optional
212					 */
213
214	/* capture */
215	unsigned int num_adc_nids;
216	hda_nid_t *adc_nids;
217	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
218
219	/* capture source */
220	unsigned int num_mux_defs;
221	const struct hda_input_mux *input_mux;
222	unsigned int cur_mux[3];
223
224	/* channel model */
225	const struct hda_channel_mode *channel_mode;
226	int num_channel_mode;
227	int need_dac_fix;
228
229	/* PCM information */
230	struct hda_pcm pcm_rec[3];	/* used in alc_build_pcms() */
231
232	/* dynamic controls, init_verbs and input_mux */
233	struct auto_pin_cfg autocfg;
234	unsigned int num_kctl_alloc, num_kctl_used;
235	struct snd_kcontrol_new *kctl_alloc;
236	struct hda_input_mux private_imux;
237	hda_nid_t private_dac_nids[5];
238
239	/* hooks */
240	void (*init_hook)(struct hda_codec *codec);
241	void (*unsol_event)(struct hda_codec *codec, unsigned int res);
242
243	/* for pin sensing */
244	unsigned int sense_updated: 1;
245	unsigned int jack_present: 1;
246
247#ifdef CONFIG_SND_HDA_POWER_SAVE
248	struct hda_loopback_check loopback;
249#endif
250};
251
252/*
253 * configuration template - to be copied to the spec instance
254 */
255struct alc_config_preset {
256	struct snd_kcontrol_new *mixers[5]; /* should be identical size
257					     * with spec
258					     */
259	const struct hda_verb *init_verbs[5];
260	unsigned int num_dacs;
261	hda_nid_t *dac_nids;
262	hda_nid_t dig_out_nid;		/* optional */
263	hda_nid_t hp_nid;		/* optional */
264	unsigned int num_adc_nids;
265	hda_nid_t *adc_nids;
266	hda_nid_t dig_in_nid;
267	unsigned int num_channel_mode;
268	const struct hda_channel_mode *channel_mode;
269	int need_dac_fix;
270	unsigned int num_mux_defs;
271	const struct hda_input_mux *input_mux;
272	void (*unsol_event)(struct hda_codec *, unsigned int);
273	void (*init_hook)(struct hda_codec *);
274#ifdef CONFIG_SND_HDA_POWER_SAVE
275	struct hda_amp_list *loopbacks;
276#endif
277};
278
279
280/*
281 * input MUX handling
282 */
283static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
284			     struct snd_ctl_elem_info *uinfo)
285{
286	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
287	struct alc_spec *spec = codec->spec;
288	unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
289	if (mux_idx >= spec->num_mux_defs)
290		mux_idx = 0;
291	return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
292}
293
294static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
295			    struct snd_ctl_elem_value *ucontrol)
296{
297	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
298	struct alc_spec *spec = codec->spec;
299	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
300
301	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
302	return 0;
303}
304
305static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
306			    struct snd_ctl_elem_value *ucontrol)
307{
308	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
309	struct alc_spec *spec = codec->spec;
310	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
311	unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
312	return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
313				     spec->adc_nids[adc_idx],
314				     &spec->cur_mux[adc_idx]);
315}
316
317
318/*
319 * channel mode setting
320 */
321static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
322			    struct snd_ctl_elem_info *uinfo)
323{
324	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
325	struct alc_spec *spec = codec->spec;
326	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
327				    spec->num_channel_mode);
328}
329
330static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
331			   struct snd_ctl_elem_value *ucontrol)
332{
333	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
334	struct alc_spec *spec = codec->spec;
335	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
336				   spec->num_channel_mode,
337				   spec->multiout.max_channels);
338}
339
340static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
341			   struct snd_ctl_elem_value *ucontrol)
342{
343	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
344	struct alc_spec *spec = codec->spec;
345	int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
346				      spec->num_channel_mode,
347				      &spec->multiout.max_channels);
348	if (err >= 0 && spec->need_dac_fix)
349		spec->multiout.num_dacs = spec->multiout.max_channels / 2;
350	return err;
351}
352
353/*
354 * Control the mode of pin widget settings via the mixer.  "pc" is used
355 * instead of "%" to avoid consequences of accidently treating the % as
356 * being part of a format specifier.  Maximum allowed length of a value is
357 * 63 characters plus NULL terminator.
358 *
359 * Note: some retasking pin complexes seem to ignore requests for input
360 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
361 * are requested.  Therefore order this list so that this behaviour will not
362 * cause problems when mixer clients move through the enum sequentially.
363 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
364 * March 2006.
365 */
366static char *alc_pin_mode_names[] = {
367	"Mic 50pc bias", "Mic 80pc bias",
368	"Line in", "Line out", "Headphone out",
369};
370static unsigned char alc_pin_mode_values[] = {
371	PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
372};
373/* The control can present all 5 options, or it can limit the options based
374 * in the pin being assumed to be exclusively an input or an output pin.  In
375 * addition, "input" pins may or may not process the mic bias option
376 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
377 * accept requests for bias as of chip versions up to March 2006) and/or
378 * wiring in the computer.
379 */
380#define ALC_PIN_DIR_IN              0x00
381#define ALC_PIN_DIR_OUT             0x01
382#define ALC_PIN_DIR_INOUT           0x02
383#define ALC_PIN_DIR_IN_NOMICBIAS    0x03
384#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
385
386/* Info about the pin modes supported by the different pin direction modes.
387 * For each direction the minimum and maximum values are given.
388 */
389static signed char alc_pin_mode_dir_info[5][2] = {
390	{ 0, 2 },    /* ALC_PIN_DIR_IN */
391	{ 3, 4 },    /* ALC_PIN_DIR_OUT */
392	{ 0, 4 },    /* ALC_PIN_DIR_INOUT */
393	{ 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
394	{ 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
395};
396#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
397#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
398#define alc_pin_mode_n_items(_dir) \
399	(alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
400
401static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
402			     struct snd_ctl_elem_info *uinfo)
403{
404	unsigned int item_num = uinfo->value.enumerated.item;
405	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
406
407	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
408	uinfo->count = 1;
409	uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
410
411	if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
412		item_num = alc_pin_mode_min(dir);
413	strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
414	return 0;
415}
416
417static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
418			    struct snd_ctl_elem_value *ucontrol)
419{
420	unsigned int i;
421	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
422	hda_nid_t nid = kcontrol->private_value & 0xffff;
423	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
424	long *valp = ucontrol->value.integer.value;
425	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
426						 AC_VERB_GET_PIN_WIDGET_CONTROL,
427						 0x00);
428
429	/* Find enumerated value for current pinctl setting */
430	i = alc_pin_mode_min(dir);
431	while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
432		i++;
433	*valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
434	return 0;
435}
436
437static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
438			    struct snd_ctl_elem_value *ucontrol)
439{
440	signed int change;
441	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
442	hda_nid_t nid = kcontrol->private_value & 0xffff;
443	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
444	long val = *ucontrol->value.integer.value;
445	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
446						 AC_VERB_GET_PIN_WIDGET_CONTROL,
447						 0x00);
448
449	if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
450		val = alc_pin_mode_min(dir);
451
452	change = pinctl != alc_pin_mode_values[val];
453	if (change) {
454		/* Set pin mode to that requested */
455		snd_hda_codec_write_cache(codec, nid, 0,
456					  AC_VERB_SET_PIN_WIDGET_CONTROL,
457					  alc_pin_mode_values[val]);
458
459		/* Also enable the retasking pin's input/output as required
460		 * for the requested pin mode.  Enum values of 2 or less are
461		 * input modes.
462		 *
463		 * Dynamically switching the input/output buffers probably
464		 * reduces noise slightly (particularly on input) so we'll
465		 * do it.  However, having both input and output buffers
466		 * enabled simultaneously doesn't seem to be problematic if
467		 * this turns out to be necessary in the future.
468		 */
469		if (val <= 2) {
470			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
471						 HDA_AMP_MUTE, HDA_AMP_MUTE);
472			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
473						 HDA_AMP_MUTE, 0);
474		} else {
475			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
476						 HDA_AMP_MUTE, HDA_AMP_MUTE);
477			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
478						 HDA_AMP_MUTE, 0);
479		}
480	}
481	return change;
482}
483
484#define ALC_PIN_MODE(xname, nid, dir) \
485	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
486	  .info = alc_pin_mode_info, \
487	  .get = alc_pin_mode_get, \
488	  .put = alc_pin_mode_put, \
489	  .private_value = nid | (dir<<16) }
490
491/* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
492 * together using a mask with more than one bit set.  This control is
493 * currently used only by the ALC260 test model.  At this stage they are not
494 * needed for any "production" models.
495 */
496#ifdef CONFIG_SND_DEBUG
497#define alc_gpio_data_info	snd_ctl_boolean_mono_info
498
499static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
500			     struct snd_ctl_elem_value *ucontrol)
501{
502	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
503	hda_nid_t nid = kcontrol->private_value & 0xffff;
504	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
505	long *valp = ucontrol->value.integer.value;
506	unsigned int val = snd_hda_codec_read(codec, nid, 0,
507					      AC_VERB_GET_GPIO_DATA, 0x00);
508
509	*valp = (val & mask) != 0;
510	return 0;
511}
512static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
513			     struct snd_ctl_elem_value *ucontrol)
514{
515	signed int change;
516	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
517	hda_nid_t nid = kcontrol->private_value & 0xffff;
518	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
519	long val = *ucontrol->value.integer.value;
520	unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
521						    AC_VERB_GET_GPIO_DATA,
522						    0x00);
523
524	/* Set/unset the masked GPIO bit(s) as needed */
525	change = (val == 0 ? 0 : mask) != (gpio_data & mask);
526	if (val == 0)
527		gpio_data &= ~mask;
528	else
529		gpio_data |= mask;
530	snd_hda_codec_write_cache(codec, nid, 0,
531				  AC_VERB_SET_GPIO_DATA, gpio_data);
532
533	return change;
534}
535#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
536	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
537	  .info = alc_gpio_data_info, \
538	  .get = alc_gpio_data_get, \
539	  .put = alc_gpio_data_put, \
540	  .private_value = nid | (mask<<16) }
541#endif   /* CONFIG_SND_DEBUG */
542
543/* A switch control to allow the enabling of the digital IO pins on the
544 * ALC260.  This is incredibly simplistic; the intention of this control is
545 * to provide something in the test model allowing digital outputs to be
546 * identified if present.  If models are found which can utilise these
547 * outputs a more complete mixer control can be devised for those models if
548 * necessary.
549 */
550#ifdef CONFIG_SND_DEBUG
551#define alc_spdif_ctrl_info	snd_ctl_boolean_mono_info
552
553static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
554			      struct snd_ctl_elem_value *ucontrol)
555{
556	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
557	hda_nid_t nid = kcontrol->private_value & 0xffff;
558	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
559	long *valp = ucontrol->value.integer.value;
560	unsigned int val = snd_hda_codec_read(codec, nid, 0,
561					      AC_VERB_GET_DIGI_CONVERT, 0x00);
562
563	*valp = (val & mask) != 0;
564	return 0;
565}
566static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
567			      struct snd_ctl_elem_value *ucontrol)
568{
569	signed int change;
570	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
571	hda_nid_t nid = kcontrol->private_value & 0xffff;
572	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
573	long val = *ucontrol->value.integer.value;
574	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
575						    AC_VERB_GET_DIGI_CONVERT,
576						    0x00);
577
578	/* Set/unset the masked control bit(s) as needed */
579	change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
580	if (val==0)
581		ctrl_data &= ~mask;
582	else
583		ctrl_data |= mask;
584	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
585				  ctrl_data);
586
587	return change;
588}
589#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
590	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
591	  .info = alc_spdif_ctrl_info, \
592	  .get = alc_spdif_ctrl_get, \
593	  .put = alc_spdif_ctrl_put, \
594	  .private_value = nid | (mask<<16) }
595#endif   /* CONFIG_SND_DEBUG */
596
597/*
598 * set up from the preset table
599 */
600static void setup_preset(struct alc_spec *spec,
601			 const struct alc_config_preset *preset)
602{
603	int i;
604
605	for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
606		spec->mixers[spec->num_mixers++] = preset->mixers[i];
607	for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
608	     i++)
609		spec->init_verbs[spec->num_init_verbs++] =
610			preset->init_verbs[i];
611
612	spec->channel_mode = preset->channel_mode;
613	spec->num_channel_mode = preset->num_channel_mode;
614	spec->need_dac_fix = preset->need_dac_fix;
615
616	spec->multiout.max_channels = spec->channel_mode[0].channels;
617
618	spec->multiout.num_dacs = preset->num_dacs;
619	spec->multiout.dac_nids = preset->dac_nids;
620	spec->multiout.dig_out_nid = preset->dig_out_nid;
621	spec->multiout.hp_nid = preset->hp_nid;
622
623	spec->num_mux_defs = preset->num_mux_defs;
624	if (!spec->num_mux_defs)
625		spec->num_mux_defs = 1;
626	spec->input_mux = preset->input_mux;
627
628	spec->num_adc_nids = preset->num_adc_nids;
629	spec->adc_nids = preset->adc_nids;
630	spec->dig_in_nid = preset->dig_in_nid;
631
632	spec->unsol_event = preset->unsol_event;
633	spec->init_hook = preset->init_hook;
634#ifdef CONFIG_SND_HDA_POWER_SAVE
635	spec->loopback.amplist = preset->loopbacks;
636#endif
637}
638
639/* Enable GPIO mask and set output */
640static struct hda_verb alc_gpio1_init_verbs[] = {
641	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
642	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
643	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
644	{ }
645};
646
647static struct hda_verb alc_gpio2_init_verbs[] = {
648	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
649	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
650	{0x01, AC_VERB_SET_GPIO_DATA, 0x02},
651	{ }
652};
653
654static struct hda_verb alc_gpio3_init_verbs[] = {
655	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
656	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
657	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
658	{ }
659};
660
661/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
662 *	31 ~ 16 :	Manufacture ID
663 *	15 ~ 8	:	SKU ID
664 *	7  ~ 0	:	Assembly ID
665 *	port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
666 */
667static void alc_subsystem_id(struct hda_codec *codec,
668			     unsigned int porta, unsigned int porte,
669			     unsigned int portd)
670{
671	unsigned int ass, tmp;
672
673	ass = codec->subsystem_id;
674	if (!(ass & 1))
675		return;
676
677	/* Override */
678	tmp = (ass & 0x38) >> 3;	/* external Amp control */
679	switch (tmp) {
680	case 1:
681		snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
682		break;
683	case 3:
684		snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
685		break;
686	case 7:
687		snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
688		break;
689	case 5:
690		switch (codec->vendor_id) {
691		case 0x10ec0862:
692		case 0x10ec0660:
693		case 0x10ec0662:
694		case 0x10ec0267:
695		case 0x10ec0268:
696			snd_hda_codec_write(codec, 0x14, 0,
697					    AC_VERB_SET_EAPD_BTLENABLE, 2);
698			snd_hda_codec_write(codec, 0x15, 0,
699					    AC_VERB_SET_EAPD_BTLENABLE, 2);
700			return;
701		}
702	case 6:
703		if (ass & 4) {	/* bit 2 : 0 = Desktop, 1 = Laptop */
704			hda_nid_t port = 0;
705			tmp = (ass & 0x1800) >> 11;
706			switch (tmp) {
707			case 0: port = porta; break;
708			case 1: port = porte; break;
709			case 2: port = portd; break;
710			}
711			if (port)
712				snd_hda_codec_write(codec, port, 0,
713						    AC_VERB_SET_EAPD_BTLENABLE,
714						    2);
715		}
716		snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
717		snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF,
718				    (tmp == 5 ? 0x3040 : 0x3050));
719		break;
720	}
721}
722
723/*
724 * Fix-up pin default configurations
725 */
726
727struct alc_pincfg {
728	hda_nid_t nid;
729	u32 val;
730};
731
732static void alc_fix_pincfg(struct hda_codec *codec,
733			   const struct snd_pci_quirk *quirk,
734			   const struct alc_pincfg **pinfix)
735{
736	const struct alc_pincfg *cfg;
737
738	quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
739	if (!quirk)
740		return;
741
742	cfg = pinfix[quirk->value];
743	for (; cfg->nid; cfg++) {
744		int i;
745		u32 val = cfg->val;
746		for (i = 0; i < 4; i++) {
747			snd_hda_codec_write(codec, cfg->nid, 0,
748				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
749				    val & 0xff);
750			val >>= 8;
751		}
752	}
753}
754
755/*
756 * ALC880 3-stack model
757 *
758 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
759 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
760 *                 F-Mic = 0x1b, HP = 0x19
761 */
762
763static hda_nid_t alc880_dac_nids[4] = {
764	/* front, rear, clfe, rear_surr */
765	0x02, 0x05, 0x04, 0x03
766};
767
768static hda_nid_t alc880_adc_nids[3] = {
769	/* ADC0-2 */
770	0x07, 0x08, 0x09,
771};
772
773/* The datasheet says the node 0x07 is connected from inputs,
774 * but it shows zero connection in the real implementation on some devices.
775 * Note: this is a 915GAV bug, fixed on 915GLV
776 */
777static hda_nid_t alc880_adc_nids_alt[2] = {
778	/* ADC1-2 */
779	0x08, 0x09,
780};
781
782#define ALC880_DIGOUT_NID	0x06
783#define ALC880_DIGIN_NID	0x0a
784
785static struct hda_input_mux alc880_capture_source = {
786	.num_items = 4,
787	.items = {
788		{ "Mic", 0x0 },
789		{ "Front Mic", 0x3 },
790		{ "Line", 0x2 },
791		{ "CD", 0x4 },
792	},
793};
794
795/* channel source setting (2/6 channel selection for 3-stack) */
796/* 2ch mode */
797static struct hda_verb alc880_threestack_ch2_init[] = {
798	/* set line-in to input, mute it */
799	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
800	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
801	/* set mic-in to input vref 80%, mute it */
802	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
803	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
804	{ } /* end */
805};
806
807/* 6ch mode */
808static struct hda_verb alc880_threestack_ch6_init[] = {
809	/* set line-in to output, unmute it */
810	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
811	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
812	/* set mic-in to output, unmute it */
813	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
814	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
815	{ } /* end */
816};
817
818static struct hda_channel_mode alc880_threestack_modes[2] = {
819	{ 2, alc880_threestack_ch2_init },
820	{ 6, alc880_threestack_ch6_init },
821};
822
823static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
824	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
825	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
826	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
827	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
828	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
829	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
830	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
831	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
832	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
833	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
834	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
835	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
836	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
837	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
838	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
839	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
840	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
841	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
842	HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
843	{
844		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
845		.name = "Channel Mode",
846		.info = alc_ch_mode_info,
847		.get = alc_ch_mode_get,
848		.put = alc_ch_mode_put,
849	},
850	{ } /* end */
851};
852
853/* capture mixer elements */
854static struct snd_kcontrol_new alc880_capture_mixer[] = {
855	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
856	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
857	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
858	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
859	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
860	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
861	{
862		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
863		/* The multiple "Capture Source" controls confuse alsamixer
864		 * So call somewhat different..
865		 * FIXME: the controls appear in the "playback" view!
866		 */
867		/* .name = "Capture Source", */
868		.name = "Input Source",
869		.count = 3,
870		.info = alc_mux_enum_info,
871		.get = alc_mux_enum_get,
872		.put = alc_mux_enum_put,
873	},
874	{ } /* end */
875};
876
877/* capture mixer elements (in case NID 0x07 not available) */
878static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
879	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
880	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
881	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
882	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
883	{
884		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
885		/* The multiple "Capture Source" controls confuse alsamixer
886		 * So call somewhat different..
887		 * FIXME: the controls appear in the "playback" view!
888		 */
889		/* .name = "Capture Source", */
890		.name = "Input Source",
891		.count = 2,
892		.info = alc_mux_enum_info,
893		.get = alc_mux_enum_get,
894		.put = alc_mux_enum_put,
895	},
896	{ } /* end */
897};
898
899
900
901/*
902 * ALC880 5-stack model
903 *
904 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
905 *      Side = 0x02 (0xd)
906 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
907 *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
908 */
909
910/* additional mixers to alc880_three_stack_mixer */
911static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
912	HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
913	HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
914	{ } /* end */
915};
916
917/* channel source setting (6/8 channel selection for 5-stack) */
918/* 6ch mode */
919static struct hda_verb alc880_fivestack_ch6_init[] = {
920	/* set line-in to input, mute it */
921	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
922	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
923	{ } /* end */
924};
925
926/* 8ch mode */
927static struct hda_verb alc880_fivestack_ch8_init[] = {
928	/* set line-in to output, unmute it */
929	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
930	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
931	{ } /* end */
932};
933
934static struct hda_channel_mode alc880_fivestack_modes[2] = {
935	{ 6, alc880_fivestack_ch6_init },
936	{ 8, alc880_fivestack_ch8_init },
937};
938
939
940/*
941 * ALC880 6-stack model
942 *
943 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
944 *      Side = 0x05 (0x0f)
945 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
946 *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
947 */
948
949static hda_nid_t alc880_6st_dac_nids[4] = {
950	/* front, rear, clfe, rear_surr */
951	0x02, 0x03, 0x04, 0x05
952};
953
954static struct hda_input_mux alc880_6stack_capture_source = {
955	.num_items = 4,
956	.items = {
957		{ "Mic", 0x0 },
958		{ "Front Mic", 0x1 },
959		{ "Line", 0x2 },
960		{ "CD", 0x4 },
961	},
962};
963
964/* fixed 8-channels */
965static struct hda_channel_mode alc880_sixstack_modes[1] = {
966	{ 8, NULL },
967};
968
969static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
970	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
971	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
972	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
973	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
974	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
975	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
976	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
977	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
978	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
979	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
980	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
981	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
982	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
983	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
984	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
985	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
986	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
987	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
988	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
989	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
990	{
991		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
992		.name = "Channel Mode",
993		.info = alc_ch_mode_info,
994		.get = alc_ch_mode_get,
995		.put = alc_ch_mode_put,
996	},
997	{ } /* end */
998};
999
1000
1001/*
1002 * ALC880 W810 model
1003 *
1004 * W810 has rear IO for:
1005 * Front (DAC 02)
1006 * Surround (DAC 03)
1007 * Center/LFE (DAC 04)
1008 * Digital out (06)
1009 *
1010 * The system also has a pair of internal speakers, and a headphone jack.
1011 * These are both connected to Line2 on the codec, hence to DAC 02.
1012 *
1013 * There is a variable resistor to control the speaker or headphone
1014 * volume. This is a hardware-only device without a software API.
1015 *
1016 * Plugging headphones in will disable the internal speakers. This is
1017 * implemented in hardware, not via the driver using jack sense. In
1018 * a similar fashion, plugging into the rear socket marked "front" will
1019 * disable both the speakers and headphones.
1020 *
1021 * For input, there's a microphone jack, and an "audio in" jack.
1022 * These may not do anything useful with this driver yet, because I
1023 * haven't setup any initialization verbs for these yet...
1024 */
1025
1026static hda_nid_t alc880_w810_dac_nids[3] = {
1027	/* front, rear/surround, clfe */
1028	0x02, 0x03, 0x04
1029};
1030
1031/* fixed 6 channels */
1032static struct hda_channel_mode alc880_w810_modes[1] = {
1033	{ 6, NULL }
1034};
1035
1036/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1037static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1038	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1039	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1040	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1041	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1042	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1043	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1044	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1045	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1046	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1047	{ } /* end */
1048};
1049
1050
1051/*
1052 * Z710V model
1053 *
1054 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1055 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1056 *                 Line = 0x1a
1057 */
1058
1059static hda_nid_t alc880_z71v_dac_nids[1] = {
1060	0x02
1061};
1062#define ALC880_Z71V_HP_DAC	0x03
1063
1064/* fixed 2 channels */
1065static struct hda_channel_mode alc880_2_jack_modes[1] = {
1066	{ 2, NULL }
1067};
1068
1069static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1070	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1071	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1072	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1073	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1074	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1075	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1076	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1077	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1078	{ } /* end */
1079};
1080
1081
1082/* FIXME! */
1083/*
1084 * ALC880 F1734 model
1085 *
1086 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1087 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1088 */
1089
1090static hda_nid_t alc880_f1734_dac_nids[1] = {
1091	0x03
1092};
1093#define ALC880_F1734_HP_DAC	0x02
1094
1095static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1096	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1097	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1098	HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1099	HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1100	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1101	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1102	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1103	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1104	{ } /* end */
1105};
1106
1107
1108/* FIXME! */
1109/*
1110 * ALC880 ASUS model
1111 *
1112 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1113 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1114 *  Mic = 0x18, Line = 0x1a
1115 */
1116
1117#define alc880_asus_dac_nids	alc880_w810_dac_nids	/* identical with w810 */
1118#define alc880_asus_modes	alc880_threestack_modes	/* 2/6 channel mode */
1119
1120static struct snd_kcontrol_new alc880_asus_mixer[] = {
1121	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1122	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1123	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1124	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1125	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1126	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1127	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1128	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1129	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1130	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1131	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1132	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1133	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1134	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1135	{
1136		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1137		.name = "Channel Mode",
1138		.info = alc_ch_mode_info,
1139		.get = alc_ch_mode_get,
1140		.put = alc_ch_mode_put,
1141	},
1142	{ } /* end */
1143};
1144
1145/* FIXME! */
1146/*
1147 * ALC880 ASUS W1V model
1148 *
1149 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1150 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1151 *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1152 */
1153
1154/* additional mixers to alc880_asus_mixer */
1155static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1156	HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1157	HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1158	{ } /* end */
1159};
1160
1161/* additional mixers to alc880_asus_mixer */
1162static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1163	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1164	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1165	{ } /* end */
1166};
1167
1168/* TCL S700 */
1169static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1170	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1171	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1172	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
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("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1176	HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1177	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1178	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1179	{
1180		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1181		/* The multiple "Capture Source" controls confuse alsamixer
1182		 * So call somewhat different..
1183		 * FIXME: the controls appear in the "playback" view!
1184		 */
1185		/* .name = "Capture Source", */
1186		.name = "Input Source",
1187		.count = 1,
1188		.info = alc_mux_enum_info,
1189		.get = alc_mux_enum_get,
1190		.put = alc_mux_enum_put,
1191	},
1192	{ } /* end */
1193};
1194
1195/* Uniwill */
1196static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1197	HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1198	HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1199	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1200	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1201	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1202	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1203	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1204	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1205	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1206	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1207	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1208	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1209	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1210	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1211	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1212	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1213	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1214	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1215	{
1216		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1217		.name = "Channel Mode",
1218		.info = alc_ch_mode_info,
1219		.get = alc_ch_mode_get,
1220		.put = alc_ch_mode_put,
1221	},
1222	{ } /* end */
1223};
1224
1225static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1226	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1227	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1228	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1229	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1230	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1231	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1232	HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1233	HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1234	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1235	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1236	{ } /* end */
1237};
1238
1239static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1240	HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1241	HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1242	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1243	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1244	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1245	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1246	{ } /* end */
1247};
1248
1249/*
1250 * build control elements
1251 */
1252static int alc_build_controls(struct hda_codec *codec)
1253{
1254	struct alc_spec *spec = codec->spec;
1255	int err;
1256	int i;
1257
1258	for (i = 0; i < spec->num_mixers; i++) {
1259		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1260		if (err < 0)
1261			return err;
1262	}
1263
1264	if (spec->multiout.dig_out_nid) {
1265		err = snd_hda_create_spdif_out_ctls(codec,
1266						    spec->multiout.dig_out_nid);
1267		if (err < 0)
1268			return err;
1269	}
1270	if (spec->dig_in_nid) {
1271		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1272		if (err < 0)
1273			return err;
1274	}
1275	return 0;
1276}
1277
1278
1279/*
1280 * initialize the codec volumes, etc
1281 */
1282
1283/*
1284 * generic initialization of ADC, input mixers and output mixers
1285 */
1286static struct hda_verb alc880_volume_init_verbs[] = {
1287	/*
1288	 * Unmute ADC0-2 and set the default input to mic-in
1289	 */
1290	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1291	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1292	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1293	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1294	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1295	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1296
1297	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1298	 * mixer widget
1299	 * Note: PASD motherboards uses the Line In 2 as the input for front
1300	 * panel mic (mic 2)
1301	 */
1302	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1303	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1304	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1305	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1306	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1307	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1308	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1309	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1310
1311	/*
1312	 * Set up output mixers (0x0c - 0x0f)
1313	 */
1314	/* set vol=0 to output mixers */
1315	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1316	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1317	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1318	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1319	/* set up input amps for analog loopback */
1320	/* Amp Indices: DAC = 0, mixer = 1 */
1321	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1322	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1323	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1324	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1325	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1326	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1327	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1328	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1329
1330	{ }
1331};
1332
1333/*
1334 * 3-stack pin configuration:
1335 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1336 */
1337static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1338	/*
1339	 * preset connection lists of input pins
1340	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1341	 */
1342	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1343	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1344	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1345
1346	/*
1347	 * Set pin mode and muting
1348	 */
1349	/* set front pin widgets 0x14 for output */
1350	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1351	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1352	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1353	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1354	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1355	/* Mic2 (as headphone out) for HP output */
1356	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1357	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1358	/* Line In pin widget for input */
1359	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1360	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1361	/* Line2 (as front mic) pin widget for input and vref at 80% */
1362	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1363	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1364	/* CD pin widget for input */
1365	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1366
1367	{ }
1368};
1369
1370/*
1371 * 5-stack pin configuration:
1372 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1373 * line-in/side = 0x1a, f-mic = 0x1b
1374 */
1375static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1376	/*
1377	 * preset connection lists of input pins
1378	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1379	 */
1380	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1381	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1382
1383	/*
1384	 * Set pin mode and muting
1385	 */
1386	/* set pin widgets 0x14-0x17 for output */
1387	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1388	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1389	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1390	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1391	/* unmute pins for output (no gain on this amp) */
1392	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1393	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1394	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1395	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1396
1397	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1398	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1399	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1400	/* Mic2 (as headphone out) for HP output */
1401	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1402	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1403	/* Line In pin widget for input */
1404	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1405	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1406	/* Line2 (as front mic) pin widget for input and vref at 80% */
1407	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1408	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1409	/* CD pin widget for input */
1410	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1411
1412	{ }
1413};
1414
1415/*
1416 * W810 pin configuration:
1417 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1418 */
1419static struct hda_verb alc880_pin_w810_init_verbs[] = {
1420	/* hphone/speaker input selector: front DAC */
1421	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1422
1423	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1424	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1425	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1426	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1427	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1428	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1429
1430	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1431	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1432
1433	{ }
1434};
1435
1436/*
1437 * Z71V pin configuration:
1438 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1439 */
1440static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1441	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1442	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1443	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1444	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1445
1446	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1447	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1448	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1449	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1450
1451	{ }
1452};
1453
1454/*
1455 * 6-stack pin configuration:
1456 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1457 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1458 */
1459static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1460	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1461
1462	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1463	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1464	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1465	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1466	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1467	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1468	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1469	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1470
1471	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1472	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1473	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1474	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1475	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1476	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1477	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1478	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1479	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1480
1481	{ }
1482};
1483
1484/*
1485 * Uniwill pin configuration:
1486 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1487 * line = 0x1a
1488 */
1489static struct hda_verb alc880_uniwill_init_verbs[] = {
1490	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1491
1492	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1493	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1494	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1495	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1496	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1497	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1498	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1499	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1500	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1501	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1502	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1503	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1504	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1505	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1506
1507	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1508	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1509	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1510	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1511	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1512	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1513	/* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1514	/* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1515	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1516
1517	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1518	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1519
1520	{ }
1521};
1522
1523/*
1524* Uniwill P53
1525* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1526 */
1527static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1528	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1529
1530	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1531	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1532	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1533	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1534	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1535	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1536	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1537	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1538	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1539	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1540	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1541	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1542
1543	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1544	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1545	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1546	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1547	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1548	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1549
1550	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1551	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1552
1553	{ }
1554};
1555
1556static struct hda_verb alc880_beep_init_verbs[] = {
1557	{ 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1558	{ }
1559};
1560
1561/* toggle speaker-output according to the hp-jack state */
1562static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1563{
1564 	unsigned int present;
1565	unsigned char bits;
1566
1567 	present = snd_hda_codec_read(codec, 0x14, 0,
1568				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1569	bits = present ? HDA_AMP_MUTE : 0;
1570	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1571				 HDA_AMP_MUTE, bits);
1572	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1573				 HDA_AMP_MUTE, bits);
1574}
1575
1576/* auto-toggle front mic */
1577static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1578{
1579 	unsigned int present;
1580	unsigned char bits;
1581
1582	present = snd_hda_codec_read(codec, 0x18, 0,
1583				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1584	bits = present ? HDA_AMP_MUTE : 0;
1585	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
1586}
1587
1588static void alc880_uniwill_automute(struct hda_codec *codec)
1589{
1590	alc880_uniwill_hp_automute(codec);
1591	alc880_uniwill_mic_automute(codec);
1592}
1593
1594static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1595				       unsigned int res)
1596{
1597	/* Looks like the unsol event is incompatible with the standard
1598	 * definition.  4bit tag is placed at 28 bit!
1599	 */
1600	switch (res >> 28) {
1601	case ALC880_HP_EVENT:
1602		alc880_uniwill_hp_automute(codec);
1603		break;
1604	case ALC880_MIC_EVENT:
1605		alc880_uniwill_mic_automute(codec);
1606		break;
1607	}
1608}
1609
1610static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1611{
1612 	unsigned int present;
1613	unsigned char bits;
1614
1615 	present = snd_hda_codec_read(codec, 0x14, 0,
1616				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1617	bits = present ? HDA_AMP_MUTE : 0;
1618	snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits);
1619}
1620
1621static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1622{
1623	unsigned int present;
1624
1625	present = snd_hda_codec_read(codec, 0x21, 0,
1626				     AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1627	present &= HDA_AMP_VOLMASK;
1628	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1629				 HDA_AMP_VOLMASK, present);
1630	snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1631				 HDA_AMP_VOLMASK, present);
1632}
1633
1634static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1635					   unsigned int res)
1636{
1637	/* Looks like the unsol event is incompatible with the standard
1638	 * definition.  4bit tag is placed at 28 bit!
1639	 */
1640	if ((res >> 28) == ALC880_HP_EVENT)
1641		alc880_uniwill_p53_hp_automute(codec);
1642	if ((res >> 28) == ALC880_DCVOL_EVENT)
1643		alc880_uniwill_p53_dcvol_automute(codec);
1644}
1645
1646/* FIXME! */
1647/*
1648 * F1734 pin configuration:
1649 * HP = 0x14, speaker-out = 0x15, mic = 0x18
1650 */
1651static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1652	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1653	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1654	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1655	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1656
1657	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1658	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1659	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1660	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1661
1662	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1663	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1664	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1665	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1666	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1667	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1668	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1669	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1670	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1671
1672	{ }
1673};
1674
1675/* FIXME! */
1676/*
1677 * ASUS pin configuration:
1678 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1679 */
1680static struct hda_verb alc880_pin_asus_init_verbs[] = {
1681	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1682	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1683	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1684	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1685
1686	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1687	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1688	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1689	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1690	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1691	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1692	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1693	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1694
1695	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1696	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1697	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1698	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1699	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1700	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1701	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1702	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1703	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1704
1705	{ }
1706};
1707
1708/* Enable GPIO mask and set output */
1709#define alc880_gpio1_init_verbs	alc_gpio1_init_verbs
1710#define alc880_gpio2_init_verbs	alc_gpio2_init_verbs
1711
1712/* Clevo m520g init */
1713static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1714	/* headphone output */
1715	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1716	/* line-out */
1717	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1718	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1719	/* Line-in */
1720	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1721	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1722	/* CD */
1723	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1724	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1725	/* Mic1 (rear panel) */
1726	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1727	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1728	/* Mic2 (front panel) */
1729	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1730	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1731	/* headphone */
1732	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1733	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1734        /* change to EAPD mode */
1735	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1736	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1737
1738	{ }
1739};
1740
1741static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
1742	/* change to EAPD mode */
1743	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1744	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1745
1746	/* Headphone output */
1747	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1748	/* Front output*/
1749	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1750	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1751
1752	/* Line In pin widget for input */
1753	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1754	/* CD pin widget for input */
1755	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1756	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1757	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1758
1759	/* change to EAPD mode */
1760	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1761	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
1762
1763	{ }
1764};
1765
1766/*
1767 * LG m1 express dual
1768 *
1769 * Pin assignment:
1770 *   Rear Line-In/Out (blue): 0x14
1771 *   Build-in Mic-In: 0x15
1772 *   Speaker-out: 0x17
1773 *   HP-Out (green): 0x1b
1774 *   Mic-In/Out (red): 0x19
1775 *   SPDIF-Out: 0x1e
1776 */
1777
1778/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
1779static hda_nid_t alc880_lg_dac_nids[3] = {
1780	0x05, 0x02, 0x03
1781};
1782
1783/* seems analog CD is not working */
1784static struct hda_input_mux alc880_lg_capture_source = {
1785	.num_items = 3,
1786	.items = {
1787		{ "Mic", 0x1 },
1788		{ "Line", 0x5 },
1789		{ "Internal Mic", 0x6 },
1790	},
1791};
1792
1793/* 2,4,6 channel modes */
1794static struct hda_verb alc880_lg_ch2_init[] = {
1795	/* set line-in and mic-in to input */
1796	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1797	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1798	{ }
1799};
1800
1801static struct hda_verb alc880_lg_ch4_init[] = {
1802	/* set line-in to out and mic-in to input */
1803	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1804	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1805	{ }
1806};
1807
1808static struct hda_verb alc880_lg_ch6_init[] = {
1809	/* set line-in and mic-in to output */
1810	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1811	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1812	{ }
1813};
1814
1815static struct hda_channel_mode alc880_lg_ch_modes[3] = {
1816	{ 2, alc880_lg_ch2_init },
1817	{ 4, alc880_lg_ch4_init },
1818	{ 6, alc880_lg_ch6_init },
1819};
1820
1821static struct snd_kcontrol_new alc880_lg_mixer[] = {
1822	/* FIXME: it's not really "master" but front channels */
1823	HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1824	HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT),
1825	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1826	HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
1827	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
1828	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
1829	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
1830	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
1831	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1832	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1833	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
1834	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
1835	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
1836	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
1837	{
1838		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1839		.name = "Channel Mode",
1840		.info = alc_ch_mode_info,
1841		.get = alc_ch_mode_get,
1842		.put = alc_ch_mode_put,
1843	},
1844	{ } /* end */
1845};
1846
1847static struct hda_verb alc880_lg_init_verbs[] = {
1848	/* set capture source to mic-in */
1849	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1850	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1851	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1852	/* mute all amp mixer inputs */
1853	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
1854	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1855	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1856	/* line-in to input */
1857	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1858	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1859	/* built-in mic */
1860	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1861	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1862	/* speaker-out */
1863	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1864	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1865	/* mic-in to input */
1866	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1867	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1868	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1869	/* HP-out */
1870	{0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
1871	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1872	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1873	/* jack sense */
1874	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1875	{ }
1876};
1877
1878/* toggle speaker-output according to the hp-jack state */
1879static void alc880_lg_automute(struct hda_codec *codec)
1880{
1881	unsigned int present;
1882	unsigned char bits;
1883
1884	present = snd_hda_codec_read(codec, 0x1b, 0,
1885				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1886	bits = present ? HDA_AMP_MUTE : 0;
1887	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
1888				 HDA_AMP_MUTE, bits);
1889}
1890
1891static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
1892{
1893	/* Looks like the unsol event is incompatible with the standard
1894	 * definition.  4bit tag is placed at 28 bit!
1895	 */
1896	if ((res >> 28) == 0x01)
1897		alc880_lg_automute(codec);
1898}
1899
1900/*
1901 * LG LW20
1902 *
1903 * Pin assignment:
1904 *   Speaker-out: 0x14
1905 *   Mic-In: 0x18
1906 *   Built-in Mic-In: 0x19
1907 *   Line-In: 0x1b
1908 *   HP-Out: 0x1a
1909 *   SPDIF-Out: 0x1e
1910 */
1911
1912static struct hda_input_mux alc880_lg_lw_capture_source = {
1913	.num_items = 3,
1914	.items = {
1915		{ "Mic", 0x0 },
1916		{ "Internal Mic", 0x1 },
1917		{ "Line In", 0x2 },
1918	},
1919};
1920
1921#define alc880_lg_lw_modes alc880_threestack_modes
1922
1923static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
1924	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1925	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1926	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1927	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1928	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1929	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1930	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1931	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1932	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1933	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1934	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1935	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1936	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
1937	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
1938	{
1939		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1940		.name = "Channel Mode",
1941		.info = alc_ch_mode_info,
1942		.get = alc_ch_mode_get,
1943		.put = alc_ch_mode_put,
1944	},
1945	{ } /* end */
1946};
1947
1948static struct hda_verb alc880_lg_lw_init_verbs[] = {
1949	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1950	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1951	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1952
1953	/* set capture source to mic-in */
1954	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1955	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1956	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1957	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1958	/* speaker-out */
1959	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1960	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1961	/* HP-out */
1962	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1963	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1964	/* mic-in to input */
1965	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1966	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1967	/* built-in mic */
1968	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1969	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1970	/* jack sense */
1971	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1972	{ }
1973};
1974
1975/* toggle speaker-output according to the hp-jack state */
1976static void alc880_lg_lw_automute(struct hda_codec *codec)
1977{
1978	unsigned int present;
1979	unsigned char bits;
1980
1981	present = snd_hda_codec_read(codec, 0x1b, 0,
1982				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1983	bits = present ? HDA_AMP_MUTE : 0;
1984	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
1985				 HDA_AMP_MUTE, bits);
1986}
1987
1988static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
1989{
1990	/* Looks like the unsol event is incompatible with the standard
1991	 * definition.  4bit tag is placed at 28 bit!
1992	 */
1993	if ((res >> 28) == 0x01)
1994		alc880_lg_lw_automute(codec);
1995}
1996
1997#ifdef CONFIG_SND_HDA_POWER_SAVE
1998static struct hda_amp_list alc880_loopbacks[] = {
1999	{ 0x0b, HDA_INPUT, 0 },
2000	{ 0x0b, HDA_INPUT, 1 },
2001	{ 0x0b, HDA_INPUT, 2 },
2002	{ 0x0b, HDA_INPUT, 3 },
2003	{ 0x0b, HDA_INPUT, 4 },
2004	{ } /* end */
2005};
2006
2007static struct hda_amp_list alc880_lg_loopbacks[] = {
2008	{ 0x0b, HDA_INPUT, 1 },
2009	{ 0x0b, HDA_INPUT, 6 },
2010	{ 0x0b, HDA_INPUT, 7 },
2011	{ } /* end */
2012};
2013#endif
2014
2015/*
2016 * Common callbacks
2017 */
2018
2019static int alc_init(struct hda_codec *codec)
2020{
2021	struct alc_spec *spec = codec->spec;
2022	unsigned int i;
2023
2024	for (i = 0; i < spec->num_init_verbs; i++)
2025		snd_hda_sequence_write(codec, spec->init_verbs[i]);
2026
2027	if (spec->init_hook)
2028		spec->init_hook(codec);
2029
2030	return 0;
2031}
2032
2033static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2034{
2035	struct alc_spec *spec = codec->spec;
2036
2037	if (spec->unsol_event)
2038		spec->unsol_event(codec, res);
2039}
2040
2041#ifdef CONFIG_SND_HDA_POWER_SAVE
2042static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2043{
2044	struct alc_spec *spec = codec->spec;
2045	return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2046}
2047#endif
2048
2049/*
2050 * Analog playback callbacks
2051 */
2052static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2053				    struct hda_codec *codec,
2054				    struct snd_pcm_substream *substream)
2055{
2056	struct alc_spec *spec = codec->spec;
2057	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
2058}
2059
2060static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2061				       struct hda_codec *codec,
2062				       unsigned int stream_tag,
2063				       unsigned int format,
2064				       struct snd_pcm_substream *substream)
2065{
2066	struct alc_spec *spec = codec->spec;
2067	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2068						stream_tag, format, substream);
2069}
2070
2071static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2072				       struct hda_codec *codec,
2073				       struct snd_pcm_substream *substream)
2074{
2075	struct alc_spec *spec = codec->spec;
2076	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2077}
2078
2079/*
2080 * Digital out
2081 */
2082static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2083					struct hda_codec *codec,
2084					struct snd_pcm_substream *substream)
2085{
2086	struct alc_spec *spec = codec->spec;
2087	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2088}
2089
2090static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2091					   struct hda_codec *codec,
2092					   unsigned int stream_tag,
2093					   unsigned int format,
2094					   struct snd_pcm_substream *substream)
2095{
2096	struct alc_spec *spec = codec->spec;
2097	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2098					     stream_tag, format, substream);
2099}
2100
2101static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2102					 struct hda_codec *codec,
2103					 struct snd_pcm_substream *substream)
2104{
2105	struct alc_spec *spec = codec->spec;
2106	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2107}
2108
2109/*
2110 * Analog capture
2111 */
2112static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2113				      struct hda_codec *codec,
2114				      unsigned int stream_tag,
2115				      unsigned int format,
2116				      struct snd_pcm_substream *substream)
2117{
2118	struct alc_spec *spec = codec->spec;
2119
2120	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2121				   stream_tag, 0, format);
2122	return 0;
2123}
2124
2125static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2126				      struct hda_codec *codec,
2127				      struct snd_pcm_substream *substream)
2128{
2129	struct alc_spec *spec = codec->spec;
2130
2131	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2132				   0, 0, 0);
2133	return 0;
2134}
2135
2136
2137/*
2138 */
2139static struct hda_pcm_stream alc880_pcm_analog_playback = {
2140	.substreams = 1,
2141	.channels_min = 2,
2142	.channels_max = 8,
2143	/* NID is set in alc_build_pcms */
2144	.ops = {
2145		.open = alc880_playback_pcm_open,
2146		.prepare = alc880_playback_pcm_prepare,
2147		.cleanup = alc880_playback_pcm_cleanup
2148	},
2149};
2150
2151static struct hda_pcm_stream alc880_pcm_analog_capture = {
2152	.substreams = 2,
2153	.channels_min = 2,
2154	.channels_max = 2,
2155	/* NID is set in alc_build_pcms */
2156	.ops = {
2157		.prepare = alc880_capture_pcm_prepare,
2158		.cleanup = alc880_capture_pcm_cleanup
2159	},
2160};
2161
2162static struct hda_pcm_stream alc880_pcm_digital_playback = {
2163	.substreams = 1,
2164	.channels_min = 2,
2165	.channels_max = 2,
2166	/* NID is set in alc_build_pcms */
2167	.ops = {
2168		.open = alc880_dig_playback_pcm_open,
2169		.close = alc880_dig_playback_pcm_close,
2170		.prepare = alc880_dig_playback_pcm_prepare
2171	},
2172};
2173
2174static struct hda_pcm_stream alc880_pcm_digital_capture = {
2175	.substreams = 1,
2176	.channels_min = 2,
2177	.channels_max = 2,
2178	/* NID is set in alc_build_pcms */
2179};
2180
2181/* Used by alc_build_pcms to flag that a PCM has no playback stream */
2182static struct hda_pcm_stream alc_pcm_null_playback = {
2183	.substreams = 0,
2184	.channels_min = 0,
2185	.channels_max = 0,
2186};
2187
2188static int alc_build_pcms(struct hda_codec *codec)
2189{
2190	struct alc_spec *spec = codec->spec;
2191	struct hda_pcm *info = spec->pcm_rec;
2192	int i;
2193
2194	codec->num_pcms = 1;
2195	codec->pcm_info = info;
2196
2197	info->name = spec->stream_name_analog;
2198	if (spec->stream_analog_playback) {
2199		snd_assert(spec->multiout.dac_nids, return -EINVAL);
2200		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2201		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2202	}
2203	if (spec->stream_analog_capture) {
2204		snd_assert(spec->adc_nids, return -EINVAL);
2205		info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2206		info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2207	}
2208
2209	if (spec->channel_mode) {
2210		info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2211		for (i = 0; i < spec->num_channel_mode; i++) {
2212			if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2213				info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2214			}
2215		}
2216	}
2217
2218	/* SPDIF for stream index #1 */
2219	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2220		codec->num_pcms = 2;
2221		info = spec->pcm_rec + 1;
2222		info->name = spec->stream_name_digital;
2223		if (spec->multiout.dig_out_nid &&
2224		    spec->stream_digital_playback) {
2225			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2226			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2227		}
2228		if (spec->dig_in_nid &&
2229		    spec->stream_digital_capture) {
2230			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2231			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2232		}
2233	}
2234
2235	/* If the use of more than one ADC is requested for the current
2236	 * model, configure a second analog capture-only PCM.
2237	 */
2238	/* Additional Analaog capture for index #2 */
2239	if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
2240	    spec->adc_nids) {
2241		codec->num_pcms = 3;
2242		info = spec->pcm_rec + 2;
2243		info->name = spec->stream_name_analog;
2244		/* No playback stream for second PCM */
2245		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
2246		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2247		if (spec->stream_analog_capture) {
2248			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2249			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
2250		}
2251	}
2252
2253	return 0;
2254}
2255
2256static void alc_free(struct hda_codec *codec)
2257{
2258	struct alc_spec *spec = codec->spec;
2259	unsigned int i;
2260
2261	if (!spec)
2262		return;
2263
2264	if (spec->kctl_alloc) {
2265		for (i = 0; i < spec->num_kctl_used; i++)
2266			kfree(spec->kctl_alloc[i].name);
2267		kfree(spec->kctl_alloc);
2268	}
2269	kfree(spec);
2270}
2271
2272/*
2273 */
2274static struct hda_codec_ops alc_patch_ops = {
2275	.build_controls = alc_build_controls,
2276	.build_pcms = alc_build_pcms,
2277	.init = alc_init,
2278	.free = alc_free,
2279	.unsol_event = alc_unsol_event,
2280#ifdef CONFIG_SND_HDA_POWER_SAVE
2281	.check_power_status = alc_check_power_status,
2282#endif
2283};
2284
2285
2286/*
2287 * Test configuration for debugging
2288 *
2289 * Almost all inputs/outputs are enabled.  I/O pins can be configured via
2290 * enum controls.
2291 */
2292#ifdef CONFIG_SND_DEBUG
2293static hda_nid_t alc880_test_dac_nids[4] = {
2294	0x02, 0x03, 0x04, 0x05
2295};
2296
2297static struct hda_input_mux alc880_test_capture_source = {
2298	.num_items = 7,
2299	.items = {
2300		{ "In-1", 0x0 },
2301		{ "In-2", 0x1 },
2302		{ "In-3", 0x2 },
2303		{ "In-4", 0x3 },
2304		{ "CD", 0x4 },
2305		{ "Front", 0x5 },
2306		{ "Surround", 0x6 },
2307	},
2308};
2309
2310static struct hda_channel_mode alc880_test_modes[4] = {
2311	{ 2, NULL },
2312	{ 4, NULL },
2313	{ 6, NULL },
2314	{ 8, NULL },
2315};
2316
2317static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2318				 struct snd_ctl_elem_info *uinfo)
2319{
2320	static char *texts[] = {
2321		"N/A", "Line Out", "HP Out",
2322		"In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2323	};
2324	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2325	uinfo->count = 1;
2326	uinfo->value.enumerated.items = 8;
2327	if (uinfo->value.enumerated.item >= 8)
2328		uinfo->value.enumerated.item = 7;
2329	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2330	return 0;
2331}
2332
2333static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2334				struct snd_ctl_elem_value *ucontrol)
2335{
2336	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2337	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2338	unsigned int pin_ctl, item = 0;
2339
2340	pin_ctl = snd_hda_codec_read(codec, nid, 0,
2341				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2342	if (pin_ctl & AC_PINCTL_OUT_EN) {
2343		if (pin_ctl & AC_PINCTL_HP_EN)
2344			item = 2;
2345		else
2346			item = 1;
2347	} else if (pin_ctl & AC_PINCTL_IN_EN) {
2348		switch (pin_ctl & AC_PINCTL_VREFEN) {
2349		case AC_PINCTL_VREF_HIZ: item = 3; break;
2350		case AC_PINCTL_VREF_50:  item = 4; break;
2351		case AC_PINCTL_VREF_GRD: item = 5; break;
2352		case AC_PINCTL_VREF_80:  item = 6; break;
2353		case AC_PINCTL_VREF_100: item = 7; break;
2354		}
2355	}
2356	ucontrol->value.enumerated.item[0] = item;
2357	return 0;
2358}
2359
2360static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2361				struct snd_ctl_elem_value *ucontrol)
2362{
2363	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2364	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2365	static unsigned int ctls[] = {
2366		0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2367		AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2368		AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2369		AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2370		AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2371		AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2372	};
2373	unsigned int old_ctl, new_ctl;
2374
2375	old_ctl = snd_hda_codec_read(codec, nid, 0,
2376				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2377	new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2378	if (old_ctl != new_ctl) {
2379		int val;
2380		snd_hda_codec_write_cache(codec, nid, 0,
2381					  AC_VERB_SET_PIN_WIDGET_CONTROL,
2382					  new_ctl);
2383		val = ucontrol->value.enumerated.item[0] >= 3 ?
2384			HDA_AMP_MUTE : 0;
2385		snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2386					 HDA_AMP_MUTE, val);
2387		return 1;
2388	}
2389	return 0;
2390}
2391
2392static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2393				 struct snd_ctl_elem_info *uinfo)
2394{
2395	static char *texts[] = {
2396		"Front", "Surround", "CLFE", "Side"
2397	};
2398	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2399	uinfo->count = 1;
2400	uinfo->value.enumerated.items = 4;
2401	if (uinfo->value.enumerated.item >= 4)
2402		uinfo->value.enumerated.item = 3;
2403	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2404	return 0;
2405}
2406
2407static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2408				struct snd_ctl_elem_value *ucontrol)
2409{
2410	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2411	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2412	unsigned int sel;
2413
2414	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2415	ucontrol->value.enumerated.item[0] = sel & 3;
2416	return 0;
2417}
2418
2419static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2420				struct snd_ctl_elem_value *ucontrol)
2421{
2422	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2423	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2424	unsigned int sel;
2425
2426	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2427	if (ucontrol->value.enumerated.item[0] != sel) {
2428		sel = ucontrol->value.enumerated.item[0] & 3;
2429		snd_hda_codec_write_cache(codec, nid, 0,
2430					  AC_VERB_SET_CONNECT_SEL, sel);
2431		return 1;
2432	}
2433	return 0;
2434}
2435
2436#define PIN_CTL_TEST(xname,nid) {			\
2437		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
2438			.name = xname,		       \
2439			.info = alc_test_pin_ctl_info, \
2440			.get = alc_test_pin_ctl_get,   \
2441			.put = alc_test_pin_ctl_put,   \
2442			.private_value = nid	       \
2443			}
2444
2445#define PIN_SRC_TEST(xname,nid) {			\
2446		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
2447			.name = xname,		       \
2448			.info = alc_test_pin_src_info, \
2449			.get = alc_test_pin_src_get,   \
2450			.put = alc_test_pin_src_put,   \
2451			.private_value = nid	       \
2452			}
2453
2454static struct snd_kcontrol_new alc880_test_mixer[] = {
2455	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2456	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2457	HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2458	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2459	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2460	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2461	HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2462	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2463	PIN_CTL_TEST("Front Pin Mode", 0x14),
2464	PIN_CTL_TEST("Surround Pin Mode", 0x15),
2465	PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2466	PIN_CTL_TEST("Side Pin Mode", 0x17),
2467	PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2468	PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2469	PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2470	PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2471	PIN_SRC_TEST("In-1 Pin Source", 0x18),
2472	PIN_SRC_TEST("In-2 Pin Source", 0x19),
2473	PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2474	PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2475	HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2476	HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2477	HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2478	HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2479	HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2480	HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2481	HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2482	HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2483	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2484	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2485	{
2486		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2487		.name = "Channel Mode",
2488		.info = alc_ch_mode_info,
2489		.get = alc_ch_mode_get,
2490		.put = alc_ch_mode_put,
2491	},
2492	{ } /* end */
2493};
2494
2495static struct hda_verb alc880_test_init_verbs[] = {
2496	/* Unmute inputs of 0x0c - 0x0f */
2497	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2498	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2499	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2500	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2501	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2502	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2503	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2504	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2505	/* Vol output for 0x0c-0x0f */
2506	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2507	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2508	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2509	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2510	/* Set output pins 0x14-0x17 */
2511	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2512	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2513	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2514	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2515	/* Unmute output pins 0x14-0x17 */
2516	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2517	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2518	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2519	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2520	/* Set input pins 0x18-0x1c */
2521	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2522	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2523	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2524	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2525	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2526	/* Mute input pins 0x18-0x1b */
2527	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2528	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2529	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2530	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2531	/* ADC set up */
2532	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2533	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2534	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2535	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2536	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2537	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2538	/* Analog input/passthru */
2539	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2540	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2541	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2542	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2543	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2544	{ }
2545};
2546#endif
2547
2548/*
2549 */
2550
2551static const char *alc880_models[ALC880_MODEL_LAST] = {
2552	[ALC880_3ST]		= "3stack",
2553	[ALC880_TCL_S700]	= "tcl",
2554	[ALC880_3ST_DIG]	= "3stack-digout",
2555	[ALC880_CLEVO]		= "clevo",
2556	[ALC880_5ST]		= "5stack",
2557	[ALC880_5ST_DIG]	= "5stack-digout",
2558	[ALC880_W810]		= "w810",
2559	[ALC880_Z71V]		= "z71v",
2560	[ALC880_6ST]		= "6stack",
2561	[ALC880_6ST_DIG]	= "6stack-digout",
2562	[ALC880_ASUS]		= "asus",
2563	[ALC880_ASUS_W1V]	= "asus-w1v",
2564	[ALC880_ASUS_DIG]	= "asus-dig",
2565	[ALC880_ASUS_DIG2]	= "asus-dig2",
2566	[ALC880_UNIWILL_DIG]	= "uniwill",
2567	[ALC880_UNIWILL_P53]	= "uniwill-p53",
2568	[ALC880_FUJITSU]	= "fujitsu",
2569	[ALC880_F1734]		= "F1734",
2570	[ALC880_LG]		= "lg",
2571	[ALC880_LG_LW]		= "lg-lw",
2572#ifdef CONFIG_SND_DEBUG
2573	[ALC880_TEST]		= "test",
2574#endif
2575	[ALC880_AUTO]		= "auto",
2576};
2577
2578static struct snd_pci_quirk alc880_cfg_tbl[] = {
2579	/* Broken BIOS configuration */
2580	SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG),
2581	SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2582
2583	SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2584	SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2585	SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
2586	SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2587	SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2588	SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2589	SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2590	SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2591	SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
2592
2593	SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2594	SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
2595
2596	SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2597	SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2598	SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2599	SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2600	SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2601	SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2602	SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2603	/* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2604	SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2605	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
2606	SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
2607	SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2608	SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2609	SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
2610	SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS),
2611
2612	SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2613	SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
2614	SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2615	SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
2616	SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
2617	SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2618	SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
2619	SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
2620	SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2621	SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
2622	SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2623	SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2624	SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
2625	SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2626	SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2627	SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2628	SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
2629	SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
2630
2631	SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
2632	SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2633	SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
2634	SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
2635
2636	SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
2637	SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2638	SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
2639	SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
2640
2641	SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2642	SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
2643	SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
2644	SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
2645
2646	SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
2647	SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2648	SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
2649	SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2650	SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
2651	SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
2652	SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2653	SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2654	SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
2655	SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
2656	SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST),
2657
2658	{}
2659};
2660
2661/*
2662 * ALC880 codec presets
2663 */
2664static struct alc_config_preset alc880_presets[] = {
2665	[ALC880_3ST] = {
2666		.mixers = { alc880_three_stack_mixer },
2667		.init_verbs = { alc880_volume_init_verbs,
2668				alc880_pin_3stack_init_verbs },
2669		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2670		.dac_nids = alc880_dac_nids,
2671		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2672		.channel_mode = alc880_threestack_modes,
2673		.need_dac_fix = 1,
2674		.input_mux = &alc880_capture_source,
2675	},
2676	[ALC880_3ST_DIG] = {
2677		.mixers = { alc880_three_stack_mixer },
2678		.init_verbs = { alc880_volume_init_verbs,
2679				alc880_pin_3stack_init_verbs },
2680		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2681		.dac_nids = alc880_dac_nids,
2682		.dig_out_nid = ALC880_DIGOUT_NID,
2683		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2684		.channel_mode = alc880_threestack_modes,
2685		.need_dac_fix = 1,
2686		.input_mux = &alc880_capture_source,
2687	},
2688	[ALC880_TCL_S700] = {
2689		.mixers = { alc880_tcl_s700_mixer },
2690		.init_verbs = { alc880_volume_init_verbs,
2691				alc880_pin_tcl_S700_init_verbs,
2692				alc880_gpio2_init_verbs },
2693		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2694		.dac_nids = alc880_dac_nids,
2695		.hp_nid = 0x03,
2696		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2697		.channel_mode = alc880_2_jack_modes,
2698		.input_mux = &alc880_capture_source,
2699	},
2700	[ALC880_5ST] = {
2701		.mixers = { alc880_three_stack_mixer,
2702			    alc880_five_stack_mixer},
2703		.init_verbs = { alc880_volume_init_verbs,
2704				alc880_pin_5stack_init_verbs },
2705		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2706		.dac_nids = alc880_dac_nids,
2707		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2708		.channel_mode = alc880_fivestack_modes,
2709		.input_mux = &alc880_capture_source,
2710	},
2711	[ALC880_5ST_DIG] = {
2712		.mixers = { alc880_three_stack_mixer,
2713			    alc880_five_stack_mixer },
2714		.init_verbs = { alc880_volume_init_verbs,
2715				alc880_pin_5stack_init_verbs },
2716		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2717		.dac_nids = alc880_dac_nids,
2718		.dig_out_nid = ALC880_DIGOUT_NID,
2719		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2720		.channel_mode = alc880_fivestack_modes,
2721		.input_mux = &alc880_capture_source,
2722	},
2723	[ALC880_6ST] = {
2724		.mixers = { alc880_six_stack_mixer },
2725		.init_verbs = { alc880_volume_init_verbs,
2726				alc880_pin_6stack_init_verbs },
2727		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2728		.dac_nids = alc880_6st_dac_nids,
2729		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2730		.channel_mode = alc880_sixstack_modes,
2731		.input_mux = &alc880_6stack_capture_source,
2732	},
2733	[ALC880_6ST_DIG] = {
2734		.mixers = { alc880_six_stack_mixer },
2735		.init_verbs = { alc880_volume_init_verbs,
2736				alc880_pin_6stack_init_verbs },
2737		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2738		.dac_nids = alc880_6st_dac_nids,
2739		.dig_out_nid = ALC880_DIGOUT_NID,
2740		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2741		.channel_mode = alc880_sixstack_modes,
2742		.input_mux = &alc880_6stack_capture_source,
2743	},
2744	[ALC880_W810] = {
2745		.mixers = { alc880_w810_base_mixer },
2746		.init_verbs = { alc880_volume_init_verbs,
2747				alc880_pin_w810_init_verbs,
2748				alc880_gpio2_init_verbs },
2749		.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2750		.dac_nids = alc880_w810_dac_nids,
2751		.dig_out_nid = ALC880_DIGOUT_NID,
2752		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2753		.channel_mode = alc880_w810_modes,
2754		.input_mux = &alc880_capture_source,
2755	},
2756	[ALC880_Z71V] = {
2757		.mixers = { alc880_z71v_mixer },
2758		.init_verbs = { alc880_volume_init_verbs,
2759				alc880_pin_z71v_init_verbs },
2760		.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
2761		.dac_nids = alc880_z71v_dac_nids,
2762		.dig_out_nid = ALC880_DIGOUT_NID,
2763		.hp_nid = 0x03,
2764		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2765		.channel_mode = alc880_2_jack_modes,
2766		.input_mux = &alc880_capture_source,
2767	},
2768	[ALC880_F1734] = {
2769		.mixers = { alc880_f1734_mixer },
2770		.init_verbs = { alc880_volume_init_verbs,
2771				alc880_pin_f1734_init_verbs },
2772		.num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
2773		.dac_nids = alc880_f1734_dac_nids,
2774		.hp_nid = 0x02,
2775		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2776		.channel_mode = alc880_2_jack_modes,
2777		.input_mux = &alc880_capture_source,
2778	},
2779	[ALC880_ASUS] = {
2780		.mixers = { alc880_asus_mixer },
2781		.init_verbs = { alc880_volume_init_verbs,
2782				alc880_pin_asus_init_verbs,
2783				alc880_gpio1_init_verbs },
2784		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2785		.dac_nids = alc880_asus_dac_nids,
2786		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2787		.channel_mode = alc880_asus_modes,
2788		.need_dac_fix = 1,
2789		.input_mux = &alc880_capture_source,
2790	},
2791	[ALC880_ASUS_DIG] = {
2792		.mixers = { alc880_asus_mixer },
2793		.init_verbs = { alc880_volume_init_verbs,
2794				alc880_pin_asus_init_verbs,
2795				alc880_gpio1_init_verbs },
2796		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2797		.dac_nids = alc880_asus_dac_nids,
2798		.dig_out_nid = ALC880_DIGOUT_NID,
2799		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2800		.channel_mode = alc880_asus_modes,
2801		.need_dac_fix = 1,
2802		.input_mux = &alc880_capture_source,
2803	},
2804	[ALC880_ASUS_DIG2] = {
2805		.mixers = { alc880_asus_mixer },
2806		.init_verbs = { alc880_volume_init_verbs,
2807				alc880_pin_asus_init_verbs,
2808				alc880_gpio2_init_verbs }, /* use GPIO2 */
2809		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2810		.dac_nids = alc880_asus_dac_nids,
2811		.dig_out_nid = ALC880_DIGOUT_NID,
2812		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2813		.channel_mode = alc880_asus_modes,
2814		.need_dac_fix = 1,
2815		.input_mux = &alc880_capture_source,
2816	},
2817	[ALC880_ASUS_W1V] = {
2818		.mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
2819		.init_verbs = { alc880_volume_init_verbs,
2820				alc880_pin_asus_init_verbs,
2821				alc880_gpio1_init_verbs },
2822		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2823		.dac_nids = alc880_asus_dac_nids,
2824		.dig_out_nid = ALC880_DIGOUT_NID,
2825		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2826		.channel_mode = alc880_asus_modes,
2827		.need_dac_fix = 1,
2828		.input_mux = &alc880_capture_source,
2829	},
2830	[ALC880_UNIWILL_DIG] = {
2831		.mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
2832		.init_verbs = { alc880_volume_init_verbs,
2833				alc880_pin_asus_init_verbs },
2834		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2835		.dac_nids = alc880_asus_dac_nids,
2836		.dig_out_nid = ALC880_DIGOUT_NID,
2837		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2838		.channel_mode = alc880_asus_modes,
2839		.need_dac_fix = 1,
2840		.input_mux = &alc880_capture_source,
2841	},
2842	[ALC880_UNIWILL] = {
2843		.mixers = { alc880_uniwill_mixer },
2844		.init_verbs = { alc880_volume_init_verbs,
2845				alc880_uniwill_init_verbs },
2846		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2847		.dac_nids = alc880_asus_dac_nids,
2848		.dig_out_nid = ALC880_DIGOUT_NID,
2849		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2850		.channel_mode = alc880_threestack_modes,
2851		.need_dac_fix = 1,
2852		.input_mux = &alc880_capture_source,
2853		.unsol_event = alc880_uniwill_unsol_event,
2854		.init_hook = alc880_uniwill_automute,
2855	},
2856	[ALC880_UNIWILL_P53] = {
2857		.mixers = { alc880_uniwill_p53_mixer },
2858		.init_verbs = { alc880_volume_init_verbs,
2859				alc880_uniwill_p53_init_verbs },
2860		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2861		.dac_nids = alc880_asus_dac_nids,
2862		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2863		.channel_mode = alc880_threestack_modes,
2864		.input_mux = &alc880_capture_source,
2865		.unsol_event = alc880_uniwill_p53_unsol_event,
2866		.init_hook = alc880_uniwill_p53_hp_automute,
2867	},
2868	[ALC880_FUJITSU] = {
2869		.mixers = { alc880_fujitsu_mixer,
2870			    alc880_pcbeep_mixer, },
2871		.init_verbs = { alc880_volume_init_verbs,
2872				alc880_uniwill_p53_init_verbs,
2873	       			alc880_beep_init_verbs },
2874		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2875		.dac_nids = alc880_dac_nids,
2876		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2877		.channel_mode = alc880_2_jack_modes,
2878		.input_mux = &alc880_capture_source,
2879		.unsol_event = alc880_uniwill_p53_unsol_event,
2880		.init_hook = alc880_uniwill_p53_hp_automute,
2881	},
2882	[ALC880_CLEVO] = {
2883		.mixers = { alc880_three_stack_mixer },
2884		.init_verbs = { alc880_volume_init_verbs,
2885				alc880_pin_clevo_init_verbs },
2886		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2887		.dac_nids = alc880_dac_nids,
2888		.hp_nid = 0x03,
2889		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2890		.channel_mode = alc880_threestack_modes,
2891		.need_dac_fix = 1,
2892		.input_mux = &alc880_capture_source,
2893	},
2894	[ALC880_LG] = {
2895		.mixers = { alc880_lg_mixer },
2896		.init_verbs = { alc880_volume_init_verbs,
2897				alc880_lg_init_verbs },
2898		.num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
2899		.dac_nids = alc880_lg_dac_nids,
2900		.dig_out_nid = ALC880_DIGOUT_NID,
2901		.num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
2902		.channel_mode = alc880_lg_ch_modes,
2903		.need_dac_fix = 1,
2904		.input_mux = &alc880_lg_capture_source,
2905		.unsol_event = alc880_lg_unsol_event,
2906		.init_hook = alc880_lg_automute,
2907#ifdef CONFIG_SND_HDA_POWER_SAVE
2908		.loopbacks = alc880_lg_loopbacks,
2909#endif
2910	},
2911	[ALC880_LG_LW] = {
2912		.mixers = { alc880_lg_lw_mixer },
2913		.init_verbs = { alc880_volume_init_verbs,
2914				alc880_lg_lw_init_verbs },
2915		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2916		.dac_nids = alc880_dac_nids,
2917		.dig_out_nid = ALC880_DIGOUT_NID,
2918		.num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
2919		.channel_mode = alc880_lg_lw_modes,
2920		.input_mux = &alc880_lg_lw_capture_source,
2921		.unsol_event = alc880_lg_lw_unsol_event,
2922		.init_hook = alc880_lg_lw_automute,
2923	},
2924#ifdef CONFIG_SND_DEBUG
2925	[ALC880_TEST] = {
2926		.mixers = { alc880_test_mixer },
2927		.init_verbs = { alc880_test_init_verbs },
2928		.num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
2929		.dac_nids = alc880_test_dac_nids,
2930		.dig_out_nid = ALC880_DIGOUT_NID,
2931		.num_channel_mode = ARRAY_SIZE(alc880_test_modes),
2932		.channel_mode = alc880_test_modes,
2933		.input_mux = &alc880_test_capture_source,
2934	},
2935#endif
2936};
2937
2938/*
2939 * Automatic parse of I/O pins from the BIOS configuration
2940 */
2941
2942#define NUM_CONTROL_ALLOC	32
2943#define NUM_VERB_ALLOC		32
2944
2945enum {
2946	ALC_CTL_WIDGET_VOL,
2947	ALC_CTL_WIDGET_MUTE,
2948	ALC_CTL_BIND_MUTE,
2949};
2950static struct snd_kcontrol_new alc880_control_templates[] = {
2951	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2952	HDA_CODEC_MUTE(NULL, 0, 0, 0),
2953	HDA_BIND_MUTE(NULL, 0, 0, 0),
2954};
2955
2956/* add dynamic controls */
2957static int add_control(struct alc_spec *spec, int type, const char *name,
2958		       unsigned long val)
2959{
2960	struct snd_kcontrol_new *knew;
2961
2962	if (spec->num_kctl_used >= spec->num_kctl_alloc) {
2963		int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
2964
2965		/* array + terminator */
2966		knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
2967		if (!knew)
2968			return -ENOMEM;
2969		if (spec->kctl_alloc) {
2970			memcpy(knew, spec->kctl_alloc,
2971			       sizeof(*knew) * spec->num_kctl_alloc);
2972			kfree(spec->kctl_alloc);
2973		}
2974		spec->kctl_alloc = knew;
2975		spec->num_kctl_alloc = num;
2976	}
2977
2978	knew = &spec->kctl_alloc[spec->num_kctl_used];
2979	*knew = alc880_control_templates[type];
2980	knew->name = kstrdup(name, GFP_KERNEL);
2981	if (!knew->name)
2982		return -ENOMEM;
2983	knew->private_value = val;
2984	spec->num_kctl_used++;
2985	return 0;
2986}
2987
2988#define alc880_is_fixed_pin(nid)	((nid) >= 0x14 && (nid) <= 0x17)
2989#define alc880_fixed_pin_idx(nid)	((nid) - 0x14)
2990#define alc880_is_multi_pin(nid)	((nid) >= 0x18)
2991#define alc880_multi_pin_idx(nid)	((nid) - 0x18)
2992#define alc880_is_input_pin(nid)	((nid) >= 0x18)
2993#define alc880_input_pin_idx(nid)	((nid) - 0x18)
2994#define alc880_idx_to_dac(nid)		((nid) + 0x02)
2995#define alc880_dac_to_idx(nid)		((nid) - 0x02)
2996#define alc880_idx_to_mixer(nid)	((nid) + 0x0c)
2997#define alc880_idx_to_selector(nid)	((nid) + 0x10)
2998#define ALC880_PIN_CD_NID		0x1c
2999
3000/* fill in the dac_nids table from the parsed pin configuration */
3001static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3002				     const struct auto_pin_cfg *cfg)
3003{
3004	hda_nid_t nid;
3005	int assigned[4];
3006	int i, j;
3007
3008	memset(assigned, 0, sizeof(assigned));
3009	spec->multiout.dac_nids = spec->private_dac_nids;
3010
3011	/* check the pins hardwired to audio widget */
3012	for (i = 0; i < cfg->line_outs; i++) {
3013		nid = cfg->line_out_pins[i];
3014		if (alc880_is_fixed_pin(nid)) {
3015			int idx = alc880_fixed_pin_idx(nid);
3016			spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3017			assigned[idx] = 1;
3018		}
3019	}
3020	/* left pins can be connect to any audio widget */
3021	for (i = 0; i < cfg->line_outs; i++) {
3022		nid = cfg->line_out_pins[i];
3023		if (alc880_is_fixed_pin(nid))
3024			continue;
3025		/* search for an empty channel */
3026		for (j = 0; j < cfg->line_outs; j++) {
3027			if (!assigned[j]) {
3028				spec->multiout.dac_nids[i] =
3029					alc880_idx_to_dac(j);
3030				assigned[j] = 1;
3031				break;
3032			}
3033		}
3034	}
3035	spec->multiout.num_dacs = cfg->line_outs;
3036	return 0;
3037}
3038
3039/* add playback controls from the parsed DAC table */
3040static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3041					     const struct auto_pin_cfg *cfg)
3042{
3043	char name[32];
3044	static const char *chname[4] = {
3045		"Front", "Surround", NULL /*CLFE*/, "Side"
3046	};
3047	hda_nid_t nid;
3048	int i, err;
3049
3050	for (i = 0; i < cfg->line_outs; i++) {
3051		if (!spec->multiout.dac_nids[i])
3052			continue;
3053		nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3054		if (i == 2) {
3055			/* Center/LFE */
3056			err = add_control(spec, ALC_CTL_WIDGET_VOL,
3057					  "Center Playback Volume",
3058					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3059							      HDA_OUTPUT));
3060			if (err < 0)
3061				return err;
3062			err = add_control(spec, ALC_CTL_WIDGET_VOL,
3063					  "LFE Playback Volume",
3064					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3065							      HDA_OUTPUT));
3066			if (err < 0)
3067				return err;
3068			err = add_control(spec, ALC_CTL_BIND_MUTE,
3069					  "Center Playback Switch",
3070					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3071							      HDA_INPUT));
3072			if (err < 0)
3073				return err;
3074			err = add_control(spec, ALC_CTL_BIND_MUTE,
3075					  "LFE Playback Switch",
3076					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3077							      HDA_INPUT));
3078			if (err < 0)
3079				return err;
3080		} else {
3081			sprintf(name, "%s Playback Volume", chname[i]);
3082			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3083					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3084							      HDA_OUTPUT));
3085			if (err < 0)
3086				return err;
3087			sprintf(name, "%s Playback Switch", chname[i]);
3088			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3089					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3090							      HDA_INPUT));
3091			if (err < 0)
3092				return err;
3093		}
3094	}
3095	return 0;
3096}
3097
3098/* add playback controls for speaker and HP outputs */
3099static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3100					const char *pfx)
3101{
3102	hda_nid_t nid;
3103	int err;
3104	char name[32];
3105
3106	if (!pin)
3107		return 0;
3108
3109	if (alc880_is_fixed_pin(pin)) {
3110		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3111		/* specify the DAC as the extra output */
3112		if (!spec->multiout.hp_nid)
3113			spec->multiout.hp_nid = nid;
3114		else
3115			spec->multiout.extra_out_nid[0] = nid;
3116		/* control HP volume/switch on the output mixer amp */
3117		nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3118		sprintf(name, "%s Playback Volume", pfx);
3119		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3120				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3121		if (err < 0)
3122			return err;
3123		sprintf(name, "%s Playback Switch", pfx);
3124		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3125				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3126		if (err < 0)
3127			return err;
3128	} else if (alc880_is_multi_pin(pin)) {
3129		/* set manual connection */
3130		/* we have only a switch on HP-out PIN */
3131		sprintf(name, "%s Playback Switch", pfx);
3132		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3133				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3134		if (err < 0)
3135			return err;
3136	}
3137	return 0;
3138}
3139
3140/* create input playback/capture controls for the given pin */
3141static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3142			    const char *ctlname,
3143			    int idx, hda_nid_t mix_nid)
3144{
3145	char name[32];
3146	int err;
3147
3148	sprintf(name, "%s Playback Volume", ctlname);
3149	err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3150			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3151	if (err < 0)
3152		return err;
3153	sprintf(name, "%s Playback Switch", ctlname);
3154	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3155			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3156	if (err < 0)
3157		return err;
3158	return 0;
3159}
3160
3161/* create playback/capture controls for input pins */
3162static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3163						const struct auto_pin_cfg *cfg)
3164{
3165	struct hda_input_mux *imux = &spec->private_imux;
3166	int i, err, idx;
3167
3168	for (i = 0; i < AUTO_PIN_LAST; i++) {
3169		if (alc880_is_input_pin(cfg->input_pins[i])) {
3170			idx = alc880_input_pin_idx(cfg->input_pins[i]);
3171			err = new_analog_input(spec, cfg->input_pins[i],
3172					       auto_pin_cfg_labels[i],
3173					       idx, 0x0b);
3174			if (err < 0)
3175				return err;
3176			imux->items[imux->num_items].label =
3177				auto_pin_cfg_labels[i];
3178			imux->items[imux->num_items].index =
3179				alc880_input_pin_idx(cfg->input_pins[i]);
3180			imux->num_items++;
3181		}
3182	}
3183	return 0;
3184}
3185
3186static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3187					      hda_nid_t nid, int pin_type,
3188					      int dac_idx)
3189{
3190	/* set as output */
3191	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3192			    pin_type);
3193	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3194			    AMP_OUT_UNMUTE);
3195	/* need the manual connection? */
3196	if (alc880_is_multi_pin(nid)) {
3197		struct alc_spec *spec = codec->spec;
3198		int idx = alc880_multi_pin_idx(nid);
3199		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3200				    AC_VERB_SET_CONNECT_SEL,
3201				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3202	}
3203}
3204
3205static int get_pin_type(int line_out_type)
3206{
3207	if (line_out_type == AUTO_PIN_HP_OUT)
3208		return PIN_HP;
3209	else
3210		return PIN_OUT;
3211}
3212
3213static void alc880_auto_init_multi_out(struct hda_codec *codec)
3214{
3215	struct alc_spec *spec = codec->spec;
3216	int i;
3217
3218	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3219	for (i = 0; i < spec->autocfg.line_outs; i++) {
3220		hda_nid_t nid = spec->autocfg.line_out_pins[i];
3221		int pin_type = get_pin_type(spec->autocfg.line_out_type);
3222		alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3223	}
3224}
3225
3226static void alc880_auto_init_extra_out(struct hda_codec *codec)
3227{
3228	struct alc_spec *spec = codec->spec;
3229	hda_nid_t pin;
3230
3231	pin = spec->autocfg.speaker_pins[0];
3232	if (pin) /* connect to front */
3233		alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3234	pin = spec->autocfg.hp_pins[0];
3235	if (pin) /* connect to front */
3236		alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3237}
3238
3239static void alc880_auto_init_analog_input(struct hda_codec *codec)
3240{
3241	struct alc_spec *spec = codec->spec;
3242	int i;
3243
3244	for (i = 0; i < AUTO_PIN_LAST; i++) {
3245		hda_nid_t nid = spec->autocfg.input_pins[i];
3246		if (alc880_is_input_pin(nid)) {
3247			snd_hda_codec_write(codec, nid, 0,
3248					    AC_VERB_SET_PIN_WIDGET_CONTROL,
3249					    i <= AUTO_PIN_FRONT_MIC ?
3250					    PIN_VREF80 : PIN_IN);
3251			if (nid != ALC880_PIN_CD_NID)
3252				snd_hda_codec_write(codec, nid, 0,
3253						    AC_VERB_SET_AMP_GAIN_MUTE,
3254						    AMP_OUT_MUTE);
3255		}
3256	}
3257}
3258
3259/* parse the BIOS configuration and set up the alc_spec */
3260/* return 1 if successful, 0 if the proper config is not found,
3261 * or a negative error code
3262 */
3263static int alc880_parse_auto_config(struct hda_codec *codec)
3264{
3265	struct alc_spec *spec = codec->spec;
3266	int err;
3267	static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3268
3269	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3270					   alc880_ignore);
3271	if (err < 0)
3272		return err;
3273	if (!spec->autocfg.line_outs)
3274		return 0; /* can't find valid BIOS pin config */
3275
3276	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3277	if (err < 0)
3278		return err;
3279	err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3280	if (err < 0)
3281		return err;
3282	err = alc880_auto_create_extra_out(spec,
3283					   spec->autocfg.speaker_pins[0],
3284					   "Speaker");
3285	if (err < 0)
3286		return err;
3287	err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3288					   "Headphone");
3289	if (err < 0)
3290		return err;
3291	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3292	if (err < 0)
3293		return err;
3294
3295	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3296
3297	if (spec->autocfg.dig_out_pin)
3298		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3299	if (spec->autocfg.dig_in_pin)
3300		spec->dig_in_nid = ALC880_DIGIN_NID;
3301
3302	if (spec->kctl_alloc)
3303		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3304
3305	spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3306
3307	spec->num_mux_defs = 1;
3308	spec->input_mux = &spec->private_imux;
3309
3310	return 1;
3311}
3312
3313/* additional initialization for auto-configuration model */
3314static void alc880_auto_init(struct hda_codec *codec)
3315{
3316	alc880_auto_init_multi_out(codec);
3317	alc880_auto_init_extra_out(codec);
3318	alc880_auto_init_analog_input(codec);
3319}
3320
3321/*
3322 * OK, here we have finally the patch for ALC880
3323 */
3324
3325static int patch_alc880(struct hda_codec *codec)
3326{
3327	struct alc_spec *spec;
3328	int board_config;
3329	int err;
3330
3331	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3332	if (spec == NULL)
3333		return -ENOMEM;
3334
3335	codec->spec = spec;
3336
3337	board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3338						  alc880_models,
3339						  alc880_cfg_tbl);
3340	if (board_config < 0) {
3341		printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3342		       "trying auto-probe from BIOS...\n");
3343		board_config = ALC880_AUTO;
3344	}
3345
3346	if (board_config == ALC880_AUTO) {
3347		/* automatic parse from the BIOS config */
3348		err = alc880_parse_auto_config(codec);
3349		if (err < 0) {
3350			alc_free(codec);
3351			return err;
3352		} else if (!err) {
3353			printk(KERN_INFO
3354			       "hda_codec: Cannot set up configuration "
3355			       "from BIOS.  Using 3-stack mode...\n");
3356			board_config = ALC880_3ST;
3357		}
3358	}
3359
3360	if (board_config != ALC880_AUTO)
3361		setup_preset(spec, &alc880_presets[board_config]);
3362
3363	spec->stream_name_analog = "ALC880 Analog";
3364	spec->stream_analog_playback = &alc880_pcm_analog_playback;
3365	spec->stream_analog_capture = &alc880_pcm_analog_capture;
3366
3367	spec->stream_name_digital = "ALC880 Digital";
3368	spec->stream_digital_playback = &alc880_pcm_digital_playback;
3369	spec->stream_digital_capture = &alc880_pcm_digital_capture;
3370
3371	if (!spec->adc_nids && spec->input_mux) {
3372		/* check whether NID 0x07 is valid */
3373		unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3374		/* get type */
3375		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3376		if (wcap != AC_WID_AUD_IN) {
3377			spec->adc_nids = alc880_adc_nids_alt;
3378			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3379			spec->mixers[spec->num_mixers] =
3380				alc880_capture_alt_mixer;
3381			spec->num_mixers++;
3382		} else {
3383			spec->adc_nids = alc880_adc_nids;
3384			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3385			spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3386			spec->num_mixers++;
3387		}
3388	}
3389
3390	codec->patch_ops = alc_patch_ops;
3391	if (board_config == ALC880_AUTO)
3392		spec->init_hook = alc880_auto_init;
3393#ifdef CONFIG_SND_HDA_POWER_SAVE
3394	if (!spec->loopback.amplist)
3395		spec->loopback.amplist = alc880_loopbacks;
3396#endif
3397
3398	return 0;
3399}
3400
3401
3402/*
3403 * ALC260 support
3404 */
3405
3406static hda_nid_t alc260_dac_nids[1] = {
3407	/* front */
3408	0x02,
3409};
3410
3411static hda_nid_t alc260_adc_nids[1] = {
3412	/* ADC0 */
3413	0x04,
3414};
3415
3416static hda_nid_t alc260_adc_nids_alt[1] = {
3417	/* ADC1 */
3418	0x05,
3419};
3420
3421static hda_nid_t alc260_hp_adc_nids[2] = {
3422	/* ADC1, 0 */
3423	0x05, 0x04
3424};
3425
3426/* NIDs used when simultaneous access to both ADCs makes sense.  Note that
3427 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3428 */
3429static hda_nid_t alc260_dual_adc_nids[2] = {
3430	/* ADC0, ADC1 */
3431	0x04, 0x05
3432};
3433
3434#define ALC260_DIGOUT_NID	0x03
3435#define ALC260_DIGIN_NID	0x06
3436
3437static struct hda_input_mux alc260_capture_source = {
3438	.num_items = 4,
3439	.items = {
3440		{ "Mic", 0x0 },
3441		{ "Front Mic", 0x1 },
3442		{ "Line", 0x2 },
3443		{ "CD", 0x4 },
3444	},
3445};
3446
3447/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3448 * headphone jack and the internal CD lines since these are the only pins at
3449 * which audio can appear.  For flexibility, also allow the option of
3450 * recording the mixer output on the second ADC (ADC0 doesn't have a
3451 * connection to the mixer output).
3452 */
3453static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3454	{
3455		.num_items = 3,
3456		.items = {
3457			{ "Mic/Line", 0x0 },
3458			{ "CD", 0x4 },
3459			{ "Headphone", 0x2 },
3460		},
3461	},
3462	{
3463		.num_items = 4,
3464		.items = {
3465			{ "Mic/Line", 0x0 },
3466			{ "CD", 0x4 },
3467			{ "Headphone", 0x2 },
3468			{ "Mixer", 0x5 },
3469		},
3470	},
3471
3472};
3473
3474/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3475 * the Fujitsu S702x, but jacks are marked differently.
3476 */
3477static struct hda_input_mux alc260_acer_capture_sources[2] = {
3478	{
3479		.num_items = 4,
3480		.items = {
3481			{ "Mic", 0x0 },
3482			{ "Line", 0x2 },
3483			{ "CD", 0x4 },
3484			{ "Headphone", 0x5 },
3485		},
3486	},
3487	{
3488		.num_items = 5,
3489		.items = {
3490			{ "Mic", 0x0 },
3491			{ "Line", 0x2 },
3492			{ "CD", 0x4 },
3493			{ "Headphone", 0x6 },
3494			{ "Mixer", 0x5 },
3495		},
3496	},
3497};
3498/*
3499 * This is just place-holder, so there's something for alc_build_pcms to look
3500 * at when it calculates the maximum number of channels. ALC260 has no mixer
3501 * element which allows changing the channel mode, so the verb list is
3502 * never used.
3503 */
3504static struct hda_channel_mode alc260_modes[1] = {
3505	{ 2, NULL },
3506};
3507
3508
3509/* Mixer combinations
3510 *
3511 * basic: base_output + input + pc_beep + capture
3512 * HP: base_output + input + capture_alt
3513 * HP_3013: hp_3013 + input + capture
3514 * fujitsu: fujitsu + capture
3515 * acer: acer + capture
3516 */
3517
3518static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3519	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3520	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3521	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3522	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3523	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3524	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3525	{ } /* end */
3526};
3527
3528static struct snd_kcontrol_new alc260_input_mixer[] = {
3529	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3530	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3531	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3532	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3533	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3534	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3535	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3536	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
3537	{ } /* end */
3538};
3539
3540static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3541	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3542	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3543	{ } /* end */
3544};
3545
3546static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
3547	HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3548	HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3549	HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3550	HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3551	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3552	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3553	HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3554	HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
3555	{ } /* end */
3556};
3557
3558/* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12,
3559 * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
3560 */
3561static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
3562	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3563	HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
3564	ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3565	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3566	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3567	HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3568	HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
3569	ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
3570	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3571	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3572	HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3573	HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
3574	{ } /* end */
3575};
3576
3577/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
3578 * versions of the ALC260 don't act on requests to enable mic bias from NID
3579 * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
3580 * datasheet doesn't mention this restriction.  At this stage it's not clear
3581 * whether this behaviour is intentional or is a hardware bug in chip
3582 * revisions available in early 2006.  Therefore for now allow the
3583 * "Headphone Jack Mode" control to span all choices, but if it turns out
3584 * that the lack of mic bias for this NID is intentional we could change the
3585 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3586 *
3587 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
3588 * don't appear to make the mic bias available from the "line" jack, even
3589 * though the NID used for this jack (0x14) can supply it.  The theory is
3590 * that perhaps Acer have included blocking capacitors between the ALC260
3591 * and the output jack.  If this turns out to be the case for all such
3592 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3593 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
3594 *
3595 * The C20x Tablet series have a mono internal speaker which is controlled
3596 * via the chip's Mono sum widget and pin complex, so include the necessary
3597 * controls for such models.  On models without a "mono speaker" the control
3598 * won't do anything.
3599 */
3600static struct snd_kcontrol_new alc260_acer_mixer[] = {
3601	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3602	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
3603	ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
3604	HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0,
3605			      HDA_OUTPUT),
3606	HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2,
3607			   HDA_INPUT),
3608	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3609	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3610	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3611	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3612	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3613	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3614	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3615	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3616	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3617	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3618	{ } /* end */
3619};
3620
3621/* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
3622 * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
3623 */
3624static struct snd_kcontrol_new alc260_will_mixer[] = {
3625	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3626	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3627	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3628	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3629	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3630	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3631	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3632	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3633	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3634	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3635	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3636	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3637	{ } /* end */
3638};
3639
3640/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
3641 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
3642 */
3643static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
3644	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3645	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3646	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3647	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3648	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3649	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
3650	HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
3651	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3652	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3653	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3654	{ } /* end */
3655};
3656
3657/* capture mixer elements */
3658static struct snd_kcontrol_new alc260_capture_mixer[] = {
3659	HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
3660	HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
3661	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
3662	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
3663	{
3664		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3665		/* The multiple "Capture Source" controls confuse alsamixer
3666		 * So call somewhat different..
3667		 * FIXME: the controls appear in the "playback" view!
3668		 */
3669		/* .name = "Capture Source", */
3670		.name = "Input Source",
3671		.count = 2,
3672		.info = alc_mux_enum_info,
3673		.get = alc_mux_enum_get,
3674		.put = alc_mux_enum_put,
3675	},
3676	{ } /* end */
3677};
3678
3679static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
3680	HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
3681	HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
3682	{
3683		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3684		/* The multiple "Capture Source" controls confuse alsamixer
3685		 * So call somewhat different..
3686		 * FIXME: the controls appear in the "playback" view!
3687		 */
3688		/* .name = "Capture Source", */
3689		.name = "Input Source",
3690		.count = 1,
3691		.info = alc_mux_enum_info,
3692		.get = alc_mux_enum_get,
3693		.put = alc_mux_enum_put,
3694	},
3695	{ } /* end */
3696};
3697
3698/*
3699 * initialization verbs
3700 */
3701static struct hda_verb alc260_init_verbs[] = {
3702	/* Line In pin widget for input */
3703	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3704	/* CD pin widget for input */
3705	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3706	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3707	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3708	/* Mic2 (front panel) pin widget for input and vref at 80% */
3709	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3710	/* LINE-2 is used for line-out in rear */
3711	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3712	/* select line-out */
3713	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
3714	/* LINE-OUT pin */
3715	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3716	/* enable HP */
3717	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3718	/* enable Mono */
3719	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3720	/* mute capture amp left and right */
3721	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3722	/* set connection select to line in (default select for this ADC) */
3723	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3724	/* mute capture amp left and right */
3725	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3726	/* set connection select to line in (default select for this ADC) */
3727	{0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
3728	/* set vol=0 Line-Out mixer amp left and right */
3729	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3730	/* unmute pin widget amp left and right (no gain on this amp) */
3731	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3732	/* set vol=0 HP mixer amp left and right */
3733	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3734	/* unmute pin widget amp left and right (no gain on this amp) */
3735	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3736	/* set vol=0 Mono mixer amp left and right */
3737	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3738	/* unmute pin widget amp left and right (no gain on this amp) */
3739	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3740	/* unmute LINE-2 out pin */
3741	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3742	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3743	 * Line In 2 = 0x03
3744	 */
3745	/* mute analog inputs */
3746	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3747	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3748	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3749	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3750	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3751	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3752	/* mute Front out path */
3753	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3754	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3755	/* mute Headphone out path */
3756	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3757	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3758	/* mute Mono out path */
3759	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3760	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3761	{ }
3762};
3763
3764#if 0 /* should be identical with alc260_init_verbs? */
3765static struct hda_verb alc260_hp_init_verbs[] = {
3766	/* Headphone and output */
3767	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3768	/* mono output */
3769	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3770	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3771	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3772	/* Mic2 (front panel) pin widget for input and vref at 80% */
3773	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3774	/* Line In pin widget for input */
3775	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3776	/* Line-2 pin widget for output */
3777	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3778	/* CD pin widget for input */
3779	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3780	/* unmute amp left and right */
3781	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3782	/* set connection select to line in (default select for this ADC) */
3783	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3784	/* unmute Line-Out mixer amp left and right (volume = 0) */
3785	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3786	/* mute pin widget amp left and right (no gain on this amp) */
3787	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3788	/* unmute HP mixer amp left and right (volume = 0) */
3789	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3790	/* mute pin widget amp left and right (no gain on this amp) */
3791	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3792	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3793	 * Line In 2 = 0x03
3794	 */
3795	/* mute analog inputs */
3796	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3797	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3798	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3799	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3800	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3801	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3802	/* Unmute Front out path */
3803	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3804	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3805	/* Unmute Headphone out path */
3806	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3807	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3808	/* Unmute Mono out path */
3809	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3810	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3811	{ }
3812};
3813#endif
3814
3815static struct hda_verb alc260_hp_3013_init_verbs[] = {
3816	/* Line out and output */
3817	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3818	/* mono output */
3819	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3820	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3821	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3822	/* Mic2 (front panel) pin widget for input and vref at 80% */
3823	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3824	/* Line In pin widget for input */
3825	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3826	/* Headphone pin widget for output */
3827	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3828	/* CD pin widget for input */
3829	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3830	/* unmute amp left and right */
3831	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3832	/* set connection select to line in (default select for this ADC) */
3833	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3834	/* unmute Line-Out mixer amp left and right (volume = 0) */
3835	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3836	/* mute pin widget amp left and right (no gain on this amp) */
3837	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3838	/* unmute HP mixer amp left and right (volume = 0) */
3839	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3840	/* mute pin widget amp left and right (no gain on this amp) */
3841	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3842	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3843	 * Line In 2 = 0x03
3844	 */
3845	/* mute analog inputs */
3846	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3847	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3848	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3849	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3850	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3851	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3852	/* Unmute Front out path */
3853	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3854	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3855	/* Unmute Headphone out path */
3856	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3857	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3858	/* Unmute Mono out path */
3859	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3860	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3861	{ }
3862};
3863
3864/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
3865 * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
3866 * audio = 0x16, internal speaker = 0x10.
3867 */
3868static struct hda_verb alc260_fujitsu_init_verbs[] = {
3869	/* Disable all GPIOs */
3870	{0x01, AC_VERB_SET_GPIO_MASK, 0},
3871	/* Internal speaker is connected to headphone pin */
3872	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3873	/* Headphone/Line-out jack connects to Line1 pin; make it an output */
3874	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3875	/* Mic/Line-in jack is connected to mic1 pin, so make it an input */
3876	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3877	/* Ensure all other unused pins are disabled and muted. */
3878	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3879	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3880	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3881	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3882	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3883	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3884	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3885	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3886
3887	/* Disable digital (SPDIF) pins */
3888	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3889	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3890
3891	/* Ensure Line1 pin widget takes its input from the OUT1 sum bus
3892	 * when acting as an output.
3893	 */
3894	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3895
3896	/* Start with output sum widgets muted and their output gains at min */
3897	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3898	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3899	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3900	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3901	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3902	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3903	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3904	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3905	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3906
3907	/* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
3908	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3909	/* Unmute Line1 pin widget output buffer since it starts as an output.
3910	 * If the pin mode is changed by the user the pin mode control will
3911	 * take care of enabling the pin's input/output buffers as needed.
3912	 * Therefore there's no need to enable the input buffer at this
3913	 * stage.
3914	 */
3915	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3916	/* Unmute input buffer of pin widget used for Line-in (no equiv
3917	 * mixer ctrl)
3918	 */
3919	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3920
3921	/* Mute capture amp left and right */
3922	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3923	/* Set ADC connection select to match default mixer setting - line
3924	 * in (on mic1 pin)
3925	 */
3926	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3927
3928	/* Do the same for the second ADC: mute capture input amp and
3929	 * set ADC connection to line in (on mic1 pin)
3930	 */
3931	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3932	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3933
3934	/* Mute all inputs to mixer widget (even unconnected ones) */
3935	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3936	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3937	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3938	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3939	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3940	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3941	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3942	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
3943
3944	{ }
3945};
3946
3947/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
3948 * similar laptops (adapted from Fujitsu init verbs).
3949 */
3950static struct hda_verb alc260_acer_init_verbs[] = {
3951	/* On TravelMate laptops, GPIO 0 enables the internal speaker and
3952	 * the headphone jack.  Turn this on and rely on the standard mute
3953	 * methods whenever the user wants to turn these outputs off.
3954	 */
3955	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
3956	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
3957	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
3958	/* Internal speaker/Headphone jack is connected to Line-out pin */
3959	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3960	/* Internal microphone/Mic jack is connected to Mic1 pin */
3961	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3962	/* Line In jack is connected to Line1 pin */
3963	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3964	/* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
3965	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3966	/* Ensure all other unused pins are disabled and muted. */
3967	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3968	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3969	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3970	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3971	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3972	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3973	/* Disable digital (SPDIF) pins */
3974	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3975	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3976
3977	/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
3978	 * bus when acting as outputs.
3979	 */
3980	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
3981	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3982
3983	/* Start with output sum widgets muted and their output gains at min */
3984	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3985	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3986	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3987	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3988	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3989	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3990	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3991	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3992	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3993
3994	/* Unmute Line-out pin widget amp left and right
3995	 * (no equiv mixer ctrl)
3996	 */
3997	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3998	/* Unmute mono pin widget amp output (no equiv mixer ctrl) */
3999	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4000	/* Unmute Mic1 and Line1 pin widget input buffers since they start as
4001	 * inputs. If the pin mode is changed by the user the pin mode control
4002	 * will take care of enabling the pin's input/output buffers as needed.
4003	 * Therefore there's no need to enable the input buffer at this
4004	 * stage.
4005	 */
4006	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4007	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4008
4009	/* Mute capture amp left and right */
4010	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4011	/* Set ADC connection select to match default mixer setting - mic
4012	 * (on mic1 pin)
4013	 */
4014	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4015
4016	/* Do similar with the second ADC: mute capture input amp and
4017	 * set ADC connection to mic to match ALSA's default state.
4018	 */
4019	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4020	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4021
4022	/* Mute all inputs to mixer widget (even unconnected ones) */
4023	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4024	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4025	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4026	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4027	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4028	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4029	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4030	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4031
4032	{ }
4033};
4034
4035static struct hda_verb alc260_will_verbs[] = {
4036	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4037	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4038	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4039	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4040	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4041	{0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4042	{}
4043};
4044
4045static struct hda_verb alc260_replacer_672v_verbs[] = {
4046	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4047	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4048	{0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4049
4050	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4051	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4052	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4053
4054	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4055	{}
4056};
4057
4058/* toggle speaker-output according to the hp-jack state */
4059static void alc260_replacer_672v_automute(struct hda_codec *codec)
4060{
4061        unsigned int present;
4062
4063	/* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4064        present = snd_hda_codec_read(codec, 0x0f, 0,
4065                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4066	if (present) {
4067		snd_hda_codec_write_cache(codec, 0x01, 0,
4068					  AC_VERB_SET_GPIO_DATA, 1);
4069		snd_hda_codec_write_cache(codec, 0x0f, 0,
4070					  AC_VERB_SET_PIN_WIDGET_CONTROL,
4071					  PIN_HP);
4072	} else {
4073		snd_hda_codec_write_cache(codec, 0x01, 0,
4074					  AC_VERB_SET_GPIO_DATA, 0);
4075		snd_hda_codec_write_cache(codec, 0x0f, 0,
4076					  AC_VERB_SET_PIN_WIDGET_CONTROL,
4077					  PIN_OUT);
4078	}
4079}
4080
4081static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4082                                       unsigned int res)
4083{
4084        if ((res >> 26) == ALC880_HP_EVENT)
4085                alc260_replacer_672v_automute(codec);
4086}
4087
4088/* Test configuration for debugging, modelled after the ALC880 test
4089 * configuration.
4090 */
4091#ifdef CONFIG_SND_DEBUG
4092static hda_nid_t alc260_test_dac_nids[1] = {
4093	0x02,
4094};
4095static hda_nid_t alc260_test_adc_nids[2] = {
4096	0x04, 0x05,
4097};
4098/* For testing the ALC260, each input MUX needs its own definition since
4099 * the signal assignments are different.  This assumes that the first ADC
4100 * is NID 0x04.
4101 */
4102static struct hda_input_mux alc260_test_capture_sources[2] = {
4103	{
4104		.num_items = 7,
4105		.items = {
4106			{ "MIC1 pin", 0x0 },
4107			{ "MIC2 pin", 0x1 },
4108			{ "LINE1 pin", 0x2 },
4109			{ "LINE2 pin", 0x3 },
4110			{ "CD pin", 0x4 },
4111			{ "LINE-OUT pin", 0x5 },
4112			{ "HP-OUT pin", 0x6 },
4113		},
4114        },
4115	{
4116		.num_items = 8,
4117		.items = {
4118			{ "MIC1 pin", 0x0 },
4119			{ "MIC2 pin", 0x1 },
4120			{ "LINE1 pin", 0x2 },
4121			{ "LINE2 pin", 0x3 },
4122			{ "CD pin", 0x4 },
4123			{ "Mixer", 0x5 },
4124			{ "LINE-OUT pin", 0x6 },
4125			{ "HP-OUT pin", 0x7 },
4126		},
4127        },
4128};
4129static struct snd_kcontrol_new alc260_test_mixer[] = {
4130	/* Output driver widgets */
4131	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4132	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4133	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4134	HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4135	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4136	HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4137
4138	/* Modes for retasking pin widgets
4139	 * Note: the ALC260 doesn't seem to act on requests to enable mic
4140         * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
4141         * mention this restriction.  At this stage it's not clear whether
4142         * this behaviour is intentional or is a hardware bug in chip
4143         * revisions available at least up until early 2006.  Therefore for
4144         * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4145         * choices, but if it turns out that the lack of mic bias for these
4146         * NIDs is intentional we could change their modes from
4147         * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4148	 */
4149	ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4150	ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4151	ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4152	ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4153	ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4154	ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4155
4156	/* Loopback mixer controls */
4157	HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4158	HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4159	HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4160	HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4161	HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4162	HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4163	HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4164	HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4165	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4166	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4167	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4168	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4169	HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4170	HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4171	HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4172	HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4173
4174	/* Controls for GPIO pins, assuming they are configured as outputs */
4175	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4176	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4177	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4178	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4179
4180	/* Switches to allow the digital IO pins to be enabled.  The datasheet
4181	 * is ambigious as to which NID is which; testing on laptops which
4182	 * make this output available should provide clarification.
4183	 */
4184	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4185	ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4186
4187	{ } /* end */
4188};
4189static struct hda_verb alc260_test_init_verbs[] = {
4190	/* Enable all GPIOs as outputs with an initial value of 0 */
4191	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4192	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4193	{0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4194
4195	/* Enable retasking pins as output, initially without power amp */
4196	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4197	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4198	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4199	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4200	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4201	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4202
4203	/* Disable digital (SPDIF) pins initially, but users can enable
4204	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
4205	 * payload also sets the generation to 0, output to be in "consumer"
4206	 * PCM format, copyright asserted, no pre-emphasis and no validity
4207	 * control.
4208	 */
4209	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4210	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4211
4212	/* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
4213	 * OUT1 sum bus when acting as an output.
4214	 */
4215	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4216	{0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4217	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4218	{0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4219
4220	/* Start with output sum widgets muted and their output gains at min */
4221	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4222	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4223	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4224	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4225	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4226	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4227	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4228	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4229	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4230
4231	/* Unmute retasking pin widget output buffers since the default
4232	 * state appears to be output.  As the pin mode is changed by the
4233	 * user the pin mode control will take care of enabling the pin's
4234	 * input/output buffers as needed.
4235	 */
4236	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4237	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4238	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4239	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4240	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4241	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4242	/* Also unmute the mono-out pin widget */
4243	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4244
4245	/* Mute capture amp left and right */
4246	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4247	/* Set ADC connection select to match default mixer setting (mic1
4248	 * pin)
4249	 */
4250	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4251
4252	/* Do the same for the second ADC: mute capture input amp and
4253	 * set ADC connection to mic1 pin
4254	 */
4255	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4256	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4257
4258	/* Mute all inputs to mixer widget (even unconnected ones) */
4259	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4260	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4261	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4262	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4263	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4264	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4265	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4266	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4267
4268	{ }
4269};
4270#endif
4271
4272static struct hda_pcm_stream alc260_pcm_analog_playback = {
4273	.substreams = 1,
4274	.channels_min = 2,
4275	.channels_max = 2,
4276};
4277
4278static struct hda_pcm_stream alc260_pcm_analog_capture = {
4279	.substreams = 1,
4280	.channels_min = 2,
4281	.channels_max = 2,
4282};
4283
4284#define alc260_pcm_digital_playback	alc880_pcm_digital_playback
4285#define alc260_pcm_digital_capture	alc880_pcm_digital_capture
4286
4287/*
4288 * for BIOS auto-configuration
4289 */
4290
4291static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4292					const char *pfx)
4293{
4294	hda_nid_t nid_vol;
4295	unsigned long vol_val, sw_val;
4296	char name[32];
4297	int err;
4298
4299	if (nid >= 0x0f && nid < 0x11) {
4300		nid_vol = nid - 0x7;
4301		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4302		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4303	} else if (nid == 0x11) {
4304		nid_vol = nid - 0x7;
4305		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4306		sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4307	} else if (nid >= 0x12 && nid <= 0x15) {
4308		nid_vol = 0x08;
4309		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4310		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4311	} else
4312		return 0; /* N/A */
4313
4314	snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4315	err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4316	if (err < 0)
4317		return err;
4318	snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4319	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4320	if (err < 0)
4321		return err;
4322	return 1;
4323}
4324
4325/* add playback controls from the parsed DAC table */
4326static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4327					     const struct auto_pin_cfg *cfg)
4328{
4329	hda_nid_t nid;
4330	int err;
4331
4332	spec->multiout.num_dacs = 1;
4333	spec->multiout.dac_nids = spec->private_dac_nids;
4334	spec->multiout.dac_nids[0] = 0x02;
4335
4336	nid = cfg->line_out_pins[0];
4337	if (nid) {
4338		err = alc260_add_playback_controls(spec, nid, "Front");
4339		if (err < 0)
4340			return err;
4341	}
4342
4343	nid = cfg->speaker_pins[0];
4344	if (nid) {
4345		err = alc260_add_playback_controls(spec, nid, "Speaker");
4346		if (err < 0)
4347			return err;
4348	}
4349
4350	nid = cfg->hp_pins[0];
4351	if (nid) {
4352		err = alc260_add_playback_controls(spec, nid, "Headphone");
4353		if (err < 0)
4354			return err;
4355	}
4356	return 0;
4357}
4358
4359/* create playback/capture controls for input pins */
4360static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4361						const struct auto_pin_cfg *cfg)
4362{
4363	struct hda_input_mux *imux = &spec->private_imux;
4364	int i, err, idx;
4365
4366	for (i = 0; i < AUTO_PIN_LAST; i++) {
4367		if (cfg->input_pins[i] >= 0x12) {
4368			idx = cfg->input_pins[i] - 0x12;
4369			err = new_analog_input(spec, cfg->input_pins[i],
4370					       auto_pin_cfg_labels[i], idx,
4371					       0x07);
4372			if (err < 0)
4373				return err;
4374			imux->items[imux->num_items].label =
4375				auto_pin_cfg_labels[i];
4376			imux->items[imux->num_items].index = idx;
4377			imux->num_items++;
4378		}
4379		if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
4380			idx = cfg->input_pins[i] - 0x09;
4381			err = new_analog_input(spec, cfg->input_pins[i],
4382					       auto_pin_cfg_labels[i], idx,
4383					       0x07);
4384			if (err < 0)
4385				return err;
4386			imux->items[imux->num_items].label =
4387				auto_pin_cfg_labels[i];
4388			imux->items[imux->num_items].index = idx;
4389			imux->num_items++;
4390		}
4391	}
4392	return 0;
4393}
4394
4395static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4396					      hda_nid_t nid, int pin_type,
4397					      int sel_idx)
4398{
4399	/* set as output */
4400	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4401			    pin_type);
4402	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4403			    AMP_OUT_UNMUTE);
4404	/* need the manual connection? */
4405	if (nid >= 0x12) {
4406		int idx = nid - 0x12;
4407		snd_hda_codec_write(codec, idx + 0x0b, 0,
4408				    AC_VERB_SET_CONNECT_SEL, sel_idx);
4409	}
4410}
4411
4412static void alc260_auto_init_multi_out(struct hda_codec *codec)
4413{
4414	struct alc_spec *spec = codec->spec;
4415	hda_nid_t nid;
4416
4417	alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
4418	nid = spec->autocfg.line_out_pins[0];
4419	if (nid) {
4420		int pin_type = get_pin_type(spec->autocfg.line_out_type);
4421		alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4422	}
4423
4424	nid = spec->autocfg.speaker_pins[0];
4425	if (nid)
4426		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4427
4428	nid = spec->autocfg.hp_pins[0];
4429	if (nid)
4430		alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
4431}
4432
4433#define ALC260_PIN_CD_NID		0x16
4434static void alc260_auto_init_analog_input(struct hda_codec *codec)
4435{
4436	struct alc_spec *spec = codec->spec;
4437	int i;
4438
4439	for (i = 0; i < AUTO_PIN_LAST; i++) {
4440		hda_nid_t nid = spec->autocfg.input_pins[i];
4441		if (nid >= 0x12) {
4442			snd_hda_codec_write(codec, nid, 0,
4443					    AC_VERB_SET_PIN_WIDGET_CONTROL,
4444					    i <= AUTO_PIN_FRONT_MIC ?
4445					    PIN_VREF80 : PIN_IN);
4446			if (nid != ALC260_PIN_CD_NID)
4447				snd_hda_codec_write(codec, nid, 0,
4448						    AC_VERB_SET_AMP_GAIN_MUTE,
4449						    AMP_OUT_MUTE);
4450		}
4451	}
4452}
4453
4454/*
4455 * generic initialization of ADC, input mixers and output mixers
4456 */
4457static struct hda_verb alc260_volume_init_verbs[] = {
4458	/*
4459	 * Unmute ADC0-1 and set the default input to mic-in
4460	 */
4461	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4462	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4463	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4464	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4465
4466	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4467	 * mixer widget
4468	 * Note: PASD motherboards uses the Line In 2 as the input for
4469	 * front panel mic (mic 2)
4470	 */
4471	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4472	/* mute analog inputs */
4473	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4474	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4475	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4476	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4477	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4478
4479	/*
4480	 * Set up output mixers (0x08 - 0x0a)
4481	 */
4482	/* set vol=0 to output mixers */
4483	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4484	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4485	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4486	/* set up input amps for analog loopback */
4487	/* Amp Indices: DAC = 0, mixer = 1 */
4488	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4489	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4490	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4491	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4492	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4493	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4494
4495	{ }
4496};
4497
4498static int alc260_parse_auto_config(struct hda_codec *codec)
4499{
4500	struct alc_spec *spec = codec->spec;
4501	unsigned int wcap;
4502	int err;
4503	static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4504
4505	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4506					   alc260_ignore);
4507	if (err < 0)
4508		return err;
4509	err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
4510	if (err < 0)
4511		return err;
4512	if (!spec->kctl_alloc)
4513		return 0; /* can't find valid BIOS pin config */
4514	err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
4515	if (err < 0)
4516		return err;
4517
4518	spec->multiout.max_channels = 2;
4519
4520	if (spec->autocfg.dig_out_pin)
4521		spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4522	if (spec->kctl_alloc)
4523		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4524
4525	spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4526
4527	spec->num_mux_defs = 1;
4528	spec->input_mux = &spec->private_imux;
4529
4530	/* check whether NID 0x04 is valid */
4531	wcap = get_wcaps(codec, 0x04);
4532	wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4533	if (wcap != AC_WID_AUD_IN) {
4534		spec->adc_nids = alc260_adc_nids_alt;
4535		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4536		spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
4537	} else {
4538		spec->adc_nids = alc260_adc_nids;
4539		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4540		spec->mixers[spec->num_mixers] = alc260_capture_mixer;
4541	}
4542	spec->num_mixers++;
4543
4544	return 1;
4545}
4546
4547/* additional initialization for auto-configuration model */
4548static void alc260_auto_init(struct hda_codec *codec)
4549{
4550	alc260_auto_init_multi_out(codec);
4551	alc260_auto_init_analog_input(codec);
4552}
4553
4554#ifdef CONFIG_SND_HDA_POWER_SAVE
4555static struct hda_amp_list alc260_loopbacks[] = {
4556	{ 0x07, HDA_INPUT, 0 },
4557	{ 0x07, HDA_INPUT, 1 },
4558	{ 0x07, HDA_INPUT, 2 },
4559	{ 0x07, HDA_INPUT, 3 },
4560	{ 0x07, HDA_INPUT, 4 },
4561	{ } /* end */
4562};
4563#endif
4564
4565/*
4566 * ALC260 configurations
4567 */
4568static const char *alc260_models[ALC260_MODEL_LAST] = {
4569	[ALC260_BASIC]		= "basic",
4570	[ALC260_HP]		= "hp",
4571	[ALC260_HP_3013]	= "hp-3013",
4572	[ALC260_FUJITSU_S702X]	= "fujitsu",
4573	[ALC260_ACER]		= "acer",
4574	[ALC260_WILL]		= "will",
4575	[ALC260_REPLACER_672V]	= "replacer",
4576#ifdef CONFIG_SND_DEBUG
4577	[ALC260_TEST]		= "test",
4578#endif
4579	[ALC260_AUTO]		= "auto",
4580};
4581
4582static struct snd_pci_quirk alc260_cfg_tbl[] = {
4583	SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
4584	SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
4585	SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4586	SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
4587	SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
4588	SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
4589	SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
4590	SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
4591	SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
4592	SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
4593	SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
4594	SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
4595	SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
4596	SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
4597	SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
4598	SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
4599	SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
4600	SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
4601	{}
4602};
4603
4604static struct alc_config_preset alc260_presets[] = {
4605	[ALC260_BASIC] = {
4606		.mixers = { alc260_base_output_mixer,
4607			    alc260_input_mixer,
4608			    alc260_pc_beep_mixer,
4609			    alc260_capture_mixer },
4610		.init_verbs = { alc260_init_verbs },
4611		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4612		.dac_nids = alc260_dac_nids,
4613		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4614		.adc_nids = alc260_adc_nids,
4615		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4616		.channel_mode = alc260_modes,
4617		.input_mux = &alc260_capture_source,
4618	},
4619	[ALC260_HP] = {
4620		.mixers = { alc260_base_output_mixer,
4621			    alc260_input_mixer,
4622			    alc260_capture_alt_mixer },
4623		.init_verbs = { alc260_init_verbs },
4624		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4625		.dac_nids = alc260_dac_nids,
4626		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4627		.adc_nids = alc260_hp_adc_nids,
4628		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4629		.channel_mode = alc260_modes,
4630		.input_mux = &alc260_capture_source,
4631	},
4632	[ALC260_HP_3013] = {
4633		.mixers = { alc260_hp_3013_mixer,
4634			    alc260_input_mixer,
4635			    alc260_capture_alt_mixer },
4636		.init_verbs = { alc260_hp_3013_init_verbs },
4637		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4638		.dac_nids = alc260_dac_nids,
4639		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4640		.adc_nids = alc260_hp_adc_nids,
4641		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4642		.channel_mode = alc260_modes,
4643		.input_mux = &alc260_capture_source,
4644	},
4645	[ALC260_FUJITSU_S702X] = {
4646		.mixers = { alc260_fujitsu_mixer,
4647			    alc260_capture_mixer },
4648		.init_verbs = { alc260_fujitsu_init_verbs },
4649		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4650		.dac_nids = alc260_dac_nids,
4651		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4652		.adc_nids = alc260_dual_adc_nids,
4653		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4654		.channel_mode = alc260_modes,
4655		.num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
4656		.input_mux = alc260_fujitsu_capture_sources,
4657	},
4658	[ALC260_ACER] = {
4659		.mixers = { alc260_acer_mixer,
4660			    alc260_capture_mixer },
4661		.init_verbs = { alc260_acer_init_verbs },
4662		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4663		.dac_nids = alc260_dac_nids,
4664		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4665		.adc_nids = alc260_dual_adc_nids,
4666		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4667		.channel_mode = alc260_modes,
4668		.num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
4669		.input_mux = alc260_acer_capture_sources,
4670	},
4671	[ALC260_WILL] = {
4672		.mixers = { alc260_will_mixer,
4673			    alc260_capture_mixer },
4674		.init_verbs = { alc260_init_verbs, alc260_will_verbs },
4675		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4676		.dac_nids = alc260_dac_nids,
4677		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4678		.adc_nids = alc260_adc_nids,
4679		.dig_out_nid = ALC260_DIGOUT_NID,
4680		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4681		.channel_mode = alc260_modes,
4682		.input_mux = &alc260_capture_source,
4683	},
4684	[ALC260_REPLACER_672V] = {
4685		.mixers = { alc260_replacer_672v_mixer,
4686			    alc260_capture_mixer },
4687		.init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
4688		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4689		.dac_nids = alc260_dac_nids,
4690		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4691		.adc_nids = alc260_adc_nids,
4692		.dig_out_nid = ALC260_DIGOUT_NID,
4693		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4694		.channel_mode = alc260_modes,
4695		.input_mux = &alc260_capture_source,
4696		.unsol_event = alc260_replacer_672v_unsol_event,
4697		.init_hook = alc260_replacer_672v_automute,
4698	},
4699#ifdef CONFIG_SND_DEBUG
4700	[ALC260_TEST] = {
4701		.mixers = { alc260_test_mixer,
4702			    alc260_capture_mixer },
4703		.init_verbs = { alc260_test_init_verbs },
4704		.num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
4705		.dac_nids = alc260_test_dac_nids,
4706		.num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
4707		.adc_nids = alc260_test_adc_nids,
4708		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4709		.channel_mode = alc260_modes,
4710		.num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
4711		.input_mux = alc260_test_capture_sources,
4712	},
4713#endif
4714};
4715
4716static int patch_alc260(struct hda_codec *codec)
4717{
4718	struct alc_spec *spec;
4719	int err, board_config;
4720
4721	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4722	if (spec == NULL)
4723		return -ENOMEM;
4724
4725	codec->spec = spec;
4726
4727	board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
4728						  alc260_models,
4729						  alc260_cfg_tbl);
4730	if (board_config < 0) {
4731		snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
4732			   "trying auto-probe from BIOS...\n");
4733		board_config = ALC260_AUTO;
4734	}
4735
4736	if (board_config == ALC260_AUTO) {
4737		/* automatic parse from the BIOS config */
4738		err = alc260_parse_auto_config(codec);
4739		if (err < 0) {
4740			alc_free(codec);
4741			return err;
4742		} else if (!err) {
4743			printk(KERN_INFO
4744			       "hda_codec: Cannot set up configuration "
4745			       "from BIOS.  Using base mode...\n");
4746			board_config = ALC260_BASIC;
4747		}
4748	}
4749
4750	if (board_config != ALC260_AUTO)
4751		setup_preset(spec, &alc260_presets[board_config]);
4752
4753	spec->stream_name_analog = "ALC260 Analog";
4754	spec->stream_analog_playback = &alc260_pcm_analog_playback;
4755	spec->stream_analog_capture = &alc260_pcm_analog_capture;
4756
4757	spec->stream_name_digital = "ALC260 Digital";
4758	spec->stream_digital_playback = &alc260_pcm_digital_playback;
4759	spec->stream_digital_capture = &alc260_pcm_digital_capture;
4760
4761	codec->patch_ops = alc_patch_ops;
4762	if (board_config == ALC260_AUTO)
4763		spec->init_hook = alc260_auto_init;
4764#ifdef CONFIG_SND_HDA_POWER_SAVE
4765	if (!spec->loopback.amplist)
4766		spec->loopback.amplist = alc260_loopbacks;
4767#endif
4768
4769	return 0;
4770}
4771
4772
4773/*
4774 * ALC882 support
4775 *
4776 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
4777 * configuration.  Each pin widget can choose any input DACs and a mixer.
4778 * Each ADC is connected from a mixer of all inputs.  This makes possible
4779 * 6-channel independent captures.
4780 *
4781 * In addition, an independent DAC for the multi-playback (not used in this
4782 * driver yet).
4783 */
4784#define ALC882_DIGOUT_NID	0x06
4785#define ALC882_DIGIN_NID	0x0a
4786
4787static struct hda_channel_mode alc882_ch_modes[1] = {
4788	{ 8, NULL }
4789};
4790
4791static hda_nid_t alc882_dac_nids[4] = {
4792	/* front, rear, clfe, rear_surr */
4793	0x02, 0x03, 0x04, 0x05
4794};
4795
4796/* identical with ALC880 */
4797#define alc882_adc_nids		alc880_adc_nids
4798#define alc882_adc_nids_alt	alc880_adc_nids_alt
4799
4800/* input MUX */
4801/* FIXME: should be a matrix-type input source selection */
4802
4803static struct hda_input_mux alc882_capture_source = {
4804	.num_items = 4,
4805	.items = {
4806		{ "Mic", 0x0 },
4807		{ "Front Mic", 0x1 },
4808		{ "Line", 0x2 },
4809		{ "CD", 0x4 },
4810	},
4811};
4812#define alc882_mux_enum_info alc_mux_enum_info
4813#define alc882_mux_enum_get alc_mux_enum_get
4814
4815static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
4816			       struct snd_ctl_elem_value *ucontrol)
4817{
4818	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4819	struct alc_spec *spec = codec->spec;
4820	const struct hda_input_mux *imux = spec->input_mux;
4821	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
4822	static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
4823	hda_nid_t nid = capture_mixers[adc_idx];
4824	unsigned int *cur_val = &spec->cur_mux[adc_idx];
4825	unsigned int i, idx;
4826
4827	idx = ucontrol->value.enumerated.item[0];
4828	if (idx >= imux->num_items)
4829		idx = imux->num_items - 1;
4830	if (*cur_val == idx)
4831		return 0;
4832	for (i = 0; i < imux->num_items; i++) {
4833		unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
4834		snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
4835					 imux->items[i].index,
4836					 HDA_AMP_MUTE, v);
4837	}
4838	*cur_val = idx;
4839	return 1;
4840}
4841
4842/*
4843 * 2ch mode
4844 */
4845static struct hda_verb alc882_3ST_ch2_init[] = {
4846	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
4847	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4848	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
4849	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4850	{ } /* end */
4851};
4852
4853/*
4854 * 6ch mode
4855 */
4856static struct hda_verb alc882_3ST_ch6_init[] = {
4857	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4858	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4859	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
4860	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4861	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4862	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
4863	{ } /* end */
4864};
4865
4866static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
4867	{ 2, alc882_3ST_ch2_init },
4868	{ 6, alc882_3ST_ch6_init },
4869};
4870
4871/*
4872 * 6ch mode
4873 */
4874static struct hda_verb alc882_sixstack_ch6_init[] = {
4875	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
4876	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4877	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4878	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4879	{ } /* end */
4880};
4881
4882/*
4883 * 8ch mode
4884 */
4885static struct hda_verb alc882_sixstack_ch8_init[] = {
4886	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4887	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4888	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4889	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4890	{ } /* end */
4891};
4892
4893static struct hda_channel_mode alc882_sixstack_modes[2] = {
4894	{ 6, alc882_sixstack_ch6_init },
4895	{ 8, alc882_sixstack_ch8_init },
4896};
4897
4898/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
4899 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
4900 */
4901static struct snd_kcontrol_new alc882_base_mixer[] = {
4902	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4903	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4904	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4905	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4906	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
4907	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4908	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
4909	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
4910	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4911	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4912	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4913	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4914	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4915	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4916	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4917	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4918	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4919	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4920	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4921	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
4922	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4923	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4924	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4925	{ } /* end */
4926};
4927
4928static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
4929	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4930	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4931	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4932	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4933	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4934	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4935	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4936	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4937	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4938	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4939	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4940	{ } /* end */
4941};
4942
4943static struct snd_kcontrol_new alc882_targa_mixer[] = {
4944	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4945	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4946	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4947	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4948	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4949	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4950	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4951	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4952	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4953	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4954	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4955	{ } /* end */
4956};
4957
4958/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
4959 *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
4960 */
4961static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
4962	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4963	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
4964	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4965	HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
4966	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4967	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4968	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4969	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4970	HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
4971	HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
4972	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4973	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4974	{ } /* end */
4975};
4976
4977static struct snd_kcontrol_new alc882_chmode_mixer[] = {
4978	{
4979		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4980		.name = "Channel Mode",
4981		.info = alc_ch_mode_info,
4982		.get = alc_ch_mode_get,
4983		.put = alc_ch_mode_put,
4984	},
4985	{ } /* end */
4986};
4987
4988static struct hda_verb alc882_init_verbs[] = {
4989	/* Front mixer: unmute input/output amp left and right (volume = 0) */
4990	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4991	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4992	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4993	/* Rear mixer */
4994	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4995	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4996	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4997	/* CLFE mixer */
4998	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4999	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5000	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5001	/* Side mixer */
5002	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5003	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5004	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5005
5006	/* Front Pin: output 0 (0x0c) */
5007	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5008	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5009	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5010	/* Rear Pin: output 1 (0x0d) */
5011	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5012	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5013	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5014	/* CLFE Pin: output 2 (0x0e) */
5015	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5016	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5017	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5018	/* Side Pin: output 3 (0x0f) */
5019	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5020	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5021	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5022	/* Mic (rear) pin: input vref at 80% */
5023	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5024	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5025	/* Front Mic pin: input vref at 80% */
5026	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5027	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5028	/* Line In pin: input */
5029	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5030	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5031	/* Line-2 In: Headphone output (output 0 - 0x0c) */
5032	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5033	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5034	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5035	/* CD pin widget for input */
5036	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5037
5038	/* FIXME: use matrix-type input source selection */
5039	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5040	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5041	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5042	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5043	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5044	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5045	/* Input mixer2 */
5046	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5047	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5048	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5049	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5050	/* Input mixer3 */
5051	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5052	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5053	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5054	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5055	/* ADC1: mute amp left and right */
5056	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5057	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5058	/* ADC2: mute amp left and right */
5059	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5060	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5061	/* ADC3: mute amp left and right */
5062	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5063	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5064
5065	{ }
5066};
5067
5068static struct hda_verb alc882_eapd_verbs[] = {
5069	/* change to EAPD mode */
5070	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5071	{0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5072	{ }
5073};
5074
5075/* Mac Pro test */
5076static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5077	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5078	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5079	HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5080	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5081	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5082	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5083	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5084	{ } /* end */
5085};
5086
5087static struct hda_verb alc882_macpro_init_verbs[] = {
5088	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5089	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5090	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5091	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5092	/* Front Pin: output 0 (0x0c) */
5093	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5094	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5095	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5096	/* Front Mic pin: input vref at 80% */
5097	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5098	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5099	/* Speaker:  output */
5100	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5101	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5102	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5103	/* Headphone output (output 0 - 0x0c) */
5104	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5105	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5106	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5107
5108	/* FIXME: use matrix-type input source selection */
5109	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5110	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5111	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5112	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5113	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5114	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5115	/* Input mixer2 */
5116	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5117	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5118	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5119	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5120	/* Input mixer3 */
5121	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5122	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5123	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5124	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5125	/* ADC1: mute amp left and right */
5126	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5127	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5128	/* ADC2: mute amp left and right */
5129	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5130	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5131	/* ADC3: mute amp left and right */
5132	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5133	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5134
5135	{ }
5136};
5137
5138/* iMac 24 mixer. */
5139static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5140	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5141	HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5142	{ } /* end */
5143};
5144
5145/* iMac 24 init verbs. */
5146static struct hda_verb alc885_imac24_init_verbs[] = {
5147	/* Internal speakers: output 0 (0x0c) */
5148	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5149	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5150	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5151	/* Internal speakers: output 0 (0x0c) */
5152	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5153	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5154	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5155	/* Headphone: output 0 (0x0c) */
5156	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5157	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5158	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5159	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5160	/* Front Mic: input vref at 80% */
5161	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5162	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5163	{ }
5164};
5165
5166/* Toggle speaker-output according to the hp-jack state */
5167static void alc885_imac24_automute(struct hda_codec *codec)
5168{
5169 	unsigned int present;
5170
5171 	present = snd_hda_codec_read(codec, 0x14, 0,
5172				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5173	snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5174				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5175	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5176				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5177}
5178
5179/* Processes unsolicited events. */
5180static void alc885_imac24_unsol_event(struct hda_codec *codec,
5181				      unsigned int res)
5182{
5183	/* Headphone insertion or removal. */
5184	if ((res >> 26) == ALC880_HP_EVENT)
5185		alc885_imac24_automute(codec);
5186}
5187
5188static struct hda_verb alc882_targa_verbs[] = {
5189	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5190	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5191
5192	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5193	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5194
5195	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5196	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5197	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5198
5199	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5200	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5201	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5202	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5203	{ } /* end */
5204};
5205
5206/* toggle speaker-output according to the hp-jack state */
5207static void alc882_targa_automute(struct hda_codec *codec)
5208{
5209 	unsigned int present;
5210
5211 	present = snd_hda_codec_read(codec, 0x14, 0,
5212				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5213	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
5214				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5215	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
5216				  present ? 1 : 3);
5217}
5218
5219static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5220{
5221	/* Looks like the unsol event is incompatible with the standard
5222	 * definition.  4bit tag is placed at 26 bit!
5223	 */
5224	if (((res >> 26) == ALC880_HP_EVENT)) {
5225		alc882_targa_automute(codec);
5226	}
5227}
5228
5229static struct hda_verb alc882_asus_a7j_verbs[] = {
5230	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5231	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5232
5233	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5234	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5235	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5236
5237	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5238	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5239	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5240
5241	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5242	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5243	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5244	{ } /* end */
5245};
5246
5247static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5248{
5249	unsigned int gpiostate, gpiomask, gpiodir;
5250
5251	gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5252				       AC_VERB_GET_GPIO_DATA, 0);
5253
5254	if (!muted)
5255		gpiostate |= (1 << pin);
5256	else
5257		gpiostate &= ~(1 << pin);
5258
5259	gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5260				      AC_VERB_GET_GPIO_MASK, 0);
5261	gpiomask |= (1 << pin);
5262
5263	gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5264				     AC_VERB_GET_GPIO_DIRECTION, 0);
5265	gpiodir |= (1 << pin);
5266
5267
5268	snd_hda_codec_write(codec, codec->afg, 0,
5269			    AC_VERB_SET_GPIO_MASK, gpiomask);
5270	snd_hda_codec_write(codec, codec->afg, 0,
5271			    AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5272
5273	msleep(1);
5274
5275	snd_hda_codec_write(codec, codec->afg, 0,
5276			    AC_VERB_SET_GPIO_DATA, gpiostate);
5277}
5278
5279/* set up GPIO at initialization */
5280static void alc885_macpro_init_hook(struct hda_codec *codec)
5281{
5282	alc882_gpio_mute(codec, 0, 0);
5283	alc882_gpio_mute(codec, 1, 0);
5284}
5285
5286/* set up GPIO and update auto-muting at initialization */
5287static void alc885_imac24_init_hook(struct hda_codec *codec)
5288{
5289	alc885_macpro_init_hook(codec);
5290	alc885_imac24_automute(codec);
5291}
5292
5293/*
5294 * generic initialization of ADC, input mixers and output mixers
5295 */
5296static struct hda_verb alc882_auto_init_verbs[] = {
5297	/*
5298	 * Unmute ADC0-2 and set the default input to mic-in
5299	 */
5300	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5301	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5302	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5303	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5304	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5305	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5306
5307	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5308	 * mixer widget
5309	 * Note: PASD motherboards uses the Line In 2 as the input for
5310	 * front panel mic (mic 2)
5311	 */
5312	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5313	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5314	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5315	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5316	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5317	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5318
5319	/*
5320	 * Set up output mixers (0x0c - 0x0f)
5321	 */
5322	/* set vol=0 to output mixers */
5323	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5324	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5325	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5326	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5327	/* set up input amps for analog loopback */
5328	/* Amp Indices: DAC = 0, mixer = 1 */
5329	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5330	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5331	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5332	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5333	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5334	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5335	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5336	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5337	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5338	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5339
5340	/* FIXME: use matrix-type input source selection */
5341	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5342	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5343	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5344	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5345	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5346	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5347	/* Input mixer2 */
5348	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5349	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5350	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5351	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5352	/* Input mixer3 */
5353	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5354	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5355	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5356	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5357
5358	{ }
5359};
5360
5361/* capture mixer elements */
5362static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
5363	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5364	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5365	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5366	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5367	{
5368		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5369		/* The multiple "Capture Source" controls confuse alsamixer
5370		 * So call somewhat different..
5371		 * FIXME: the controls appear in the "playback" view!
5372		 */
5373		/* .name = "Capture Source", */
5374		.name = "Input Source",
5375		.count = 2,
5376		.info = alc882_mux_enum_info,
5377		.get = alc882_mux_enum_get,
5378		.put = alc882_mux_enum_put,
5379	},
5380	{ } /* end */
5381};
5382
5383static struct snd_kcontrol_new alc882_capture_mixer[] = {
5384	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
5385	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
5386	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
5387	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
5388	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
5389	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
5390	{
5391		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5392		/* The multiple "Capture Source" controls confuse alsamixer
5393		 * So call somewhat different..
5394		 * FIXME: the controls appear in the "playback" view!
5395		 */
5396		/* .name = "Capture Source", */
5397		.name = "Input Source",
5398		.count = 3,
5399		.info = alc882_mux_enum_info,
5400		.get = alc882_mux_enum_get,
5401		.put = alc882_mux_enum_put,
5402	},
5403	{ } /* end */
5404};
5405
5406#ifdef CONFIG_SND_HDA_POWER_SAVE
5407#define alc882_loopbacks	alc880_loopbacks
5408#endif
5409
5410/* pcm configuration: identiacal with ALC880 */
5411#define alc882_pcm_analog_playback	alc880_pcm_analog_playback
5412#define alc882_pcm_analog_capture	alc880_pcm_analog_capture
5413#define alc882_pcm_digital_playback	alc880_pcm_digital_playback
5414#define alc882_pcm_digital_capture	alc880_pcm_digital_capture
5415
5416/*
5417 * configuration and preset
5418 */
5419static const char *alc882_models[ALC882_MODEL_LAST] = {
5420	[ALC882_3ST_DIG]	= "3stack-dig",
5421	[ALC882_6ST_DIG]	= "6stack-dig",
5422	[ALC882_ARIMA]		= "arima",
5423	[ALC882_W2JC]		= "w2jc",
5424	[ALC885_MACPRO]		= "macpro",
5425	[ALC885_IMAC24]		= "imac24",
5426	[ALC882_AUTO]		= "auto",
5427};
5428
5429static struct snd_pci_quirk alc882_cfg_tbl[] = {
5430	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
5431	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
5432	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
5433	SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
5434	SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
5435	SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
5436	SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
5437	SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
5438	SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
5439	{}
5440};
5441
5442static struct alc_config_preset alc882_presets[] = {
5443	[ALC882_3ST_DIG] = {
5444		.mixers = { alc882_base_mixer },
5445		.init_verbs = { alc882_init_verbs },
5446		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5447		.dac_nids = alc882_dac_nids,
5448		.dig_out_nid = ALC882_DIGOUT_NID,
5449		.dig_in_nid = ALC882_DIGIN_NID,
5450		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5451		.channel_mode = alc882_ch_modes,
5452		.need_dac_fix = 1,
5453		.input_mux = &alc882_capture_source,
5454	},
5455	[ALC882_6ST_DIG] = {
5456		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
5457		.init_verbs = { alc882_init_verbs },
5458		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5459		.dac_nids = alc882_dac_nids,
5460		.dig_out_nid = ALC882_DIGOUT_NID,
5461		.dig_in_nid = ALC882_DIGIN_NID,
5462		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5463		.channel_mode = alc882_sixstack_modes,
5464		.input_mux = &alc882_capture_source,
5465	},
5466	[ALC882_ARIMA] = {
5467		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
5468		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
5469		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5470		.dac_nids = alc882_dac_nids,
5471		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5472		.channel_mode = alc882_sixstack_modes,
5473		.input_mux = &alc882_capture_source,
5474	},
5475	[ALC882_W2JC] = {
5476		.mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
5477		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5478				alc880_gpio1_init_verbs },
5479		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5480		.dac_nids = alc882_dac_nids,
5481		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5482		.channel_mode = alc880_threestack_modes,
5483		.need_dac_fix = 1,
5484		.input_mux = &alc882_capture_source,
5485		.dig_out_nid = ALC882_DIGOUT_NID,
5486	},
5487	[ALC885_MACPRO] = {
5488		.mixers = { alc882_macpro_mixer },
5489		.init_verbs = { alc882_macpro_init_verbs },
5490		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5491		.dac_nids = alc882_dac_nids,
5492		.dig_out_nid = ALC882_DIGOUT_NID,
5493		.dig_in_nid = ALC882_DIGIN_NID,
5494		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5495		.channel_mode = alc882_ch_modes,
5496		.input_mux = &alc882_capture_source,
5497		.init_hook = alc885_macpro_init_hook,
5498	},
5499	[ALC885_IMAC24] = {
5500		.mixers = { alc885_imac24_mixer },
5501		.init_verbs = { alc885_imac24_init_verbs },
5502		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5503		.dac_nids = alc882_dac_nids,
5504		.dig_out_nid = ALC882_DIGOUT_NID,
5505		.dig_in_nid = ALC882_DIGIN_NID,
5506		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5507		.channel_mode = alc882_ch_modes,
5508		.input_mux = &alc882_capture_source,
5509		.unsol_event = alc885_imac24_unsol_event,
5510		.init_hook = alc885_imac24_init_hook,
5511	},
5512	[ALC882_TARGA] = {
5513		.mixers = { alc882_targa_mixer, alc882_chmode_mixer,
5514			    alc882_capture_mixer },
5515		.init_verbs = { alc882_init_verbs, alc882_targa_verbs},
5516		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5517		.dac_nids = alc882_dac_nids,
5518		.dig_out_nid = ALC882_DIGOUT_NID,
5519		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5520		.adc_nids = alc882_adc_nids,
5521		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5522		.channel_mode = alc882_3ST_6ch_modes,
5523		.need_dac_fix = 1,
5524		.input_mux = &alc882_capture_source,
5525		.unsol_event = alc882_targa_unsol_event,
5526		.init_hook = alc882_targa_automute,
5527	},
5528	[ALC882_ASUS_A7J] = {
5529		.mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
5530			    alc882_capture_mixer },
5531		.init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
5532		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5533		.dac_nids = alc882_dac_nids,
5534		.dig_out_nid = ALC882_DIGOUT_NID,
5535		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5536		.adc_nids = alc882_adc_nids,
5537		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5538		.channel_mode = alc882_3ST_6ch_modes,
5539		.need_dac_fix = 1,
5540		.input_mux = &alc882_capture_source,
5541	},
5542};
5543
5544
5545/*
5546 * Pin config fixes
5547 */
5548enum {
5549	PINFIX_ABIT_AW9D_MAX
5550};
5551
5552static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
5553	{ 0x15, 0x01080104 }, /* side */
5554	{ 0x16, 0x01011012 }, /* rear */
5555	{ 0x17, 0x01016011 }, /* clfe */
5556	{ }
5557};
5558
5559static const struct alc_pincfg *alc882_pin_fixes[] = {
5560	[PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
5561};
5562
5563static struct snd_pci_quirk alc882_pinfix_tbl[] = {
5564	SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
5565	{}
5566};
5567
5568/*
5569 * BIOS auto configuration
5570 */
5571static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
5572					      hda_nid_t nid, int pin_type,
5573					      int dac_idx)
5574{
5575	/* set as output */
5576	struct alc_spec *spec = codec->spec;
5577	int idx;
5578
5579	if (spec->multiout.dac_nids[dac_idx] == 0x25)
5580		idx = 4;
5581	else
5582		idx = spec->multiout.dac_nids[dac_idx] - 2;
5583
5584	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5585			    pin_type);
5586	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5587			    AMP_OUT_UNMUTE);
5588	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
5589
5590}
5591
5592static void alc882_auto_init_multi_out(struct hda_codec *codec)
5593{
5594	struct alc_spec *spec = codec->spec;
5595	int i;
5596
5597	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
5598	for (i = 0; i <= HDA_SIDE; i++) {
5599		hda_nid_t nid = spec->autocfg.line_out_pins[i];
5600		int pin_type = get_pin_type(spec->autocfg.line_out_type);
5601		if (nid)
5602			alc882_auto_set_output_and_unmute(codec, nid, pin_type,
5603							  i);
5604	}
5605}
5606
5607static void alc882_auto_init_hp_out(struct hda_codec *codec)
5608{
5609	struct alc_spec *spec = codec->spec;
5610	hda_nid_t pin;
5611
5612	pin = spec->autocfg.hp_pins[0];
5613	if (pin) /* connect to front */
5614		/* use dac 0 */
5615		alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5616}
5617
5618#define alc882_is_input_pin(nid)	alc880_is_input_pin(nid)
5619#define ALC882_PIN_CD_NID		ALC880_PIN_CD_NID
5620
5621static void alc882_auto_init_analog_input(struct hda_codec *codec)
5622{
5623	struct alc_spec *spec = codec->spec;
5624	int i;
5625
5626	for (i = 0; i < AUTO_PIN_LAST; i++) {
5627		hda_nid_t nid = spec->autocfg.input_pins[i];
5628		if (alc882_is_input_pin(nid)) {
5629			snd_hda_codec_write(codec, nid, 0,
5630					    AC_VERB_SET_PIN_WIDGET_CONTROL,
5631					    i <= AUTO_PIN_FRONT_MIC ?
5632					    PIN_VREF80 : PIN_IN);
5633			if (nid != ALC882_PIN_CD_NID)
5634				snd_hda_codec_write(codec, nid, 0,
5635						    AC_VERB_SET_AMP_GAIN_MUTE,
5636						    AMP_OUT_MUTE);
5637		}
5638	}
5639}
5640
5641/* almost identical with ALC880 parser... */
5642static int alc882_parse_auto_config(struct hda_codec *codec)
5643{
5644	struct alc_spec *spec = codec->spec;
5645	int err = alc880_parse_auto_config(codec);
5646
5647	if (err < 0)
5648		return err;
5649	else if (err > 0)
5650		/* hack - override the init verbs */
5651		spec->init_verbs[0] = alc882_auto_init_verbs;
5652	return err;
5653}
5654
5655/* additional initialization for auto-configuration model */
5656static void alc882_auto_init(struct hda_codec *codec)
5657{
5658	alc882_auto_init_multi_out(codec);
5659	alc882_auto_init_hp_out(codec);
5660	alc882_auto_init_analog_input(codec);
5661}
5662
5663static int patch_alc882(struct hda_codec *codec)
5664{
5665	struct alc_spec *spec;
5666	int err, board_config;
5667
5668	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5669	if (spec == NULL)
5670		return -ENOMEM;
5671
5672	codec->spec = spec;
5673
5674	board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
5675						  alc882_models,
5676						  alc882_cfg_tbl);
5677
5678	if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
5679		/* Pick up systems that don't supply PCI SSID */
5680		switch (codec->subsystem_id) {
5681		case 0x106b0c00: /* Mac Pro */
5682			board_config = ALC885_MACPRO;
5683			break;
5684		case 0x106b1000: /* iMac 24 */
5685			board_config = ALC885_IMAC24;
5686			break;
5687		default:
5688			printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
5689		       			 "trying auto-probe from BIOS...\n");
5690			board_config = ALC882_AUTO;
5691		}
5692	}
5693
5694	alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
5695
5696	if (board_config == ALC882_AUTO) {
5697		/* automatic parse from the BIOS config */
5698		err = alc882_parse_auto_config(codec);
5699		if (err < 0) {
5700			alc_free(codec);
5701			return err;
5702		} else if (!err) {
5703			printk(KERN_INFO
5704			       "hda_codec: Cannot set up configuration "
5705			       "from BIOS.  Using base mode...\n");
5706			board_config = ALC882_3ST_DIG;
5707		}
5708	}
5709
5710	if (board_config != ALC882_AUTO)
5711		setup_preset(spec, &alc882_presets[board_config]);
5712
5713	spec->stream_name_analog = "ALC882 Analog";
5714	spec->stream_analog_playback = &alc882_pcm_analog_playback;
5715	spec->stream_analog_capture = &alc882_pcm_analog_capture;
5716
5717	spec->stream_name_digital = "ALC882 Digital";
5718	spec->stream_digital_playback = &alc882_pcm_digital_playback;
5719	spec->stream_digital_capture = &alc882_pcm_digital_capture;
5720
5721	if (!spec->adc_nids && spec->input_mux) {
5722		/* check whether NID 0x07 is valid */
5723		unsigned int wcap = get_wcaps(codec, 0x07);
5724		/* get type */
5725		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
5726		if (wcap != AC_WID_AUD_IN) {
5727			spec->adc_nids = alc882_adc_nids_alt;
5728			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
5729			spec->mixers[spec->num_mixers] =
5730				alc882_capture_alt_mixer;
5731			spec->num_mixers++;
5732		} else {
5733			spec->adc_nids = alc882_adc_nids;
5734			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
5735			spec->mixers[spec->num_mixers] = alc882_capture_mixer;
5736			spec->num_mixers++;
5737		}
5738	}
5739
5740	codec->patch_ops = alc_patch_ops;
5741	if (board_config == ALC882_AUTO)
5742		spec->init_hook = alc882_auto_init;
5743#ifdef CONFIG_SND_HDA_POWER_SAVE
5744	if (!spec->loopback.amplist)
5745		spec->loopback.amplist = alc882_loopbacks;
5746#endif
5747
5748	return 0;
5749}
5750
5751/*
5752 * ALC883 support
5753 *
5754 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
5755 * configuration.  Each pin widget can choose any input DACs and a mixer.
5756 * Each ADC is connected from a mixer of all inputs.  This makes possible
5757 * 6-channel independent captures.
5758 *
5759 * In addition, an independent DAC for the multi-playback (not used in this
5760 * driver yet).
5761 */
5762#define ALC883_DIGOUT_NID	0x06
5763#define ALC883_DIGIN_NID	0x0a
5764
5765static hda_nid_t alc883_dac_nids[4] = {
5766	/* front, rear, clfe, rear_surr */
5767	0x02, 0x04, 0x03, 0x05
5768};
5769
5770static hda_nid_t alc883_adc_nids[2] = {
5771	/* ADC1-2 */
5772	0x08, 0x09,
5773};
5774
5775/* input MUX */
5776/* FIXME: should be a matrix-type input source selection */
5777
5778static struct hda_input_mux alc883_capture_source = {
5779	.num_items = 4,
5780	.items = {
5781		{ "Mic", 0x0 },
5782		{ "Front Mic", 0x1 },
5783		{ "Line", 0x2 },
5784		{ "CD", 0x4 },
5785	},
5786};
5787
5788static struct hda_input_mux alc883_lenovo_101e_capture_source = {
5789	.num_items = 2,
5790	.items = {
5791		{ "Mic", 0x1 },
5792		{ "Line", 0x2 },
5793	},
5794};
5795
5796static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
5797	.num_items = 4,
5798	.items = {
5799		{ "Mic", 0x0 },
5800		{ "iMic", 0x1 },
5801		{ "Line", 0x2 },
5802		{ "CD", 0x4 },
5803	},
5804};
5805
5806#define alc883_mux_enum_info alc_mux_enum_info
5807#define alc883_mux_enum_get alc_mux_enum_get
5808
5809static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
5810			       struct snd_ctl_elem_value *ucontrol)
5811{
5812	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5813	struct alc_spec *spec = codec->spec;
5814	const struct hda_input_mux *imux = spec->input_mux;
5815	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5816	static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
5817	hda_nid_t nid = capture_mixers[adc_idx];
5818	unsigned int *cur_val = &spec->cur_mux[adc_idx];
5819	unsigned int i, idx;
5820
5821	idx = ucontrol->value.enumerated.item[0];
5822	if (idx >= imux->num_items)
5823		idx = imux->num_items - 1;
5824	if (*cur_val == idx)
5825		return 0;
5826	for (i = 0; i < imux->num_items; i++) {
5827		unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5828		snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
5829					 imux->items[i].index,
5830					 HDA_AMP_MUTE, v);
5831	}
5832	*cur_val = idx;
5833	return 1;
5834}
5835
5836/*
5837 * 2ch mode
5838 */
5839static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
5840	{ 2, NULL }
5841};
5842
5843/*
5844 * 2ch mode
5845 */
5846static struct hda_verb alc883_3ST_ch2_init[] = {
5847	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5848	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5849	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5850	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5851	{ } /* end */
5852};
5853
5854/*
5855 * 6ch mode
5856 */
5857static struct hda_verb alc883_3ST_ch6_init[] = {
5858	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5859	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5860	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5861	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5862	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5863	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5864	{ } /* end */
5865};
5866
5867static struct hda_channel_mode alc883_3ST_6ch_modes[2] = {
5868	{ 2, alc883_3ST_ch2_init },
5869	{ 6, alc883_3ST_ch6_init },
5870};
5871
5872/*
5873 * 6ch mode
5874 */
5875static struct hda_verb alc883_sixstack_ch6_init[] = {
5876	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5877	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5878	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5879	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5880	{ } /* end */
5881};
5882
5883/*
5884 * 8ch mode
5885 */
5886static struct hda_verb alc883_sixstack_ch8_init[] = {
5887	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5888	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5889	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5890	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5891	{ } /* end */
5892};
5893
5894static struct hda_channel_mode alc883_sixstack_modes[2] = {
5895	{ 6, alc883_sixstack_ch6_init },
5896	{ 8, alc883_sixstack_ch8_init },
5897};
5898
5899static struct hda_verb alc883_medion_eapd_verbs[] = {
5900        /* eanable EAPD on medion laptop */
5901	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5902	{0x20, AC_VERB_SET_PROC_COEF, 0x3070},
5903	{ }
5904};
5905
5906/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5907 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5908 */
5909
5910static struct snd_kcontrol_new alc883_base_mixer[] = {
5911	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5912	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5913	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5914	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5915	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5916	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5917	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5918	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5919	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5920	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5921	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5922	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5923	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5924	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5925	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5926	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5927	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5928	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5929	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5930	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5931	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5932	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5933	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5934	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5935	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5936	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5937	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5938	{
5939		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5940		/* .name = "Capture Source", */
5941		.name = "Input Source",
5942		.count = 2,
5943		.info = alc883_mux_enum_info,
5944		.get = alc883_mux_enum_get,
5945		.put = alc883_mux_enum_put,
5946	},
5947	{ } /* end */
5948};
5949
5950static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
5951	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5952	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5953	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5954	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5955	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5956	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5957	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5958	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5959	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5960	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5961	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5962	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5963	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5964	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5965	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5966	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5967	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5968	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5969	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5970	{
5971		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5972		/* .name = "Capture Source", */
5973		.name = "Input Source",
5974		.count = 2,
5975		.info = alc883_mux_enum_info,
5976		.get = alc883_mux_enum_get,
5977		.put = alc883_mux_enum_put,
5978	},
5979	{ } /* end */
5980};
5981
5982static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
5983	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5984	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5985	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5986	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5987	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5988	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5989	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5990	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5991	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5992	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5993	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5994	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5995	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5996	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5997	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5998	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5999	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6000	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6001	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6002	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6003	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6004	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6005	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6006	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6007	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6008	{
6009		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6010		/* .name = "Capture Source", */
6011		.name = "Input Source",
6012		.count = 2,
6013		.info = alc883_mux_enum_info,
6014		.get = alc883_mux_enum_get,
6015		.put = alc883_mux_enum_put,
6016	},
6017	{ } /* end */
6018};
6019
6020static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
6021	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6022	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6023	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6024	HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6025	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6026	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6027	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
6028	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6029	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6030	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6031	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6032	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6033	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6034	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6035	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6036	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6037	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6038	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6039	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6040	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6041	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6042	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6043	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6044
6045	{
6046		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6047		/* .name = "Capture Source", */
6048		.name = "Input Source",
6049		.count = 1,
6050		.info = alc883_mux_enum_info,
6051		.get = alc883_mux_enum_get,
6052		.put = alc883_mux_enum_put,
6053	},
6054	{ } /* end */
6055};
6056
6057static struct snd_kcontrol_new alc883_tagra_mixer[] = {
6058	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6059	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6060	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6061	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6062	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6063	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6064	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6065	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6066	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6067	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6068	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6069	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6070	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6071	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6072	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6073	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6074	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6075	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6076	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6077	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6078	{
6079		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6080		/* .name = "Capture Source", */
6081		.name = "Input Source",
6082		.count = 2,
6083		.info = alc883_mux_enum_info,
6084		.get = alc883_mux_enum_get,
6085		.put = alc883_mux_enum_put,
6086	},
6087	{ } /* end */
6088};
6089
6090static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
6091	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6092	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6093	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6094	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6095	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6096	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6097	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6098	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6099	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6100	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6101	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6102	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6103	{
6104		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6105		/* .name = "Capture Source", */
6106		.name = "Input Source",
6107		.count = 2,
6108		.info = alc883_mux_enum_info,
6109		.get = alc883_mux_enum_get,
6110		.put = alc883_mux_enum_put,
6111	},
6112	{ } /* end */
6113};
6114
6115static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
6116	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6117	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6118	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6119	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
6120	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6121	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6122	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6123	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6124	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6125	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6126	{
6127		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6128		/* .name = "Capture Source", */
6129		.name = "Input Source",
6130		.count = 1,
6131		.info = alc883_mux_enum_info,
6132		.get = alc883_mux_enum_get,
6133		.put = alc883_mux_enum_put,
6134	},
6135	{ } /* end */
6136};
6137
6138static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
6139	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6140	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
6141	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6142	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6143	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6144	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6145	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6146	HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6147	HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6148	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6149	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6150	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6151	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6152	{
6153		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6154		/* .name = "Capture Source", */
6155		.name = "Input Source",
6156		.count = 2,
6157		.info = alc883_mux_enum_info,
6158		.get = alc883_mux_enum_get,
6159		.put = alc883_mux_enum_put,
6160	},
6161	{ } /* end */
6162};
6163
6164static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
6165	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6166	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6167	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6168	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6169	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6170	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6171	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6172	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6173	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6174	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6175	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6176	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6177	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6178	{
6179		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6180		/* .name = "Capture Source", */
6181		.name = "Input Source",
6182		.count = 2,
6183		.info = alc883_mux_enum_info,
6184		.get = alc883_mux_enum_get,
6185		.put = alc883_mux_enum_put,
6186	},
6187	{ } /* end */
6188};
6189
6190static struct snd_kcontrol_new alc888_6st_hp_mixer[] = {
6191	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6192	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6193	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6194	HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6195	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6196	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6197	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6198	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6199	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6200	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6201	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6202	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6203	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6204	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6205	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6206	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6207	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6208	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6209	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6210	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6211	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6212	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6213	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6214	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6215	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6216	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6217	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6218	{
6219		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6220		/* .name = "Capture Source", */
6221		.name = "Input Source",
6222		.count = 2,
6223		.info = alc883_mux_enum_info,
6224		.get = alc883_mux_enum_get,
6225		.put = alc883_mux_enum_put,
6226	},
6227	{ } /* end */
6228};
6229
6230static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
6231	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6232	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6233	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6234	HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6235	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6236	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6237	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6238	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6239	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6240	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6241	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6242	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6243	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6244	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6245	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6246	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6247	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6248	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6249	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6250	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6251	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6252	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6253	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6254	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6255	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6256	{
6257		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6258		/* .name = "Capture Source", */
6259		.name = "Input Source",
6260		.count = 2,
6261		.info = alc883_mux_enum_info,
6262		.get = alc883_mux_enum_get,
6263		.put = alc883_mux_enum_put,
6264	},
6265	{ } /* end */
6266};
6267
6268static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
6269	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6270	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6271	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6272	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6273	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6274	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6275	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6276	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6277	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6278	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6279	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6280	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6281	{
6282		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6283		/* .name = "Capture Source", */
6284		.name = "Input Source",
6285		.count = 2,
6286		.info = alc883_mux_enum_info,
6287		.get = alc883_mux_enum_get,
6288		.put = alc883_mux_enum_put,
6289	},
6290	{ } /* end */
6291};
6292
6293static struct snd_kcontrol_new alc883_chmode_mixer[] = {
6294	{
6295		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6296		.name = "Channel Mode",
6297		.info = alc_ch_mode_info,
6298		.get = alc_ch_mode_get,
6299		.put = alc_ch_mode_put,
6300	},
6301	{ } /* end */
6302};
6303
6304static struct hda_verb alc883_init_verbs[] = {
6305	/* ADC1: mute amp left and right */
6306	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6307	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6308	/* ADC2: mute amp left and right */
6309	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6310	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6311	/* Front mixer: unmute input/output amp left and right (volume = 0) */
6312	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6313	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6314	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6315	/* Rear mixer */
6316	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6317	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6318	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6319	/* CLFE mixer */
6320	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6321	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6322	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6323	/* Side mixer */
6324	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6325	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6326	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6327
6328	/* mute analog input loopbacks */
6329	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6330	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6331	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6332	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6333	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6334
6335	/* Front Pin: output 0 (0x0c) */
6336	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6337	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6338	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6339	/* Rear Pin: output 1 (0x0d) */
6340	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6341	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6342	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6343	/* CLFE Pin: output 2 (0x0e) */
6344	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6345	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6346	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6347	/* Side Pin: output 3 (0x0f) */
6348	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6349	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6350	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6351	/* Mic (rear) pin: input vref at 80% */
6352	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6353	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6354	/* Front Mic pin: input vref at 80% */
6355	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6356	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6357	/* Line In pin: input */
6358	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6359	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6360	/* Line-2 In: Headphone output (output 0 - 0x0c) */
6361	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6362	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6363	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6364	/* CD pin widget for input */
6365	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6366
6367	/* FIXME: use matrix-type input source selection */
6368	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6369	/* Input mixer2 */
6370	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6371	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6372	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6373	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6374	/* Input mixer3 */
6375	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6376	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6377	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6378	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6379	{ }
6380};
6381
6382static struct hda_verb alc883_tagra_verbs[] = {
6383	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6384	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6385
6386	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6387	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6388
6389	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6390	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6391	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6392
6393	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6394	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6395	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6396	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6397
6398	{ } /* end */
6399};
6400
6401static struct hda_verb alc883_lenovo_101e_verbs[] = {
6402	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6403	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
6404        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
6405	{ } /* end */
6406};
6407
6408static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
6409        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6410	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6411        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6412        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6413	{ } /* end */
6414};
6415
6416static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
6417	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6418	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6419	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6420	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
6421	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
6422	{ } /* end */
6423};
6424
6425static struct hda_verb alc888_6st_hp_verbs[] = {
6426	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Front: output 0 (0x0c) */
6427	{0x15, AC_VERB_SET_CONNECT_SEL, 0x02},	/* Rear : output 2 (0x0e) */
6428	{0x16, AC_VERB_SET_CONNECT_SEL, 0x01},	/* CLFE : output 1 (0x0d) */
6429	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},	/* Side : output 3 (0x0f) */
6430	{ }
6431};
6432
6433static struct hda_verb alc888_3st_hp_verbs[] = {
6434	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Front: output 0 (0x0c) */
6435	{0x18, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Rear : output 1 (0x0d) */
6436	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},	/* CLFE : output 2 (0x0e) */
6437	{ }
6438};
6439
6440static struct hda_verb alc888_3st_hp_2ch_init[] = {
6441	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6442	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6443	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6444	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6445	{ }
6446};
6447
6448static struct hda_verb alc888_3st_hp_6ch_init[] = {
6449	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6450	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6451	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6452	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6453	{ }
6454};
6455
6456static struct hda_channel_mode alc888_3st_hp_modes[2] = {
6457	{ 2, alc888_3st_hp_2ch_init },
6458	{ 6, alc888_3st_hp_6ch_init },
6459};
6460
6461/* toggle front-jack and RCA according to the hp-jack state */
6462static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
6463{
6464 	unsigned int present;
6465
6466 	present = snd_hda_codec_read(codec, 0x1b, 0,
6467				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6468	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6469				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6470	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6471				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6472}
6473
6474/* toggle RCA according to the front-jack state */
6475static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
6476{
6477 	unsigned int present;
6478
6479 	present = snd_hda_codec_read(codec, 0x14, 0,
6480				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6481	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6482				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6483}
6484
6485static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
6486					     unsigned int res)
6487{
6488	if ((res >> 26) == ALC880_HP_EVENT)
6489		alc888_lenovo_ms7195_front_automute(codec);
6490	if ((res >> 26) == ALC880_FRONT_EVENT)
6491		alc888_lenovo_ms7195_rca_automute(codec);
6492}
6493
6494static struct hda_verb alc883_medion_md2_verbs[] = {
6495	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6496	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6497
6498	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6499
6500	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6501	{ } /* end */
6502};
6503
6504/* toggle speaker-output according to the hp-jack state */
6505static void alc883_medion_md2_automute(struct hda_codec *codec)
6506{
6507 	unsigned int present;
6508
6509 	present = snd_hda_codec_read(codec, 0x14, 0,
6510				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6511	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6512				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6513}
6514
6515static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
6516					  unsigned int res)
6517{
6518	if ((res >> 26) == ALC880_HP_EVENT)
6519		alc883_medion_md2_automute(codec);
6520}
6521
6522/* toggle speaker-output according to the hp-jack state */
6523static void alc883_tagra_automute(struct hda_codec *codec)
6524{
6525 	unsigned int present;
6526	unsigned char bits;
6527
6528 	present = snd_hda_codec_read(codec, 0x14, 0,
6529				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6530	bits = present ? HDA_AMP_MUTE : 0;
6531	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6532				 HDA_AMP_MUTE, bits);
6533	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6534				  present ? 1 : 3);
6535}
6536
6537static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
6538{
6539	if ((res >> 26) == ALC880_HP_EVENT)
6540		alc883_tagra_automute(codec);
6541}
6542
6543static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
6544{
6545 	unsigned int present;
6546	unsigned char bits;
6547
6548 	present = snd_hda_codec_read(codec, 0x14, 0,
6549				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6550	bits = present ? HDA_AMP_MUTE : 0;
6551	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6552				 HDA_AMP_MUTE, bits);
6553}
6554
6555static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
6556{
6557 	unsigned int present;
6558	unsigned char bits;
6559
6560 	present = snd_hda_codec_read(codec, 0x1b, 0,
6561				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6562	bits = present ? HDA_AMP_MUTE : 0;
6563	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6564				 HDA_AMP_MUTE, bits);
6565	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6566				 HDA_AMP_MUTE, bits);
6567}
6568
6569static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
6570					   unsigned int res)
6571{
6572	if ((res >> 26) == ALC880_HP_EVENT)
6573		alc883_lenovo_101e_all_automute(codec);
6574	if ((res >> 26) == ALC880_FRONT_EVENT)
6575		alc883_lenovo_101e_ispeaker_automute(codec);
6576}
6577
6578/* toggle speaker-output according to the hp-jack state */
6579static void alc883_acer_aspire_automute(struct hda_codec *codec)
6580{
6581 	unsigned int present;
6582
6583 	present = snd_hda_codec_read(codec, 0x14, 0,
6584				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6585	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6586				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6587	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
6588				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6589}
6590
6591static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
6592					   unsigned int res)
6593{
6594	if ((res >> 26) == ALC880_HP_EVENT)
6595		alc883_acer_aspire_automute(codec);
6596}
6597
6598static struct hda_verb alc883_acer_eapd_verbs[] = {
6599	/* HP Pin: output 0 (0x0c) */
6600	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6601	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6602	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6603	/* Front Pin: output 0 (0x0c) */
6604	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6605	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6606	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6607	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
6608        /* eanable EAPD on medion laptop */
6609	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6610	{0x20, AC_VERB_SET_PROC_COEF, 0x3050},
6611	/* enable unsolicited event */
6612	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6613	{ }
6614};
6615
6616/*
6617 * generic initialization of ADC, input mixers and output mixers
6618 */
6619static struct hda_verb alc883_auto_init_verbs[] = {
6620	/*
6621	 * Unmute ADC0-2 and set the default input to mic-in
6622	 */
6623	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6624	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6625	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6626	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6627
6628	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6629	 * mixer widget
6630	 * Note: PASD motherboards uses the Line In 2 as the input for
6631	 * front panel mic (mic 2)
6632	 */
6633	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6634	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6635	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6636	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6637	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6638	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6639
6640	/*
6641	 * Set up output mixers (0x0c - 0x0f)
6642	 */
6643	/* set vol=0 to output mixers */
6644	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6645	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6646	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6647	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6648	/* set up input amps for analog loopback */
6649	/* Amp Indices: DAC = 0, mixer = 1 */
6650	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6651	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6652	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6653	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6654	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6655	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6656	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6657	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6658	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6659	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6660
6661	/* FIXME: use matrix-type input source selection */
6662	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6663	/* Input mixer1 */
6664	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6665	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6666	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6667	/* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
6668	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6669	/* Input mixer2 */
6670	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6671	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6672	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6673	/* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
6674	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6675
6676	{ }
6677};
6678
6679/* capture mixer elements */
6680static struct snd_kcontrol_new alc883_capture_mixer[] = {
6681	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6682	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6683	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6684	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6685	{
6686		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6687		/* The multiple "Capture Source" controls confuse alsamixer
6688		 * So call somewhat different..
6689		 * FIXME: the controls appear in the "playback" view!
6690		 */
6691		/* .name = "Capture Source", */
6692		.name = "Input Source",
6693		.count = 2,
6694		.info = alc882_mux_enum_info,
6695		.get = alc882_mux_enum_get,
6696		.put = alc882_mux_enum_put,
6697	},
6698	{ } /* end */
6699};
6700
6701#ifdef CONFIG_SND_HDA_POWER_SAVE
6702#define alc883_loopbacks	alc880_loopbacks
6703#endif
6704
6705/* pcm configuration: identiacal with ALC880 */
6706#define alc883_pcm_analog_playback	alc880_pcm_analog_playback
6707#define alc883_pcm_analog_capture	alc880_pcm_analog_capture
6708#define alc883_pcm_digital_playback	alc880_pcm_digital_playback
6709#define alc883_pcm_digital_capture	alc880_pcm_digital_capture
6710
6711/*
6712 * configuration and preset
6713 */
6714static const char *alc883_models[ALC883_MODEL_LAST] = {
6715	[ALC883_3ST_2ch_DIG]	= "3stack-dig",
6716	[ALC883_3ST_6ch_DIG]	= "3stack-6ch-dig",
6717	[ALC883_3ST_6ch]	= "3stack-6ch",
6718	[ALC883_6ST_DIG]	= "6stack-dig",
6719	[ALC883_TARGA_DIG]	= "targa-dig",
6720	[ALC883_TARGA_2ch_DIG]	= "targa-2ch-dig",
6721	[ALC883_ACER]		= "acer",
6722	[ALC883_ACER_ASPIRE]	= "acer-aspire",
6723	[ALC883_MEDION]		= "medion",
6724	[ALC883_MEDION_MD2]	= "medion-md2",
6725	[ALC883_LAPTOP_EAPD]	= "laptop-eapd",
6726	[ALC883_LENOVO_101E_2ch] = "lenovo-101e",
6727	[ALC883_LENOVO_NB0763]	= "lenovo-nb0763",
6728	[ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
6729	[ALC888_6ST_HP]		= "6stack-hp",
6730	[ALC888_3ST_HP]		= "3stack-hp",
6731	[ALC883_AUTO]		= "auto",
6732};
6733
6734static struct snd_pci_quirk alc883_cfg_tbl[] = {
6735	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
6736	SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
6737	SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
6738	SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
6739	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
6740	SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
6741	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
6742	SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
6743	SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
6744	SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
6745	SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
6746	SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
6747	SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
6748	SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
6749	SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
6750	SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
6751	SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
6752	SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
6753	SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
6754	SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
6755	SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
6756	SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
6757	SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
6758	SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
6759	SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
6760	SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
6761	SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER),
6762	SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
6763	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
6764	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
6765	SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
6766	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
6767	SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
6768	SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
6769	SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP),
6770	SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
6771	SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
6772	SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
6773	{}
6774};
6775
6776static struct alc_config_preset alc883_presets[] = {
6777	[ALC883_3ST_2ch_DIG] = {
6778		.mixers = { alc883_3ST_2ch_mixer },
6779		.init_verbs = { alc883_init_verbs },
6780		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6781		.dac_nids = alc883_dac_nids,
6782		.dig_out_nid = ALC883_DIGOUT_NID,
6783		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6784		.adc_nids = alc883_adc_nids,
6785		.dig_in_nid = ALC883_DIGIN_NID,
6786		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6787		.channel_mode = alc883_3ST_2ch_modes,
6788		.input_mux = &alc883_capture_source,
6789	},
6790	[ALC883_3ST_6ch_DIG] = {
6791		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6792		.init_verbs = { alc883_init_verbs },
6793		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6794		.dac_nids = alc883_dac_nids,
6795		.dig_out_nid = ALC883_DIGOUT_NID,
6796		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6797		.adc_nids = alc883_adc_nids,
6798		.dig_in_nid = ALC883_DIGIN_NID,
6799		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6800		.channel_mode = alc883_3ST_6ch_modes,
6801		.need_dac_fix = 1,
6802		.input_mux = &alc883_capture_source,
6803	},
6804	[ALC883_3ST_6ch] = {
6805		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6806		.init_verbs = { alc883_init_verbs },
6807		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6808		.dac_nids = alc883_dac_nids,
6809		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6810		.adc_nids = alc883_adc_nids,
6811		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6812		.channel_mode = alc883_3ST_6ch_modes,
6813		.need_dac_fix = 1,
6814		.input_mux = &alc883_capture_source,
6815	},
6816	[ALC883_6ST_DIG] = {
6817		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
6818		.init_verbs = { alc883_init_verbs },
6819		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6820		.dac_nids = alc883_dac_nids,
6821		.dig_out_nid = ALC883_DIGOUT_NID,
6822		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6823		.adc_nids = alc883_adc_nids,
6824		.dig_in_nid = ALC883_DIGIN_NID,
6825		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6826		.channel_mode = alc883_sixstack_modes,
6827		.input_mux = &alc883_capture_source,
6828	},
6829	[ALC883_TARGA_DIG] = {
6830		.mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
6831		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
6832		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6833		.dac_nids = alc883_dac_nids,
6834		.dig_out_nid = ALC883_DIGOUT_NID,
6835		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6836		.adc_nids = alc883_adc_nids,
6837		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6838		.channel_mode = alc883_3ST_6ch_modes,
6839		.need_dac_fix = 1,
6840		.input_mux = &alc883_capture_source,
6841		.unsol_event = alc883_tagra_unsol_event,
6842		.init_hook = alc883_tagra_automute,
6843	},
6844	[ALC883_TARGA_2ch_DIG] = {
6845		.mixers = { alc883_tagra_2ch_mixer},
6846		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
6847		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6848		.dac_nids = alc883_dac_nids,
6849		.dig_out_nid = ALC883_DIGOUT_NID,
6850		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6851		.adc_nids = alc883_adc_nids,
6852		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6853		.channel_mode = alc883_3ST_2ch_modes,
6854		.input_mux = &alc883_capture_source,
6855		.unsol_event = alc883_tagra_unsol_event,
6856		.init_hook = alc883_tagra_automute,
6857	},
6858	[ALC883_ACER] = {
6859		.mixers = { alc883_base_mixer },
6860		/* On TravelMate laptops, GPIO 0 enables the internal speaker
6861		 * and the headphone jack.  Turn this on and rely on the
6862		 * standard mute methods whenever the user wants to turn
6863		 * these outputs off.
6864		 */
6865		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
6866		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6867		.dac_nids = alc883_dac_nids,
6868		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6869		.adc_nids = alc883_adc_nids,
6870		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6871		.channel_mode = alc883_3ST_2ch_modes,
6872		.input_mux = &alc883_capture_source,
6873	},
6874	[ALC883_ACER_ASPIRE] = {
6875		.mixers = { alc883_acer_aspire_mixer },
6876		.init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
6877		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6878		.dac_nids = alc883_dac_nids,
6879		.dig_out_nid = ALC883_DIGOUT_NID,
6880		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6881		.adc_nids = alc883_adc_nids,
6882		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6883		.channel_mode = alc883_3ST_2ch_modes,
6884		.input_mux = &alc883_capture_source,
6885		.unsol_event = alc883_acer_aspire_unsol_event,
6886		.init_hook = alc883_acer_aspire_automute,
6887	},
6888	[ALC883_MEDION] = {
6889		.mixers = { alc883_fivestack_mixer,
6890			    alc883_chmode_mixer },
6891		.init_verbs = { alc883_init_verbs,
6892				alc883_medion_eapd_verbs },
6893		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6894		.dac_nids = alc883_dac_nids,
6895		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6896		.adc_nids = alc883_adc_nids,
6897		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6898		.channel_mode = alc883_sixstack_modes,
6899		.input_mux = &alc883_capture_source,
6900	},
6901	[ALC883_MEDION_MD2] = {
6902		.mixers = { alc883_medion_md2_mixer},
6903		.init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
6904		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6905		.dac_nids = alc883_dac_nids,
6906		.dig_out_nid = ALC883_DIGOUT_NID,
6907		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6908		.adc_nids = alc883_adc_nids,
6909		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6910		.channel_mode = alc883_3ST_2ch_modes,
6911		.input_mux = &alc883_capture_source,
6912		.unsol_event = alc883_medion_md2_unsol_event,
6913		.init_hook = alc883_medion_md2_automute,
6914	},
6915	[ALC883_LAPTOP_EAPD] = {
6916		.mixers = { alc883_base_mixer },
6917		.init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
6918		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6919		.dac_nids = alc883_dac_nids,
6920		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6921		.adc_nids = alc883_adc_nids,
6922		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6923		.channel_mode = alc883_3ST_2ch_modes,
6924		.input_mux = &alc883_capture_source,
6925	},
6926	[ALC883_LENOVO_101E_2ch] = {
6927		.mixers = { alc883_lenovo_101e_2ch_mixer},
6928		.init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
6929		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6930		.dac_nids = alc883_dac_nids,
6931		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6932		.adc_nids = alc883_adc_nids,
6933		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6934		.channel_mode = alc883_3ST_2ch_modes,
6935		.input_mux = &alc883_lenovo_101e_capture_source,
6936		.unsol_event = alc883_lenovo_101e_unsol_event,
6937		.init_hook = alc883_lenovo_101e_all_automute,
6938	},
6939	[ALC883_LENOVO_NB0763] = {
6940		.mixers = { alc883_lenovo_nb0763_mixer },
6941		.init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
6942		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6943		.dac_nids = alc883_dac_nids,
6944		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6945		.adc_nids = alc883_adc_nids,
6946		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6947		.channel_mode = alc883_3ST_2ch_modes,
6948		.need_dac_fix = 1,
6949		.input_mux = &alc883_lenovo_nb0763_capture_source,
6950		.unsol_event = alc883_medion_md2_unsol_event,
6951		.init_hook = alc883_medion_md2_automute,
6952	},
6953	[ALC888_LENOVO_MS7195_DIG] = {
6954		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6955		.init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
6956		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6957		.dac_nids = alc883_dac_nids,
6958		.dig_out_nid = ALC883_DIGOUT_NID,
6959		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6960		.adc_nids = alc883_adc_nids,
6961		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6962		.channel_mode = alc883_3ST_6ch_modes,
6963		.need_dac_fix = 1,
6964		.input_mux = &alc883_capture_source,
6965		.unsol_event = alc883_lenovo_ms7195_unsol_event,
6966		.init_hook = alc888_lenovo_ms7195_front_automute,
6967	},
6968	[ALC888_6ST_HP] = {
6969		.mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer },
6970		.init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs },
6971		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6972		.dac_nids = alc883_dac_nids,
6973		.dig_out_nid = ALC883_DIGOUT_NID,
6974		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6975		.adc_nids = alc883_adc_nids,
6976		.dig_in_nid = ALC883_DIGIN_NID,
6977		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6978		.channel_mode = alc883_sixstack_modes,
6979		.input_mux = &alc883_capture_source,
6980	},
6981	[ALC888_3ST_HP] = {
6982		.mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer },
6983		.init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
6984		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6985		.dac_nids = alc883_dac_nids,
6986		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6987		.adc_nids = alc883_adc_nids,
6988		.num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
6989		.channel_mode = alc888_3st_hp_modes,
6990		.need_dac_fix = 1,
6991		.input_mux = &alc883_capture_source,
6992	},
6993};
6994
6995
6996/*
6997 * BIOS auto configuration
6998 */
6999static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
7000					      hda_nid_t nid, int pin_type,
7001					      int dac_idx)
7002{
7003	/* set as output */
7004	struct alc_spec *spec = codec->spec;
7005	int idx;
7006
7007	if (spec->multiout.dac_nids[dac_idx] == 0x25)
7008		idx = 4;
7009	else
7010		idx = spec->multiout.dac_nids[dac_idx] - 2;
7011
7012	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
7013			    pin_type);
7014	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7015			    AMP_OUT_UNMUTE);
7016	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7017
7018}
7019
7020static void alc883_auto_init_multi_out(struct hda_codec *codec)
7021{
7022	struct alc_spec *spec = codec->spec;
7023	int i;
7024
7025	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
7026	for (i = 0; i <= HDA_SIDE; i++) {
7027		hda_nid_t nid = spec->autocfg.line_out_pins[i];
7028		int pin_type = get_pin_type(spec->autocfg.line_out_type);
7029		if (nid)
7030			alc883_auto_set_output_and_unmute(codec, nid, pin_type,
7031							  i);
7032	}
7033}
7034
7035static void alc883_auto_init_hp_out(struct hda_codec *codec)
7036{
7037	struct alc_spec *spec = codec->spec;
7038	hda_nid_t pin;
7039
7040	pin = spec->autocfg.hp_pins[0];
7041	if (pin) /* connect to front */
7042		/* use dac 0 */
7043		alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7044}
7045
7046#define alc883_is_input_pin(nid)	alc880_is_input_pin(nid)
7047#define ALC883_PIN_CD_NID		ALC880_PIN_CD_NID
7048
7049static void alc883_auto_init_analog_input(struct hda_codec *codec)
7050{
7051	struct alc_spec *spec = codec->spec;
7052	int i;
7053
7054	for (i = 0; i < AUTO_PIN_LAST; i++) {
7055		hda_nid_t nid = spec->autocfg.input_pins[i];
7056		if (alc883_is_input_pin(nid)) {
7057			snd_hda_codec_write(codec, nid, 0,
7058					    AC_VERB_SET_PIN_WIDGET_CONTROL,
7059					    (i <= AUTO_PIN_FRONT_MIC ?
7060					     PIN_VREF80 : PIN_IN));
7061			if (nid != ALC883_PIN_CD_NID)
7062				snd_hda_codec_write(codec, nid, 0,
7063						    AC_VERB_SET_AMP_GAIN_MUTE,
7064						    AMP_OUT_MUTE);
7065		}
7066	}
7067}
7068
7069/* almost identical with ALC880 parser... */
7070static int alc883_parse_auto_config(struct hda_codec *codec)
7071{
7072	struct alc_spec *spec = codec->spec;
7073	int err = alc880_parse_auto_config(codec);
7074
7075	if (err < 0)
7076		return err;
7077	else if (err > 0)
7078		/* hack - override the init verbs */
7079		spec->init_verbs[0] = alc883_auto_init_verbs;
7080	spec->mixers[spec->num_mixers] = alc883_capture_mixer;
7081	spec->num_mixers++;
7082	return err;
7083}
7084
7085/* additional initialization for auto-configuration model */
7086static void alc883_auto_init(struct hda_codec *codec)
7087{
7088	alc883_auto_init_multi_out(codec);
7089	alc883_auto_init_hp_out(codec);
7090	alc883_auto_init_analog_input(codec);
7091}
7092
7093static int patch_alc883(struct hda_codec *codec)
7094{
7095	struct alc_spec *spec;
7096	int err, board_config;
7097
7098	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7099	if (spec == NULL)
7100		return -ENOMEM;
7101
7102	codec->spec = spec;
7103
7104	board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
7105						  alc883_models,
7106						  alc883_cfg_tbl);
7107	if (board_config < 0) {
7108		printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
7109		       "trying auto-probe from BIOS...\n");
7110		board_config = ALC883_AUTO;
7111	}
7112
7113	if (board_config == ALC883_AUTO) {
7114		/* automatic parse from the BIOS config */
7115		err = alc883_parse_auto_config(codec);
7116		if (err < 0) {
7117			alc_free(codec);
7118			return err;
7119		} else if (!err) {
7120			printk(KERN_INFO
7121			       "hda_codec: Cannot set up configuration "
7122			       "from BIOS.  Using base mode...\n");
7123			board_config = ALC883_3ST_2ch_DIG;
7124		}
7125	}
7126
7127	if (board_config != ALC883_AUTO)
7128		setup_preset(spec, &alc883_presets[board_config]);
7129
7130	spec->stream_name_analog = "ALC883 Analog";
7131	spec->stream_analog_playback = &alc883_pcm_analog_playback;
7132	spec->stream_analog_capture = &alc883_pcm_analog_capture;
7133
7134	spec->stream_name_digital = "ALC883 Digital";
7135	spec->stream_digital_playback = &alc883_pcm_digital_playback;
7136	spec->stream_digital_capture = &alc883_pcm_digital_capture;
7137
7138	if (!spec->adc_nids && spec->input_mux) {
7139		spec->adc_nids = alc883_adc_nids;
7140		spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
7141	}
7142
7143	codec->patch_ops = alc_patch_ops;
7144	if (board_config == ALC883_AUTO)
7145		spec->init_hook = alc883_auto_init;
7146#ifdef CONFIG_SND_HDA_POWER_SAVE
7147	if (!spec->loopback.amplist)
7148		spec->loopback.amplist = alc883_loopbacks;
7149#endif
7150
7151	return 0;
7152}
7153
7154/*
7155 * ALC262 support
7156 */
7157
7158#define ALC262_DIGOUT_NID	ALC880_DIGOUT_NID
7159#define ALC262_DIGIN_NID	ALC880_DIGIN_NID
7160
7161#define alc262_dac_nids		alc260_dac_nids
7162#define alc262_adc_nids		alc882_adc_nids
7163#define alc262_adc_nids_alt	alc882_adc_nids_alt
7164
7165#define alc262_modes		alc260_modes
7166#define alc262_capture_source	alc882_capture_source
7167
7168static struct snd_kcontrol_new alc262_base_mixer[] = {
7169	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7170	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7171	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7172	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7173	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7174	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7175	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7176	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7177	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7178	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7179	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7180	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7181	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7182	   HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7183	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
7184	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7185	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7186	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7187	{ } /* end */
7188};
7189
7190static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
7191	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7192	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7193	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7194	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7195	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7196	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7197	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7198	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7199	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7200	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7201	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7202	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7203	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7204	   HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7205	/*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
7206	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7207	{ } /* end */
7208};
7209
7210static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
7211	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7212	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7213	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7214	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7215	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7216
7217	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7218	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7219	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7220	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7221	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7222	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7223	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7224	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7225	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7226	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7227	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7228	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7229	HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
7230	HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
7231	{ } /* end */
7232};
7233
7234static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
7235	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7236	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7237	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7238	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7239	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7240	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7241	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
7242	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
7243	HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
7244	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7245	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7246	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7247	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7248	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7249	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7250	{ } /* end */
7251};
7252
7253static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
7254	HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7255	HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7256	HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
7257	{ } /* end */
7258};
7259
7260static struct hda_bind_ctls alc262_sony_bind_sw = {
7261	.ops = &snd_hda_bind_sw,
7262	.values = {
7263		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
7264		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
7265		0,
7266	},
7267};
7268
7269static struct snd_kcontrol_new alc262_sony_mixer[] = {
7270	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7271	HDA_BIND_SW("Front Playback Switch", &alc262_sony_bind_sw),
7272	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7273	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7274	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7275	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7276	{ } /* end */
7277};
7278
7279static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
7280	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7281	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7282	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7283	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7284	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7285	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7286	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7287	{ } /* end */
7288};
7289
7290#define alc262_capture_mixer		alc882_capture_mixer
7291#define alc262_capture_alt_mixer	alc882_capture_alt_mixer
7292
7293/*
7294 * generic initialization of ADC, input mixers and output mixers
7295 */
7296static struct hda_verb alc262_init_verbs[] = {
7297	/*
7298	 * Unmute ADC0-2 and set the default input to mic-in
7299	 */
7300	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7301	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7302	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7303	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7304	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7305	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7306
7307	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7308	 * mixer widget
7309	 * Note: PASD motherboards uses the Line In 2 as the input for
7310	 * front panel mic (mic 2)
7311	 */
7312	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7313	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7314	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7315	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7316	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7317	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7318
7319	/*
7320	 * Set up output mixers (0x0c - 0x0e)
7321	 */
7322	/* set vol=0 to output mixers */
7323	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7324	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7325	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7326	/* set up input amps for analog loopback */
7327	/* Amp Indices: DAC = 0, mixer = 1 */
7328	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7329	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7330	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7331	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7332	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7333	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7334
7335	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7336	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7337	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7338	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7339	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7340	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7341
7342	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7343	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7344	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7345	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7346	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7347
7348	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7349	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7350
7351	/* FIXME: use matrix-type input source selection */
7352	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7353	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7354	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7355	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7356	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7357	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7358	/* Input mixer2 */
7359	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7360	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7361	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7362	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7363	/* Input mixer3 */
7364	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7365	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7366	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7367	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7368
7369	{ }
7370};
7371
7372static struct hda_verb alc262_hippo_unsol_verbs[] = {
7373	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7374	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7375	{}
7376};
7377
7378static struct hda_verb alc262_hippo1_unsol_verbs[] = {
7379	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7380	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7381	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7382
7383	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7384	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7385	{}
7386};
7387
7388static struct hda_verb alc262_sony_unsol_verbs[] = {
7389	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7390	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7391	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},	// Front Mic
7392
7393	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7394	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7395};
7396
7397/* mute/unmute internal speaker according to the hp jack and mute state */
7398static void alc262_hippo_automute(struct hda_codec *codec)
7399{
7400	struct alc_spec *spec = codec->spec;
7401	unsigned int mute;
7402	unsigned int present;
7403
7404	/* need to execute and sync at first */
7405	snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
7406	present = snd_hda_codec_read(codec, 0x15, 0,
7407				     AC_VERB_GET_PIN_SENSE, 0);
7408	spec->jack_present = (present & 0x80000000) != 0;
7409	if (spec->jack_present) {
7410		/* mute internal speaker */
7411		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7412					 HDA_AMP_MUTE, HDA_AMP_MUTE);
7413	} else {
7414		/* unmute internal speaker if necessary */
7415		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
7416		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7417					 HDA_AMP_MUTE, mute);
7418	}
7419}
7420
7421/* unsolicited event for HP jack sensing */
7422static void alc262_hippo_unsol_event(struct hda_codec *codec,
7423				       unsigned int res)
7424{
7425	if ((res >> 26) != ALC880_HP_EVENT)
7426		return;
7427	alc262_hippo_automute(codec);
7428}
7429
7430static void alc262_hippo1_automute(struct hda_codec *codec)
7431{
7432	unsigned int mute;
7433	unsigned int present;
7434
7435	snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
7436	present = snd_hda_codec_read(codec, 0x1b, 0,
7437				     AC_VERB_GET_PIN_SENSE, 0);
7438	present = (present & 0x80000000) != 0;
7439	if (present) {
7440		/* mute internal speaker */
7441		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7442					 HDA_AMP_MUTE, HDA_AMP_MUTE);
7443	} else {
7444		/* unmute internal speaker if necessary */
7445		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
7446		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7447					 HDA_AMP_MUTE, mute);
7448	}
7449}
7450
7451/* unsolicited event for HP jack sensing */
7452static void alc262_hippo1_unsol_event(struct hda_codec *codec,
7453				       unsigned int res)
7454{
7455	if ((res >> 26) != ALC880_HP_EVENT)
7456		return;
7457	alc262_hippo1_automute(codec);
7458}
7459
7460/*
7461 * fujitsu model
7462 *  0x14 = headphone/spdif-out, 0x15 = internal speaker
7463 */
7464
7465#define ALC_HP_EVENT	0x37
7466
7467static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
7468	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
7469	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7470	{}
7471};
7472
7473static struct hda_input_mux alc262_fujitsu_capture_source = {
7474	.num_items = 2,
7475	.items = {
7476		{ "Mic", 0x0 },
7477		{ "CD", 0x4 },
7478	},
7479};
7480
7481static struct hda_input_mux alc262_HP_capture_source = {
7482	.num_items = 5,
7483	.items = {
7484		{ "Mic", 0x0 },
7485		{ "Front Mic", 0x3 },
7486		{ "Line", 0x2 },
7487		{ "CD", 0x4 },
7488		{ "AUX IN", 0x6 },
7489	},
7490};
7491
7492/* mute/unmute internal speaker according to the hp jack and mute state */
7493static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
7494{
7495	struct alc_spec *spec = codec->spec;
7496	unsigned int mute;
7497
7498	if (force || !spec->sense_updated) {
7499		unsigned int present;
7500		/* need to execute and sync at first */
7501		snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
7502		present = snd_hda_codec_read(codec, 0x14, 0,
7503				    	 AC_VERB_GET_PIN_SENSE, 0);
7504		spec->jack_present = (present & 0x80000000) != 0;
7505		spec->sense_updated = 1;
7506	}
7507	if (spec->jack_present) {
7508		/* mute internal speaker */
7509		snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7510					 HDA_AMP_MUTE, HDA_AMP_MUTE);
7511	} else {
7512		/* unmute internal speaker if necessary */
7513		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
7514		snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7515					 HDA_AMP_MUTE, mute);
7516	}
7517}
7518
7519/* unsolicited event for HP jack sensing */
7520static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
7521				       unsigned int res)
7522{
7523	if ((res >> 26) != ALC_HP_EVENT)
7524		return;
7525	alc262_fujitsu_automute(codec, 1);
7526}
7527
7528/* bind volumes of both NID 0x0c and 0x0d */
7529static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
7530	.ops = &snd_hda_bind_vol,
7531	.values = {
7532		HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
7533		HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
7534		0
7535	},
7536};
7537
7538/* bind hp and internal speaker mute (with plug check) */
7539static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
7540					 struct snd_ctl_elem_value *ucontrol)
7541{
7542	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7543	long *valp = ucontrol->value.integer.value;
7544	int change;
7545
7546	change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7547					  HDA_AMP_MUTE,
7548					  valp[0] ? 0 : HDA_AMP_MUTE);
7549	change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7550					   HDA_AMP_MUTE,
7551					   valp[1] ? 0 : HDA_AMP_MUTE);
7552	if (change)
7553		alc262_fujitsu_automute(codec, 0);
7554	return change;
7555}
7556
7557static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
7558	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
7559	{
7560		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7561		.name = "Master Playback Switch",
7562		.info = snd_hda_mixer_amp_switch_info,
7563		.get = snd_hda_mixer_amp_switch_get,
7564		.put = alc262_fujitsu_master_sw_put,
7565		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
7566	},
7567	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7568	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7569	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7570	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7571	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7572	{ } /* end */
7573};
7574
7575/* additional init verbs for Benq laptops */
7576static struct hda_verb alc262_EAPD_verbs[] = {
7577	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7578	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
7579	{}
7580};
7581
7582static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
7583	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7584	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7585
7586	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7587	{0x20, AC_VERB_SET_PROC_COEF,  0x3050},
7588	{}
7589};
7590
7591/* add playback controls from the parsed DAC table */
7592static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
7593					     const struct auto_pin_cfg *cfg)
7594{
7595	hda_nid_t nid;
7596	int err;
7597
7598	spec->multiout.num_dacs = 1;	/* only use one dac */
7599	spec->multiout.dac_nids = spec->private_dac_nids;
7600	spec->multiout.dac_nids[0] = 2;
7601
7602	nid = cfg->line_out_pins[0];
7603	if (nid) {
7604		err = add_control(spec, ALC_CTL_WIDGET_VOL,
7605				  "Front Playback Volume",
7606				  HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
7607		if (err < 0)
7608			return err;
7609		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7610				  "Front Playback Switch",
7611				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
7612		if (err < 0)
7613			return err;
7614	}
7615
7616	nid = cfg->speaker_pins[0];
7617	if (nid) {
7618		if (nid == 0x16) {
7619			err = add_control(spec, ALC_CTL_WIDGET_VOL,
7620					  "Speaker Playback Volume",
7621					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
7622							      HDA_OUTPUT));
7623			if (err < 0)
7624				return err;
7625			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7626					  "Speaker Playback Switch",
7627					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
7628							      HDA_OUTPUT));
7629			if (err < 0)
7630				return err;
7631		} else {
7632			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7633					  "Speaker Playback Switch",
7634					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
7635							      HDA_OUTPUT));
7636			if (err < 0)
7637				return err;
7638		}
7639	}
7640	nid = cfg->hp_pins[0];
7641	if (nid) {
7642		/* spec->multiout.hp_nid = 2; */
7643		if (nid == 0x16) {
7644			err = add_control(spec, ALC_CTL_WIDGET_VOL,
7645					  "Headphone Playback Volume",
7646					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
7647							      HDA_OUTPUT));
7648			if (err < 0)
7649				return err;
7650			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7651					  "Headphone Playback Switch",
7652					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
7653							      HDA_OUTPUT));
7654			if (err < 0)
7655				return err;
7656		} else {
7657			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7658					  "Headphone Playback Switch",
7659					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
7660							      HDA_OUTPUT));
7661			if (err < 0)
7662				return err;
7663		}
7664	}
7665	return 0;
7666}
7667
7668/* identical with ALC880 */
7669#define alc262_auto_create_analog_input_ctls \
7670	alc880_auto_create_analog_input_ctls
7671
7672/*
7673 * generic initialization of ADC, input mixers and output mixers
7674 */
7675static struct hda_verb alc262_volume_init_verbs[] = {
7676	/*
7677	 * Unmute ADC0-2 and set the default input to mic-in
7678	 */
7679	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7680	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7681	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7682	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7683	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7684	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7685
7686	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7687	 * mixer widget
7688	 * Note: PASD motherboards uses the Line In 2 as the input for
7689	 * front panel mic (mic 2)
7690	 */
7691	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7692	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7693	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7694	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7695	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7696	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7697
7698	/*
7699	 * Set up output mixers (0x0c - 0x0f)
7700	 */
7701	/* set vol=0 to output mixers */
7702	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7703	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7704	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7705
7706	/* set up input amps for analog loopback */
7707	/* Amp Indices: DAC = 0, mixer = 1 */
7708	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7709	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7710	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7711	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7712	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7713	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7714
7715	/* FIXME: use matrix-type input source selection */
7716	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7717	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7718	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7719	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7720	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7721	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7722	/* Input mixer2 */
7723	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7724	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7725	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7726	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7727	/* Input mixer3 */
7728	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7729	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7730	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7731	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7732
7733	{ }
7734};
7735
7736static struct hda_verb alc262_HP_BPC_init_verbs[] = {
7737	/*
7738	 * Unmute ADC0-2 and set the default input to mic-in
7739	 */
7740	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7741	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7742	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7743	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7744	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7745	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7746
7747	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7748	 * mixer widget
7749	 * Note: PASD motherboards uses the Line In 2 as the input for
7750	 * front panel mic (mic 2)
7751	 */
7752	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7753	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7754	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7755	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7756	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7757	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7758	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
7759        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
7760
7761	/*
7762	 * Set up output mixers (0x0c - 0x0e)
7763	 */
7764	/* set vol=0 to output mixers */
7765	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7766	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7767	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7768
7769	/* set up input amps for analog loopback */
7770	/* Amp Indices: DAC = 0, mixer = 1 */
7771	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7772	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7773	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7774	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7775	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7776	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7777
7778	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7779	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7780	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7781
7782	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7783	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7784
7785	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7786	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7787
7788	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7789	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7790        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7791	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7792	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7793
7794	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7795	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7796        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7797	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7798	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7799	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7800
7801
7802	/* FIXME: use matrix-type input source selection */
7803	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7804	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7805	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7806	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7807	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7808	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7809	/* Input mixer2 */
7810	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7811	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7812	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7813	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7814	/* Input mixer3 */
7815	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7816	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7817	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7818	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7819
7820	{ }
7821};
7822
7823static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
7824	/*
7825	 * Unmute ADC0-2 and set the default input to mic-in
7826	 */
7827	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7828	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7829	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7830	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7831	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7832	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7833
7834	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7835	 * mixer widget
7836	 * Note: PASD motherboards uses the Line In 2 as the input for front
7837	 * panel mic (mic 2)
7838	 */
7839	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7840	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7841	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7842	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7843	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7844	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7845	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
7846	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
7847	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
7848	/*
7849	 * Set up output mixers (0x0c - 0x0e)
7850	 */
7851	/* set vol=0 to output mixers */
7852	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7853	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7854	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7855
7856	/* set up input amps for analog loopback */
7857	/* Amp Indices: DAC = 0, mixer = 1 */
7858	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7859	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7860	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7861	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7862	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7863	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7864
7865
7866	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },	/* HP */
7867	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Mono */
7868	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* rear MIC */
7869	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* Line in */
7870	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* Front MIC */
7871	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Line out */
7872	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* CD in */
7873
7874	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7875	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7876
7877	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7878	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7879
7880	/* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
7881	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7882	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7883	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7884	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7885	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7886
7887	/* FIXME: use matrix-type input source selection */
7888	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7889	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7890	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
7891	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
7892	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
7893	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
7894	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
7895        /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
7896	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
7897	/* Input mixer2 */
7898	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7899	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
7900	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7901	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7902	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7903        /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
7904	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
7905	/* Input mixer3 */
7906	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7907	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
7908	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7909	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7910	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7911        /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
7912	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
7913
7914	{ }
7915};
7916
7917#ifdef CONFIG_SND_HDA_POWER_SAVE
7918#define alc262_loopbacks	alc880_loopbacks
7919#endif
7920
7921/* pcm configuration: identiacal with ALC880 */
7922#define alc262_pcm_analog_playback	alc880_pcm_analog_playback
7923#define alc262_pcm_analog_capture	alc880_pcm_analog_capture
7924#define alc262_pcm_digital_playback	alc880_pcm_digital_playback
7925#define alc262_pcm_digital_capture	alc880_pcm_digital_capture
7926
7927/*
7928 * BIOS auto configuration
7929 */
7930static int alc262_parse_auto_config(struct hda_codec *codec)
7931{
7932	struct alc_spec *spec = codec->spec;
7933	int err;
7934	static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
7935
7936	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7937					   alc262_ignore);
7938	if (err < 0)
7939		return err;
7940	if (!spec->autocfg.line_outs)
7941		return 0; /* can't find valid BIOS pin config */
7942	err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
7943	if (err < 0)
7944		return err;
7945	err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
7946	if (err < 0)
7947		return err;
7948
7949	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
7950
7951	if (spec->autocfg.dig_out_pin)
7952		spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
7953	if (spec->autocfg.dig_in_pin)
7954		spec->dig_in_nid = ALC262_DIGIN_NID;
7955
7956	if (spec->kctl_alloc)
7957		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
7958
7959	spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
7960	spec->num_mux_defs = 1;
7961	spec->input_mux = &spec->private_imux;
7962
7963	return 1;
7964}
7965
7966#define alc262_auto_init_multi_out	alc882_auto_init_multi_out
7967#define alc262_auto_init_hp_out		alc882_auto_init_hp_out
7968#define alc262_auto_init_analog_input	alc882_auto_init_analog_input
7969
7970
7971/* init callback for auto-configuration model -- overriding the default init */
7972static void alc262_auto_init(struct hda_codec *codec)
7973{
7974	alc262_auto_init_multi_out(codec);
7975	alc262_auto_init_hp_out(codec);
7976	alc262_auto_init_analog_input(codec);
7977}
7978
7979/*
7980 * configuration and preset
7981 */
7982static const char *alc262_models[ALC262_MODEL_LAST] = {
7983	[ALC262_BASIC]		= "basic",
7984	[ALC262_HIPPO]		= "hippo",
7985	[ALC262_HIPPO_1]	= "hippo_1",
7986	[ALC262_FUJITSU]	= "fujitsu",
7987	[ALC262_HP_BPC]		= "hp-bpc",
7988	[ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
7989	[ALC262_BENQ_ED8]	= "benq",
7990	[ALC262_BENQ_T31]	= "benq-t31",
7991	[ALC262_SONY_ASSAMD]	= "sony-assamd",
7992	[ALC262_AUTO]		= "auto",
7993};
7994
7995static struct snd_pci_quirk alc262_cfg_tbl[] = {
7996	SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
7997	SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
7998	SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
7999	SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
8000	SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
8001	SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
8002	SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
8003	SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
8004	SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
8005	SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
8006	SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
8007	SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
8008	SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
8009	SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
8010	SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
8011	SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
8012	SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
8013	SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
8014	SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
8015	SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
8016	SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
8017	SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
8018	SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8019	SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
8020	SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8021	SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8022	{}
8023};
8024
8025static struct alc_config_preset alc262_presets[] = {
8026	[ALC262_BASIC] = {
8027		.mixers = { alc262_base_mixer },
8028		.init_verbs = { alc262_init_verbs },
8029		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8030		.dac_nids = alc262_dac_nids,
8031		.hp_nid = 0x03,
8032		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8033		.channel_mode = alc262_modes,
8034		.input_mux = &alc262_capture_source,
8035	},
8036	[ALC262_HIPPO] = {
8037		.mixers = { alc262_base_mixer },
8038		.init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
8039		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8040		.dac_nids = alc262_dac_nids,
8041		.hp_nid = 0x03,
8042		.dig_out_nid = ALC262_DIGOUT_NID,
8043		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8044		.channel_mode = alc262_modes,
8045		.input_mux = &alc262_capture_source,
8046		.unsol_event = alc262_hippo_unsol_event,
8047		.init_hook = alc262_hippo_automute,
8048	},
8049	[ALC262_HIPPO_1] = {
8050		.mixers = { alc262_hippo1_mixer },
8051		.init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
8052		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8053		.dac_nids = alc262_dac_nids,
8054		.hp_nid = 0x02,
8055		.dig_out_nid = ALC262_DIGOUT_NID,
8056		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8057		.channel_mode = alc262_modes,
8058		.input_mux = &alc262_capture_source,
8059		.unsol_event = alc262_hippo1_unsol_event,
8060		.init_hook = alc262_hippo1_automute,
8061	},
8062	[ALC262_FUJITSU] = {
8063		.mixers = { alc262_fujitsu_mixer },
8064		.init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs },
8065		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8066		.dac_nids = alc262_dac_nids,
8067		.hp_nid = 0x03,
8068		.dig_out_nid = ALC262_DIGOUT_NID,
8069		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8070		.channel_mode = alc262_modes,
8071		.input_mux = &alc262_fujitsu_capture_source,
8072		.unsol_event = alc262_fujitsu_unsol_event,
8073	},
8074	[ALC262_HP_BPC] = {
8075		.mixers = { alc262_HP_BPC_mixer },
8076		.init_verbs = { alc262_HP_BPC_init_verbs },
8077		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8078		.dac_nids = alc262_dac_nids,
8079		.hp_nid = 0x03,
8080		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8081		.channel_mode = alc262_modes,
8082		.input_mux = &alc262_HP_capture_source,
8083	},
8084	[ALC262_HP_BPC_D7000_WF] = {
8085		.mixers = { alc262_HP_BPC_WildWest_mixer },
8086		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8087		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8088		.dac_nids = alc262_dac_nids,
8089		.hp_nid = 0x03,
8090		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8091		.channel_mode = alc262_modes,
8092		.input_mux = &alc262_HP_capture_source,
8093	},
8094	[ALC262_HP_BPC_D7000_WL] = {
8095		.mixers = { alc262_HP_BPC_WildWest_mixer,
8096			    alc262_HP_BPC_WildWest_option_mixer },
8097		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8098		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8099		.dac_nids = alc262_dac_nids,
8100		.hp_nid = 0x03,
8101		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8102		.channel_mode = alc262_modes,
8103		.input_mux = &alc262_HP_capture_source,
8104	},
8105	[ALC262_BENQ_ED8] = {
8106		.mixers = { alc262_base_mixer },
8107		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
8108		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8109		.dac_nids = alc262_dac_nids,
8110		.hp_nid = 0x03,
8111		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8112		.channel_mode = alc262_modes,
8113		.input_mux = &alc262_capture_source,
8114	},
8115	[ALC262_SONY_ASSAMD] = {
8116		.mixers = { alc262_sony_mixer },
8117		.init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
8118		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8119		.dac_nids = alc262_dac_nids,
8120		.hp_nid = 0x02,
8121		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8122		.channel_mode = alc262_modes,
8123		.input_mux = &alc262_capture_source,
8124		.unsol_event = alc262_hippo_unsol_event,
8125		.init_hook = alc262_hippo_automute,
8126	},
8127	[ALC262_BENQ_T31] = {
8128		.mixers = { alc262_benq_t31_mixer },
8129		.init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
8130		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8131		.dac_nids = alc262_dac_nids,
8132		.hp_nid = 0x03,
8133		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8134		.channel_mode = alc262_modes,
8135		.input_mux = &alc262_capture_source,
8136		.unsol_event = alc262_hippo_unsol_event,
8137		.init_hook = alc262_hippo_automute,
8138	},
8139};
8140
8141static int patch_alc262(struct hda_codec *codec)
8142{
8143	struct alc_spec *spec;
8144	int board_config;
8145	int err;
8146
8147	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8148	if (spec == NULL)
8149		return -ENOMEM;
8150
8151	codec->spec = spec;
8152#if 0
8153	/* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
8154	 * under-run
8155	 */
8156	{
8157	int tmp;
8158	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8159	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
8160	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8161	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
8162	}
8163#endif
8164
8165	board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
8166						  alc262_models,
8167						  alc262_cfg_tbl);
8168
8169	if (board_config < 0) {
8170		printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
8171		       "trying auto-probe from BIOS...\n");
8172		board_config = ALC262_AUTO;
8173	}
8174
8175	if (board_config == ALC262_AUTO) {
8176		/* automatic parse from the BIOS config */
8177		err = alc262_parse_auto_config(codec);
8178		if (err < 0) {
8179			alc_free(codec);
8180			return err;
8181		} else if (!err) {
8182			printk(KERN_INFO
8183			       "hda_codec: Cannot set up configuration "
8184			       "from BIOS.  Using base mode...\n");
8185			board_config = ALC262_BASIC;
8186		}
8187	}
8188
8189	if (board_config != ALC262_AUTO)
8190		setup_preset(spec, &alc262_presets[board_config]);
8191
8192	spec->stream_name_analog = "ALC262 Analog";
8193	spec->stream_analog_playback = &alc262_pcm_analog_playback;
8194	spec->stream_analog_capture = &alc262_pcm_analog_capture;
8195
8196	spec->stream_name_digital = "ALC262 Digital";
8197	spec->stream_digital_playback = &alc262_pcm_digital_playback;
8198	spec->stream_digital_capture = &alc262_pcm_digital_capture;
8199
8200	if (!spec->adc_nids && spec->input_mux) {
8201		/* check whether NID 0x07 is valid */
8202		unsigned int wcap = get_wcaps(codec, 0x07);
8203
8204		/* get type */
8205		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
8206		if (wcap != AC_WID_AUD_IN) {
8207			spec->adc_nids = alc262_adc_nids_alt;
8208			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
8209			spec->mixers[spec->num_mixers] =
8210				alc262_capture_alt_mixer;
8211			spec->num_mixers++;
8212		} else {
8213			spec->adc_nids = alc262_adc_nids;
8214			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
8215			spec->mixers[spec->num_mixers] = alc262_capture_mixer;
8216			spec->num_mixers++;
8217		}
8218	}
8219
8220	codec->patch_ops = alc_patch_ops;
8221	if (board_config == ALC262_AUTO)
8222		spec->init_hook = alc262_auto_init;
8223#ifdef CONFIG_SND_HDA_POWER_SAVE
8224	if (!spec->loopback.amplist)
8225		spec->loopback.amplist = alc262_loopbacks;
8226#endif
8227
8228	return 0;
8229}
8230
8231/*
8232 *  ALC268 channel source setting (2 channel)
8233 */
8234#define ALC268_DIGOUT_NID	ALC880_DIGOUT_NID
8235#define alc268_modes		alc260_modes
8236
8237static hda_nid_t alc268_dac_nids[2] = {
8238	/* front, hp */
8239	0x02, 0x03
8240};
8241
8242static hda_nid_t alc268_adc_nids[2] = {
8243	/* ADC0-1 */
8244	0x08, 0x07
8245};
8246
8247static hda_nid_t alc268_adc_nids_alt[1] = {
8248	/* ADC0 */
8249	0x08
8250};
8251
8252static struct snd_kcontrol_new alc268_base_mixer[] = {
8253	/* output mixer control */
8254	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
8255	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8256	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
8257	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8258	{ }
8259};
8260
8261static struct hda_verb alc268_eapd_verbs[] = {
8262	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8263	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8264	{ }
8265};
8266
8267/* Toshiba specific */
8268#define alc268_toshiba_automute	alc262_hippo_automute
8269
8270static struct hda_verb alc268_toshiba_verbs[] = {
8271	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8272	{ } /* end */
8273};
8274
8275/* Acer specific */
8276#define alc268_acer_bind_master_vol	alc262_fujitsu_bind_master_vol
8277#define alc268_acer_master_sw_put	alc262_fujitsu_master_sw_put
8278#define alc268_acer_automute	alc262_fujitsu_automute
8279
8280static struct snd_kcontrol_new alc268_acer_mixer[] = {
8281	/* output mixer control */
8282	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
8283	{
8284		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8285		.name = "Master Playback Switch",
8286		.info = snd_hda_mixer_amp_switch_info,
8287		.get = snd_hda_mixer_amp_switch_get,
8288		.put = alc268_acer_master_sw_put,
8289		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
8290	},
8291	{ }
8292};
8293
8294static struct hda_verb alc268_acer_verbs[] = {
8295	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8296	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8297
8298	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8299	{ }
8300};
8301
8302/* unsolicited event for HP jack sensing */
8303static void alc268_toshiba_unsol_event(struct hda_codec *codec,
8304				       unsigned int res)
8305{
8306	if ((res >> 28) != ALC880_HP_EVENT)
8307		return;
8308	alc268_toshiba_automute(codec);
8309}
8310
8311static void alc268_acer_unsol_event(struct hda_codec *codec,
8312				       unsigned int res)
8313{
8314	if ((res >> 28) != ALC880_HP_EVENT)
8315		return;
8316	alc268_acer_automute(codec, 1);
8317}
8318
8319/*
8320 * generic initialization of ADC, input mixers and output mixers
8321 */
8322static struct hda_verb alc268_base_init_verbs[] = {
8323	/* Unmute DAC0-1 and set vol = 0 */
8324	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8325	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8326	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8327	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8328	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8329	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8330
8331	/*
8332	 * Set up output mixers (0x0c - 0x0e)
8333	 */
8334	/* set vol=0 to output mixers */
8335	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8336	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8337	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8338        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
8339
8340	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8341	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8342
8343	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8344	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8345	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8346	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8347	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8348	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8349	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8350	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8351
8352	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8353	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8354	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8355	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8356	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8357	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8358	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8359	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8360
8361	/* FIXME: use matrix-type input source selection */
8362	/* Mixer elements: 0x18, 19, 1a, 1c, 14, 15, 0b */
8363	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8364	/* Input mixer2 */
8365	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8366	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8367	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8368	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8369
8370	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8371	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8372	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8373	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8374	{ }
8375};
8376
8377/*
8378 * generic initialization of ADC, input mixers and output mixers
8379 */
8380static struct hda_verb alc268_volume_init_verbs[] = {
8381	/* set output DAC */
8382	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8383	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8384	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8385	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8386
8387	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8388	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8389	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8390	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8391	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8392
8393	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8394	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8395	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8396	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8397	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8398
8399	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8400	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8401	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8402	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8403
8404	/* set PCBEEP vol = 0 */
8405	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
8406
8407	{ }
8408};
8409
8410#define alc268_mux_enum_info alc_mux_enum_info
8411#define alc268_mux_enum_get alc_mux_enum_get
8412
8413static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol,
8414			       struct snd_ctl_elem_value *ucontrol)
8415{
8416	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8417	struct alc_spec *spec = codec->spec;
8418	const struct hda_input_mux *imux = spec->input_mux;
8419	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
8420	static hda_nid_t capture_mixers[3] = { 0x23, 0x24 };
8421	hda_nid_t nid = capture_mixers[adc_idx];
8422	unsigned int *cur_val = &spec->cur_mux[adc_idx];
8423	unsigned int i, idx;
8424
8425	idx = ucontrol->value.enumerated.item[0];
8426	if (idx >= imux->num_items)
8427		idx = imux->num_items - 1;
8428	if (*cur_val == idx)
8429		return 0;
8430	for (i = 0; i < imux->num_items; i++) {
8431		unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
8432		snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
8433					 imux->items[i].index,
8434					 HDA_AMP_MUTE, v);
8435                snd_hda_codec_write_cache(codec, nid, 0,
8436					  AC_VERB_SET_CONNECT_SEL,
8437					  idx );
8438	}
8439	*cur_val = idx;
8440	return 1;
8441}
8442
8443static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
8444	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
8445	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
8446	{
8447		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8448		/* The multiple "Capture Source" controls confuse alsamixer
8449		 * So call somewhat different..
8450		 * FIXME: the controls appear in the "playback" view!
8451		 */
8452		/* .name = "Capture Source", */
8453		.name = "Input Source",
8454		.count = 1,
8455		.info = alc268_mux_enum_info,
8456		.get = alc268_mux_enum_get,
8457		.put = alc268_mux_enum_put,
8458	},
8459	{ } /* end */
8460};
8461
8462static struct snd_kcontrol_new alc268_capture_mixer[] = {
8463	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
8464	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
8465	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
8466	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
8467	{
8468		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8469		/* The multiple "Capture Source" controls confuse alsamixer
8470		 * So call somewhat different..
8471		 * FIXME: the controls appear in the "playback" view!
8472		 */
8473		/* .name = "Capture Source", */
8474		.name = "Input Source",
8475		.count = 2,
8476		.info = alc268_mux_enum_info,
8477		.get = alc268_mux_enum_get,
8478		.put = alc268_mux_enum_put,
8479	},
8480	{ } /* end */
8481};
8482
8483static struct hda_input_mux alc268_capture_source = {
8484	.num_items = 4,
8485	.items = {
8486		{ "Mic", 0x0 },
8487		{ "Front Mic", 0x1 },
8488		{ "Line", 0x2 },
8489		{ "CD", 0x3 },
8490	},
8491};
8492
8493/* create input playback/capture controls for the given pin */
8494static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
8495				    const char *ctlname, int idx)
8496{
8497	char name[32];
8498	int err;
8499
8500	sprintf(name, "%s Playback Volume", ctlname);
8501	if (nid == 0x14) {
8502		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
8503				  HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
8504						      HDA_OUTPUT));
8505		if (err < 0)
8506			return err;
8507	} else if (nid == 0x15) {
8508		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
8509				  HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
8510						      HDA_OUTPUT));
8511		if (err < 0)
8512			return err;
8513	} else
8514		return -1;
8515	sprintf(name, "%s Playback Switch", ctlname);
8516	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
8517			  HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
8518	if (err < 0)
8519		return err;
8520	return 0;
8521}
8522
8523/* add playback controls from the parsed DAC table */
8524static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
8525					     const struct auto_pin_cfg *cfg)
8526{
8527	hda_nid_t nid;
8528	int err;
8529
8530	spec->multiout.num_dacs = 2;	/* only use one dac */
8531	spec->multiout.dac_nids = spec->private_dac_nids;
8532	spec->multiout.dac_nids[0] = 2;
8533	spec->multiout.dac_nids[1] = 3;
8534
8535	nid = cfg->line_out_pins[0];
8536	if (nid)
8537		alc268_new_analog_output(spec, nid, "Front", 0);
8538
8539	nid = cfg->speaker_pins[0];
8540	if (nid == 0x1d) {
8541		err = add_control(spec, ALC_CTL_WIDGET_VOL,
8542				  "Speaker Playback Volume",
8543				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
8544		if (err < 0)
8545			return err;
8546	}
8547	nid = cfg->hp_pins[0];
8548	if (nid)
8549		alc268_new_analog_output(spec, nid, "Headphone", 0);
8550
8551	nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
8552	if (nid == 0x16) {
8553		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8554				  "Mono Playback Switch",
8555				  HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
8556		if (err < 0)
8557			return err;
8558	}
8559	return 0;
8560}
8561
8562/* create playback/capture controls for input pins */
8563static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
8564						const struct auto_pin_cfg *cfg)
8565{
8566	struct hda_input_mux *imux = &spec->private_imux;
8567	int i, idx1;
8568
8569	for (i = 0; i < AUTO_PIN_LAST; i++) {
8570		switch(cfg->input_pins[i]) {
8571		case 0x18:
8572			idx1 = 0;	/* Mic 1 */
8573			break;
8574		case 0x19:
8575			idx1 = 1;	/* Mic 2 */
8576			break;
8577		case 0x1a:
8578			idx1 = 2;	/* Line In */
8579			break;
8580		case 0x1c:
8581			idx1 = 3;	/* CD */
8582			break;
8583		default:
8584			continue;
8585		}
8586		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
8587		imux->items[imux->num_items].index = idx1;
8588		imux->num_items++;
8589	}
8590	return 0;
8591}
8592
8593static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
8594{
8595	struct alc_spec *spec = codec->spec;
8596	hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
8597	hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
8598	hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
8599	unsigned int	dac_vol1, dac_vol2;
8600
8601	if (speaker_nid) {
8602		snd_hda_codec_write(codec, speaker_nid, 0,
8603				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
8604		snd_hda_codec_write(codec, 0x0f, 0,
8605				    AC_VERB_SET_AMP_GAIN_MUTE,
8606				    AMP_IN_UNMUTE(1));
8607		snd_hda_codec_write(codec, 0x10, 0,
8608				    AC_VERB_SET_AMP_GAIN_MUTE,
8609				    AMP_IN_UNMUTE(1));
8610	} else {
8611		snd_hda_codec_write(codec, 0x0f, 0,
8612				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
8613		snd_hda_codec_write(codec, 0x10, 0,
8614				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
8615	}
8616
8617	dac_vol1 = dac_vol2 = 0xb000 | 0x40;	/* set max volume  */
8618	if (line_nid == 0x14)
8619		dac_vol2 = AMP_OUT_ZERO;
8620	else if (line_nid == 0x15)
8621		dac_vol1 = AMP_OUT_ZERO;
8622	if (hp_nid == 0x14)
8623		dac_vol2 = AMP_OUT_ZERO;
8624	else if (hp_nid == 0x15)
8625		dac_vol1 = AMP_OUT_ZERO;
8626	if (line_nid != 0x16 || hp_nid != 0x16 ||
8627	    spec->autocfg.line_out_pins[1] != 0x16 ||
8628	    spec->autocfg.line_out_pins[2] != 0x16)
8629		dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
8630
8631	snd_hda_codec_write(codec, 0x02, 0,
8632			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
8633	snd_hda_codec_write(codec, 0x03, 0,
8634			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
8635}
8636
8637/* pcm configuration: identiacal with ALC880 */
8638#define alc268_pcm_analog_playback	alc880_pcm_analog_playback
8639#define alc268_pcm_analog_capture	alc880_pcm_analog_capture
8640#define alc268_pcm_digital_playback	alc880_pcm_digital_playback
8641
8642/*
8643 * BIOS auto configuration
8644 */
8645static int alc268_parse_auto_config(struct hda_codec *codec)
8646{
8647	struct alc_spec *spec = codec->spec;
8648	int err;
8649	static hda_nid_t alc268_ignore[] = { 0 };
8650
8651	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
8652					   alc268_ignore);
8653	if (err < 0)
8654		return err;
8655	if (!spec->autocfg.line_outs)
8656		return 0; /* can't find valid BIOS pin config */
8657
8658	err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
8659	if (err < 0)
8660		return err;
8661	err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
8662	if (err < 0)
8663		return err;
8664
8665	spec->multiout.max_channels = 2;
8666
8667	/* digital only support output */
8668	if (spec->autocfg.dig_out_pin)
8669		spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
8670
8671	if (spec->kctl_alloc)
8672		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
8673
8674	spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
8675	spec->num_mux_defs = 1;
8676	spec->input_mux = &spec->private_imux;
8677
8678	return 1;
8679}
8680
8681#define alc268_auto_init_multi_out	alc882_auto_init_multi_out
8682#define alc268_auto_init_hp_out		alc882_auto_init_hp_out
8683#define alc268_auto_init_analog_input	alc882_auto_init_analog_input
8684
8685/* init callback for auto-configuration model -- overriding the default init */
8686static void alc268_auto_init(struct hda_codec *codec)
8687{
8688	alc268_auto_init_multi_out(codec);
8689	alc268_auto_init_hp_out(codec);
8690	alc268_auto_init_mono_speaker_out(codec);
8691	alc268_auto_init_analog_input(codec);
8692}
8693
8694/*
8695 * configuration and preset
8696 */
8697static const char *alc268_models[ALC268_MODEL_LAST] = {
8698	[ALC268_3ST]		= "3stack",
8699	[ALC268_TOSHIBA]	= "toshiba",
8700	[ALC268_ACER]		= "acer",
8701	[ALC268_AUTO]		= "auto",
8702};
8703
8704static struct snd_pci_quirk alc268_cfg_tbl[] = {
8705	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8706	SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
8707	SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
8708	SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
8709	{}
8710};
8711
8712static struct alc_config_preset alc268_presets[] = {
8713	[ALC268_3ST] = {
8714		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
8715		.init_verbs = { alc268_base_init_verbs },
8716		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
8717		.dac_nids = alc268_dac_nids,
8718                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
8719                .adc_nids = alc268_adc_nids_alt,
8720		.hp_nid = 0x03,
8721		.dig_out_nid = ALC268_DIGOUT_NID,
8722		.num_channel_mode = ARRAY_SIZE(alc268_modes),
8723		.channel_mode = alc268_modes,
8724		.input_mux = &alc268_capture_source,
8725	},
8726	[ALC268_TOSHIBA] = {
8727		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
8728		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
8729				alc268_toshiba_verbs },
8730		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
8731		.dac_nids = alc268_dac_nids,
8732		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
8733		.adc_nids = alc268_adc_nids_alt,
8734		.hp_nid = 0x03,
8735		.num_channel_mode = ARRAY_SIZE(alc268_modes),
8736		.channel_mode = alc268_modes,
8737		.input_mux = &alc268_capture_source,
8738		.input_mux = &alc268_capture_source,
8739		.unsol_event = alc268_toshiba_unsol_event,
8740		.init_hook = alc268_toshiba_automute,
8741	},
8742	[ALC268_ACER] = {
8743		.mixers = { alc268_acer_mixer, alc268_capture_alt_mixer },
8744		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
8745				alc268_acer_verbs },
8746		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
8747		.dac_nids = alc268_dac_nids,
8748		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
8749		.adc_nids = alc268_adc_nids_alt,
8750		.hp_nid = 0x02,
8751		.num_channel_mode = ARRAY_SIZE(alc268_modes),
8752		.channel_mode = alc268_modes,
8753		.input_mux = &alc268_capture_source,
8754		.unsol_event = alc268_acer_unsol_event,
8755	},
8756};
8757
8758static int patch_alc268(struct hda_codec *codec)
8759{
8760	struct alc_spec *spec;
8761	int board_config;
8762	int err;
8763
8764	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
8765	if (spec == NULL)
8766		return -ENOMEM;
8767
8768	codec->spec = spec;
8769
8770	board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
8771						  alc268_models,
8772						  alc268_cfg_tbl);
8773
8774	if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
8775		printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
8776		       "trying auto-probe from BIOS...\n");
8777		board_config = ALC268_AUTO;
8778	}
8779
8780	if (board_config == ALC268_AUTO) {
8781		/* automatic parse from the BIOS config */
8782		err = alc268_parse_auto_config(codec);
8783		if (err < 0) {
8784			alc_free(codec);
8785			return err;
8786		} else if (!err) {
8787			printk(KERN_INFO
8788			       "hda_codec: Cannot set up configuration "
8789			       "from BIOS.  Using base mode...\n");
8790			board_config = ALC268_3ST;
8791		}
8792	}
8793
8794	if (board_config != ALC268_AUTO)
8795		setup_preset(spec, &alc268_presets[board_config]);
8796
8797	spec->stream_name_analog = "ALC268 Analog";
8798	spec->stream_analog_playback = &alc268_pcm_analog_playback;
8799	spec->stream_analog_capture = &alc268_pcm_analog_capture;
8800
8801	spec->stream_name_digital = "ALC268 Digital";
8802	spec->stream_digital_playback = &alc268_pcm_digital_playback;
8803
8804	if (board_config == ALC268_AUTO) {
8805		if (!spec->adc_nids && spec->input_mux) {
8806			/* check whether NID 0x07 is valid */
8807			unsigned int wcap = get_wcaps(codec, 0x07);
8808
8809			/* get type */
8810			wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
8811			if (wcap != AC_WID_AUD_IN) {
8812				spec->adc_nids = alc268_adc_nids_alt;
8813				spec->num_adc_nids =
8814					ARRAY_SIZE(alc268_adc_nids_alt);
8815				spec->mixers[spec->num_mixers] =
8816					alc268_capture_alt_mixer;
8817				spec->num_mixers++;
8818			} else {
8819				spec->adc_nids = alc268_adc_nids;
8820				spec->num_adc_nids =
8821					ARRAY_SIZE(alc268_adc_nids);
8822				spec->mixers[spec->num_mixers] =
8823					alc268_capture_mixer;
8824				spec->num_mixers++;
8825			}
8826		}
8827	}
8828	codec->patch_ops = alc_patch_ops;
8829	if (board_config == ALC268_AUTO)
8830		spec->init_hook = alc268_auto_init;
8831
8832	return 0;
8833}
8834
8835/*
8836 *  ALC861 channel source setting (2/6 channel selection for 3-stack)
8837 */
8838
8839/*
8840 * set the path ways for 2 channel output
8841 * need to set the codec line out and mic 1 pin widgets to inputs
8842 */
8843static struct hda_verb alc861_threestack_ch2_init[] = {
8844	/* set pin widget 1Ah (line in) for input */
8845	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8846	/* set pin widget 18h (mic1/2) for input, for mic also enable
8847	 * the vref
8848	 */
8849	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8850
8851	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
8852#if 0
8853	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8854	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
8855#endif
8856	{ } /* end */
8857};
8858/*
8859 * 6ch mode
8860 * need to set the codec line out and mic 1 pin widgets to outputs
8861 */
8862static struct hda_verb alc861_threestack_ch6_init[] = {
8863	/* set pin widget 1Ah (line in) for output (Back Surround)*/
8864	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8865	/* set pin widget 18h (mic1) for output (CLFE)*/
8866	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8867
8868	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
8869	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
8870
8871	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
8872#if 0
8873	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8874	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
8875#endif
8876	{ } /* end */
8877};
8878
8879static struct hda_channel_mode alc861_threestack_modes[2] = {
8880	{ 2, alc861_threestack_ch2_init },
8881	{ 6, alc861_threestack_ch6_init },
8882};
8883/* Set mic1 as input and unmute the mixer */
8884static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
8885	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8886	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8887	{ } /* end */
8888};
8889/* Set mic1 as output and mute mixer */
8890static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
8891	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8892	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8893	{ } /* end */
8894};
8895
8896static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
8897	{ 2, alc861_uniwill_m31_ch2_init },
8898	{ 4, alc861_uniwill_m31_ch4_init },
8899};
8900
8901/* Set mic1 and line-in as input and unmute the mixer */
8902static struct hda_verb alc861_asus_ch2_init[] = {
8903	/* set pin widget 1Ah (line in) for input */
8904	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8905	/* set pin widget 18h (mic1/2) for input, for mic also enable
8906	 * the vref
8907	 */
8908	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8909
8910	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
8911#if 0
8912	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8913	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
8914#endif
8915	{ } /* end */
8916};
8917/* Set mic1 nad line-in as output and mute mixer */
8918static struct hda_verb alc861_asus_ch6_init[] = {
8919	/* set pin widget 1Ah (line in) for output (Back Surround)*/
8920	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8921	/* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
8922	/* set pin widget 18h (mic1) for output (CLFE)*/
8923	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8924	/* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
8925	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
8926	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
8927
8928	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
8929#if 0
8930	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8931	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
8932#endif
8933	{ } /* end */
8934};
8935
8936static struct hda_channel_mode alc861_asus_modes[2] = {
8937	{ 2, alc861_asus_ch2_init },
8938	{ 6, alc861_asus_ch6_init },
8939};
8940
8941/* patch-ALC861 */
8942
8943static struct snd_kcontrol_new alc861_base_mixer[] = {
8944        /* output mixer control */
8945	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8946	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8947	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8948	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8949	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
8950
8951        /*Input mixer control */
8952	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8953	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8954	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8955	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8956	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8957	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8958	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8959	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8960	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8961	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
8962
8963        /* Capture mixer control */
8964	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8965	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8966	{
8967		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8968		.name = "Capture Source",
8969		.count = 1,
8970		.info = alc_mux_enum_info,
8971		.get = alc_mux_enum_get,
8972		.put = alc_mux_enum_put,
8973	},
8974	{ } /* end */
8975};
8976
8977static struct snd_kcontrol_new alc861_3ST_mixer[] = {
8978        /* output mixer control */
8979	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8980	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8981	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8982	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8983	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
8984
8985	/* Input mixer control */
8986	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8987	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8988	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8989	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8990	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8991	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8992	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8993	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8994	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8995	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
8996
8997	/* Capture mixer control */
8998	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8999	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9000	{
9001		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9002		.name = "Capture Source",
9003		.count = 1,
9004		.info = alc_mux_enum_info,
9005		.get = alc_mux_enum_get,
9006		.put = alc_mux_enum_put,
9007	},
9008	{
9009		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9010		.name = "Channel Mode",
9011		.info = alc_ch_mode_info,
9012		.get = alc_ch_mode_get,
9013		.put = alc_ch_mode_put,
9014                .private_value = ARRAY_SIZE(alc861_threestack_modes),
9015	},
9016	{ } /* end */
9017};
9018
9019static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
9020        /* output mixer control */
9021	HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
9022	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
9023	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
9024
9025        /*Capture mixer control */
9026	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9027	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9028	{
9029		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9030		.name = "Capture Source",
9031		.count = 1,
9032		.info = alc_mux_enum_info,
9033		.get = alc_mux_enum_get,
9034		.put = alc_mux_enum_put,
9035	},
9036
9037	{ } /* end */
9038};
9039
9040static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
9041        /* output mixer control */
9042	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
9043	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
9044	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
9045	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
9046	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
9047
9048	/* Input mixer control */
9049	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
9050	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
9051	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9052	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9053	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
9054	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
9055	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
9056	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
9057	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
9058	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
9059
9060	/* Capture mixer control */
9061	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9062	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9063	{
9064		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9065		.name = "Capture Source",
9066		.count = 1,
9067		.info = alc_mux_enum_info,
9068		.get = alc_mux_enum_get,
9069		.put = alc_mux_enum_put,
9070	},
9071	{
9072		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9073		.name = "Channel Mode",
9074		.info = alc_ch_mode_info,
9075		.get = alc_ch_mode_get,
9076		.put = alc_ch_mode_put,
9077                .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
9078	},
9079	{ } /* end */
9080};
9081
9082static struct snd_kcontrol_new alc861_asus_mixer[] = {
9083        /* output mixer control */
9084	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
9085	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
9086	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
9087	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
9088	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
9089
9090	/* Input mixer control */
9091	HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
9092	HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9093	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9094	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9095	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
9096	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
9097	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
9098	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
9099	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
9100	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
9101
9102	/* Capture mixer control */
9103	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9104	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9105	{
9106		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9107		.name = "Capture Source",
9108		.count = 1,
9109		.info = alc_mux_enum_info,
9110		.get = alc_mux_enum_get,
9111		.put = alc_mux_enum_put,
9112	},
9113	{
9114		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9115		.name = "Channel Mode",
9116		.info = alc_ch_mode_info,
9117		.get = alc_ch_mode_get,
9118		.put = alc_ch_mode_put,
9119                .private_value = ARRAY_SIZE(alc861_asus_modes),
9120	},
9121	{ }
9122};
9123
9124/* additional mixer */
9125static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
9126	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9127	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9128	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
9129	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
9130	{ }
9131};
9132
9133/*
9134 * generic initialization of ADC, input mixers and output mixers
9135 */
9136static struct hda_verb alc861_base_init_verbs[] = {
9137	/*
9138	 * Unmute ADC0 and set the default input to mic-in
9139	 */
9140	/* port-A for surround (rear panel) */
9141	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9142	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
9143	/* port-B for mic-in (rear panel) with vref */
9144	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9145	/* port-C for line-in (rear panel) */
9146	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9147	/* port-D for Front */
9148	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9149	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9150	/* port-E for HP out (front panel) */
9151	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
9152	/* route front PCM to HP */
9153	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9154	/* port-F for mic-in (front panel) with vref */
9155	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9156	/* port-G for CLFE (rear panel) */
9157	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9158	{ 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9159	/* port-H for side (rear panel) */
9160	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9161	{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
9162	/* CD-in */
9163	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9164	/* route front mic to ADC1*/
9165	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9166	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9167
9168	/* Unmute DAC0~3 & spdif out*/
9169	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9170	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9171	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9172	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9173	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9174
9175	/* Unmute Mixer 14 (mic) 1c (Line in)*/
9176	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9177        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9178	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9179        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9180
9181	/* Unmute Stereo Mixer 15 */
9182	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9183	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9184	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9185	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9186
9187	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9188	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9189	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9190	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9191	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9192	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9193	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9194	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9195	/* hp used DAC 3 (Front) */
9196	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9197        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9198
9199	{ }
9200};
9201
9202static struct hda_verb alc861_threestack_init_verbs[] = {
9203	/*
9204	 * Unmute ADC0 and set the default input to mic-in
9205	 */
9206	/* port-A for surround (rear panel) */
9207	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9208	/* port-B for mic-in (rear panel) with vref */
9209	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9210	/* port-C for line-in (rear panel) */
9211	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9212	/* port-D for Front */
9213	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9214	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9215	/* port-E for HP out (front panel) */
9216	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
9217	/* route front PCM to HP */
9218	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9219	/* port-F for mic-in (front panel) with vref */
9220	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9221	/* port-G for CLFE (rear panel) */
9222	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9223	/* port-H for side (rear panel) */
9224	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9225	/* CD-in */
9226	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9227	/* route front mic to ADC1*/
9228	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9229	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9230	/* Unmute DAC0~3 & spdif out*/
9231	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9232	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9233	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9234	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9235	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9236
9237	/* Unmute Mixer 14 (mic) 1c (Line in)*/
9238	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9239        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9240	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9241        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9242
9243	/* Unmute Stereo Mixer 15 */
9244	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9245	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9246	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9247	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9248
9249	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9250	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9251	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9252	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9253	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9254	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9255	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9256	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9257	/* hp used DAC 3 (Front) */
9258	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9259        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9260	{ }
9261};
9262
9263static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
9264	/*
9265	 * Unmute ADC0 and set the default input to mic-in
9266	 */
9267	/* port-A for surround (rear panel) */
9268	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9269	/* port-B for mic-in (rear panel) with vref */
9270	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9271	/* port-C for line-in (rear panel) */
9272	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9273	/* port-D for Front */
9274	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9275	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9276	/* port-E for HP out (front panel) */
9277	/* this has to be set to VREF80 */
9278	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9279	/* route front PCM to HP */
9280	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9281	/* port-F for mic-in (front panel) with vref */
9282	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9283	/* port-G for CLFE (rear panel) */
9284	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9285	/* port-H for side (rear panel) */
9286	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9287	/* CD-in */
9288	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9289	/* route front mic to ADC1*/
9290	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9291	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9292	/* Unmute DAC0~3 & spdif out*/
9293	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9294	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9295	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9296	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9297	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9298
9299	/* Unmute Mixer 14 (mic) 1c (Line in)*/
9300	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9301        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9302	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9303        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9304
9305	/* Unmute Stereo Mixer 15 */
9306	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9307	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9308	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9309	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9310
9311	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9312	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9313	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9314	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9315	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9316	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9317	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9318	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9319	/* hp used DAC 3 (Front) */
9320	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9321        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9322	{ }
9323};
9324
9325static struct hda_verb alc861_asus_init_verbs[] = {
9326	/*
9327	 * Unmute ADC0 and set the default input to mic-in
9328	 */
9329	/* port-A for surround (rear panel)
9330	 * according to codec#0 this is the HP jack
9331	 */
9332	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
9333	/* route front PCM to HP */
9334	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
9335	/* port-B for mic-in (rear panel) with vref */
9336	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9337	/* port-C for line-in (rear panel) */
9338	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9339	/* port-D for Front */
9340	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9341	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9342	/* port-E for HP out (front panel) */
9343	/* this has to be set to VREF80 */
9344	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9345	/* route front PCM to HP */
9346	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9347	/* port-F for mic-in (front panel) with vref */
9348	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9349	/* port-G for CLFE (rear panel) */
9350	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9351	/* port-H for side (rear panel) */
9352	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9353	/* CD-in */
9354	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9355	/* route front mic to ADC1*/
9356	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9357	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9358	/* Unmute DAC0~3 & spdif out*/
9359	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9360	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9361	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9362	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9363	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9364	/* Unmute Mixer 14 (mic) 1c (Line in)*/
9365	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9366        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9367	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9368        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9369
9370	/* Unmute Stereo Mixer 15 */
9371	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9372	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9373	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9374	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9375
9376	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9377	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9378	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9379	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9380	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9381	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9382	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9383	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9384	/* hp used DAC 3 (Front) */
9385	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9386	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9387	{ }
9388};
9389
9390/* additional init verbs for ASUS laptops */
9391static struct hda_verb alc861_asus_laptop_init_verbs[] = {
9392	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
9393	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
9394	{ }
9395};
9396
9397/*
9398 * generic initialization of ADC, input mixers and output mixers
9399 */
9400static struct hda_verb alc861_auto_init_verbs[] = {
9401	/*
9402	 * Unmute ADC0 and set the default input to mic-in
9403	 */
9404	/* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
9405	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9406
9407	/* Unmute DAC0~3 & spdif out*/
9408	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9409	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9410	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9411	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9412	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9413
9414	/* Unmute Mixer 14 (mic) 1c (Line in)*/
9415	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9416	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9417	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9418	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9419
9420	/* Unmute Stereo Mixer 15 */
9421	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9422	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9423	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9424	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
9425
9426	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9427	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9428	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9429	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9430	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9431	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9432	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9433	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9434
9435	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9436	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9437	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9438	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9439	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9440	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9441	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9442	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9443
9444	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},	/* set Mic 1 */
9445
9446	{ }
9447};
9448
9449static struct hda_verb alc861_toshiba_init_verbs[] = {
9450	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9451
9452	{ }
9453};
9454
9455/* toggle speaker-output according to the hp-jack state */
9456static void alc861_toshiba_automute(struct hda_codec *codec)
9457{
9458	unsigned int present;
9459
9460	present = snd_hda_codec_read(codec, 0x0f, 0,
9461				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9462	snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
9463				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9464	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
9465				 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
9466}
9467
9468static void alc861_toshiba_unsol_event(struct hda_codec *codec,
9469				       unsigned int res)
9470{
9471	if ((res >> 26) == ALC880_HP_EVENT)
9472		alc861_toshiba_automute(codec);
9473}
9474
9475/* pcm configuration: identiacal with ALC880 */
9476#define alc861_pcm_analog_playback	alc880_pcm_analog_playback
9477#define alc861_pcm_analog_capture	alc880_pcm_analog_capture
9478#define alc861_pcm_digital_playback	alc880_pcm_digital_playback
9479#define alc861_pcm_digital_capture	alc880_pcm_digital_capture
9480
9481
9482#define ALC861_DIGOUT_NID	0x07
9483
9484static struct hda_channel_mode alc861_8ch_modes[1] = {
9485	{ 8, NULL }
9486};
9487
9488static hda_nid_t alc861_dac_nids[4] = {
9489	/* front, surround, clfe, side */
9490	0x03, 0x06, 0x05, 0x04
9491};
9492
9493static hda_nid_t alc660_dac_nids[3] = {
9494	/* front, clfe, surround */
9495	0x03, 0x05, 0x06
9496};
9497
9498static hda_nid_t alc861_adc_nids[1] = {
9499	/* ADC0-2 */
9500	0x08,
9501};
9502
9503static struct hda_input_mux alc861_capture_source = {
9504	.num_items = 5,
9505	.items = {
9506		{ "Mic", 0x0 },
9507		{ "Front Mic", 0x3 },
9508		{ "Line", 0x1 },
9509		{ "CD", 0x4 },
9510		{ "Mixer", 0x5 },
9511	},
9512};
9513
9514/* fill in the dac_nids table from the parsed pin configuration */
9515static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
9516				     const struct auto_pin_cfg *cfg)
9517{
9518	int i;
9519	hda_nid_t nid;
9520
9521	spec->multiout.dac_nids = spec->private_dac_nids;
9522	for (i = 0; i < cfg->line_outs; i++) {
9523		nid = cfg->line_out_pins[i];
9524		if (nid) {
9525			if (i >= ARRAY_SIZE(alc861_dac_nids))
9526				continue;
9527			spec->multiout.dac_nids[i] = alc861_dac_nids[i];
9528		}
9529	}
9530	spec->multiout.num_dacs = cfg->line_outs;
9531	return 0;
9532}
9533
9534/* add playback controls from the parsed DAC table */
9535static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
9536					     const struct auto_pin_cfg *cfg)
9537{
9538	char name[32];
9539	static const char *chname[4] = {
9540		"Front", "Surround", NULL /*CLFE*/, "Side"
9541	};
9542	hda_nid_t nid;
9543	int i, idx, err;
9544
9545	for (i = 0; i < cfg->line_outs; i++) {
9546		nid = spec->multiout.dac_nids[i];
9547		if (!nid)
9548			continue;
9549		if (nid == 0x05) {
9550			/* Center/LFE */
9551			err = add_control(spec, ALC_CTL_BIND_MUTE,
9552					  "Center Playback Switch",
9553					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
9554							      HDA_OUTPUT));
9555			if (err < 0)
9556				return err;
9557			err = add_control(spec, ALC_CTL_BIND_MUTE,
9558					  "LFE Playback Switch",
9559					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9560							      HDA_OUTPUT));
9561			if (err < 0)
9562				return err;
9563		} else {
9564			for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
9565			     idx++)
9566				if (nid == alc861_dac_nids[idx])
9567					break;
9568			sprintf(name, "%s Playback Switch", chname[idx]);
9569			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
9570					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9571							      HDA_OUTPUT));
9572			if (err < 0)
9573				return err;
9574		}
9575	}
9576	return 0;
9577}
9578
9579static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
9580{
9581	int err;
9582	hda_nid_t nid;
9583
9584	if (!pin)
9585		return 0;
9586
9587	if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
9588		nid = 0x03;
9589		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9590				  "Headphone Playback Switch",
9591				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9592		if (err < 0)
9593			return err;
9594		spec->multiout.hp_nid = nid;
9595	}
9596	return 0;
9597}
9598
9599/* create playback/capture controls for input pins */
9600static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
9601						const struct auto_pin_cfg *cfg)
9602{
9603	struct hda_input_mux *imux = &spec->private_imux;
9604	int i, err, idx, idx1;
9605
9606	for (i = 0; i < AUTO_PIN_LAST; i++) {
9607		switch (cfg->input_pins[i]) {
9608		case 0x0c:
9609			idx1 = 1;
9610			idx = 2;	/* Line In */
9611			break;
9612		case 0x0f:
9613			idx1 = 2;
9614			idx = 2;	/* Line In */
9615			break;
9616		case 0x0d:
9617			idx1 = 0;
9618			idx = 1;	/* Mic In */
9619			break;
9620		case 0x10:
9621			idx1 = 3;
9622			idx = 1;	/* Mic In */
9623			break;
9624		case 0x11:
9625			idx1 = 4;
9626			idx = 0;	/* CD */
9627			break;
9628		default:
9629			continue;
9630		}
9631
9632		err = new_analog_input(spec, cfg->input_pins[i],
9633				       auto_pin_cfg_labels[i], idx, 0x15);
9634		if (err < 0)
9635			return err;
9636
9637		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
9638		imux->items[imux->num_items].index = idx1;
9639		imux->num_items++;
9640	}
9641	return 0;
9642}
9643
9644static struct snd_kcontrol_new alc861_capture_mixer[] = {
9645	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9646	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9647
9648	{
9649		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9650		/* The multiple "Capture Source" controls confuse alsamixer
9651		 * So call somewhat different..
9652		 *FIXME: the controls appear in the "playback" view!
9653		 */
9654		/* .name = "Capture Source", */
9655		.name = "Input Source",
9656		.count = 1,
9657		.info = alc_mux_enum_info,
9658		.get = alc_mux_enum_get,
9659		.put = alc_mux_enum_put,
9660	},
9661	{ } /* end */
9662};
9663
9664static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
9665					      hda_nid_t nid,
9666					      int pin_type, int dac_idx)
9667{
9668	/* set as output */
9669
9670	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
9671			    pin_type);
9672	snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
9673			    AMP_OUT_UNMUTE);
9674
9675}
9676
9677static void alc861_auto_init_multi_out(struct hda_codec *codec)
9678{
9679	struct alc_spec *spec = codec->spec;
9680	int i;
9681
9682	alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
9683	for (i = 0; i < spec->autocfg.line_outs; i++) {
9684		hda_nid_t nid = spec->autocfg.line_out_pins[i];
9685		int pin_type = get_pin_type(spec->autocfg.line_out_type);
9686		if (nid)
9687			alc861_auto_set_output_and_unmute(codec, nid, pin_type,
9688							  spec->multiout.dac_nids[i]);
9689	}
9690}
9691
9692static void alc861_auto_init_hp_out(struct hda_codec *codec)
9693{
9694	struct alc_spec *spec = codec->spec;
9695	hda_nid_t pin;
9696
9697	pin = spec->autocfg.hp_pins[0];
9698	if (pin) /* connect to front */
9699		alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
9700						  spec->multiout.dac_nids[0]);
9701}
9702
9703static void alc861_auto_init_analog_input(struct hda_codec *codec)
9704{
9705	struct alc_spec *spec = codec->spec;
9706	int i;
9707
9708	for (i = 0; i < AUTO_PIN_LAST; i++) {
9709		hda_nid_t nid = spec->autocfg.input_pins[i];
9710		if (nid >= 0x0c && nid <= 0x11) {
9711			snd_hda_codec_write(codec, nid, 0,
9712					    AC_VERB_SET_PIN_WIDGET_CONTROL,
9713					    i <= AUTO_PIN_FRONT_MIC ?
9714					    PIN_VREF80 : PIN_IN);
9715		}
9716	}
9717}
9718
9719/* parse the BIOS configuration and set up the alc_spec */
9720/* return 1 if successful, 0 if the proper config is not found,
9721 * or a negative error code
9722 */
9723static int alc861_parse_auto_config(struct hda_codec *codec)
9724{
9725	struct alc_spec *spec = codec->spec;
9726	int err;
9727	static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
9728
9729	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9730					   alc861_ignore);
9731	if (err < 0)
9732		return err;
9733	if (!spec->autocfg.line_outs)
9734		return 0; /* can't find valid BIOS pin config */
9735
9736	err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
9737	if (err < 0)
9738		return err;
9739	err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
9740	if (err < 0)
9741		return err;
9742	err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
9743	if (err < 0)
9744		return err;
9745	err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
9746	if (err < 0)
9747		return err;
9748
9749	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9750
9751	if (spec->autocfg.dig_out_pin)
9752		spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
9753
9754	if (spec->kctl_alloc)
9755		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9756
9757	spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
9758
9759	spec->num_mux_defs = 1;
9760	spec->input_mux = &spec->private_imux;
9761
9762	spec->adc_nids = alc861_adc_nids;
9763	spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
9764	spec->mixers[spec->num_mixers] = alc861_capture_mixer;
9765	spec->num_mixers++;
9766
9767	return 1;
9768}
9769
9770/* additional initialization for auto-configuration model */
9771static void alc861_auto_init(struct hda_codec *codec)
9772{
9773	alc861_auto_init_multi_out(codec);
9774	alc861_auto_init_hp_out(codec);
9775	alc861_auto_init_analog_input(codec);
9776}
9777
9778#ifdef CONFIG_SND_HDA_POWER_SAVE
9779static struct hda_amp_list alc861_loopbacks[] = {
9780	{ 0x15, HDA_INPUT, 0 },
9781	{ 0x15, HDA_INPUT, 1 },
9782	{ 0x15, HDA_INPUT, 2 },
9783	{ 0x15, HDA_INPUT, 3 },
9784	{ } /* end */
9785};
9786#endif
9787
9788
9789/*
9790 * configuration and preset
9791 */
9792static const char *alc861_models[ALC861_MODEL_LAST] = {
9793	[ALC861_3ST]		= "3stack",
9794	[ALC660_3ST]		= "3stack-660",
9795	[ALC861_3ST_DIG]	= "3stack-dig",
9796	[ALC861_6ST_DIG]	= "6stack-dig",
9797	[ALC861_UNIWILL_M31]	= "uniwill-m31",
9798	[ALC861_TOSHIBA]	= "toshiba",
9799	[ALC861_ASUS]		= "asus",
9800	[ALC861_ASUS_LAPTOP]	= "asus-laptop",
9801	[ALC861_AUTO]		= "auto",
9802};
9803
9804static struct snd_pci_quirk alc861_cfg_tbl[] = {
9805	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
9806	SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
9807	SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
9808	SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
9809	SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
9810	SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
9811	SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
9812	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
9813	/* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
9814	 *        Any other models that need this preset?
9815	 */
9816	/* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
9817	SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
9818	SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31),
9819	SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
9820	SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
9821	SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
9822	SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
9823	SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
9824	{}
9825};
9826
9827static struct alc_config_preset alc861_presets[] = {
9828	[ALC861_3ST] = {
9829		.mixers = { alc861_3ST_mixer },
9830		.init_verbs = { alc861_threestack_init_verbs },
9831		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9832		.dac_nids = alc861_dac_nids,
9833		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9834		.channel_mode = alc861_threestack_modes,
9835		.need_dac_fix = 1,
9836		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9837		.adc_nids = alc861_adc_nids,
9838		.input_mux = &alc861_capture_source,
9839	},
9840	[ALC861_3ST_DIG] = {
9841		.mixers = { alc861_base_mixer },
9842		.init_verbs = { alc861_threestack_init_verbs },
9843		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9844		.dac_nids = alc861_dac_nids,
9845		.dig_out_nid = ALC861_DIGOUT_NID,
9846		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9847		.channel_mode = alc861_threestack_modes,
9848		.need_dac_fix = 1,
9849		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9850		.adc_nids = alc861_adc_nids,
9851		.input_mux = &alc861_capture_source,
9852	},
9853	[ALC861_6ST_DIG] = {
9854		.mixers = { alc861_base_mixer },
9855		.init_verbs = { alc861_base_init_verbs },
9856		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9857		.dac_nids = alc861_dac_nids,
9858		.dig_out_nid = ALC861_DIGOUT_NID,
9859		.num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
9860		.channel_mode = alc861_8ch_modes,
9861		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9862		.adc_nids = alc861_adc_nids,
9863		.input_mux = &alc861_capture_source,
9864	},
9865	[ALC660_3ST] = {
9866		.mixers = { alc861_3ST_mixer },
9867		.init_verbs = { alc861_threestack_init_verbs },
9868		.num_dacs = ARRAY_SIZE(alc660_dac_nids),
9869		.dac_nids = alc660_dac_nids,
9870		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9871		.channel_mode = alc861_threestack_modes,
9872		.need_dac_fix = 1,
9873		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9874		.adc_nids = alc861_adc_nids,
9875		.input_mux = &alc861_capture_source,
9876	},
9877	[ALC861_UNIWILL_M31] = {
9878		.mixers = { alc861_uniwill_m31_mixer },
9879		.init_verbs = { alc861_uniwill_m31_init_verbs },
9880		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9881		.dac_nids = alc861_dac_nids,
9882		.dig_out_nid = ALC861_DIGOUT_NID,
9883		.num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
9884		.channel_mode = alc861_uniwill_m31_modes,
9885		.need_dac_fix = 1,
9886		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9887		.adc_nids = alc861_adc_nids,
9888		.input_mux = &alc861_capture_source,
9889	},
9890	[ALC861_TOSHIBA] = {
9891		.mixers = { alc861_toshiba_mixer },
9892		.init_verbs = { alc861_base_init_verbs,
9893				alc861_toshiba_init_verbs },
9894		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9895		.dac_nids = alc861_dac_nids,
9896		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9897		.channel_mode = alc883_3ST_2ch_modes,
9898		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9899		.adc_nids = alc861_adc_nids,
9900		.input_mux = &alc861_capture_source,
9901		.unsol_event = alc861_toshiba_unsol_event,
9902		.init_hook = alc861_toshiba_automute,
9903	},
9904	[ALC861_ASUS] = {
9905		.mixers = { alc861_asus_mixer },
9906		.init_verbs = { alc861_asus_init_verbs },
9907		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9908		.dac_nids = alc861_dac_nids,
9909		.dig_out_nid = ALC861_DIGOUT_NID,
9910		.num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
9911		.channel_mode = alc861_asus_modes,
9912		.need_dac_fix = 1,
9913		.hp_nid = 0x06,
9914		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9915		.adc_nids = alc861_adc_nids,
9916		.input_mux = &alc861_capture_source,
9917	},
9918	[ALC861_ASUS_LAPTOP] = {
9919		.mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
9920		.init_verbs = { alc861_asus_init_verbs,
9921				alc861_asus_laptop_init_verbs },
9922		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9923		.dac_nids = alc861_dac_nids,
9924		.dig_out_nid = ALC861_DIGOUT_NID,
9925		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9926		.channel_mode = alc883_3ST_2ch_modes,
9927		.need_dac_fix = 1,
9928		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9929		.adc_nids = alc861_adc_nids,
9930		.input_mux = &alc861_capture_source,
9931	},
9932};
9933
9934
9935static int patch_alc861(struct hda_codec *codec)
9936{
9937	struct alc_spec *spec;
9938	int board_config;
9939	int err;
9940
9941	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9942	if (spec == NULL)
9943		return -ENOMEM;
9944
9945	codec->spec = spec;
9946
9947        board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
9948						  alc861_models,
9949						  alc861_cfg_tbl);
9950
9951	if (board_config < 0) {
9952		printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
9953		       "trying auto-probe from BIOS...\n");
9954		board_config = ALC861_AUTO;
9955	}
9956
9957	if (board_config == ALC861_AUTO) {
9958		/* automatic parse from the BIOS config */
9959		err = alc861_parse_auto_config(codec);
9960		if (err < 0) {
9961			alc_free(codec);
9962			return err;
9963		} else if (!err) {
9964			printk(KERN_INFO
9965			       "hda_codec: Cannot set up configuration "
9966			       "from BIOS.  Using base mode...\n");
9967		   board_config = ALC861_3ST_DIG;
9968		}
9969	}
9970
9971	if (board_config != ALC861_AUTO)
9972		setup_preset(spec, &alc861_presets[board_config]);
9973
9974	spec->stream_name_analog = "ALC861 Analog";
9975	spec->stream_analog_playback = &alc861_pcm_analog_playback;
9976	spec->stream_analog_capture = &alc861_pcm_analog_capture;
9977
9978	spec->stream_name_digital = "ALC861 Digital";
9979	spec->stream_digital_playback = &alc861_pcm_digital_playback;
9980	spec->stream_digital_capture = &alc861_pcm_digital_capture;
9981
9982	codec->patch_ops = alc_patch_ops;
9983	if (board_config == ALC861_AUTO)
9984		spec->init_hook = alc861_auto_init;
9985#ifdef CONFIG_SND_HDA_POWER_SAVE
9986	if (!spec->loopback.amplist)
9987		spec->loopback.amplist = alc861_loopbacks;
9988#endif
9989
9990	return 0;
9991}
9992
9993/*
9994 * ALC861-VD support
9995 *
9996 * Based on ALC882
9997 *
9998 * In addition, an independent DAC
9999 */
10000#define ALC861VD_DIGOUT_NID	0x06
10001
10002static hda_nid_t alc861vd_dac_nids[4] = {
10003	/* front, surr, clfe, side surr */
10004	0x02, 0x03, 0x04, 0x05
10005};
10006
10007/* dac_nids for ALC660vd are in a different order - according to
10008 * Realtek's driver.
10009 * This should probably tesult in a different mixer for 6stack models
10010 * of ALC660vd codecs, but for now there is only 3stack mixer
10011 * - and it is the same as in 861vd.
10012 * adc_nids in ALC660vd are (is) the same as in 861vd
10013 */
10014static hda_nid_t alc660vd_dac_nids[3] = {
10015	/* front, rear, clfe, rear_surr */
10016	0x02, 0x04, 0x03
10017};
10018
10019static hda_nid_t alc861vd_adc_nids[1] = {
10020	/* ADC0 */
10021	0x09,
10022};
10023
10024/* input MUX */
10025/* FIXME: should be a matrix-type input source selection */
10026static struct hda_input_mux alc861vd_capture_source = {
10027	.num_items = 4,
10028	.items = {
10029		{ "Mic", 0x0 },
10030		{ "Front Mic", 0x1 },
10031		{ "Line", 0x2 },
10032		{ "CD", 0x4 },
10033	},
10034};
10035
10036static struct hda_input_mux alc861vd_dallas_capture_source = {
10037	.num_items = 3,
10038	.items = {
10039		{ "Front Mic", 0x0 },
10040		{ "ATAPI Mic", 0x1 },
10041		{ "Line In", 0x5 },
10042	},
10043};
10044
10045static struct hda_input_mux alc861vd_hp_capture_source = {
10046	.num_items = 2,
10047	.items = {
10048		{ "Front Mic", 0x0 },
10049		{ "ATAPI Mic", 0x1 },
10050	},
10051};
10052
10053#define alc861vd_mux_enum_info alc_mux_enum_info
10054#define alc861vd_mux_enum_get alc_mux_enum_get
10055
10056static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
10057				struct snd_ctl_elem_value *ucontrol)
10058{
10059	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10060	struct alc_spec *spec = codec->spec;
10061	const struct hda_input_mux *imux = spec->input_mux;
10062	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
10063	static hda_nid_t capture_mixers[1] = { 0x22 };
10064	hda_nid_t nid = capture_mixers[adc_idx];
10065	unsigned int *cur_val = &spec->cur_mux[adc_idx];
10066	unsigned int i, idx;
10067
10068	idx = ucontrol->value.enumerated.item[0];
10069	if (idx >= imux->num_items)
10070		idx = imux->num_items - 1;
10071	if (*cur_val == idx)
10072		return 0;
10073	for (i = 0; i < imux->num_items; i++) {
10074		unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
10075		snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
10076					 imux->items[i].index,
10077					 HDA_AMP_MUTE, v);
10078	}
10079	*cur_val = idx;
10080	return 1;
10081}
10082
10083/*
10084 * 2ch mode
10085 */
10086static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
10087	{ 2, NULL }
10088};
10089
10090/*
10091 * 6ch mode
10092 */
10093static struct hda_verb alc861vd_6stack_ch6_init[] = {
10094	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10095	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10096	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10097	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10098	{ } /* end */
10099};
10100
10101/*
10102 * 8ch mode
10103 */
10104static struct hda_verb alc861vd_6stack_ch8_init[] = {
10105	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10106	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10107	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10108	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10109	{ } /* end */
10110};
10111
10112static struct hda_channel_mode alc861vd_6stack_modes[2] = {
10113	{ 6, alc861vd_6stack_ch6_init },
10114	{ 8, alc861vd_6stack_ch8_init },
10115};
10116
10117static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
10118	{
10119		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10120		.name = "Channel Mode",
10121		.info = alc_ch_mode_info,
10122		.get = alc_ch_mode_get,
10123		.put = alc_ch_mode_put,
10124	},
10125	{ } /* end */
10126};
10127
10128static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
10129	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10130	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10131
10132	{
10133		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10134		/* The multiple "Capture Source" controls confuse alsamixer
10135		 * So call somewhat different..
10136		 *FIXME: the controls appear in the "playback" view!
10137		 */
10138		/* .name = "Capture Source", */
10139		.name = "Input Source",
10140		.count = 1,
10141		.info = alc861vd_mux_enum_info,
10142		.get = alc861vd_mux_enum_get,
10143		.put = alc861vd_mux_enum_put,
10144	},
10145	{ } /* end */
10146};
10147
10148/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
10149 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
10150 */
10151static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
10152	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10153	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10154
10155	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10156	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
10157
10158	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
10159				HDA_OUTPUT),
10160	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
10161				HDA_OUTPUT),
10162	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
10163	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
10164
10165	HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
10166	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
10167
10168	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10169
10170	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10171	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10172	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10173
10174	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10175	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10176	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10177
10178	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10179	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10180
10181	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10182	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10183
10184	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10185	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10186
10187	{ } /* end */
10188};
10189
10190static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
10191	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10192	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10193
10194	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10195
10196	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10197	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10198	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10199
10200	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10201	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10202	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10203
10204	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10205	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10206
10207	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10208	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10209
10210	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10211	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10212
10213	{ } /* end */
10214};
10215
10216static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
10217	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10218	/*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
10219	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10220
10221	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10222
10223	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10224	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10225	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10226
10227	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10228	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10229	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10230
10231	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10232	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10233
10234	{ } /* end */
10235};
10236
10237/* Pin assignment: Front=0x14, HP = 0x15,
10238 *                 Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
10239 */
10240static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
10241	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10242	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10243	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10244	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
10245	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10246	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10247	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10248	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10249	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
10250	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
10251	{ } /* end */
10252};
10253
10254/* Pin assignment: Speaker=0x14, Line-out = 0x15,
10255 *                 Front Mic=0x18, ATAPI Mic = 0x19,
10256 */
10257static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
10258	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10259	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10260	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10261	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
10262	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10263	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10264	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10265	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10266
10267	{ } /* end */
10268};
10269
10270/*
10271 * generic initialization of ADC, input mixers and output mixers
10272 */
10273static struct hda_verb alc861vd_volume_init_verbs[] = {
10274	/*
10275	 * Unmute ADC0 and set the default input to mic-in
10276	 */
10277	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10278	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10279
10280	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
10281	 * the analog-loopback mixer widget
10282	 */
10283	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10284	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10285	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10286	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10287	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10288	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10289
10290	/* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
10291	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10292	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10293	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10294	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10295
10296	/*
10297	 * Set up output mixers (0x02 - 0x05)
10298	 */
10299	/* set vol=0 to output mixers */
10300	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10301	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10302	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10303	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10304
10305	/* set up input amps for analog loopback */
10306	/* Amp Indices: DAC = 0, mixer = 1 */
10307	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10308	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10309	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10310	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10311	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10312	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10313	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10314	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10315
10316	{ }
10317};
10318
10319/*
10320 * 3-stack pin configuration:
10321 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
10322 */
10323static struct hda_verb alc861vd_3stack_init_verbs[] = {
10324	/*
10325	 * Set pin mode and muting
10326	 */
10327	/* set front pin widgets 0x14 for output */
10328	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10329	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10330	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10331
10332	/* Mic (rear) pin: input vref at 80% */
10333	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10334	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10335	/* Front Mic pin: input vref at 80% */
10336	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10337	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10338	/* Line In pin: input */
10339	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10340	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10341	/* Line-2 In: Headphone output (output 0 - 0x0c) */
10342	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10343	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10344	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10345	/* CD pin widget for input */
10346	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10347
10348	{ }
10349};
10350
10351/*
10352 * 6-stack pin configuration:
10353 */
10354static struct hda_verb alc861vd_6stack_init_verbs[] = {
10355	/*
10356	 * Set pin mode and muting
10357	 */
10358	/* set front pin widgets 0x14 for output */
10359	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10360	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10361	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10362
10363	/* Rear Pin: output 1 (0x0d) */
10364	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10365	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10366	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10367	/* CLFE Pin: output 2 (0x0e) */
10368	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10369	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10370	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
10371	/* Side Pin: output 3 (0x0f) */
10372	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10373	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10374	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
10375
10376	/* Mic (rear) pin: input vref at 80% */
10377	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10378	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10379	/* Front Mic pin: input vref at 80% */
10380	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10381	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10382	/* Line In pin: input */
10383	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10384	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10385	/* Line-2 In: Headphone output (output 0 - 0x0c) */
10386	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10387	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10388	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10389	/* CD pin widget for input */
10390	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10391
10392	{ }
10393};
10394
10395static struct hda_verb alc861vd_eapd_verbs[] = {
10396	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10397	{ }
10398};
10399
10400static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
10401	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10402	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10403	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10404	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10405	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10406	{}
10407};
10408
10409/* toggle speaker-output according to the hp-jack state */
10410static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
10411{
10412	unsigned int present;
10413	unsigned char bits;
10414
10415	present = snd_hda_codec_read(codec, 0x1b, 0,
10416				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10417	bits = present ? HDA_AMP_MUTE : 0;
10418	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10419				 HDA_AMP_MUTE, bits);
10420}
10421
10422static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
10423{
10424	unsigned int present;
10425	unsigned char bits;
10426
10427	present = snd_hda_codec_read(codec, 0x18, 0,
10428				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10429	bits = present ? HDA_AMP_MUTE : 0;
10430	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
10431				 HDA_AMP_MUTE, bits);
10432}
10433
10434static void alc861vd_lenovo_automute(struct hda_codec *codec)
10435{
10436	alc861vd_lenovo_hp_automute(codec);
10437	alc861vd_lenovo_mic_automute(codec);
10438}
10439
10440static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
10441					unsigned int res)
10442{
10443	switch (res >> 26) {
10444	case ALC880_HP_EVENT:
10445		alc861vd_lenovo_hp_automute(codec);
10446		break;
10447	case ALC880_MIC_EVENT:
10448		alc861vd_lenovo_mic_automute(codec);
10449		break;
10450	}
10451}
10452
10453static struct hda_verb alc861vd_dallas_verbs[] = {
10454	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10455	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10456	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10457	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10458
10459	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10460	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10461	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10462	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10463	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10464	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10465	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10466	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10467
10468	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10469	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10470	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10471	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10472	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10473	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10474	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10475	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10476
10477	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
10478	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10479	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
10480	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10481	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10482	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10483	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10484	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10485
10486	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10487	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10488	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10489	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10490
10491	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10492	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10493	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10494
10495	{ } /* end */
10496};
10497
10498/* toggle speaker-output according to the hp-jack state */
10499static void alc861vd_dallas_automute(struct hda_codec *codec)
10500{
10501	unsigned int present;
10502
10503	present = snd_hda_codec_read(codec, 0x15, 0,
10504				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10505	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10506				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
10507}
10508
10509static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
10510{
10511	if ((res >> 26) == ALC880_HP_EVENT)
10512		alc861vd_dallas_automute(codec);
10513}
10514
10515#ifdef CONFIG_SND_HDA_POWER_SAVE
10516#define alc861vd_loopbacks	alc880_loopbacks
10517#endif
10518
10519/* pcm configuration: identiacal with ALC880 */
10520#define alc861vd_pcm_analog_playback	alc880_pcm_analog_playback
10521#define alc861vd_pcm_analog_capture	alc880_pcm_analog_capture
10522#define alc861vd_pcm_digital_playback	alc880_pcm_digital_playback
10523#define alc861vd_pcm_digital_capture	alc880_pcm_digital_capture
10524
10525/*
10526 * configuration and preset
10527 */
10528static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
10529	[ALC660VD_3ST]		= "3stack-660",
10530	[ALC660VD_3ST_DIG]	= "3stack-660-digout",
10531	[ALC861VD_3ST]		= "3stack",
10532	[ALC861VD_3ST_DIG]	= "3stack-digout",
10533	[ALC861VD_6ST_DIG]	= "6stack-digout",
10534	[ALC861VD_LENOVO]	= "lenovo",
10535	[ALC861VD_DALLAS]	= "dallas",
10536	[ALC861VD_HP]		= "hp",
10537	[ALC861VD_AUTO]		= "auto",
10538};
10539
10540static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
10541	SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
10542	SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
10543	SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
10544	SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
10545	SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
10546
10547	/*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
10548	SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
10549	SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
10550	SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
10551	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
10552	SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
10553	SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
10554	SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
10555	{}
10556};
10557
10558static struct alc_config_preset alc861vd_presets[] = {
10559	[ALC660VD_3ST] = {
10560		.mixers = { alc861vd_3st_mixer },
10561		.init_verbs = { alc861vd_volume_init_verbs,
10562				 alc861vd_3stack_init_verbs },
10563		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10564		.dac_nids = alc660vd_dac_nids,
10565		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10566		.adc_nids = alc861vd_adc_nids,
10567		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10568		.channel_mode = alc861vd_3stack_2ch_modes,
10569		.input_mux = &alc861vd_capture_source,
10570	},
10571	[ALC660VD_3ST_DIG] = {
10572		.mixers = { alc861vd_3st_mixer },
10573		.init_verbs = { alc861vd_volume_init_verbs,
10574				 alc861vd_3stack_init_verbs },
10575		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10576		.dac_nids = alc660vd_dac_nids,
10577		.dig_out_nid = ALC861VD_DIGOUT_NID,
10578		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10579		.adc_nids = alc861vd_adc_nids,
10580		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10581		.channel_mode = alc861vd_3stack_2ch_modes,
10582		.input_mux = &alc861vd_capture_source,
10583	},
10584	[ALC861VD_3ST] = {
10585		.mixers = { alc861vd_3st_mixer },
10586		.init_verbs = { alc861vd_volume_init_verbs,
10587				 alc861vd_3stack_init_verbs },
10588		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10589		.dac_nids = alc861vd_dac_nids,
10590		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10591		.channel_mode = alc861vd_3stack_2ch_modes,
10592		.input_mux = &alc861vd_capture_source,
10593	},
10594	[ALC861VD_3ST_DIG] = {
10595		.mixers = { alc861vd_3st_mixer },
10596		.init_verbs = { alc861vd_volume_init_verbs,
10597		 		 alc861vd_3stack_init_verbs },
10598		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10599		.dac_nids = alc861vd_dac_nids,
10600		.dig_out_nid = ALC861VD_DIGOUT_NID,
10601		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10602		.channel_mode = alc861vd_3stack_2ch_modes,
10603		.input_mux = &alc861vd_capture_source,
10604	},
10605	[ALC861VD_6ST_DIG] = {
10606		.mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
10607		.init_verbs = { alc861vd_volume_init_verbs,
10608				alc861vd_6stack_init_verbs },
10609		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10610		.dac_nids = alc861vd_dac_nids,
10611		.dig_out_nid = ALC861VD_DIGOUT_NID,
10612		.num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
10613		.channel_mode = alc861vd_6stack_modes,
10614		.input_mux = &alc861vd_capture_source,
10615	},
10616	[ALC861VD_LENOVO] = {
10617		.mixers = { alc861vd_lenovo_mixer },
10618		.init_verbs = { alc861vd_volume_init_verbs,
10619				alc861vd_3stack_init_verbs,
10620				alc861vd_eapd_verbs,
10621				alc861vd_lenovo_unsol_verbs },
10622		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10623		.dac_nids = alc660vd_dac_nids,
10624		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10625		.adc_nids = alc861vd_adc_nids,
10626		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10627		.channel_mode = alc861vd_3stack_2ch_modes,
10628		.input_mux = &alc861vd_capture_source,
10629		.unsol_event = alc861vd_lenovo_unsol_event,
10630		.init_hook = alc861vd_lenovo_automute,
10631	},
10632	[ALC861VD_DALLAS] = {
10633		.mixers = { alc861vd_dallas_mixer },
10634		.init_verbs = { alc861vd_dallas_verbs },
10635		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10636		.dac_nids = alc861vd_dac_nids,
10637		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10638		.adc_nids = alc861vd_adc_nids,
10639		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10640		.channel_mode = alc861vd_3stack_2ch_modes,
10641		.input_mux = &alc861vd_dallas_capture_source,
10642		.unsol_event = alc861vd_dallas_unsol_event,
10643		.init_hook = alc861vd_dallas_automute,
10644	},
10645	[ALC861VD_HP] = {
10646		.mixers = { alc861vd_hp_mixer },
10647		.init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
10648		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10649		.dac_nids = alc861vd_dac_nids,
10650		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10651		.dig_out_nid = ALC861VD_DIGOUT_NID,
10652		.adc_nids = alc861vd_adc_nids,
10653		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10654		.channel_mode = alc861vd_3stack_2ch_modes,
10655		.input_mux = &alc861vd_hp_capture_source,
10656		.unsol_event = alc861vd_dallas_unsol_event,
10657		.init_hook = alc861vd_dallas_automute,
10658	},
10659};
10660
10661/*
10662 * BIOS auto configuration
10663 */
10664static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
10665				hda_nid_t nid, int pin_type, int dac_idx)
10666{
10667	/* set as output */
10668	snd_hda_codec_write(codec, nid, 0,
10669				AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
10670	snd_hda_codec_write(codec, nid, 0,
10671				AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
10672}
10673
10674static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
10675{
10676	struct alc_spec *spec = codec->spec;
10677	int i;
10678
10679	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
10680	for (i = 0; i <= HDA_SIDE; i++) {
10681		hda_nid_t nid = spec->autocfg.line_out_pins[i];
10682		int pin_type = get_pin_type(spec->autocfg.line_out_type);
10683		if (nid)
10684			alc861vd_auto_set_output_and_unmute(codec, nid,
10685							    pin_type, i);
10686	}
10687}
10688
10689
10690static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
10691{
10692	struct alc_spec *spec = codec->spec;
10693	hda_nid_t pin;
10694
10695	pin = spec->autocfg.hp_pins[0];
10696	if (pin) /* connect to front and  use dac 0 */
10697		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
10698}
10699
10700#define alc861vd_is_input_pin(nid)	alc880_is_input_pin(nid)
10701#define ALC861VD_PIN_CD_NID		ALC880_PIN_CD_NID
10702
10703static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
10704{
10705	struct alc_spec *spec = codec->spec;
10706	int i;
10707
10708	for (i = 0; i < AUTO_PIN_LAST; i++) {
10709		hda_nid_t nid = spec->autocfg.input_pins[i];
10710		if (alc861vd_is_input_pin(nid)) {
10711			snd_hda_codec_write(codec, nid, 0,
10712					AC_VERB_SET_PIN_WIDGET_CONTROL,
10713					i <= AUTO_PIN_FRONT_MIC ?
10714							PIN_VREF80 : PIN_IN);
10715			if (nid != ALC861VD_PIN_CD_NID)
10716				snd_hda_codec_write(codec, nid, 0,
10717						AC_VERB_SET_AMP_GAIN_MUTE,
10718						AMP_OUT_MUTE);
10719		}
10720	}
10721}
10722
10723#define alc861vd_idx_to_mixer_vol(nid)		((nid) + 0x02)
10724#define alc861vd_idx_to_mixer_switch(nid)	((nid) + 0x0c)
10725
10726/* add playback controls from the parsed DAC table */
10727/* Based on ALC880 version. But ALC861VD has separate,
10728 * different NIDs for mute/unmute switch and volume control */
10729static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
10730					     const struct auto_pin_cfg *cfg)
10731{
10732	char name[32];
10733	static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
10734	hda_nid_t nid_v, nid_s;
10735	int i, err;
10736
10737	for (i = 0; i < cfg->line_outs; i++) {
10738		if (!spec->multiout.dac_nids[i])
10739			continue;
10740		nid_v = alc861vd_idx_to_mixer_vol(
10741				alc880_dac_to_idx(
10742					spec->multiout.dac_nids[i]));
10743		nid_s = alc861vd_idx_to_mixer_switch(
10744				alc880_dac_to_idx(
10745					spec->multiout.dac_nids[i]));
10746
10747		if (i == 2) {
10748			/* Center/LFE */
10749			err = add_control(spec, ALC_CTL_WIDGET_VOL,
10750					  "Center Playback Volume",
10751					  HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
10752							      HDA_OUTPUT));
10753			if (err < 0)
10754				return err;
10755			err = add_control(spec, ALC_CTL_WIDGET_VOL,
10756					  "LFE Playback Volume",
10757					  HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
10758							      HDA_OUTPUT));
10759			if (err < 0)
10760				return err;
10761			err = add_control(spec, ALC_CTL_BIND_MUTE,
10762					  "Center Playback Switch",
10763					  HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
10764							      HDA_INPUT));
10765			if (err < 0)
10766				return err;
10767			err = add_control(spec, ALC_CTL_BIND_MUTE,
10768					  "LFE Playback Switch",
10769					  HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
10770							      HDA_INPUT));
10771			if (err < 0)
10772				return err;
10773		} else {
10774			sprintf(name, "%s Playback Volume", chname[i]);
10775			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10776					  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
10777							      HDA_OUTPUT));
10778			if (err < 0)
10779				return err;
10780			sprintf(name, "%s Playback Switch", chname[i]);
10781			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10782					  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
10783							      HDA_INPUT));
10784			if (err < 0)
10785				return err;
10786		}
10787	}
10788	return 0;
10789}
10790
10791/* add playback controls for speaker and HP outputs */
10792/* Based on ALC880 version. But ALC861VD has separate,
10793 * different NIDs for mute/unmute switch and volume control */
10794static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
10795					hda_nid_t pin, const char *pfx)
10796{
10797	hda_nid_t nid_v, nid_s;
10798	int err;
10799	char name[32];
10800
10801	if (!pin)
10802		return 0;
10803
10804	if (alc880_is_fixed_pin(pin)) {
10805		nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
10806		/* specify the DAC as the extra output */
10807		if (!spec->multiout.hp_nid)
10808			spec->multiout.hp_nid = nid_v;
10809		else
10810			spec->multiout.extra_out_nid[0] = nid_v;
10811		/* control HP volume/switch on the output mixer amp */
10812		nid_v = alc861vd_idx_to_mixer_vol(
10813				alc880_fixed_pin_idx(pin));
10814		nid_s = alc861vd_idx_to_mixer_switch(
10815				alc880_fixed_pin_idx(pin));
10816
10817		sprintf(name, "%s Playback Volume", pfx);
10818		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10819				  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
10820		if (err < 0)
10821			return err;
10822		sprintf(name, "%s Playback Switch", pfx);
10823		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10824				  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
10825		if (err < 0)
10826			return err;
10827	} else if (alc880_is_multi_pin(pin)) {
10828		/* set manual connection */
10829		/* we have only a switch on HP-out PIN */
10830		sprintf(name, "%s Playback Switch", pfx);
10831		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
10832				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
10833		if (err < 0)
10834			return err;
10835	}
10836	return 0;
10837}
10838
10839/* parse the BIOS configuration and set up the alc_spec
10840 * return 1 if successful, 0 if the proper config is not found,
10841 * or a negative error code
10842 * Based on ALC880 version - had to change it to override
10843 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
10844static int alc861vd_parse_auto_config(struct hda_codec *codec)
10845{
10846	struct alc_spec *spec = codec->spec;
10847	int err;
10848	static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
10849
10850	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10851					   alc861vd_ignore);
10852	if (err < 0)
10853		return err;
10854	if (!spec->autocfg.line_outs)
10855		return 0; /* can't find valid BIOS pin config */
10856
10857	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10858	if (err < 0)
10859		return err;
10860	err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
10861	if (err < 0)
10862		return err;
10863	err = alc861vd_auto_create_extra_out(spec,
10864					     spec->autocfg.speaker_pins[0],
10865					     "Speaker");
10866	if (err < 0)
10867		return err;
10868	err = alc861vd_auto_create_extra_out(spec,
10869					     spec->autocfg.hp_pins[0],
10870					     "Headphone");
10871	if (err < 0)
10872		return err;
10873	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
10874	if (err < 0)
10875		return err;
10876
10877	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10878
10879	if (spec->autocfg.dig_out_pin)
10880		spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
10881
10882	if (spec->kctl_alloc)
10883		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10884
10885	spec->init_verbs[spec->num_init_verbs++]
10886		= alc861vd_volume_init_verbs;
10887
10888	spec->num_mux_defs = 1;
10889	spec->input_mux = &spec->private_imux;
10890
10891	return 1;
10892}
10893
10894/* additional initialization for auto-configuration model */
10895static void alc861vd_auto_init(struct hda_codec *codec)
10896{
10897	alc861vd_auto_init_multi_out(codec);
10898	alc861vd_auto_init_hp_out(codec);
10899	alc861vd_auto_init_analog_input(codec);
10900}
10901
10902static int patch_alc861vd(struct hda_codec *codec)
10903{
10904	struct alc_spec *spec;
10905	int err, board_config;
10906
10907	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10908	if (spec == NULL)
10909		return -ENOMEM;
10910
10911	codec->spec = spec;
10912
10913	board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
10914						  alc861vd_models,
10915						  alc861vd_cfg_tbl);
10916
10917	if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
10918		printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
10919			"ALC861VD, trying auto-probe from BIOS...\n");
10920		board_config = ALC861VD_AUTO;
10921	}
10922
10923	if (board_config == ALC861VD_AUTO) {
10924		/* automatic parse from the BIOS config */
10925		err = alc861vd_parse_auto_config(codec);
10926		if (err < 0) {
10927			alc_free(codec);
10928			return err;
10929		} else if (!err) {
10930			printk(KERN_INFO
10931			       "hda_codec: Cannot set up configuration "
10932			       "from BIOS.  Using base mode...\n");
10933			board_config = ALC861VD_3ST;
10934		}
10935	}
10936
10937	if (board_config != ALC861VD_AUTO)
10938		setup_preset(spec, &alc861vd_presets[board_config]);
10939
10940	spec->stream_name_analog = "ALC861VD Analog";
10941	spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
10942	spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
10943
10944	spec->stream_name_digital = "ALC861VD Digital";
10945	spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
10946	spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
10947
10948	spec->adc_nids = alc861vd_adc_nids;
10949	spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
10950
10951	spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
10952	spec->num_mixers++;
10953
10954	codec->patch_ops = alc_patch_ops;
10955
10956	if (board_config == ALC861VD_AUTO)
10957		spec->init_hook = alc861vd_auto_init;
10958#ifdef CONFIG_SND_HDA_POWER_SAVE
10959	if (!spec->loopback.amplist)
10960		spec->loopback.amplist = alc861vd_loopbacks;
10961#endif
10962
10963	return 0;
10964}
10965
10966/*
10967 * ALC662 support
10968 *
10969 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
10970 * configuration.  Each pin widget can choose any input DACs and a mixer.
10971 * Each ADC is connected from a mixer of all inputs.  This makes possible
10972 * 6-channel independent captures.
10973 *
10974 * In addition, an independent DAC for the multi-playback (not used in this
10975 * driver yet).
10976 */
10977#define ALC662_DIGOUT_NID	0x06
10978#define ALC662_DIGIN_NID	0x0a
10979
10980static hda_nid_t alc662_dac_nids[4] = {
10981	/* front, rear, clfe, rear_surr */
10982	0x02, 0x03, 0x04
10983};
10984
10985static hda_nid_t alc662_adc_nids[1] = {
10986	/* ADC1-2 */
10987	0x09,
10988};
10989/* input MUX */
10990/* FIXME: should be a matrix-type input source selection */
10991
10992static struct hda_input_mux alc662_capture_source = {
10993	.num_items = 4,
10994	.items = {
10995		{ "Mic", 0x0 },
10996		{ "Front Mic", 0x1 },
10997		{ "Line", 0x2 },
10998		{ "CD", 0x4 },
10999	},
11000};
11001
11002static struct hda_input_mux alc662_lenovo_101e_capture_source = {
11003	.num_items = 2,
11004	.items = {
11005		{ "Mic", 0x1 },
11006		{ "Line", 0x2 },
11007	},
11008};
11009#define alc662_mux_enum_info alc_mux_enum_info
11010#define alc662_mux_enum_get alc_mux_enum_get
11011
11012static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
11013			       struct snd_ctl_elem_value *ucontrol)
11014{
11015	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11016	struct alc_spec *spec = codec->spec;
11017	const struct hda_input_mux *imux = spec->input_mux;
11018	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
11019	static hda_nid_t capture_mixers[2] = { 0x23, 0x22 };
11020	hda_nid_t nid = capture_mixers[adc_idx];
11021	unsigned int *cur_val = &spec->cur_mux[adc_idx];
11022	unsigned int i, idx;
11023
11024	idx = ucontrol->value.enumerated.item[0];
11025	if (idx >= imux->num_items)
11026		idx = imux->num_items - 1;
11027	if (*cur_val == idx)
11028		return 0;
11029	for (i = 0; i < imux->num_items; i++) {
11030		unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
11031		snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
11032					 imux->items[i].index,
11033					 HDA_AMP_MUTE, v);
11034	}
11035	*cur_val = idx;
11036	return 1;
11037}
11038/*
11039 * 2ch mode
11040 */
11041static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
11042	{ 2, NULL }
11043};
11044
11045/*
11046 * 2ch mode
11047 */
11048static struct hda_verb alc662_3ST_ch2_init[] = {
11049	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
11050	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
11051	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
11052	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
11053	{ } /* end */
11054};
11055
11056/*
11057 * 6ch mode
11058 */
11059static struct hda_verb alc662_3ST_ch6_init[] = {
11060	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11061	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11062	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
11063	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11064	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11065	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
11066	{ } /* end */
11067};
11068
11069static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
11070	{ 2, alc662_3ST_ch2_init },
11071	{ 6, alc662_3ST_ch6_init },
11072};
11073
11074/*
11075 * 2ch mode
11076 */
11077static struct hda_verb alc662_sixstack_ch6_init[] = {
11078	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11079	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11080	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11081	{ } /* end */
11082};
11083
11084/*
11085 * 6ch mode
11086 */
11087static struct hda_verb alc662_sixstack_ch8_init[] = {
11088	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11089	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11090	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11091	{ } /* end */
11092};
11093
11094static struct hda_channel_mode alc662_5stack_modes[2] = {
11095	{ 2, alc662_sixstack_ch6_init },
11096	{ 6, alc662_sixstack_ch8_init },
11097};
11098
11099/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
11100 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
11101 */
11102
11103static struct snd_kcontrol_new alc662_base_mixer[] = {
11104	/* output mixer control */
11105	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11106	HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
11107	HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11108	HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11109	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
11110	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
11111	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
11112	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
11113	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11114
11115	/*Input mixer control */
11116	HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
11117	HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
11118	HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
11119	HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
11120	HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
11121	HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
11122	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
11123	HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
11124
11125	/* Capture mixer control */
11126	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11127	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11128	{
11129		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11130		.name = "Capture Source",
11131		.count = 1,
11132		.info = alc_mux_enum_info,
11133		.get = alc_mux_enum_get,
11134		.put = alc_mux_enum_put,
11135	},
11136	{ } /* end */
11137};
11138
11139static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
11140	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11141	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
11142	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11143	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11144	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11145	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11146	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11147	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11148	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11149	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11150	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11151	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11152	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11153	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11154	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11155	{
11156		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11157		/* .name = "Capture Source", */
11158		.name = "Input Source",
11159		.count = 1,
11160		.info = alc662_mux_enum_info,
11161		.get = alc662_mux_enum_get,
11162		.put = alc662_mux_enum_put,
11163	},
11164	{ } /* end */
11165};
11166
11167static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
11168	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11169	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
11170	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11171	HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
11172	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
11173	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
11174	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
11175	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
11176	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11177	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11178	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11179	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11180	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11181	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11182	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11183	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11184	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11185	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11186	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11187	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11188	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11189	{
11190		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11191		/* .name = "Capture Source", */
11192		.name = "Input Source",
11193		.count = 1,
11194		.info = alc662_mux_enum_info,
11195		.get = alc662_mux_enum_get,
11196		.put = alc662_mux_enum_put,
11197	},
11198	{ } /* end */
11199};
11200
11201static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
11202	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11203	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
11204	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11205	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT),
11206	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11207	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11208	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11209	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11210	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11211	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11212	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11213	{
11214		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11215		/* .name = "Capture Source", */
11216		.name = "Input Source",
11217		.count = 1,
11218		.info = alc662_mux_enum_info,
11219		.get = alc662_mux_enum_get,
11220		.put = alc662_mux_enum_put,
11221	},
11222	{ } /* end */
11223};
11224
11225static struct snd_kcontrol_new alc662_chmode_mixer[] = {
11226	{
11227		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11228		.name = "Channel Mode",
11229		.info = alc_ch_mode_info,
11230		.get = alc_ch_mode_get,
11231		.put = alc_ch_mode_put,
11232	},
11233	{ } /* end */
11234};
11235
11236static struct hda_verb alc662_init_verbs[] = {
11237	/* ADC: mute amp left and right */
11238	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11239	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11240	/* Front mixer: unmute input/output amp left and right (volume = 0) */
11241
11242	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11243	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11244	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11245	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11246	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11247
11248	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11249	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11250	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11251	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11252	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11253	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11254
11255	/* Front Pin: output 0 (0x0c) */
11256	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11257	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11258
11259	/* Rear Pin: output 1 (0x0d) */
11260	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11261	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11262
11263	/* CLFE Pin: output 2 (0x0e) */
11264	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11265	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11266
11267	/* Mic (rear) pin: input vref at 80% */
11268	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11269	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11270	/* Front Mic pin: input vref at 80% */
11271	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11272	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11273	/* Line In pin: input */
11274	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11275	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11276	/* Line-2 In: Headphone output (output 0 - 0x0c) */
11277	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11278	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11279	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11280	/* CD pin widget for input */
11281	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11282
11283	/* FIXME: use matrix-type input source selection */
11284	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11285	/* Input mixer */
11286	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11287	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11288	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11289	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11290	{ }
11291};
11292
11293static struct hda_verb alc662_sue_init_verbs[] = {
11294	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
11295	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
11296        {}
11297};
11298
11299/*
11300 * generic initialization of ADC, input mixers and output mixers
11301 */
11302static struct hda_verb alc662_auto_init_verbs[] = {
11303	/*
11304	 * Unmute ADC and set the default input to mic-in
11305	 */
11306	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11307	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11308
11309	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11310	 * mixer widget
11311	 * Note: PASD motherboards uses the Line In 2 as the input for front
11312	 * panel mic (mic 2)
11313	 */
11314	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11315	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11316	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11317	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11318	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11319	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11320
11321	/*
11322	 * Set up output mixers (0x0c - 0x0f)
11323	 */
11324	/* set vol=0 to output mixers */
11325	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11326	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11327	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11328
11329	/* set up input amps for analog loopback */
11330	/* Amp Indices: DAC = 0, mixer = 1 */
11331	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11332	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11333	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11334	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11335	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11336	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11337
11338
11339	/* FIXME: use matrix-type input source selection */
11340	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11341	/* Input mixer */
11342	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11343	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11344	{ }
11345};
11346
11347/* capture mixer elements */
11348static struct snd_kcontrol_new alc662_capture_mixer[] = {
11349	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11350	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11351	{
11352		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11353		/* The multiple "Capture Source" controls confuse alsamixer
11354		 * So call somewhat different..
11355		 * FIXME: the controls appear in the "playback" view!
11356		 */
11357		/* .name = "Capture Source", */
11358		.name = "Input Source",
11359		.count = 1,
11360		.info = alc882_mux_enum_info,
11361		.get = alc882_mux_enum_get,
11362		.put = alc882_mux_enum_put,
11363	},
11364	{ } /* end */
11365};
11366
11367static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
11368{
11369	unsigned int present;
11370	unsigned char bits;
11371
11372	present = snd_hda_codec_read(codec, 0x14, 0,
11373				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11374	bits = present ? HDA_AMP_MUTE : 0;
11375	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11376				 HDA_AMP_MUTE, bits);
11377}
11378
11379static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
11380{
11381	unsigned int present;
11382	unsigned char bits;
11383
11384 	present = snd_hda_codec_read(codec, 0x1b, 0,
11385				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11386	bits = present ? HDA_AMP_MUTE : 0;
11387	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11388				 HDA_AMP_MUTE, bits);
11389	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11390				 HDA_AMP_MUTE, bits);
11391}
11392
11393static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
11394					   unsigned int res)
11395{
11396	if ((res >> 26) == ALC880_HP_EVENT)
11397		alc662_lenovo_101e_all_automute(codec);
11398	if ((res >> 26) == ALC880_FRONT_EVENT)
11399		alc662_lenovo_101e_ispeaker_automute(codec);
11400}
11401
11402#ifdef CONFIG_SND_HDA_POWER_SAVE
11403#define alc662_loopbacks	alc880_loopbacks
11404#endif
11405
11406
11407/* pcm configuration: identiacal with ALC880 */
11408#define alc662_pcm_analog_playback	alc880_pcm_analog_playback
11409#define alc662_pcm_analog_capture	alc880_pcm_analog_capture
11410#define alc662_pcm_digital_playback	alc880_pcm_digital_playback
11411#define alc662_pcm_digital_capture	alc880_pcm_digital_capture
11412
11413/*
11414 * configuration and preset
11415 */
11416static const char *alc662_models[ALC662_MODEL_LAST] = {
11417	[ALC662_3ST_2ch_DIG]	= "3stack-dig",
11418	[ALC662_3ST_6ch_DIG]	= "3stack-6ch-dig",
11419	[ALC662_3ST_6ch]	= "3stack-6ch",
11420	[ALC662_5ST_DIG]	= "6stack-dig",
11421	[ALC662_LENOVO_101E]	= "lenovo-101e",
11422	[ALC662_AUTO]		= "auto",
11423};
11424
11425static struct snd_pci_quirk alc662_cfg_tbl[] = {
11426	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
11427	{}
11428};
11429
11430static struct alc_config_preset alc662_presets[] = {
11431	[ALC662_3ST_2ch_DIG] = {
11432		.mixers = { alc662_3ST_2ch_mixer },
11433		.init_verbs = { alc662_init_verbs },
11434		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
11435		.dac_nids = alc662_dac_nids,
11436		.dig_out_nid = ALC662_DIGOUT_NID,
11437		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11438		.adc_nids = alc662_adc_nids,
11439		.dig_in_nid = ALC662_DIGIN_NID,
11440		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
11441		.channel_mode = alc662_3ST_2ch_modes,
11442		.input_mux = &alc662_capture_source,
11443	},
11444	[ALC662_3ST_6ch_DIG] = {
11445		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
11446		.init_verbs = { alc662_init_verbs },
11447		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
11448		.dac_nids = alc662_dac_nids,
11449		.dig_out_nid = ALC662_DIGOUT_NID,
11450		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11451		.adc_nids = alc662_adc_nids,
11452		.dig_in_nid = ALC662_DIGIN_NID,
11453		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
11454		.channel_mode = alc662_3ST_6ch_modes,
11455		.need_dac_fix = 1,
11456		.input_mux = &alc662_capture_source,
11457	},
11458	[ALC662_3ST_6ch] = {
11459		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
11460		.init_verbs = { alc662_init_verbs },
11461		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
11462		.dac_nids = alc662_dac_nids,
11463		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11464		.adc_nids = alc662_adc_nids,
11465		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
11466		.channel_mode = alc662_3ST_6ch_modes,
11467		.need_dac_fix = 1,
11468		.input_mux = &alc662_capture_source,
11469	},
11470	[ALC662_5ST_DIG] = {
11471		.mixers = { alc662_base_mixer, alc662_chmode_mixer },
11472		.init_verbs = { alc662_init_verbs },
11473		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
11474		.dac_nids = alc662_dac_nids,
11475		.dig_out_nid = ALC662_DIGOUT_NID,
11476		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11477		.adc_nids = alc662_adc_nids,
11478		.dig_in_nid = ALC662_DIGIN_NID,
11479		.num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
11480		.channel_mode = alc662_5stack_modes,
11481		.input_mux = &alc662_capture_source,
11482	},
11483	[ALC662_LENOVO_101E] = {
11484		.mixers = { alc662_lenovo_101e_mixer },
11485		.init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
11486		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
11487		.dac_nids = alc662_dac_nids,
11488		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11489		.adc_nids = alc662_adc_nids,
11490		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
11491		.channel_mode = alc662_3ST_2ch_modes,
11492		.input_mux = &alc662_lenovo_101e_capture_source,
11493		.unsol_event = alc662_lenovo_101e_unsol_event,
11494		.init_hook = alc662_lenovo_101e_all_automute,
11495	},
11496
11497};
11498
11499
11500/*
11501 * BIOS auto configuration
11502 */
11503
11504/* add playback controls from the parsed DAC table */
11505static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
11506					     const struct auto_pin_cfg *cfg)
11507{
11508	char name[32];
11509	static const char *chname[4] = {
11510		"Front", "Surround", NULL /*CLFE*/, "Side"
11511	};
11512	hda_nid_t nid;
11513	int i, err;
11514
11515	for (i = 0; i < cfg->line_outs; i++) {
11516		if (!spec->multiout.dac_nids[i])
11517			continue;
11518		nid = alc880_idx_to_mixer(i);
11519		if (i == 2) {
11520			/* Center/LFE */
11521			err = add_control(spec, ALC_CTL_WIDGET_VOL,
11522					  "Center Playback Volume",
11523					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
11524							      HDA_OUTPUT));
11525			if (err < 0)
11526				return err;
11527			err = add_control(spec, ALC_CTL_WIDGET_VOL,
11528					  "LFE Playback Volume",
11529					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11530							      HDA_OUTPUT));
11531			if (err < 0)
11532				return err;
11533			err = add_control(spec, ALC_CTL_BIND_MUTE,
11534					  "Center Playback Switch",
11535					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
11536							      HDA_INPUT));
11537			if (err < 0)
11538				return err;
11539			err = add_control(spec, ALC_CTL_BIND_MUTE,
11540					  "LFE Playback Switch",
11541					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
11542							      HDA_INPUT));
11543			if (err < 0)
11544				return err;
11545		} else {
11546			sprintf(name, "%s Playback Volume", chname[i]);
11547			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11548					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11549							      HDA_OUTPUT));
11550			if (err < 0)
11551				return err;
11552			sprintf(name, "%s Playback Switch", chname[i]);
11553			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11554					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
11555							      HDA_INPUT));
11556			if (err < 0)
11557				return err;
11558		}
11559	}
11560	return 0;
11561}
11562
11563/* add playback controls for speaker and HP outputs */
11564static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
11565					const char *pfx)
11566{
11567	hda_nid_t nid;
11568	int err;
11569	char name[32];
11570
11571	if (!pin)
11572		return 0;
11573
11574	if (alc880_is_fixed_pin(pin)) {
11575		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
11576                /* printk("DAC nid=%x\n",nid); */
11577		/* specify the DAC as the extra output */
11578		if (!spec->multiout.hp_nid)
11579			spec->multiout.hp_nid = nid;
11580		else
11581			spec->multiout.extra_out_nid[0] = nid;
11582		/* control HP volume/switch on the output mixer amp */
11583		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
11584		sprintf(name, "%s Playback Volume", pfx);
11585		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11586				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
11587		if (err < 0)
11588			return err;
11589		sprintf(name, "%s Playback Switch", pfx);
11590		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11591				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
11592		if (err < 0)
11593			return err;
11594	} else if (alc880_is_multi_pin(pin)) {
11595		/* set manual connection */
11596		/* we have only a switch on HP-out PIN */
11597		sprintf(name, "%s Playback Switch", pfx);
11598		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11599				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
11600		if (err < 0)
11601			return err;
11602	}
11603	return 0;
11604}
11605
11606/* create playback/capture controls for input pins */
11607static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
11608						const struct auto_pin_cfg *cfg)
11609{
11610	struct hda_input_mux *imux = &spec->private_imux;
11611	int i, err, idx;
11612
11613	for (i = 0; i < AUTO_PIN_LAST; i++) {
11614		if (alc880_is_input_pin(cfg->input_pins[i])) {
11615			idx = alc880_input_pin_idx(cfg->input_pins[i]);
11616			err = new_analog_input(spec, cfg->input_pins[i],
11617					       auto_pin_cfg_labels[i],
11618					       idx, 0x0b);
11619			if (err < 0)
11620				return err;
11621			imux->items[imux->num_items].label =
11622				auto_pin_cfg_labels[i];
11623			imux->items[imux->num_items].index =
11624				alc880_input_pin_idx(cfg->input_pins[i]);
11625			imux->num_items++;
11626		}
11627	}
11628	return 0;
11629}
11630
11631static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
11632					      hda_nid_t nid, int pin_type,
11633					      int dac_idx)
11634{
11635	/* set as output */
11636	snd_hda_codec_write(codec, nid, 0,
11637			    AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
11638	snd_hda_codec_write(codec, nid, 0,
11639			    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
11640	/* need the manual connection? */
11641	if (alc880_is_multi_pin(nid)) {
11642		struct alc_spec *spec = codec->spec;
11643		int idx = alc880_multi_pin_idx(nid);
11644		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
11645				    AC_VERB_SET_CONNECT_SEL,
11646				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
11647	}
11648}
11649
11650static void alc662_auto_init_multi_out(struct hda_codec *codec)
11651{
11652	struct alc_spec *spec = codec->spec;
11653	int i;
11654
11655	for (i = 0; i <= HDA_SIDE; i++) {
11656		hda_nid_t nid = spec->autocfg.line_out_pins[i];
11657		int pin_type = get_pin_type(spec->autocfg.line_out_type);
11658		if (nid)
11659			alc662_auto_set_output_and_unmute(codec, nid, pin_type,
11660							  i);
11661	}
11662}
11663
11664static void alc662_auto_init_hp_out(struct hda_codec *codec)
11665{
11666	struct alc_spec *spec = codec->spec;
11667	hda_nid_t pin;
11668
11669	pin = spec->autocfg.hp_pins[0];
11670	if (pin) /* connect to front */
11671		/* use dac 0 */
11672		alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
11673}
11674
11675#define alc662_is_input_pin(nid)	alc880_is_input_pin(nid)
11676#define ALC662_PIN_CD_NID		ALC880_PIN_CD_NID
11677
11678static void alc662_auto_init_analog_input(struct hda_codec *codec)
11679{
11680	struct alc_spec *spec = codec->spec;
11681	int i;
11682
11683	for (i = 0; i < AUTO_PIN_LAST; i++) {
11684		hda_nid_t nid = spec->autocfg.input_pins[i];
11685		if (alc662_is_input_pin(nid)) {
11686			snd_hda_codec_write(codec, nid, 0,
11687					    AC_VERB_SET_PIN_WIDGET_CONTROL,
11688					    (i <= AUTO_PIN_FRONT_MIC ?
11689					     PIN_VREF80 : PIN_IN));
11690			if (nid != ALC662_PIN_CD_NID)
11691				snd_hda_codec_write(codec, nid, 0,
11692						    AC_VERB_SET_AMP_GAIN_MUTE,
11693						    AMP_OUT_MUTE);
11694		}
11695	}
11696}
11697
11698static int alc662_parse_auto_config(struct hda_codec *codec)
11699{
11700	struct alc_spec *spec = codec->spec;
11701	int err;
11702	static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
11703
11704	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11705					   alc662_ignore);
11706	if (err < 0)
11707		return err;
11708	if (!spec->autocfg.line_outs)
11709		return 0; /* can't find valid BIOS pin config */
11710
11711	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
11712	if (err < 0)
11713		return err;
11714	err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
11715	if (err < 0)
11716		return err;
11717	err = alc662_auto_create_extra_out(spec,
11718					   spec->autocfg.speaker_pins[0],
11719					   "Speaker");
11720	if (err < 0)
11721		return err;
11722	err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
11723					   "Headphone");
11724	if (err < 0)
11725		return err;
11726	err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
11727	if (err < 0)
11728		return err;
11729
11730	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11731
11732	if (spec->autocfg.dig_out_pin)
11733		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
11734
11735	if (spec->kctl_alloc)
11736		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11737
11738	spec->num_mux_defs = 1;
11739	spec->input_mux = &spec->private_imux;
11740
11741	spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
11742	spec->mixers[spec->num_mixers] = alc662_capture_mixer;
11743	spec->num_mixers++;
11744	return 1;
11745}
11746
11747/* additional initialization for auto-configuration model */
11748static void alc662_auto_init(struct hda_codec *codec)
11749{
11750	alc662_auto_init_multi_out(codec);
11751	alc662_auto_init_hp_out(codec);
11752	alc662_auto_init_analog_input(codec);
11753}
11754
11755static int patch_alc662(struct hda_codec *codec)
11756{
11757	struct alc_spec *spec;
11758	int err, board_config;
11759
11760	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11761	if (!spec)
11762		return -ENOMEM;
11763
11764	codec->spec = spec;
11765
11766	board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
11767						  alc662_models,
11768			  	                  alc662_cfg_tbl);
11769	if (board_config < 0) {
11770		printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
11771		       "trying auto-probe from BIOS...\n");
11772		board_config = ALC662_AUTO;
11773	}
11774
11775	if (board_config == ALC662_AUTO) {
11776		/* automatic parse from the BIOS config */
11777		err = alc662_parse_auto_config(codec);
11778		if (err < 0) {
11779			alc_free(codec);
11780			return err;
11781		} else if (!err) {
11782			printk(KERN_INFO
11783			       "hda_codec: Cannot set up configuration "
11784			       "from BIOS.  Using base mode...\n");
11785			board_config = ALC662_3ST_2ch_DIG;
11786		}
11787	}
11788
11789	if (board_config != ALC662_AUTO)
11790		setup_preset(spec, &alc662_presets[board_config]);
11791
11792	spec->stream_name_analog = "ALC662 Analog";
11793	spec->stream_analog_playback = &alc662_pcm_analog_playback;
11794	spec->stream_analog_capture = &alc662_pcm_analog_capture;
11795
11796	spec->stream_name_digital = "ALC662 Digital";
11797	spec->stream_digital_playback = &alc662_pcm_digital_playback;
11798	spec->stream_digital_capture = &alc662_pcm_digital_capture;
11799
11800	if (!spec->adc_nids && spec->input_mux) {
11801		spec->adc_nids = alc662_adc_nids;
11802		spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
11803	}
11804
11805	codec->patch_ops = alc_patch_ops;
11806	if (board_config == ALC662_AUTO)
11807		spec->init_hook = alc662_auto_init;
11808#ifdef CONFIG_SND_HDA_POWER_SAVE
11809	if (!spec->loopback.amplist)
11810		spec->loopback.amplist = alc662_loopbacks;
11811#endif
11812
11813	return 0;
11814}
11815
11816/*
11817 * patch entries
11818 */
11819struct hda_codec_preset snd_hda_preset_realtek[] = {
11820	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
11821	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
11822	{ .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
11823	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
11824	  .patch = patch_alc861 },
11825	{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
11826	{ .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
11827	{ .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
11828	{ .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
11829	  .patch = patch_alc883 },
11830	{ .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
11831	  .patch = patch_alc662 },
11832	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
11833	{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
11834	{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
11835	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
11836	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
11837	{} /* terminator */
11838};
11839