patch_realtek.c revision 983f8ae4067cf0731f19fc6bda3bc3ef200c32e7
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_AUTO,
107	ALC268_MODEL_LAST /* last tag */
108};
109
110/* ALC861 models */
111enum {
112	ALC861_3ST,
113	ALC660_3ST,
114	ALC861_3ST_DIG,
115	ALC861_6ST_DIG,
116	ALC861_UNIWILL_M31,
117	ALC861_TOSHIBA,
118	ALC861_ASUS,
119	ALC861_ASUS_LAPTOP,
120	ALC861_AUTO,
121	ALC861_MODEL_LAST,
122};
123
124/* ALC861-VD models */
125enum {
126	ALC660VD_3ST,
127	ALC660VD_3ST_DIG,
128	ALC861VD_3ST,
129	ALC861VD_3ST_DIG,
130	ALC861VD_6ST_DIG,
131	ALC861VD_LENOVO,
132	ALC861VD_DALLAS,
133	ALC861VD_HP,
134	ALC861VD_AUTO,
135	ALC861VD_MODEL_LAST,
136};
137
138/* ALC662 models */
139enum {
140	ALC662_3ST_2ch_DIG,
141	ALC662_3ST_6ch_DIG,
142	ALC662_3ST_6ch,
143	ALC662_5ST_DIG,
144	ALC662_LENOVO_101E,
145	ALC662_AUTO,
146	ALC662_MODEL_LAST,
147};
148
149/* ALC882 models */
150enum {
151	ALC882_3ST_DIG,
152	ALC882_6ST_DIG,
153	ALC882_ARIMA,
154	ALC882_W2JC,
155	ALC882_TARGA,
156	ALC882_ASUS_A7J,
157	ALC885_MACPRO,
158	ALC885_IMAC24,
159	ALC882_AUTO,
160	ALC882_MODEL_LAST,
161};
162
163/* ALC883 models */
164enum {
165	ALC883_3ST_2ch_DIG,
166	ALC883_3ST_6ch_DIG,
167	ALC883_3ST_6ch,
168	ALC883_6ST_DIG,
169	ALC883_TARGA_DIG,
170	ALC883_TARGA_2ch_DIG,
171	ALC883_ACER,
172	ALC883_ACER_ASPIRE,
173	ALC883_MEDION,
174	ALC883_MEDION_MD2,
175	ALC883_LAPTOP_EAPD,
176	ALC883_LENOVO_101E_2ch,
177	ALC883_LENOVO_NB0763,
178	ALC888_LENOVO_MS7195_DIG,
179	ALC888_6ST_HP,
180	ALC888_3ST_HP,
181	ALC883_AUTO,
182	ALC883_MODEL_LAST,
183};
184
185/* for GPIO Poll */
186#define GPIO_MASK	0x03
187
188struct alc_spec {
189	/* codec parameterization */
190	struct snd_kcontrol_new *mixers[5];	/* mixer arrays */
191	unsigned int num_mixers;
192
193	const struct hda_verb *init_verbs[5];	/* initialization verbs
194						 * don't forget NULL
195						 * termination!
196						 */
197	unsigned int num_init_verbs;
198
199	char *stream_name_analog;	/* analog PCM stream */
200	struct hda_pcm_stream *stream_analog_playback;
201	struct hda_pcm_stream *stream_analog_capture;
202
203	char *stream_name_digital;	/* digital PCM stream */
204	struct hda_pcm_stream *stream_digital_playback;
205	struct hda_pcm_stream *stream_digital_capture;
206
207	/* playback */
208	struct hda_multi_out multiout;	/* playback set-up
209					 * max_channels, dacs must be set
210					 * dig_out_nid and hp_nid are optional
211					 */
212
213	/* capture */
214	unsigned int num_adc_nids;
215	hda_nid_t *adc_nids;
216	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
217
218	/* capture source */
219	unsigned int num_mux_defs;
220	const struct hda_input_mux *input_mux;
221	unsigned int cur_mux[3];
222
223	/* channel model */
224	const struct hda_channel_mode *channel_mode;
225	int num_channel_mode;
226	int need_dac_fix;
227
228	/* PCM information */
229	struct hda_pcm pcm_rec[3];	/* used in alc_build_pcms() */
230
231	/* dynamic controls, init_verbs and input_mux */
232	struct auto_pin_cfg autocfg;
233	unsigned int num_kctl_alloc, num_kctl_used;
234	struct snd_kcontrol_new *kctl_alloc;
235	struct hda_input_mux private_imux;
236	hda_nid_t private_dac_nids[5];
237
238	/* hooks */
239	void (*init_hook)(struct hda_codec *codec);
240	void (*unsol_event)(struct hda_codec *codec, unsigned int res);
241
242	/* for pin sensing */
243	unsigned int sense_updated: 1;
244	unsigned int jack_present: 1;
245
246#ifdef CONFIG_SND_HDA_POWER_SAVE
247	struct hda_loopback_check loopback;
248#endif
249};
250
251/*
252 * configuration template - to be copied to the spec instance
253 */
254struct alc_config_preset {
255	struct snd_kcontrol_new *mixers[5]; /* should be identical size
256					     * with spec
257					     */
258	const struct hda_verb *init_verbs[5];
259	unsigned int num_dacs;
260	hda_nid_t *dac_nids;
261	hda_nid_t dig_out_nid;		/* optional */
262	hda_nid_t hp_nid;		/* optional */
263	unsigned int num_adc_nids;
264	hda_nid_t *adc_nids;
265	hda_nid_t dig_in_nid;
266	unsigned int num_channel_mode;
267	const struct hda_channel_mode *channel_mode;
268	int need_dac_fix;
269	unsigned int num_mux_defs;
270	const struct hda_input_mux *input_mux;
271	void (*unsol_event)(struct hda_codec *, unsigned int);
272	void (*init_hook)(struct hda_codec *);
273#ifdef CONFIG_SND_HDA_POWER_SAVE
274	struct hda_amp_list *loopbacks;
275#endif
276};
277
278
279/*
280 * input MUX handling
281 */
282static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
283			     struct snd_ctl_elem_info *uinfo)
284{
285	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
286	struct alc_spec *spec = codec->spec;
287	unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
288	if (mux_idx >= spec->num_mux_defs)
289		mux_idx = 0;
290	return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
291}
292
293static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
294			    struct snd_ctl_elem_value *ucontrol)
295{
296	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
297	struct alc_spec *spec = codec->spec;
298	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
299
300	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
301	return 0;
302}
303
304static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
305			    struct snd_ctl_elem_value *ucontrol)
306{
307	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
308	struct alc_spec *spec = codec->spec;
309	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
310	unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
311	return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
312				     spec->adc_nids[adc_idx],
313				     &spec->cur_mux[adc_idx]);
314}
315
316
317/*
318 * channel mode setting
319 */
320static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
321			    struct snd_ctl_elem_info *uinfo)
322{
323	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
324	struct alc_spec *spec = codec->spec;
325	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
326				    spec->num_channel_mode);
327}
328
329static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
330			   struct snd_ctl_elem_value *ucontrol)
331{
332	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
333	struct alc_spec *spec = codec->spec;
334	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
335				   spec->num_channel_mode,
336				   spec->multiout.max_channels);
337}
338
339static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
340			   struct snd_ctl_elem_value *ucontrol)
341{
342	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
343	struct alc_spec *spec = codec->spec;
344	int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
345				      spec->num_channel_mode,
346				      &spec->multiout.max_channels);
347	if (err >= 0 && spec->need_dac_fix)
348		spec->multiout.num_dacs = spec->multiout.max_channels / 2;
349	return err;
350}
351
352/*
353 * Control the mode of pin widget settings via the mixer.  "pc" is used
354 * instead of "%" to avoid consequences of accidently treating the % as
355 * being part of a format specifier.  Maximum allowed length of a value is
356 * 63 characters plus NULL terminator.
357 *
358 * Note: some retasking pin complexes seem to ignore requests for input
359 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
360 * are requested.  Therefore order this list so that this behaviour will not
361 * cause problems when mixer clients move through the enum sequentially.
362 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
363 * March 2006.
364 */
365static char *alc_pin_mode_names[] = {
366	"Mic 50pc bias", "Mic 80pc bias",
367	"Line in", "Line out", "Headphone out",
368};
369static unsigned char alc_pin_mode_values[] = {
370	PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
371};
372/* The control can present all 5 options, or it can limit the options based
373 * in the pin being assumed to be exclusively an input or an output pin.  In
374 * addition, "input" pins may or may not process the mic bias option
375 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
376 * accept requests for bias as of chip versions up to March 2006) and/or
377 * wiring in the computer.
378 */
379#define ALC_PIN_DIR_IN              0x00
380#define ALC_PIN_DIR_OUT             0x01
381#define ALC_PIN_DIR_INOUT           0x02
382#define ALC_PIN_DIR_IN_NOMICBIAS    0x03
383#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
384
385/* Info about the pin modes supported by the different pin direction modes.
386 * For each direction the minimum and maximum values are given.
387 */
388static signed char alc_pin_mode_dir_info[5][2] = {
389	{ 0, 2 },    /* ALC_PIN_DIR_IN */
390	{ 3, 4 },    /* ALC_PIN_DIR_OUT */
391	{ 0, 4 },    /* ALC_PIN_DIR_INOUT */
392	{ 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
393	{ 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
394};
395#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
396#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
397#define alc_pin_mode_n_items(_dir) \
398	(alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
399
400static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
401			     struct snd_ctl_elem_info *uinfo)
402{
403	unsigned int item_num = uinfo->value.enumerated.item;
404	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
405
406	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
407	uinfo->count = 1;
408	uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
409
410	if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
411		item_num = alc_pin_mode_min(dir);
412	strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
413	return 0;
414}
415
416static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
417			    struct snd_ctl_elem_value *ucontrol)
418{
419	unsigned int i;
420	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
421	hda_nid_t nid = kcontrol->private_value & 0xffff;
422	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
423	long *valp = ucontrol->value.integer.value;
424	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
425						 AC_VERB_GET_PIN_WIDGET_CONTROL,
426						 0x00);
427
428	/* Find enumerated value for current pinctl setting */
429	i = alc_pin_mode_min(dir);
430	while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
431		i++;
432	*valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
433	return 0;
434}
435
436static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
437			    struct snd_ctl_elem_value *ucontrol)
438{
439	signed int change;
440	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
441	hda_nid_t nid = kcontrol->private_value & 0xffff;
442	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
443	long val = *ucontrol->value.integer.value;
444	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
445						 AC_VERB_GET_PIN_WIDGET_CONTROL,
446						 0x00);
447
448	if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
449		val = alc_pin_mode_min(dir);
450
451	change = pinctl != alc_pin_mode_values[val];
452	if (change) {
453		/* Set pin mode to that requested */
454		snd_hda_codec_write_cache(codec, nid, 0,
455					  AC_VERB_SET_PIN_WIDGET_CONTROL,
456					  alc_pin_mode_values[val]);
457
458		/* Also enable the retasking pin's input/output as required
459		 * for the requested pin mode.  Enum values of 2 or less are
460		 * input modes.
461		 *
462		 * Dynamically switching the input/output buffers probably
463		 * reduces noise slightly (particularly on input) so we'll
464		 * do it.  However, having both input and output buffers
465		 * enabled simultaneously doesn't seem to be problematic if
466		 * this turns out to be necessary in the future.
467		 */
468		if (val <= 2) {
469			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
470						 HDA_AMP_MUTE, HDA_AMP_MUTE);
471			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
472						 HDA_AMP_MUTE, 0);
473		} else {
474			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
475						 HDA_AMP_MUTE, HDA_AMP_MUTE);
476			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
477						 HDA_AMP_MUTE, 0);
478		}
479	}
480	return change;
481}
482
483#define ALC_PIN_MODE(xname, nid, dir) \
484	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
485	  .info = alc_pin_mode_info, \
486	  .get = alc_pin_mode_get, \
487	  .put = alc_pin_mode_put, \
488	  .private_value = nid | (dir<<16) }
489
490/* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
491 * together using a mask with more than one bit set.  This control is
492 * currently used only by the ALC260 test model.  At this stage they are not
493 * needed for any "production" models.
494 */
495#ifdef CONFIG_SND_DEBUG
496#define alc_gpio_data_info	snd_ctl_boolean_mono_info
497
498static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
499			     struct snd_ctl_elem_value *ucontrol)
500{
501	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
502	hda_nid_t nid = kcontrol->private_value & 0xffff;
503	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
504	long *valp = ucontrol->value.integer.value;
505	unsigned int val = snd_hda_codec_read(codec, nid, 0,
506					      AC_VERB_GET_GPIO_DATA, 0x00);
507
508	*valp = (val & mask) != 0;
509	return 0;
510}
511static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
512			     struct snd_ctl_elem_value *ucontrol)
513{
514	signed int change;
515	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
516	hda_nid_t nid = kcontrol->private_value & 0xffff;
517	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
518	long val = *ucontrol->value.integer.value;
519	unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
520						    AC_VERB_GET_GPIO_DATA,
521						    0x00);
522
523	/* Set/unset the masked GPIO bit(s) as needed */
524	change = (val == 0 ? 0 : mask) != (gpio_data & mask);
525	if (val == 0)
526		gpio_data &= ~mask;
527	else
528		gpio_data |= mask;
529	snd_hda_codec_write_cache(codec, nid, 0,
530				  AC_VERB_SET_GPIO_DATA, gpio_data);
531
532	return change;
533}
534#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
535	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
536	  .info = alc_gpio_data_info, \
537	  .get = alc_gpio_data_get, \
538	  .put = alc_gpio_data_put, \
539	  .private_value = nid | (mask<<16) }
540#endif   /* CONFIG_SND_DEBUG */
541
542/* A switch control to allow the enabling of the digital IO pins on the
543 * ALC260.  This is incredibly simplistic; the intention of this control is
544 * to provide something in the test model allowing digital outputs to be
545 * identified if present.  If models are found which can utilise these
546 * outputs a more complete mixer control can be devised for those models if
547 * necessary.
548 */
549#ifdef CONFIG_SND_DEBUG
550#define alc_spdif_ctrl_info	snd_ctl_boolean_mono_info
551
552static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
553			      struct snd_ctl_elem_value *ucontrol)
554{
555	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
556	hda_nid_t nid = kcontrol->private_value & 0xffff;
557	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
558	long *valp = ucontrol->value.integer.value;
559	unsigned int val = snd_hda_codec_read(codec, nid, 0,
560					      AC_VERB_GET_DIGI_CONVERT, 0x00);
561
562	*valp = (val & mask) != 0;
563	return 0;
564}
565static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
566			      struct snd_ctl_elem_value *ucontrol)
567{
568	signed int change;
569	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
570	hda_nid_t nid = kcontrol->private_value & 0xffff;
571	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
572	long val = *ucontrol->value.integer.value;
573	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
574						    AC_VERB_GET_DIGI_CONVERT,
575						    0x00);
576
577	/* Set/unset the masked control bit(s) as needed */
578	change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
579	if (val==0)
580		ctrl_data &= ~mask;
581	else
582		ctrl_data |= mask;
583	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
584				  ctrl_data);
585
586	return change;
587}
588#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
589	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
590	  .info = alc_spdif_ctrl_info, \
591	  .get = alc_spdif_ctrl_get, \
592	  .put = alc_spdif_ctrl_put, \
593	  .private_value = nid | (mask<<16) }
594#endif   /* CONFIG_SND_DEBUG */
595
596/*
597 * set up from the preset table
598 */
599static void setup_preset(struct alc_spec *spec,
600			 const struct alc_config_preset *preset)
601{
602	int i;
603
604	for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
605		spec->mixers[spec->num_mixers++] = preset->mixers[i];
606	for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
607	     i++)
608		spec->init_verbs[spec->num_init_verbs++] =
609			preset->init_verbs[i];
610
611	spec->channel_mode = preset->channel_mode;
612	spec->num_channel_mode = preset->num_channel_mode;
613	spec->need_dac_fix = preset->need_dac_fix;
614
615	spec->multiout.max_channels = spec->channel_mode[0].channels;
616
617	spec->multiout.num_dacs = preset->num_dacs;
618	spec->multiout.dac_nids = preset->dac_nids;
619	spec->multiout.dig_out_nid = preset->dig_out_nid;
620	spec->multiout.hp_nid = preset->hp_nid;
621
622	spec->num_mux_defs = preset->num_mux_defs;
623	if (!spec->num_mux_defs)
624		spec->num_mux_defs = 1;
625	spec->input_mux = preset->input_mux;
626
627	spec->num_adc_nids = preset->num_adc_nids;
628	spec->adc_nids = preset->adc_nids;
629	spec->dig_in_nid = preset->dig_in_nid;
630
631	spec->unsol_event = preset->unsol_event;
632	spec->init_hook = preset->init_hook;
633#ifdef CONFIG_SND_HDA_POWER_SAVE
634	spec->loopback.amplist = preset->loopbacks;
635#endif
636}
637
638/* Enable GPIO mask and set output */
639static struct hda_verb alc_gpio1_init_verbs[] = {
640	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
641	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
642	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
643	{ }
644};
645
646static struct hda_verb alc_gpio2_init_verbs[] = {
647	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
648	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
649	{0x01, AC_VERB_SET_GPIO_DATA, 0x02},
650	{ }
651};
652
653static struct hda_verb alc_gpio3_init_verbs[] = {
654	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
655	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
656	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
657	{ }
658};
659
660/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
661 *	31 ~ 16 :	Manufacture ID
662 *	15 ~ 8	:	SKU ID
663 *	7  ~ 0	:	Assembly ID
664 *	port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
665 */
666static void alc_subsystem_id(struct hda_codec *codec,
667			     unsigned int porta, unsigned int porte,
668			     unsigned int portd)
669{
670	unsigned int ass, tmp;
671
672	ass = codec->subsystem_id;
673	if (!(ass & 1))
674		return;
675
676	/* Override */
677	tmp = (ass & 0x38) >> 3;	/* external Amp control */
678	switch (tmp) {
679	case 1:
680		snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
681		break;
682	case 3:
683		snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
684		break;
685	case 7:
686		snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
687		break;
688	case 5:
689		switch (codec->vendor_id) {
690		case 0x10ec0862:
691		case 0x10ec0660:
692		case 0x10ec0662:
693		case 0x10ec0267:
694		case 0x10ec0268:
695			snd_hda_codec_write(codec, 0x14, 0,
696					    AC_VERB_SET_EAPD_BTLENABLE, 2);
697			snd_hda_codec_write(codec, 0x15, 0,
698					    AC_VERB_SET_EAPD_BTLENABLE, 2);
699			return;
700		}
701	case 6:
702		if (ass & 4) {	/* bit 2 : 0 = Desktop, 1 = Laptop */
703			hda_nid_t port = 0;
704			tmp = (ass & 0x1800) >> 11;
705			switch (tmp) {
706			case 0: port = porta; break;
707			case 1: port = porte; break;
708			case 2: port = portd; break;
709			}
710			if (port)
711				snd_hda_codec_write(codec, port, 0,
712						    AC_VERB_SET_EAPD_BTLENABLE,
713						    2);
714		}
715		snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
716		snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF,
717				    (tmp == 5 ? 0x3040 : 0x3050));
718		break;
719	}
720}
721
722/*
723 * Fix-up pin default configurations
724 */
725
726struct alc_pincfg {
727	hda_nid_t nid;
728	u32 val;
729};
730
731static void alc_fix_pincfg(struct hda_codec *codec,
732			   const struct snd_pci_quirk *quirk,
733			   const struct alc_pincfg **pinfix)
734{
735	const struct alc_pincfg *cfg;
736
737	quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
738	if (!quirk)
739		return;
740
741	cfg = pinfix[quirk->value];
742	for (; cfg->nid; cfg++) {
743		int i;
744		u32 val = cfg->val;
745		for (i = 0; i < 4; i++) {
746			snd_hda_codec_write(codec, cfg->nid, 0,
747				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
748				    val & 0xff);
749			val >>= 8;
750		}
751	}
752}
753
754/*
755 * ALC880 3-stack model
756 *
757 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
758 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
759 *                 F-Mic = 0x1b, HP = 0x19
760 */
761
762static hda_nid_t alc880_dac_nids[4] = {
763	/* front, rear, clfe, rear_surr */
764	0x02, 0x05, 0x04, 0x03
765};
766
767static hda_nid_t alc880_adc_nids[3] = {
768	/* ADC0-2 */
769	0x07, 0x08, 0x09,
770};
771
772/* The datasheet says the node 0x07 is connected from inputs,
773 * but it shows zero connection in the real implementation on some devices.
774 * Note: this is a 915GAV bug, fixed on 915GLV
775 */
776static hda_nid_t alc880_adc_nids_alt[2] = {
777	/* ADC1-2 */
778	0x08, 0x09,
779};
780
781#define ALC880_DIGOUT_NID	0x06
782#define ALC880_DIGIN_NID	0x0a
783
784static struct hda_input_mux alc880_capture_source = {
785	.num_items = 4,
786	.items = {
787		{ "Mic", 0x0 },
788		{ "Front Mic", 0x3 },
789		{ "Line", 0x2 },
790		{ "CD", 0x4 },
791	},
792};
793
794/* channel source setting (2/6 channel selection for 3-stack) */
795/* 2ch mode */
796static struct hda_verb alc880_threestack_ch2_init[] = {
797	/* set line-in to input, mute it */
798	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
799	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
800	/* set mic-in to input vref 80%, mute it */
801	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
802	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
803	{ } /* end */
804};
805
806/* 6ch mode */
807static struct hda_verb alc880_threestack_ch6_init[] = {
808	/* set line-in to output, unmute it */
809	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
810	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
811	/* set mic-in to output, unmute it */
812	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
813	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
814	{ } /* end */
815};
816
817static struct hda_channel_mode alc880_threestack_modes[2] = {
818	{ 2, alc880_threestack_ch2_init },
819	{ 6, alc880_threestack_ch6_init },
820};
821
822static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
823	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
824	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
825	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
826	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
827	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
828	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
829	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
830	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
831	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
832	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
833	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
834	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
835	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
836	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
837	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
838	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
839	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
840	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
841	HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
842	{
843		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
844		.name = "Channel Mode",
845		.info = alc_ch_mode_info,
846		.get = alc_ch_mode_get,
847		.put = alc_ch_mode_put,
848	},
849	{ } /* end */
850};
851
852/* capture mixer elements */
853static struct snd_kcontrol_new alc880_capture_mixer[] = {
854	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
855	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
856	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
857	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
858	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
859	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
860	{
861		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
862		/* The multiple "Capture Source" controls confuse alsamixer
863		 * So call somewhat different..
864		 * FIXME: the controls appear in the "playback" view!
865		 */
866		/* .name = "Capture Source", */
867		.name = "Input Source",
868		.count = 3,
869		.info = alc_mux_enum_info,
870		.get = alc_mux_enum_get,
871		.put = alc_mux_enum_put,
872	},
873	{ } /* end */
874};
875
876/* capture mixer elements (in case NID 0x07 not available) */
877static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
878	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
879	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
880	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
881	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
882	{
883		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
884		/* The multiple "Capture Source" controls confuse alsamixer
885		 * So call somewhat different..
886		 * FIXME: the controls appear in the "playback" view!
887		 */
888		/* .name = "Capture Source", */
889		.name = "Input Source",
890		.count = 2,
891		.info = alc_mux_enum_info,
892		.get = alc_mux_enum_get,
893		.put = alc_mux_enum_put,
894	},
895	{ } /* end */
896};
897
898
899
900/*
901 * ALC880 5-stack model
902 *
903 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
904 *      Side = 0x02 (0xd)
905 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
906 *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
907 */
908
909/* additional mixers to alc880_three_stack_mixer */
910static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
911	HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
912	HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
913	{ } /* end */
914};
915
916/* channel source setting (6/8 channel selection for 5-stack) */
917/* 6ch mode */
918static struct hda_verb alc880_fivestack_ch6_init[] = {
919	/* set line-in to input, mute it */
920	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
921	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
922	{ } /* end */
923};
924
925/* 8ch mode */
926static struct hda_verb alc880_fivestack_ch8_init[] = {
927	/* set line-in to output, unmute it */
928	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
929	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
930	{ } /* end */
931};
932
933static struct hda_channel_mode alc880_fivestack_modes[2] = {
934	{ 6, alc880_fivestack_ch6_init },
935	{ 8, alc880_fivestack_ch8_init },
936};
937
938
939/*
940 * ALC880 6-stack model
941 *
942 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
943 *      Side = 0x05 (0x0f)
944 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
945 *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
946 */
947
948static hda_nid_t alc880_6st_dac_nids[4] = {
949	/* front, rear, clfe, rear_surr */
950	0x02, 0x03, 0x04, 0x05
951};
952
953static struct hda_input_mux alc880_6stack_capture_source = {
954	.num_items = 4,
955	.items = {
956		{ "Mic", 0x0 },
957		{ "Front Mic", 0x1 },
958		{ "Line", 0x2 },
959		{ "CD", 0x4 },
960	},
961};
962
963/* fixed 8-channels */
964static struct hda_channel_mode alc880_sixstack_modes[1] = {
965	{ 8, NULL },
966};
967
968static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
969	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
970	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
971	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
972	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
973	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
974	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
975	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
976	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
977	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
978	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
979	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
980	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
981	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
982	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
983	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
984	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
985	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
986	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
987	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
988	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
989	{
990		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
991		.name = "Channel Mode",
992		.info = alc_ch_mode_info,
993		.get = alc_ch_mode_get,
994		.put = alc_ch_mode_put,
995	},
996	{ } /* end */
997};
998
999
1000/*
1001 * ALC880 W810 model
1002 *
1003 * W810 has rear IO for:
1004 * Front (DAC 02)
1005 * Surround (DAC 03)
1006 * Center/LFE (DAC 04)
1007 * Digital out (06)
1008 *
1009 * The system also has a pair of internal speakers, and a headphone jack.
1010 * These are both connected to Line2 on the codec, hence to DAC 02.
1011 *
1012 * There is a variable resistor to control the speaker or headphone
1013 * volume. This is a hardware-only device without a software API.
1014 *
1015 * Plugging headphones in will disable the internal speakers. This is
1016 * implemented in hardware, not via the driver using jack sense. In
1017 * a similar fashion, plugging into the rear socket marked "front" will
1018 * disable both the speakers and headphones.
1019 *
1020 * For input, there's a microphone jack, and an "audio in" jack.
1021 * These may not do anything useful with this driver yet, because I
1022 * haven't setup any initialization verbs for these yet...
1023 */
1024
1025static hda_nid_t alc880_w810_dac_nids[3] = {
1026	/* front, rear/surround, clfe */
1027	0x02, 0x03, 0x04
1028};
1029
1030/* fixed 6 channels */
1031static struct hda_channel_mode alc880_w810_modes[1] = {
1032	{ 6, NULL }
1033};
1034
1035/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1036static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1037	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1038	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1039	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1040	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1041	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1042	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1043	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1044	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1045	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1046	{ } /* end */
1047};
1048
1049
1050/*
1051 * Z710V model
1052 *
1053 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1054 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1055 *                 Line = 0x1a
1056 */
1057
1058static hda_nid_t alc880_z71v_dac_nids[1] = {
1059	0x02
1060};
1061#define ALC880_Z71V_HP_DAC	0x03
1062
1063/* fixed 2 channels */
1064static struct hda_channel_mode alc880_2_jack_modes[1] = {
1065	{ 2, NULL }
1066};
1067
1068static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1069	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1070	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1071	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1072	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1073	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1074	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1075	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1076	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1077	{ } /* end */
1078};
1079
1080
1081/* FIXME! */
1082/*
1083 * ALC880 F1734 model
1084 *
1085 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1086 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1087 */
1088
1089static hda_nid_t alc880_f1734_dac_nids[1] = {
1090	0x03
1091};
1092#define ALC880_F1734_HP_DAC	0x02
1093
1094static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1095	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1096	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1097	HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1098	HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1099	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1100	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1101	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1102	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1103	{ } /* end */
1104};
1105
1106
1107/* FIXME! */
1108/*
1109 * ALC880 ASUS model
1110 *
1111 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1112 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1113 *  Mic = 0x18, Line = 0x1a
1114 */
1115
1116#define alc880_asus_dac_nids	alc880_w810_dac_nids	/* identical with w810 */
1117#define alc880_asus_modes	alc880_threestack_modes	/* 2/6 channel mode */
1118
1119static struct snd_kcontrol_new alc880_asus_mixer[] = {
1120	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1121	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1122	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1123	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1124	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1125	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1126	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1127	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1128	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1129	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1130	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1131	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1132	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1133	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1134	{
1135		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1136		.name = "Channel Mode",
1137		.info = alc_ch_mode_info,
1138		.get = alc_ch_mode_get,
1139		.put = alc_ch_mode_put,
1140	},
1141	{ } /* end */
1142};
1143
1144/* FIXME! */
1145/*
1146 * ALC880 ASUS W1V model
1147 *
1148 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1149 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1150 *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1151 */
1152
1153/* additional mixers to alc880_asus_mixer */
1154static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1155	HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1156	HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1157	{ } /* end */
1158};
1159
1160/* additional mixers to alc880_asus_mixer */
1161static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1162	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1163	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1164	{ } /* end */
1165};
1166
1167/* TCL S700 */
1168static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1169	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1170	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1171	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1172	HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1173	HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1174	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1175	HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1176	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1177	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1178	{
1179		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1180		/* The multiple "Capture Source" controls confuse alsamixer
1181		 * So call somewhat different..
1182		 * FIXME: the controls appear in the "playback" view!
1183		 */
1184		/* .name = "Capture Source", */
1185		.name = "Input Source",
1186		.count = 1,
1187		.info = alc_mux_enum_info,
1188		.get = alc_mux_enum_get,
1189		.put = alc_mux_enum_put,
1190	},
1191	{ } /* end */
1192};
1193
1194/* Uniwill */
1195static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1196	HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1197	HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1198	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1199	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1200	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1201	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1202	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1203	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1204	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1205	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1206	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1207	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1208	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1209	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1210	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1211	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1212	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1213	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1214	{
1215		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1216		.name = "Channel Mode",
1217		.info = alc_ch_mode_info,
1218		.get = alc_ch_mode_get,
1219		.put = alc_ch_mode_put,
1220	},
1221	{ } /* end */
1222};
1223
1224static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1225	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1226	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1227	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1228	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1229	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1230	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1231	HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1232	HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1233	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1234	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1235	{ } /* end */
1236};
1237
1238static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1239	HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1240	HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1241	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1242	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1243	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1244	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1245	{ } /* end */
1246};
1247
1248/*
1249 * build control elements
1250 */
1251static int alc_build_controls(struct hda_codec *codec)
1252{
1253	struct alc_spec *spec = codec->spec;
1254	int err;
1255	int i;
1256
1257	for (i = 0; i < spec->num_mixers; i++) {
1258		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1259		if (err < 0)
1260			return err;
1261	}
1262
1263	if (spec->multiout.dig_out_nid) {
1264		err = snd_hda_create_spdif_out_ctls(codec,
1265						    spec->multiout.dig_out_nid);
1266		if (err < 0)
1267			return err;
1268	}
1269	if (spec->dig_in_nid) {
1270		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1271		if (err < 0)
1272			return err;
1273	}
1274	return 0;
1275}
1276
1277
1278/*
1279 * initialize the codec volumes, etc
1280 */
1281
1282/*
1283 * generic initialization of ADC, input mixers and output mixers
1284 */
1285static struct hda_verb alc880_volume_init_verbs[] = {
1286	/*
1287	 * Unmute ADC0-2 and set the default input to mic-in
1288	 */
1289	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1290	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1291	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1292	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1293	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1294	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1295
1296	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1297	 * mixer widget
1298	 * Note: PASD motherboards uses the Line In 2 as the input for front
1299	 * panel mic (mic 2)
1300	 */
1301	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1302	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1303	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1304	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1305	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1306	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1307	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1308	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1309
1310	/*
1311	 * Set up output mixers (0x0c - 0x0f)
1312	 */
1313	/* set vol=0 to output mixers */
1314	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1315	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1316	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1317	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1318	/* set up input amps for analog loopback */
1319	/* Amp Indices: DAC = 0, mixer = 1 */
1320	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1321	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1322	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1323	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1324	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1325	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1326	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1327	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1328
1329	{ }
1330};
1331
1332/*
1333 * 3-stack pin configuration:
1334 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1335 */
1336static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1337	/*
1338	 * preset connection lists of input pins
1339	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1340	 */
1341	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1342	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1343	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1344
1345	/*
1346	 * Set pin mode and muting
1347	 */
1348	/* set front pin widgets 0x14 for output */
1349	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1350	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1351	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1352	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1353	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1354	/* Mic2 (as headphone out) for HP output */
1355	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1356	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1357	/* Line In pin widget for input */
1358	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1359	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1360	/* Line2 (as front mic) pin widget for input and vref at 80% */
1361	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1362	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1363	/* CD pin widget for input */
1364	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1365
1366	{ }
1367};
1368
1369/*
1370 * 5-stack pin configuration:
1371 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1372 * line-in/side = 0x1a, f-mic = 0x1b
1373 */
1374static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1375	/*
1376	 * preset connection lists of input pins
1377	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1378	 */
1379	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1380	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1381
1382	/*
1383	 * Set pin mode and muting
1384	 */
1385	/* set pin widgets 0x14-0x17 for output */
1386	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1387	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1388	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1389	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1390	/* unmute pins for output (no gain on this amp) */
1391	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1392	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1393	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1394	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1395
1396	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1397	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1398	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1399	/* Mic2 (as headphone out) for HP output */
1400	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1401	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1402	/* Line In pin widget for input */
1403	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1404	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1405	/* Line2 (as front mic) pin widget for input and vref at 80% */
1406	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1407	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1408	/* CD pin widget for input */
1409	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1410
1411	{ }
1412};
1413
1414/*
1415 * W810 pin configuration:
1416 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1417 */
1418static struct hda_verb alc880_pin_w810_init_verbs[] = {
1419	/* hphone/speaker input selector: front DAC */
1420	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1421
1422	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1423	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1424	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1425	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1426	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1427	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1428
1429	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1430	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1431
1432	{ }
1433};
1434
1435/*
1436 * Z71V pin configuration:
1437 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1438 */
1439static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1440	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1441	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1442	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1443	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1444
1445	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1446	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1447	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1448	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1449
1450	{ }
1451};
1452
1453/*
1454 * 6-stack pin configuration:
1455 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1456 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1457 */
1458static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1459	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1460
1461	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1462	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1463	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1464	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1465	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1466	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1467	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1468	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1469
1470	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1471	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1472	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1473	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1474	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1475	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1476	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1477	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1478	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1479
1480	{ }
1481};
1482
1483/*
1484 * Uniwill pin configuration:
1485 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1486 * line = 0x1a
1487 */
1488static struct hda_verb alc880_uniwill_init_verbs[] = {
1489	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1490
1491	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1492	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1493	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1494	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1495	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1496	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1497	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1498	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1499	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1500	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1501	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1502	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1503	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1504	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1505
1506	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1507	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1508	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1509	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1510	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1511	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1512	/* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1513	/* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1514	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1515
1516	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1517	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1518
1519	{ }
1520};
1521
1522/*
1523* Uniwill P53
1524* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1525 */
1526static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1527	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1528
1529	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1530	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1531	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1532	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1533	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1534	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1535	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1536	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1537	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1538	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1539	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1540	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1541
1542	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1543	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1544	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1545	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1546	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1547	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1548
1549	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1550	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1551
1552	{ }
1553};
1554
1555static struct hda_verb alc880_beep_init_verbs[] = {
1556	{ 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1557	{ }
1558};
1559
1560/* toggle speaker-output according to the hp-jack state */
1561static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1562{
1563 	unsigned int present;
1564	unsigned char bits;
1565
1566 	present = snd_hda_codec_read(codec, 0x14, 0,
1567				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1568	bits = present ? HDA_AMP_MUTE : 0;
1569	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1570				 HDA_AMP_MUTE, bits);
1571	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1572				 HDA_AMP_MUTE, bits);
1573}
1574
1575/* auto-toggle front mic */
1576static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1577{
1578 	unsigned int present;
1579	unsigned char bits;
1580
1581	present = snd_hda_codec_read(codec, 0x18, 0,
1582				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1583	bits = present ? HDA_AMP_MUTE : 0;
1584	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
1585}
1586
1587static void alc880_uniwill_automute(struct hda_codec *codec)
1588{
1589	alc880_uniwill_hp_automute(codec);
1590	alc880_uniwill_mic_automute(codec);
1591}
1592
1593static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1594				       unsigned int res)
1595{
1596	/* Looks like the unsol event is incompatible with the standard
1597	 * definition.  4bit tag is placed at 28 bit!
1598	 */
1599	switch (res >> 28) {
1600	case ALC880_HP_EVENT:
1601		alc880_uniwill_hp_automute(codec);
1602		break;
1603	case ALC880_MIC_EVENT:
1604		alc880_uniwill_mic_automute(codec);
1605		break;
1606	}
1607}
1608
1609static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1610{
1611 	unsigned int present;
1612	unsigned char bits;
1613
1614 	present = snd_hda_codec_read(codec, 0x14, 0,
1615				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1616	bits = present ? HDA_AMP_MUTE : 0;
1617	snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits);
1618}
1619
1620static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1621{
1622	unsigned int present;
1623
1624	present = snd_hda_codec_read(codec, 0x21, 0,
1625				     AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1626	present &= HDA_AMP_VOLMASK;
1627	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1628				 HDA_AMP_VOLMASK, present);
1629	snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1630				 HDA_AMP_VOLMASK, present);
1631}
1632
1633static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1634					   unsigned int res)
1635{
1636	/* Looks like the unsol event is incompatible with the standard
1637	 * definition.  4bit tag is placed at 28 bit!
1638	 */
1639	if ((res >> 28) == ALC880_HP_EVENT)
1640		alc880_uniwill_p53_hp_automute(codec);
1641	if ((res >> 28) == ALC880_DCVOL_EVENT)
1642		alc880_uniwill_p53_dcvol_automute(codec);
1643}
1644
1645/* FIXME! */
1646/*
1647 * F1734 pin configuration:
1648 * HP = 0x14, speaker-out = 0x15, mic = 0x18
1649 */
1650static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1651	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1652	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1653	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1654	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1655
1656	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1657	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1658	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1659	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1660
1661	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1662	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1663	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1664	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1665	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1666	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1667	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1668	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1669	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1670
1671	{ }
1672};
1673
1674/* FIXME! */
1675/*
1676 * ASUS pin configuration:
1677 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1678 */
1679static struct hda_verb alc880_pin_asus_init_verbs[] = {
1680	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1681	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1682	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1683	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1684
1685	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1686	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1687	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1688	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1689	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1690	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1691	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1692	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1693
1694	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1695	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1696	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1697	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1698	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1699	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1700	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1701	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1702	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1703
1704	{ }
1705};
1706
1707/* Enable GPIO mask and set output */
1708#define alc880_gpio1_init_verbs	alc_gpio1_init_verbs
1709#define alc880_gpio2_init_verbs	alc_gpio2_init_verbs
1710
1711/* Clevo m520g init */
1712static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1713	/* headphone output */
1714	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1715	/* line-out */
1716	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1717	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1718	/* Line-in */
1719	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1720	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1721	/* CD */
1722	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1723	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1724	/* Mic1 (rear panel) */
1725	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1726	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1727	/* Mic2 (front panel) */
1728	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1729	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1730	/* headphone */
1731	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1732	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1733        /* change to EAPD mode */
1734	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1735	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1736
1737	{ }
1738};
1739
1740static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
1741	/* change to EAPD mode */
1742	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1743	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1744
1745	/* Headphone output */
1746	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1747	/* Front output*/
1748	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1749	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1750
1751	/* Line In pin widget for input */
1752	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1753	/* CD pin widget for input */
1754	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1755	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1756	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1757
1758	/* change to EAPD mode */
1759	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1760	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
1761
1762	{ }
1763};
1764
1765/*
1766 * LG m1 express dual
1767 *
1768 * Pin assignment:
1769 *   Rear Line-In/Out (blue): 0x14
1770 *   Build-in Mic-In: 0x15
1771 *   Speaker-out: 0x17
1772 *   HP-Out (green): 0x1b
1773 *   Mic-In/Out (red): 0x19
1774 *   SPDIF-Out: 0x1e
1775 */
1776
1777/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
1778static hda_nid_t alc880_lg_dac_nids[3] = {
1779	0x05, 0x02, 0x03
1780};
1781
1782/* seems analog CD is not working */
1783static struct hda_input_mux alc880_lg_capture_source = {
1784	.num_items = 3,
1785	.items = {
1786		{ "Mic", 0x1 },
1787		{ "Line", 0x5 },
1788		{ "Internal Mic", 0x6 },
1789	},
1790};
1791
1792/* 2,4,6 channel modes */
1793static struct hda_verb alc880_lg_ch2_init[] = {
1794	/* set line-in and mic-in to input */
1795	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1796	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1797	{ }
1798};
1799
1800static struct hda_verb alc880_lg_ch4_init[] = {
1801	/* set line-in to out and mic-in to input */
1802	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1803	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1804	{ }
1805};
1806
1807static struct hda_verb alc880_lg_ch6_init[] = {
1808	/* set line-in and mic-in to output */
1809	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1810	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1811	{ }
1812};
1813
1814static struct hda_channel_mode alc880_lg_ch_modes[3] = {
1815	{ 2, alc880_lg_ch2_init },
1816	{ 4, alc880_lg_ch4_init },
1817	{ 6, alc880_lg_ch6_init },
1818};
1819
1820static struct snd_kcontrol_new alc880_lg_mixer[] = {
1821	/* FIXME: it's not really "master" but front channels */
1822	HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1823	HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT),
1824	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1825	HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
1826	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
1827	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
1828	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
1829	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
1830	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1831	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1832	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
1833	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
1834	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
1835	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
1836	{
1837		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1838		.name = "Channel Mode",
1839		.info = alc_ch_mode_info,
1840		.get = alc_ch_mode_get,
1841		.put = alc_ch_mode_put,
1842	},
1843	{ } /* end */
1844};
1845
1846static struct hda_verb alc880_lg_init_verbs[] = {
1847	/* set capture source to mic-in */
1848	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1849	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1850	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1851	/* mute all amp mixer inputs */
1852	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
1853	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1854	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1855	/* line-in to input */
1856	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1857	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1858	/* built-in mic */
1859	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1860	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1861	/* speaker-out */
1862	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1863	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1864	/* mic-in to input */
1865	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1866	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1867	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1868	/* HP-out */
1869	{0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
1870	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1871	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1872	/* jack sense */
1873	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1874	{ }
1875};
1876
1877/* toggle speaker-output according to the hp-jack state */
1878static void alc880_lg_automute(struct hda_codec *codec)
1879{
1880	unsigned int present;
1881	unsigned char bits;
1882
1883	present = snd_hda_codec_read(codec, 0x1b, 0,
1884				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1885	bits = present ? HDA_AMP_MUTE : 0;
1886	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
1887				 HDA_AMP_MUTE, bits);
1888}
1889
1890static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
1891{
1892	/* Looks like the unsol event is incompatible with the standard
1893	 * definition.  4bit tag is placed at 28 bit!
1894	 */
1895	if ((res >> 28) == 0x01)
1896		alc880_lg_automute(codec);
1897}
1898
1899/*
1900 * LG LW20
1901 *
1902 * Pin assignment:
1903 *   Speaker-out: 0x14
1904 *   Mic-In: 0x18
1905 *   Built-in Mic-In: 0x19
1906 *   Line-In: 0x1b
1907 *   HP-Out: 0x1a
1908 *   SPDIF-Out: 0x1e
1909 */
1910
1911static struct hda_input_mux alc880_lg_lw_capture_source = {
1912	.num_items = 3,
1913	.items = {
1914		{ "Mic", 0x0 },
1915		{ "Internal Mic", 0x1 },
1916		{ "Line In", 0x2 },
1917	},
1918};
1919
1920#define alc880_lg_lw_modes alc880_threestack_modes
1921
1922static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
1923	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1924	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1925	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1926	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1927	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1928	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1929	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1930	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1931	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1932	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1933	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1934	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1935	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
1936	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
1937	{
1938		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1939		.name = "Channel Mode",
1940		.info = alc_ch_mode_info,
1941		.get = alc_ch_mode_get,
1942		.put = alc_ch_mode_put,
1943	},
1944	{ } /* end */
1945};
1946
1947static struct hda_verb alc880_lg_lw_init_verbs[] = {
1948	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1949	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1950	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1951
1952	/* set capture source to mic-in */
1953	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1954	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1955	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1956	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1957	/* speaker-out */
1958	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1959	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1960	/* HP-out */
1961	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1962	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1963	/* mic-in to input */
1964	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1965	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1966	/* built-in mic */
1967	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1968	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1969	/* jack sense */
1970	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1971	{ }
1972};
1973
1974/* toggle speaker-output according to the hp-jack state */
1975static void alc880_lg_lw_automute(struct hda_codec *codec)
1976{
1977	unsigned int present;
1978	unsigned char bits;
1979
1980	present = snd_hda_codec_read(codec, 0x1b, 0,
1981				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1982	bits = present ? HDA_AMP_MUTE : 0;
1983	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
1984				 HDA_AMP_MUTE, bits);
1985}
1986
1987static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
1988{
1989	/* Looks like the unsol event is incompatible with the standard
1990	 * definition.  4bit tag is placed at 28 bit!
1991	 */
1992	if ((res >> 28) == 0x01)
1993		alc880_lg_lw_automute(codec);
1994}
1995
1996#ifdef CONFIG_SND_HDA_POWER_SAVE
1997static struct hda_amp_list alc880_loopbacks[] = {
1998	{ 0x0b, HDA_INPUT, 0 },
1999	{ 0x0b, HDA_INPUT, 1 },
2000	{ 0x0b, HDA_INPUT, 2 },
2001	{ 0x0b, HDA_INPUT, 3 },
2002	{ 0x0b, HDA_INPUT, 4 },
2003	{ } /* end */
2004};
2005
2006static struct hda_amp_list alc880_lg_loopbacks[] = {
2007	{ 0x0b, HDA_INPUT, 1 },
2008	{ 0x0b, HDA_INPUT, 6 },
2009	{ 0x0b, HDA_INPUT, 7 },
2010	{ } /* end */
2011};
2012#endif
2013
2014/*
2015 * Common callbacks
2016 */
2017
2018static int alc_init(struct hda_codec *codec)
2019{
2020	struct alc_spec *spec = codec->spec;
2021	unsigned int i;
2022
2023	for (i = 0; i < spec->num_init_verbs; i++)
2024		snd_hda_sequence_write(codec, spec->init_verbs[i]);
2025
2026	if (spec->init_hook)
2027		spec->init_hook(codec);
2028
2029	return 0;
2030}
2031
2032static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2033{
2034	struct alc_spec *spec = codec->spec;
2035
2036	if (spec->unsol_event)
2037		spec->unsol_event(codec, res);
2038}
2039
2040#ifdef CONFIG_SND_HDA_POWER_SAVE
2041static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2042{
2043	struct alc_spec *spec = codec->spec;
2044	return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2045}
2046#endif
2047
2048/*
2049 * Analog playback callbacks
2050 */
2051static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2052				    struct hda_codec *codec,
2053				    struct snd_pcm_substream *substream)
2054{
2055	struct alc_spec *spec = codec->spec;
2056	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
2057}
2058
2059static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2060				       struct hda_codec *codec,
2061				       unsigned int stream_tag,
2062				       unsigned int format,
2063				       struct snd_pcm_substream *substream)
2064{
2065	struct alc_spec *spec = codec->spec;
2066	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2067						stream_tag, format, substream);
2068}
2069
2070static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2071				       struct hda_codec *codec,
2072				       struct snd_pcm_substream *substream)
2073{
2074	struct alc_spec *spec = codec->spec;
2075	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2076}
2077
2078/*
2079 * Digital out
2080 */
2081static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2082					struct hda_codec *codec,
2083					struct snd_pcm_substream *substream)
2084{
2085	struct alc_spec *spec = codec->spec;
2086	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2087}
2088
2089static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2090					   struct hda_codec *codec,
2091					   unsigned int stream_tag,
2092					   unsigned int format,
2093					   struct snd_pcm_substream *substream)
2094{
2095	struct alc_spec *spec = codec->spec;
2096	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2097					     stream_tag, format, substream);
2098}
2099
2100static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2101					 struct hda_codec *codec,
2102					 struct snd_pcm_substream *substream)
2103{
2104	struct alc_spec *spec = codec->spec;
2105	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2106}
2107
2108/*
2109 * Analog capture
2110 */
2111static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2112				      struct hda_codec *codec,
2113				      unsigned int stream_tag,
2114				      unsigned int format,
2115				      struct snd_pcm_substream *substream)
2116{
2117	struct alc_spec *spec = codec->spec;
2118
2119	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2120				   stream_tag, 0, format);
2121	return 0;
2122}
2123
2124static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2125				      struct hda_codec *codec,
2126				      struct snd_pcm_substream *substream)
2127{
2128	struct alc_spec *spec = codec->spec;
2129
2130	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2131				   0, 0, 0);
2132	return 0;
2133}
2134
2135
2136/*
2137 */
2138static struct hda_pcm_stream alc880_pcm_analog_playback = {
2139	.substreams = 1,
2140	.channels_min = 2,
2141	.channels_max = 8,
2142	/* NID is set in alc_build_pcms */
2143	.ops = {
2144		.open = alc880_playback_pcm_open,
2145		.prepare = alc880_playback_pcm_prepare,
2146		.cleanup = alc880_playback_pcm_cleanup
2147	},
2148};
2149
2150static struct hda_pcm_stream alc880_pcm_analog_capture = {
2151	.substreams = 2,
2152	.channels_min = 2,
2153	.channels_max = 2,
2154	/* NID is set in alc_build_pcms */
2155	.ops = {
2156		.prepare = alc880_capture_pcm_prepare,
2157		.cleanup = alc880_capture_pcm_cleanup
2158	},
2159};
2160
2161static struct hda_pcm_stream alc880_pcm_digital_playback = {
2162	.substreams = 1,
2163	.channels_min = 2,
2164	.channels_max = 2,
2165	/* NID is set in alc_build_pcms */
2166	.ops = {
2167		.open = alc880_dig_playback_pcm_open,
2168		.close = alc880_dig_playback_pcm_close,
2169		.prepare = alc880_dig_playback_pcm_prepare
2170	},
2171};
2172
2173static struct hda_pcm_stream alc880_pcm_digital_capture = {
2174	.substreams = 1,
2175	.channels_min = 2,
2176	.channels_max = 2,
2177	/* NID is set in alc_build_pcms */
2178};
2179
2180/* Used by alc_build_pcms to flag that a PCM has no playback stream */
2181static struct hda_pcm_stream alc_pcm_null_playback = {
2182	.substreams = 0,
2183	.channels_min = 0,
2184	.channels_max = 0,
2185};
2186
2187static int alc_build_pcms(struct hda_codec *codec)
2188{
2189	struct alc_spec *spec = codec->spec;
2190	struct hda_pcm *info = spec->pcm_rec;
2191	int i;
2192
2193	codec->num_pcms = 1;
2194	codec->pcm_info = info;
2195
2196	info->name = spec->stream_name_analog;
2197	if (spec->stream_analog_playback) {
2198		snd_assert(spec->multiout.dac_nids, return -EINVAL);
2199		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2200		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2201	}
2202	if (spec->stream_analog_capture) {
2203		snd_assert(spec->adc_nids, return -EINVAL);
2204		info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2205		info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2206	}
2207
2208	if (spec->channel_mode) {
2209		info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2210		for (i = 0; i < spec->num_channel_mode; i++) {
2211			if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2212				info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2213			}
2214		}
2215	}
2216
2217	/* SPDIF for stream index #1 */
2218	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2219		codec->num_pcms = 2;
2220		info = spec->pcm_rec + 1;
2221		info->name = spec->stream_name_digital;
2222		if (spec->multiout.dig_out_nid &&
2223		    spec->stream_digital_playback) {
2224			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2225			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2226		}
2227		if (spec->dig_in_nid &&
2228		    spec->stream_digital_capture) {
2229			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2230			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2231		}
2232	}
2233
2234	/* If the use of more than one ADC is requested for the current
2235	 * model, configure a second analog capture-only PCM.
2236	 */
2237	/* Additional Analaog capture for index #2 */
2238	if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
2239	    spec->adc_nids) {
2240		codec->num_pcms = 3;
2241		info = spec->pcm_rec + 2;
2242		info->name = spec->stream_name_analog;
2243		/* No playback stream for second PCM */
2244		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
2245		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2246		if (spec->stream_analog_capture) {
2247			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2248			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
2249		}
2250	}
2251
2252	return 0;
2253}
2254
2255static void alc_free(struct hda_codec *codec)
2256{
2257	struct alc_spec *spec = codec->spec;
2258	unsigned int i;
2259
2260	if (!spec)
2261		return;
2262
2263	if (spec->kctl_alloc) {
2264		for (i = 0; i < spec->num_kctl_used; i++)
2265			kfree(spec->kctl_alloc[i].name);
2266		kfree(spec->kctl_alloc);
2267	}
2268	kfree(spec);
2269}
2270
2271/*
2272 */
2273static struct hda_codec_ops alc_patch_ops = {
2274	.build_controls = alc_build_controls,
2275	.build_pcms = alc_build_pcms,
2276	.init = alc_init,
2277	.free = alc_free,
2278	.unsol_event = alc_unsol_event,
2279#ifdef CONFIG_SND_HDA_POWER_SAVE
2280	.check_power_status = alc_check_power_status,
2281#endif
2282};
2283
2284
2285/*
2286 * Test configuration for debugging
2287 *
2288 * Almost all inputs/outputs are enabled.  I/O pins can be configured via
2289 * enum controls.
2290 */
2291#ifdef CONFIG_SND_DEBUG
2292static hda_nid_t alc880_test_dac_nids[4] = {
2293	0x02, 0x03, 0x04, 0x05
2294};
2295
2296static struct hda_input_mux alc880_test_capture_source = {
2297	.num_items = 7,
2298	.items = {
2299		{ "In-1", 0x0 },
2300		{ "In-2", 0x1 },
2301		{ "In-3", 0x2 },
2302		{ "In-4", 0x3 },
2303		{ "CD", 0x4 },
2304		{ "Front", 0x5 },
2305		{ "Surround", 0x6 },
2306	},
2307};
2308
2309static struct hda_channel_mode alc880_test_modes[4] = {
2310	{ 2, NULL },
2311	{ 4, NULL },
2312	{ 6, NULL },
2313	{ 8, NULL },
2314};
2315
2316static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2317				 struct snd_ctl_elem_info *uinfo)
2318{
2319	static char *texts[] = {
2320		"N/A", "Line Out", "HP Out",
2321		"In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2322	};
2323	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2324	uinfo->count = 1;
2325	uinfo->value.enumerated.items = 8;
2326	if (uinfo->value.enumerated.item >= 8)
2327		uinfo->value.enumerated.item = 7;
2328	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2329	return 0;
2330}
2331
2332static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2333				struct snd_ctl_elem_value *ucontrol)
2334{
2335	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2336	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2337	unsigned int pin_ctl, item = 0;
2338
2339	pin_ctl = snd_hda_codec_read(codec, nid, 0,
2340				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2341	if (pin_ctl & AC_PINCTL_OUT_EN) {
2342		if (pin_ctl & AC_PINCTL_HP_EN)
2343			item = 2;
2344		else
2345			item = 1;
2346	} else if (pin_ctl & AC_PINCTL_IN_EN) {
2347		switch (pin_ctl & AC_PINCTL_VREFEN) {
2348		case AC_PINCTL_VREF_HIZ: item = 3; break;
2349		case AC_PINCTL_VREF_50:  item = 4; break;
2350		case AC_PINCTL_VREF_GRD: item = 5; break;
2351		case AC_PINCTL_VREF_80:  item = 6; break;
2352		case AC_PINCTL_VREF_100: item = 7; break;
2353		}
2354	}
2355	ucontrol->value.enumerated.item[0] = item;
2356	return 0;
2357}
2358
2359static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2360				struct snd_ctl_elem_value *ucontrol)
2361{
2362	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2363	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2364	static unsigned int ctls[] = {
2365		0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2366		AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2367		AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2368		AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2369		AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2370		AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2371	};
2372	unsigned int old_ctl, new_ctl;
2373
2374	old_ctl = snd_hda_codec_read(codec, nid, 0,
2375				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2376	new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2377	if (old_ctl != new_ctl) {
2378		int val;
2379		snd_hda_codec_write_cache(codec, nid, 0,
2380					  AC_VERB_SET_PIN_WIDGET_CONTROL,
2381					  new_ctl);
2382		val = ucontrol->value.enumerated.item[0] >= 3 ?
2383			HDA_AMP_MUTE : 0;
2384		snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2385					 HDA_AMP_MUTE, val);
2386		return 1;
2387	}
2388	return 0;
2389}
2390
2391static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2392				 struct snd_ctl_elem_info *uinfo)
2393{
2394	static char *texts[] = {
2395		"Front", "Surround", "CLFE", "Side"
2396	};
2397	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2398	uinfo->count = 1;
2399	uinfo->value.enumerated.items = 4;
2400	if (uinfo->value.enumerated.item >= 4)
2401		uinfo->value.enumerated.item = 3;
2402	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2403	return 0;
2404}
2405
2406static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2407				struct snd_ctl_elem_value *ucontrol)
2408{
2409	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2410	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2411	unsigned int sel;
2412
2413	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2414	ucontrol->value.enumerated.item[0] = sel & 3;
2415	return 0;
2416}
2417
2418static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2419				struct snd_ctl_elem_value *ucontrol)
2420{
2421	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2422	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2423	unsigned int sel;
2424
2425	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2426	if (ucontrol->value.enumerated.item[0] != sel) {
2427		sel = ucontrol->value.enumerated.item[0] & 3;
2428		snd_hda_codec_write_cache(codec, nid, 0,
2429					  AC_VERB_SET_CONNECT_SEL, sel);
2430		return 1;
2431	}
2432	return 0;
2433}
2434
2435#define PIN_CTL_TEST(xname,nid) {			\
2436		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
2437			.name = xname,		       \
2438			.info = alc_test_pin_ctl_info, \
2439			.get = alc_test_pin_ctl_get,   \
2440			.put = alc_test_pin_ctl_put,   \
2441			.private_value = nid	       \
2442			}
2443
2444#define PIN_SRC_TEST(xname,nid) {			\
2445		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
2446			.name = xname,		       \
2447			.info = alc_test_pin_src_info, \
2448			.get = alc_test_pin_src_get,   \
2449			.put = alc_test_pin_src_put,   \
2450			.private_value = nid	       \
2451			}
2452
2453static struct snd_kcontrol_new alc880_test_mixer[] = {
2454	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2455	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2456	HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2457	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2458	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2459	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2460	HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2461	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2462	PIN_CTL_TEST("Front Pin Mode", 0x14),
2463	PIN_CTL_TEST("Surround Pin Mode", 0x15),
2464	PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2465	PIN_CTL_TEST("Side Pin Mode", 0x17),
2466	PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2467	PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2468	PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2469	PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2470	PIN_SRC_TEST("In-1 Pin Source", 0x18),
2471	PIN_SRC_TEST("In-2 Pin Source", 0x19),
2472	PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2473	PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2474	HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2475	HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2476	HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2477	HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2478	HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2479	HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2480	HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2481	HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2482	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2483	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2484	{
2485		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2486		.name = "Channel Mode",
2487		.info = alc_ch_mode_info,
2488		.get = alc_ch_mode_get,
2489		.put = alc_ch_mode_put,
2490	},
2491	{ } /* end */
2492};
2493
2494static struct hda_verb alc880_test_init_verbs[] = {
2495	/* Unmute inputs of 0x0c - 0x0f */
2496	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2497	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2498	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2499	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2500	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2501	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2502	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2503	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2504	/* Vol output for 0x0c-0x0f */
2505	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2506	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2507	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2508	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2509	/* Set output pins 0x14-0x17 */
2510	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2511	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2512	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2513	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2514	/* Unmute output pins 0x14-0x17 */
2515	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2516	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2517	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2518	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2519	/* Set input pins 0x18-0x1c */
2520	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2521	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2522	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2523	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2524	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2525	/* Mute input pins 0x18-0x1b */
2526	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2527	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2528	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2529	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2530	/* ADC set up */
2531	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2532	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2533	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2534	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2535	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2536	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2537	/* Analog input/passthru */
2538	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2539	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2540	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2541	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2542	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2543	{ }
2544};
2545#endif
2546
2547/*
2548 */
2549
2550static const char *alc880_models[ALC880_MODEL_LAST] = {
2551	[ALC880_3ST]		= "3stack",
2552	[ALC880_TCL_S700]	= "tcl",
2553	[ALC880_3ST_DIG]	= "3stack-digout",
2554	[ALC880_CLEVO]		= "clevo",
2555	[ALC880_5ST]		= "5stack",
2556	[ALC880_5ST_DIG]	= "5stack-digout",
2557	[ALC880_W810]		= "w810",
2558	[ALC880_Z71V]		= "z71v",
2559	[ALC880_6ST]		= "6stack",
2560	[ALC880_6ST_DIG]	= "6stack-digout",
2561	[ALC880_ASUS]		= "asus",
2562	[ALC880_ASUS_W1V]	= "asus-w1v",
2563	[ALC880_ASUS_DIG]	= "asus-dig",
2564	[ALC880_ASUS_DIG2]	= "asus-dig2",
2565	[ALC880_UNIWILL_DIG]	= "uniwill",
2566	[ALC880_UNIWILL_P53]	= "uniwill-p53",
2567	[ALC880_FUJITSU]	= "fujitsu",
2568	[ALC880_F1734]		= "F1734",
2569	[ALC880_LG]		= "lg",
2570	[ALC880_LG_LW]		= "lg-lw",
2571#ifdef CONFIG_SND_DEBUG
2572	[ALC880_TEST]		= "test",
2573#endif
2574	[ALC880_AUTO]		= "auto",
2575};
2576
2577static struct snd_pci_quirk alc880_cfg_tbl[] = {
2578	/* Broken BIOS configuration */
2579	SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG),
2580	SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2581
2582	SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2583	SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2584	SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
2585	SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2586	SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2587	SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2588	SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2589	SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2590	SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
2591
2592	SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2593	SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
2594
2595	SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2596	SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2597	SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2598	SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2599	SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2600	SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2601	SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2602	/* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2603	SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2604	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
2605	SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
2606	SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2607	SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2608	SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
2609	SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS),
2610
2611	SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2612	SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
2613	SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2614	SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
2615	SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
2616	SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2617	SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
2618	SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
2619	SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2620	SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
2621	SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2622	SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2623	SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
2624	SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2625	SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2626	SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2627	SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
2628	SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
2629
2630	SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
2631	SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2632	SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
2633	SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
2634
2635	SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
2636	SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2637	SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
2638	SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
2639
2640	SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2641	SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
2642	SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
2643	SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
2644
2645	SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
2646	SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2647	SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
2648	SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2649	SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
2650	SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
2651	SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2652	SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2653	SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
2654	SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
2655	SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST),
2656
2657	{}
2658};
2659
2660/*
2661 * ALC880 codec presets
2662 */
2663static struct alc_config_preset alc880_presets[] = {
2664	[ALC880_3ST] = {
2665		.mixers = { alc880_three_stack_mixer },
2666		.init_verbs = { alc880_volume_init_verbs,
2667				alc880_pin_3stack_init_verbs },
2668		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2669		.dac_nids = alc880_dac_nids,
2670		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2671		.channel_mode = alc880_threestack_modes,
2672		.need_dac_fix = 1,
2673		.input_mux = &alc880_capture_source,
2674	},
2675	[ALC880_3ST_DIG] = {
2676		.mixers = { alc880_three_stack_mixer },
2677		.init_verbs = { alc880_volume_init_verbs,
2678				alc880_pin_3stack_init_verbs },
2679		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2680		.dac_nids = alc880_dac_nids,
2681		.dig_out_nid = ALC880_DIGOUT_NID,
2682		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2683		.channel_mode = alc880_threestack_modes,
2684		.need_dac_fix = 1,
2685		.input_mux = &alc880_capture_source,
2686	},
2687	[ALC880_TCL_S700] = {
2688		.mixers = { alc880_tcl_s700_mixer },
2689		.init_verbs = { alc880_volume_init_verbs,
2690				alc880_pin_tcl_S700_init_verbs,
2691				alc880_gpio2_init_verbs },
2692		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2693		.dac_nids = alc880_dac_nids,
2694		.hp_nid = 0x03,
2695		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2696		.channel_mode = alc880_2_jack_modes,
2697		.input_mux = &alc880_capture_source,
2698	},
2699	[ALC880_5ST] = {
2700		.mixers = { alc880_three_stack_mixer,
2701			    alc880_five_stack_mixer},
2702		.init_verbs = { alc880_volume_init_verbs,
2703				alc880_pin_5stack_init_verbs },
2704		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2705		.dac_nids = alc880_dac_nids,
2706		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2707		.channel_mode = alc880_fivestack_modes,
2708		.input_mux = &alc880_capture_source,
2709	},
2710	[ALC880_5ST_DIG] = {
2711		.mixers = { alc880_three_stack_mixer,
2712			    alc880_five_stack_mixer },
2713		.init_verbs = { alc880_volume_init_verbs,
2714				alc880_pin_5stack_init_verbs },
2715		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2716		.dac_nids = alc880_dac_nids,
2717		.dig_out_nid = ALC880_DIGOUT_NID,
2718		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2719		.channel_mode = alc880_fivestack_modes,
2720		.input_mux = &alc880_capture_source,
2721	},
2722	[ALC880_6ST] = {
2723		.mixers = { alc880_six_stack_mixer },
2724		.init_verbs = { alc880_volume_init_verbs,
2725				alc880_pin_6stack_init_verbs },
2726		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2727		.dac_nids = alc880_6st_dac_nids,
2728		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2729		.channel_mode = alc880_sixstack_modes,
2730		.input_mux = &alc880_6stack_capture_source,
2731	},
2732	[ALC880_6ST_DIG] = {
2733		.mixers = { alc880_six_stack_mixer },
2734		.init_verbs = { alc880_volume_init_verbs,
2735				alc880_pin_6stack_init_verbs },
2736		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2737		.dac_nids = alc880_6st_dac_nids,
2738		.dig_out_nid = ALC880_DIGOUT_NID,
2739		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2740		.channel_mode = alc880_sixstack_modes,
2741		.input_mux = &alc880_6stack_capture_source,
2742	},
2743	[ALC880_W810] = {
2744		.mixers = { alc880_w810_base_mixer },
2745		.init_verbs = { alc880_volume_init_verbs,
2746				alc880_pin_w810_init_verbs,
2747				alc880_gpio2_init_verbs },
2748		.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2749		.dac_nids = alc880_w810_dac_nids,
2750		.dig_out_nid = ALC880_DIGOUT_NID,
2751		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2752		.channel_mode = alc880_w810_modes,
2753		.input_mux = &alc880_capture_source,
2754	},
2755	[ALC880_Z71V] = {
2756		.mixers = { alc880_z71v_mixer },
2757		.init_verbs = { alc880_volume_init_verbs,
2758				alc880_pin_z71v_init_verbs },
2759		.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
2760		.dac_nids = alc880_z71v_dac_nids,
2761		.dig_out_nid = ALC880_DIGOUT_NID,
2762		.hp_nid = 0x03,
2763		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2764		.channel_mode = alc880_2_jack_modes,
2765		.input_mux = &alc880_capture_source,
2766	},
2767	[ALC880_F1734] = {
2768		.mixers = { alc880_f1734_mixer },
2769		.init_verbs = { alc880_volume_init_verbs,
2770				alc880_pin_f1734_init_verbs },
2771		.num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
2772		.dac_nids = alc880_f1734_dac_nids,
2773		.hp_nid = 0x02,
2774		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2775		.channel_mode = alc880_2_jack_modes,
2776		.input_mux = &alc880_capture_source,
2777	},
2778	[ALC880_ASUS] = {
2779		.mixers = { alc880_asus_mixer },
2780		.init_verbs = { alc880_volume_init_verbs,
2781				alc880_pin_asus_init_verbs,
2782				alc880_gpio1_init_verbs },
2783		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2784		.dac_nids = alc880_asus_dac_nids,
2785		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2786		.channel_mode = alc880_asus_modes,
2787		.need_dac_fix = 1,
2788		.input_mux = &alc880_capture_source,
2789	},
2790	[ALC880_ASUS_DIG] = {
2791		.mixers = { alc880_asus_mixer },
2792		.init_verbs = { alc880_volume_init_verbs,
2793				alc880_pin_asus_init_verbs,
2794				alc880_gpio1_init_verbs },
2795		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2796		.dac_nids = alc880_asus_dac_nids,
2797		.dig_out_nid = ALC880_DIGOUT_NID,
2798		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2799		.channel_mode = alc880_asus_modes,
2800		.need_dac_fix = 1,
2801		.input_mux = &alc880_capture_source,
2802	},
2803	[ALC880_ASUS_DIG2] = {
2804		.mixers = { alc880_asus_mixer },
2805		.init_verbs = { alc880_volume_init_verbs,
2806				alc880_pin_asus_init_verbs,
2807				alc880_gpio2_init_verbs }, /* use GPIO2 */
2808		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2809		.dac_nids = alc880_asus_dac_nids,
2810		.dig_out_nid = ALC880_DIGOUT_NID,
2811		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2812		.channel_mode = alc880_asus_modes,
2813		.need_dac_fix = 1,
2814		.input_mux = &alc880_capture_source,
2815	},
2816	[ALC880_ASUS_W1V] = {
2817		.mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
2818		.init_verbs = { alc880_volume_init_verbs,
2819				alc880_pin_asus_init_verbs,
2820				alc880_gpio1_init_verbs },
2821		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2822		.dac_nids = alc880_asus_dac_nids,
2823		.dig_out_nid = ALC880_DIGOUT_NID,
2824		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2825		.channel_mode = alc880_asus_modes,
2826		.need_dac_fix = 1,
2827		.input_mux = &alc880_capture_source,
2828	},
2829	[ALC880_UNIWILL_DIG] = {
2830		.mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
2831		.init_verbs = { alc880_volume_init_verbs,
2832				alc880_pin_asus_init_verbs },
2833		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2834		.dac_nids = alc880_asus_dac_nids,
2835		.dig_out_nid = ALC880_DIGOUT_NID,
2836		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2837		.channel_mode = alc880_asus_modes,
2838		.need_dac_fix = 1,
2839		.input_mux = &alc880_capture_source,
2840	},
2841	[ALC880_UNIWILL] = {
2842		.mixers = { alc880_uniwill_mixer },
2843		.init_verbs = { alc880_volume_init_verbs,
2844				alc880_uniwill_init_verbs },
2845		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2846		.dac_nids = alc880_asus_dac_nids,
2847		.dig_out_nid = ALC880_DIGOUT_NID,
2848		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2849		.channel_mode = alc880_threestack_modes,
2850		.need_dac_fix = 1,
2851		.input_mux = &alc880_capture_source,
2852		.unsol_event = alc880_uniwill_unsol_event,
2853		.init_hook = alc880_uniwill_automute,
2854	},
2855	[ALC880_UNIWILL_P53] = {
2856		.mixers = { alc880_uniwill_p53_mixer },
2857		.init_verbs = { alc880_volume_init_verbs,
2858				alc880_uniwill_p53_init_verbs },
2859		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2860		.dac_nids = alc880_asus_dac_nids,
2861		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2862		.channel_mode = alc880_threestack_modes,
2863		.input_mux = &alc880_capture_source,
2864		.unsol_event = alc880_uniwill_p53_unsol_event,
2865		.init_hook = alc880_uniwill_p53_hp_automute,
2866	},
2867	[ALC880_FUJITSU] = {
2868		.mixers = { alc880_fujitsu_mixer,
2869			    alc880_pcbeep_mixer, },
2870		.init_verbs = { alc880_volume_init_verbs,
2871				alc880_uniwill_p53_init_verbs,
2872	       			alc880_beep_init_verbs },
2873		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2874		.dac_nids = alc880_dac_nids,
2875		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2876		.channel_mode = alc880_2_jack_modes,
2877		.input_mux = &alc880_capture_source,
2878		.unsol_event = alc880_uniwill_p53_unsol_event,
2879		.init_hook = alc880_uniwill_p53_hp_automute,
2880	},
2881	[ALC880_CLEVO] = {
2882		.mixers = { alc880_three_stack_mixer },
2883		.init_verbs = { alc880_volume_init_verbs,
2884				alc880_pin_clevo_init_verbs },
2885		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2886		.dac_nids = alc880_dac_nids,
2887		.hp_nid = 0x03,
2888		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2889		.channel_mode = alc880_threestack_modes,
2890		.need_dac_fix = 1,
2891		.input_mux = &alc880_capture_source,
2892	},
2893	[ALC880_LG] = {
2894		.mixers = { alc880_lg_mixer },
2895		.init_verbs = { alc880_volume_init_verbs,
2896				alc880_lg_init_verbs },
2897		.num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
2898		.dac_nids = alc880_lg_dac_nids,
2899		.dig_out_nid = ALC880_DIGOUT_NID,
2900		.num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
2901		.channel_mode = alc880_lg_ch_modes,
2902		.need_dac_fix = 1,
2903		.input_mux = &alc880_lg_capture_source,
2904		.unsol_event = alc880_lg_unsol_event,
2905		.init_hook = alc880_lg_automute,
2906#ifdef CONFIG_SND_HDA_POWER_SAVE
2907		.loopbacks = alc880_lg_loopbacks,
2908#endif
2909	},
2910	[ALC880_LG_LW] = {
2911		.mixers = { alc880_lg_lw_mixer },
2912		.init_verbs = { alc880_volume_init_verbs,
2913				alc880_lg_lw_init_verbs },
2914		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2915		.dac_nids = alc880_dac_nids,
2916		.dig_out_nid = ALC880_DIGOUT_NID,
2917		.num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
2918		.channel_mode = alc880_lg_lw_modes,
2919		.input_mux = &alc880_lg_lw_capture_source,
2920		.unsol_event = alc880_lg_lw_unsol_event,
2921		.init_hook = alc880_lg_lw_automute,
2922	},
2923#ifdef CONFIG_SND_DEBUG
2924	[ALC880_TEST] = {
2925		.mixers = { alc880_test_mixer },
2926		.init_verbs = { alc880_test_init_verbs },
2927		.num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
2928		.dac_nids = alc880_test_dac_nids,
2929		.dig_out_nid = ALC880_DIGOUT_NID,
2930		.num_channel_mode = ARRAY_SIZE(alc880_test_modes),
2931		.channel_mode = alc880_test_modes,
2932		.input_mux = &alc880_test_capture_source,
2933	},
2934#endif
2935};
2936
2937/*
2938 * Automatic parse of I/O pins from the BIOS configuration
2939 */
2940
2941#define NUM_CONTROL_ALLOC	32
2942#define NUM_VERB_ALLOC		32
2943
2944enum {
2945	ALC_CTL_WIDGET_VOL,
2946	ALC_CTL_WIDGET_MUTE,
2947	ALC_CTL_BIND_MUTE,
2948};
2949static struct snd_kcontrol_new alc880_control_templates[] = {
2950	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2951	HDA_CODEC_MUTE(NULL, 0, 0, 0),
2952	HDA_BIND_MUTE(NULL, 0, 0, 0),
2953};
2954
2955/* add dynamic controls */
2956static int add_control(struct alc_spec *spec, int type, const char *name,
2957		       unsigned long val)
2958{
2959	struct snd_kcontrol_new *knew;
2960
2961	if (spec->num_kctl_used >= spec->num_kctl_alloc) {
2962		int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
2963
2964		/* array + terminator */
2965		knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
2966		if (!knew)
2967			return -ENOMEM;
2968		if (spec->kctl_alloc) {
2969			memcpy(knew, spec->kctl_alloc,
2970			       sizeof(*knew) * spec->num_kctl_alloc);
2971			kfree(spec->kctl_alloc);
2972		}
2973		spec->kctl_alloc = knew;
2974		spec->num_kctl_alloc = num;
2975	}
2976
2977	knew = &spec->kctl_alloc[spec->num_kctl_used];
2978	*knew = alc880_control_templates[type];
2979	knew->name = kstrdup(name, GFP_KERNEL);
2980	if (!knew->name)
2981		return -ENOMEM;
2982	knew->private_value = val;
2983	spec->num_kctl_used++;
2984	return 0;
2985}
2986
2987#define alc880_is_fixed_pin(nid)	((nid) >= 0x14 && (nid) <= 0x17)
2988#define alc880_fixed_pin_idx(nid)	((nid) - 0x14)
2989#define alc880_is_multi_pin(nid)	((nid) >= 0x18)
2990#define alc880_multi_pin_idx(nid)	((nid) - 0x18)
2991#define alc880_is_input_pin(nid)	((nid) >= 0x18)
2992#define alc880_input_pin_idx(nid)	((nid) - 0x18)
2993#define alc880_idx_to_dac(nid)		((nid) + 0x02)
2994#define alc880_dac_to_idx(nid)		((nid) - 0x02)
2995#define alc880_idx_to_mixer(nid)	((nid) + 0x0c)
2996#define alc880_idx_to_selector(nid)	((nid) + 0x10)
2997#define ALC880_PIN_CD_NID		0x1c
2998
2999/* fill in the dac_nids table from the parsed pin configuration */
3000static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3001				     const struct auto_pin_cfg *cfg)
3002{
3003	hda_nid_t nid;
3004	int assigned[4];
3005	int i, j;
3006
3007	memset(assigned, 0, sizeof(assigned));
3008	spec->multiout.dac_nids = spec->private_dac_nids;
3009
3010	/* check the pins hardwired to audio widget */
3011	for (i = 0; i < cfg->line_outs; i++) {
3012		nid = cfg->line_out_pins[i];
3013		if (alc880_is_fixed_pin(nid)) {
3014			int idx = alc880_fixed_pin_idx(nid);
3015			spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3016			assigned[idx] = 1;
3017		}
3018	}
3019	/* left pins can be connect to any audio widget */
3020	for (i = 0; i < cfg->line_outs; i++) {
3021		nid = cfg->line_out_pins[i];
3022		if (alc880_is_fixed_pin(nid))
3023			continue;
3024		/* search for an empty channel */
3025		for (j = 0; j < cfg->line_outs; j++) {
3026			if (!assigned[j]) {
3027				spec->multiout.dac_nids[i] =
3028					alc880_idx_to_dac(j);
3029				assigned[j] = 1;
3030				break;
3031			}
3032		}
3033	}
3034	spec->multiout.num_dacs = cfg->line_outs;
3035	return 0;
3036}
3037
3038/* add playback controls from the parsed DAC table */
3039static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3040					     const struct auto_pin_cfg *cfg)
3041{
3042	char name[32];
3043	static const char *chname[4] = {
3044		"Front", "Surround", NULL /*CLFE*/, "Side"
3045	};
3046	hda_nid_t nid;
3047	int i, err;
3048
3049	for (i = 0; i < cfg->line_outs; i++) {
3050		if (!spec->multiout.dac_nids[i])
3051			continue;
3052		nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3053		if (i == 2) {
3054			/* Center/LFE */
3055			err = add_control(spec, ALC_CTL_WIDGET_VOL,
3056					  "Center Playback Volume",
3057					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3058							      HDA_OUTPUT));
3059			if (err < 0)
3060				return err;
3061			err = add_control(spec, ALC_CTL_WIDGET_VOL,
3062					  "LFE Playback Volume",
3063					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3064							      HDA_OUTPUT));
3065			if (err < 0)
3066				return err;
3067			err = add_control(spec, ALC_CTL_BIND_MUTE,
3068					  "Center Playback Switch",
3069					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3070							      HDA_INPUT));
3071			if (err < 0)
3072				return err;
3073			err = add_control(spec, ALC_CTL_BIND_MUTE,
3074					  "LFE Playback Switch",
3075					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3076							      HDA_INPUT));
3077			if (err < 0)
3078				return err;
3079		} else {
3080			sprintf(name, "%s Playback Volume", chname[i]);
3081			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3082					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3083							      HDA_OUTPUT));
3084			if (err < 0)
3085				return err;
3086			sprintf(name, "%s Playback Switch", chname[i]);
3087			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3088					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3089							      HDA_INPUT));
3090			if (err < 0)
3091				return err;
3092		}
3093	}
3094	return 0;
3095}
3096
3097/* add playback controls for speaker and HP outputs */
3098static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3099					const char *pfx)
3100{
3101	hda_nid_t nid;
3102	int err;
3103	char name[32];
3104
3105	if (!pin)
3106		return 0;
3107
3108	if (alc880_is_fixed_pin(pin)) {
3109		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3110		/* specify the DAC as the extra output */
3111		if (!spec->multiout.hp_nid)
3112			spec->multiout.hp_nid = nid;
3113		else
3114			spec->multiout.extra_out_nid[0] = nid;
3115		/* control HP volume/switch on the output mixer amp */
3116		nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3117		sprintf(name, "%s Playback Volume", pfx);
3118		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3119				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3120		if (err < 0)
3121			return err;
3122		sprintf(name, "%s Playback Switch", pfx);
3123		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3124				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3125		if (err < 0)
3126			return err;
3127	} else if (alc880_is_multi_pin(pin)) {
3128		/* set manual connection */
3129		/* we have only a switch on HP-out PIN */
3130		sprintf(name, "%s Playback Switch", pfx);
3131		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3132				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3133		if (err < 0)
3134			return err;
3135	}
3136	return 0;
3137}
3138
3139/* create input playback/capture controls for the given pin */
3140static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3141			    const char *ctlname,
3142			    int idx, hda_nid_t mix_nid)
3143{
3144	char name[32];
3145	int err;
3146
3147	sprintf(name, "%s Playback Volume", ctlname);
3148	err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3149			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3150	if (err < 0)
3151		return err;
3152	sprintf(name, "%s Playback Switch", ctlname);
3153	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3154			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3155	if (err < 0)
3156		return err;
3157	return 0;
3158}
3159
3160/* create playback/capture controls for input pins */
3161static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3162						const struct auto_pin_cfg *cfg)
3163{
3164	struct hda_input_mux *imux = &spec->private_imux;
3165	int i, err, idx;
3166
3167	for (i = 0; i < AUTO_PIN_LAST; i++) {
3168		if (alc880_is_input_pin(cfg->input_pins[i])) {
3169			idx = alc880_input_pin_idx(cfg->input_pins[i]);
3170			err = new_analog_input(spec, cfg->input_pins[i],
3171					       auto_pin_cfg_labels[i],
3172					       idx, 0x0b);
3173			if (err < 0)
3174				return err;
3175			imux->items[imux->num_items].label =
3176				auto_pin_cfg_labels[i];
3177			imux->items[imux->num_items].index =
3178				alc880_input_pin_idx(cfg->input_pins[i]);
3179			imux->num_items++;
3180		}
3181	}
3182	return 0;
3183}
3184
3185static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3186					      hda_nid_t nid, int pin_type,
3187					      int dac_idx)
3188{
3189	/* set as output */
3190	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3191			    pin_type);
3192	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3193			    AMP_OUT_UNMUTE);
3194	/* need the manual connection? */
3195	if (alc880_is_multi_pin(nid)) {
3196		struct alc_spec *spec = codec->spec;
3197		int idx = alc880_multi_pin_idx(nid);
3198		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3199				    AC_VERB_SET_CONNECT_SEL,
3200				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3201	}
3202}
3203
3204static int get_pin_type(int line_out_type)
3205{
3206	if (line_out_type == AUTO_PIN_HP_OUT)
3207		return PIN_HP;
3208	else
3209		return PIN_OUT;
3210}
3211
3212static void alc880_auto_init_multi_out(struct hda_codec *codec)
3213{
3214	struct alc_spec *spec = codec->spec;
3215	int i;
3216
3217	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3218	for (i = 0; i < spec->autocfg.line_outs; i++) {
3219		hda_nid_t nid = spec->autocfg.line_out_pins[i];
3220		int pin_type = get_pin_type(spec->autocfg.line_out_type);
3221		alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3222	}
3223}
3224
3225static void alc880_auto_init_extra_out(struct hda_codec *codec)
3226{
3227	struct alc_spec *spec = codec->spec;
3228	hda_nid_t pin;
3229
3230	pin = spec->autocfg.speaker_pins[0];
3231	if (pin) /* connect to front */
3232		alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3233	pin = spec->autocfg.hp_pins[0];
3234	if (pin) /* connect to front */
3235		alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3236}
3237
3238static void alc880_auto_init_analog_input(struct hda_codec *codec)
3239{
3240	struct alc_spec *spec = codec->spec;
3241	int i;
3242
3243	for (i = 0; i < AUTO_PIN_LAST; i++) {
3244		hda_nid_t nid = spec->autocfg.input_pins[i];
3245		if (alc880_is_input_pin(nid)) {
3246			snd_hda_codec_write(codec, nid, 0,
3247					    AC_VERB_SET_PIN_WIDGET_CONTROL,
3248					    i <= AUTO_PIN_FRONT_MIC ?
3249					    PIN_VREF80 : PIN_IN);
3250			if (nid != ALC880_PIN_CD_NID)
3251				snd_hda_codec_write(codec, nid, 0,
3252						    AC_VERB_SET_AMP_GAIN_MUTE,
3253						    AMP_OUT_MUTE);
3254		}
3255	}
3256}
3257
3258/* parse the BIOS configuration and set up the alc_spec */
3259/* return 1 if successful, 0 if the proper config is not found,
3260 * or a negative error code
3261 */
3262static int alc880_parse_auto_config(struct hda_codec *codec)
3263{
3264	struct alc_spec *spec = codec->spec;
3265	int err;
3266	static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3267
3268	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3269					   alc880_ignore);
3270	if (err < 0)
3271		return err;
3272	if (!spec->autocfg.line_outs)
3273		return 0; /* can't find valid BIOS pin config */
3274
3275	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3276	if (err < 0)
3277		return err;
3278	err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3279	if (err < 0)
3280		return err;
3281	err = alc880_auto_create_extra_out(spec,
3282					   spec->autocfg.speaker_pins[0],
3283					   "Speaker");
3284	if (err < 0)
3285		return err;
3286	err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3287					   "Headphone");
3288	if (err < 0)
3289		return err;
3290	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3291	if (err < 0)
3292		return err;
3293
3294	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3295
3296	if (spec->autocfg.dig_out_pin)
3297		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3298	if (spec->autocfg.dig_in_pin)
3299		spec->dig_in_nid = ALC880_DIGIN_NID;
3300
3301	if (spec->kctl_alloc)
3302		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3303
3304	spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3305
3306	spec->num_mux_defs = 1;
3307	spec->input_mux = &spec->private_imux;
3308
3309	return 1;
3310}
3311
3312/* additional initialization for auto-configuration model */
3313static void alc880_auto_init(struct hda_codec *codec)
3314{
3315	alc880_auto_init_multi_out(codec);
3316	alc880_auto_init_extra_out(codec);
3317	alc880_auto_init_analog_input(codec);
3318}
3319
3320/*
3321 * OK, here we have finally the patch for ALC880
3322 */
3323
3324static int patch_alc880(struct hda_codec *codec)
3325{
3326	struct alc_spec *spec;
3327	int board_config;
3328	int err;
3329
3330	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3331	if (spec == NULL)
3332		return -ENOMEM;
3333
3334	codec->spec = spec;
3335
3336	board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3337						  alc880_models,
3338						  alc880_cfg_tbl);
3339	if (board_config < 0) {
3340		printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3341		       "trying auto-probe from BIOS...\n");
3342		board_config = ALC880_AUTO;
3343	}
3344
3345	if (board_config == ALC880_AUTO) {
3346		/* automatic parse from the BIOS config */
3347		err = alc880_parse_auto_config(codec);
3348		if (err < 0) {
3349			alc_free(codec);
3350			return err;
3351		} else if (!err) {
3352			printk(KERN_INFO
3353			       "hda_codec: Cannot set up configuration "
3354			       "from BIOS.  Using 3-stack mode...\n");
3355			board_config = ALC880_3ST;
3356		}
3357	}
3358
3359	if (board_config != ALC880_AUTO)
3360		setup_preset(spec, &alc880_presets[board_config]);
3361
3362	spec->stream_name_analog = "ALC880 Analog";
3363	spec->stream_analog_playback = &alc880_pcm_analog_playback;
3364	spec->stream_analog_capture = &alc880_pcm_analog_capture;
3365
3366	spec->stream_name_digital = "ALC880 Digital";
3367	spec->stream_digital_playback = &alc880_pcm_digital_playback;
3368	spec->stream_digital_capture = &alc880_pcm_digital_capture;
3369
3370	if (!spec->adc_nids && spec->input_mux) {
3371		/* check whether NID 0x07 is valid */
3372		unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3373		/* get type */
3374		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3375		if (wcap != AC_WID_AUD_IN) {
3376			spec->adc_nids = alc880_adc_nids_alt;
3377			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3378			spec->mixers[spec->num_mixers] =
3379				alc880_capture_alt_mixer;
3380			spec->num_mixers++;
3381		} else {
3382			spec->adc_nids = alc880_adc_nids;
3383			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3384			spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3385			spec->num_mixers++;
3386		}
3387	}
3388
3389	codec->patch_ops = alc_patch_ops;
3390	if (board_config == ALC880_AUTO)
3391		spec->init_hook = alc880_auto_init;
3392#ifdef CONFIG_SND_HDA_POWER_SAVE
3393	if (!spec->loopback.amplist)
3394		spec->loopback.amplist = alc880_loopbacks;
3395#endif
3396
3397	return 0;
3398}
3399
3400
3401/*
3402 * ALC260 support
3403 */
3404
3405static hda_nid_t alc260_dac_nids[1] = {
3406	/* front */
3407	0x02,
3408};
3409
3410static hda_nid_t alc260_adc_nids[1] = {
3411	/* ADC0 */
3412	0x04,
3413};
3414
3415static hda_nid_t alc260_adc_nids_alt[1] = {
3416	/* ADC1 */
3417	0x05,
3418};
3419
3420static hda_nid_t alc260_hp_adc_nids[2] = {
3421	/* ADC1, 0 */
3422	0x05, 0x04
3423};
3424
3425/* NIDs used when simultaneous access to both ADCs makes sense.  Note that
3426 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3427 */
3428static hda_nid_t alc260_dual_adc_nids[2] = {
3429	/* ADC0, ADC1 */
3430	0x04, 0x05
3431};
3432
3433#define ALC260_DIGOUT_NID	0x03
3434#define ALC260_DIGIN_NID	0x06
3435
3436static struct hda_input_mux alc260_capture_source = {
3437	.num_items = 4,
3438	.items = {
3439		{ "Mic", 0x0 },
3440		{ "Front Mic", 0x1 },
3441		{ "Line", 0x2 },
3442		{ "CD", 0x4 },
3443	},
3444};
3445
3446/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3447 * headphone jack and the internal CD lines since these are the only pins at
3448 * which audio can appear.  For flexibility, also allow the option of
3449 * recording the mixer output on the second ADC (ADC0 doesn't have a
3450 * connection to the mixer output).
3451 */
3452static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3453	{
3454		.num_items = 3,
3455		.items = {
3456			{ "Mic/Line", 0x0 },
3457			{ "CD", 0x4 },
3458			{ "Headphone", 0x2 },
3459		},
3460	},
3461	{
3462		.num_items = 4,
3463		.items = {
3464			{ "Mic/Line", 0x0 },
3465			{ "CD", 0x4 },
3466			{ "Headphone", 0x2 },
3467			{ "Mixer", 0x5 },
3468		},
3469	},
3470
3471};
3472
3473/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3474 * the Fujitsu S702x, but jacks are marked differently.
3475 */
3476static struct hda_input_mux alc260_acer_capture_sources[2] = {
3477	{
3478		.num_items = 4,
3479		.items = {
3480			{ "Mic", 0x0 },
3481			{ "Line", 0x2 },
3482			{ "CD", 0x4 },
3483			{ "Headphone", 0x5 },
3484		},
3485	},
3486	{
3487		.num_items = 5,
3488		.items = {
3489			{ "Mic", 0x0 },
3490			{ "Line", 0x2 },
3491			{ "CD", 0x4 },
3492			{ "Headphone", 0x6 },
3493			{ "Mixer", 0x5 },
3494		},
3495	},
3496};
3497/*
3498 * This is just place-holder, so there's something for alc_build_pcms to look
3499 * at when it calculates the maximum number of channels. ALC260 has no mixer
3500 * element which allows changing the channel mode, so the verb list is
3501 * never used.
3502 */
3503static struct hda_channel_mode alc260_modes[1] = {
3504	{ 2, NULL },
3505};
3506
3507
3508/* Mixer combinations
3509 *
3510 * basic: base_output + input + pc_beep + capture
3511 * HP: base_output + input + capture_alt
3512 * HP_3013: hp_3013 + input + capture
3513 * fujitsu: fujitsu + capture
3514 * acer: acer + capture
3515 */
3516
3517static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3518	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3519	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3520	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3521	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3522	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3523	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3524	{ } /* end */
3525};
3526
3527static struct snd_kcontrol_new alc260_input_mixer[] = {
3528	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3529	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3530	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3531	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3532	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3533	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3534	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3535	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
3536	{ } /* end */
3537};
3538
3539static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3540	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3541	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3542	{ } /* end */
3543};
3544
3545static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
3546	HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3547	HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3548	HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3549	HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3550	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3551	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3552	HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3553	HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
3554	{ } /* end */
3555};
3556
3557/* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12,
3558 * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
3559 */
3560static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
3561	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3562	HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
3563	ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3564	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3565	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3566	HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3567	HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
3568	ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
3569	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3570	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3571	HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3572	HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
3573	{ } /* end */
3574};
3575
3576/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
3577 * versions of the ALC260 don't act on requests to enable mic bias from NID
3578 * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
3579 * datasheet doesn't mention this restriction.  At this stage it's not clear
3580 * whether this behaviour is intentional or is a hardware bug in chip
3581 * revisions available in early 2006.  Therefore for now allow the
3582 * "Headphone Jack Mode" control to span all choices, but if it turns out
3583 * that the lack of mic bias for this NID is intentional we could change the
3584 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3585 *
3586 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
3587 * don't appear to make the mic bias available from the "line" jack, even
3588 * though the NID used for this jack (0x14) can supply it.  The theory is
3589 * that perhaps Acer have included blocking capacitors between the ALC260
3590 * and the output jack.  If this turns out to be the case for all such
3591 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3592 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
3593 *
3594 * The C20x Tablet series have a mono internal speaker which is controlled
3595 * via the chip's Mono sum widget and pin complex, so include the necessary
3596 * controls for such models.  On models without a "mono speaker" the control
3597 * won't do anything.
3598 */
3599static struct snd_kcontrol_new alc260_acer_mixer[] = {
3600	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3601	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
3602	ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
3603	HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0,
3604			      HDA_OUTPUT),
3605	HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2,
3606			   HDA_INPUT),
3607	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3608	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3609	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3610	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3611	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3612	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3613	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3614	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3615	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3616	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3617	{ } /* end */
3618};
3619
3620/* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
3621 * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
3622 */
3623static struct snd_kcontrol_new alc260_will_mixer[] = {
3624	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3625	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3626	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3627	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3628	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3629	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3630	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3631	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3632	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3633	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3634	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3635	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3636	{ } /* end */
3637};
3638
3639/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
3640 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
3641 */
3642static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
3643	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3644	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3645	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3646	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3647	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3648	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
3649	HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
3650	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3651	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3652	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3653	{ } /* end */
3654};
3655
3656/* capture mixer elements */
3657static struct snd_kcontrol_new alc260_capture_mixer[] = {
3658	HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
3659	HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
3660	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
3661	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
3662	{
3663		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3664		/* The multiple "Capture Source" controls confuse alsamixer
3665		 * So call somewhat different..
3666		 * FIXME: the controls appear in the "playback" view!
3667		 */
3668		/* .name = "Capture Source", */
3669		.name = "Input Source",
3670		.count = 2,
3671		.info = alc_mux_enum_info,
3672		.get = alc_mux_enum_get,
3673		.put = alc_mux_enum_put,
3674	},
3675	{ } /* end */
3676};
3677
3678static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
3679	HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
3680	HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
3681	{
3682		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3683		/* The multiple "Capture Source" controls confuse alsamixer
3684		 * So call somewhat different..
3685		 * FIXME: the controls appear in the "playback" view!
3686		 */
3687		/* .name = "Capture Source", */
3688		.name = "Input Source",
3689		.count = 1,
3690		.info = alc_mux_enum_info,
3691		.get = alc_mux_enum_get,
3692		.put = alc_mux_enum_put,
3693	},
3694	{ } /* end */
3695};
3696
3697/*
3698 * initialization verbs
3699 */
3700static struct hda_verb alc260_init_verbs[] = {
3701	/* Line In pin widget for input */
3702	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3703	/* CD pin widget for input */
3704	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3705	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3706	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3707	/* Mic2 (front panel) pin widget for input and vref at 80% */
3708	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3709	/* LINE-2 is used for line-out in rear */
3710	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3711	/* select line-out */
3712	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
3713	/* LINE-OUT pin */
3714	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3715	/* enable HP */
3716	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3717	/* enable Mono */
3718	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3719	/* mute capture amp left and right */
3720	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3721	/* set connection select to line in (default select for this ADC) */
3722	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3723	/* mute capture amp left and right */
3724	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3725	/* set connection select to line in (default select for this ADC) */
3726	{0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
3727	/* set vol=0 Line-Out mixer amp left and right */
3728	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3729	/* unmute pin widget amp left and right (no gain on this amp) */
3730	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3731	/* set vol=0 HP mixer amp left and right */
3732	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3733	/* unmute pin widget amp left and right (no gain on this amp) */
3734	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3735	/* set vol=0 Mono mixer amp left and right */
3736	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3737	/* unmute pin widget amp left and right (no gain on this amp) */
3738	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3739	/* unmute LINE-2 out pin */
3740	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3741	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3742	 * Line In 2 = 0x03
3743	 */
3744	/* mute analog inputs */
3745	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3746	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3747	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3748	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3749	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3750	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3751	/* mute Front out path */
3752	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3753	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3754	/* mute Headphone out path */
3755	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3756	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3757	/* mute Mono out path */
3758	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3759	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3760	{ }
3761};
3762
3763#if 0 /* should be identical with alc260_init_verbs? */
3764static struct hda_verb alc260_hp_init_verbs[] = {
3765	/* Headphone and output */
3766	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3767	/* mono output */
3768	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3769	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3770	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3771	/* Mic2 (front panel) pin widget for input and vref at 80% */
3772	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3773	/* Line In pin widget for input */
3774	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3775	/* Line-2 pin widget for output */
3776	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3777	/* CD pin widget for input */
3778	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3779	/* unmute amp left and right */
3780	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3781	/* set connection select to line in (default select for this ADC) */
3782	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3783	/* unmute Line-Out mixer amp left and right (volume = 0) */
3784	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3785	/* mute pin widget amp left and right (no gain on this amp) */
3786	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3787	/* unmute HP mixer amp left and right (volume = 0) */
3788	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3789	/* mute pin widget amp left and right (no gain on this amp) */
3790	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3791	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3792	 * Line In 2 = 0x03
3793	 */
3794	/* mute analog inputs */
3795	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3796	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3797	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3798	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3799	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3800	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3801	/* Unmute Front out path */
3802	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3803	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3804	/* Unmute Headphone out path */
3805	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3806	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3807	/* Unmute Mono out path */
3808	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3809	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3810	{ }
3811};
3812#endif
3813
3814static struct hda_verb alc260_hp_3013_init_verbs[] = {
3815	/* Line out and output */
3816	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3817	/* mono output */
3818	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3819	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3820	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3821	/* Mic2 (front panel) pin widget for input and vref at 80% */
3822	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3823	/* Line In pin widget for input */
3824	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3825	/* Headphone pin widget for output */
3826	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3827	/* CD pin widget for input */
3828	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3829	/* unmute amp left and right */
3830	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3831	/* set connection select to line in (default select for this ADC) */
3832	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3833	/* unmute Line-Out mixer amp left and right (volume = 0) */
3834	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3835	/* mute pin widget amp left and right (no gain on this amp) */
3836	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3837	/* unmute HP mixer amp left and right (volume = 0) */
3838	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3839	/* mute pin widget amp left and right (no gain on this amp) */
3840	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3841	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3842	 * Line In 2 = 0x03
3843	 */
3844	/* mute analog inputs */
3845	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3846	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3847	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3848	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3849	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3850	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3851	/* Unmute Front out path */
3852	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3853	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3854	/* Unmute Headphone out path */
3855	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3856	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3857	/* Unmute Mono out path */
3858	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3859	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3860	{ }
3861};
3862
3863/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
3864 * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
3865 * audio = 0x16, internal speaker = 0x10.
3866 */
3867static struct hda_verb alc260_fujitsu_init_verbs[] = {
3868	/* Disable all GPIOs */
3869	{0x01, AC_VERB_SET_GPIO_MASK, 0},
3870	/* Internal speaker is connected to headphone pin */
3871	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3872	/* Headphone/Line-out jack connects to Line1 pin; make it an output */
3873	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3874	/* Mic/Line-in jack is connected to mic1 pin, so make it an input */
3875	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3876	/* Ensure all other unused pins are disabled and muted. */
3877	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3878	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3879	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3880	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3881	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3882	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3883	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3884	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3885
3886	/* Disable digital (SPDIF) pins */
3887	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3888	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3889
3890	/* Ensure Line1 pin widget takes its input from the OUT1 sum bus
3891	 * when acting as an output.
3892	 */
3893	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3894
3895	/* Start with output sum widgets muted and their output gains at min */
3896	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3897	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3898	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3899	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3900	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3901	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3902	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3903	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3904	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3905
3906	/* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
3907	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3908	/* Unmute Line1 pin widget output buffer since it starts as an output.
3909	 * If the pin mode is changed by the user the pin mode control will
3910	 * take care of enabling the pin's input/output buffers as needed.
3911	 * Therefore there's no need to enable the input buffer at this
3912	 * stage.
3913	 */
3914	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3915	/* Unmute input buffer of pin widget used for Line-in (no equiv
3916	 * mixer ctrl)
3917	 */
3918	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3919
3920	/* Mute capture amp left and right */
3921	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3922	/* Set ADC connection select to match default mixer setting - line
3923	 * in (on mic1 pin)
3924	 */
3925	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3926
3927	/* Do the same for the second ADC: mute capture input amp and
3928	 * set ADC connection to line in (on mic1 pin)
3929	 */
3930	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3931	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3932
3933	/* Mute all inputs to mixer widget (even unconnected ones) */
3934	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3935	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3936	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3937	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3938	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3939	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3940	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3941	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
3942
3943	{ }
3944};
3945
3946/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
3947 * similar laptops (adapted from Fujitsu init verbs).
3948 */
3949static struct hda_verb alc260_acer_init_verbs[] = {
3950	/* On TravelMate laptops, GPIO 0 enables the internal speaker and
3951	 * the headphone jack.  Turn this on and rely on the standard mute
3952	 * methods whenever the user wants to turn these outputs off.
3953	 */
3954	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
3955	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
3956	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
3957	/* Internal speaker/Headphone jack is connected to Line-out pin */
3958	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3959	/* Internal microphone/Mic jack is connected to Mic1 pin */
3960	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3961	/* Line In jack is connected to Line1 pin */
3962	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3963	/* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
3964	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3965	/* Ensure all other unused pins are disabled and muted. */
3966	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3967	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3968	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3969	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3970	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3971	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3972	/* Disable digital (SPDIF) pins */
3973	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3974	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3975
3976	/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
3977	 * bus when acting as outputs.
3978	 */
3979	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
3980	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3981
3982	/* Start with output sum widgets muted and their output gains at min */
3983	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3984	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3985	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3986	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3987	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3988	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3989	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3990	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3991	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3992
3993	/* Unmute Line-out pin widget amp left and right
3994	 * (no equiv mixer ctrl)
3995	 */
3996	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3997	/* Unmute mono pin widget amp output (no equiv mixer ctrl) */
3998	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3999	/* Unmute Mic1 and Line1 pin widget input buffers since they start as
4000	 * inputs. If the pin mode is changed by the user the pin mode control
4001	 * will take care of enabling the pin's input/output buffers as needed.
4002	 * Therefore there's no need to enable the input buffer at this
4003	 * stage.
4004	 */
4005	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4006	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4007
4008	/* Mute capture amp left and right */
4009	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4010	/* Set ADC connection select to match default mixer setting - mic
4011	 * (on mic1 pin)
4012	 */
4013	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4014
4015	/* Do similar with the second ADC: mute capture input amp and
4016	 * set ADC connection to mic to match ALSA's default state.
4017	 */
4018	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4019	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4020
4021	/* Mute all inputs to mixer widget (even unconnected ones) */
4022	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4023	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4024	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4025	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4026	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4027	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4028	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4029	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4030
4031	{ }
4032};
4033
4034static struct hda_verb alc260_will_verbs[] = {
4035	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4036	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4037	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4038	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4039	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4040	{0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4041	{}
4042};
4043
4044static struct hda_verb alc260_replacer_672v_verbs[] = {
4045	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4046	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4047	{0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4048
4049	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4050	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4051	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4052
4053	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4054	{}
4055};
4056
4057/* toggle speaker-output according to the hp-jack state */
4058static void alc260_replacer_672v_automute(struct hda_codec *codec)
4059{
4060        unsigned int present;
4061
4062	/* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4063        present = snd_hda_codec_read(codec, 0x0f, 0,
4064                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4065	if (present) {
4066		snd_hda_codec_write_cache(codec, 0x01, 0,
4067					  AC_VERB_SET_GPIO_DATA, 1);
4068		snd_hda_codec_write_cache(codec, 0x0f, 0,
4069					  AC_VERB_SET_PIN_WIDGET_CONTROL,
4070					  PIN_HP);
4071	} else {
4072		snd_hda_codec_write_cache(codec, 0x01, 0,
4073					  AC_VERB_SET_GPIO_DATA, 0);
4074		snd_hda_codec_write_cache(codec, 0x0f, 0,
4075					  AC_VERB_SET_PIN_WIDGET_CONTROL,
4076					  PIN_OUT);
4077	}
4078}
4079
4080static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4081                                       unsigned int res)
4082{
4083        if ((res >> 26) == ALC880_HP_EVENT)
4084                alc260_replacer_672v_automute(codec);
4085}
4086
4087/* Test configuration for debugging, modelled after the ALC880 test
4088 * configuration.
4089 */
4090#ifdef CONFIG_SND_DEBUG
4091static hda_nid_t alc260_test_dac_nids[1] = {
4092	0x02,
4093};
4094static hda_nid_t alc260_test_adc_nids[2] = {
4095	0x04, 0x05,
4096};
4097/* For testing the ALC260, each input MUX needs its own definition since
4098 * the signal assignments are different.  This assumes that the first ADC
4099 * is NID 0x04.
4100 */
4101static struct hda_input_mux alc260_test_capture_sources[2] = {
4102	{
4103		.num_items = 7,
4104		.items = {
4105			{ "MIC1 pin", 0x0 },
4106			{ "MIC2 pin", 0x1 },
4107			{ "LINE1 pin", 0x2 },
4108			{ "LINE2 pin", 0x3 },
4109			{ "CD pin", 0x4 },
4110			{ "LINE-OUT pin", 0x5 },
4111			{ "HP-OUT pin", 0x6 },
4112		},
4113        },
4114	{
4115		.num_items = 8,
4116		.items = {
4117			{ "MIC1 pin", 0x0 },
4118			{ "MIC2 pin", 0x1 },
4119			{ "LINE1 pin", 0x2 },
4120			{ "LINE2 pin", 0x3 },
4121			{ "CD pin", 0x4 },
4122			{ "Mixer", 0x5 },
4123			{ "LINE-OUT pin", 0x6 },
4124			{ "HP-OUT pin", 0x7 },
4125		},
4126        },
4127};
4128static struct snd_kcontrol_new alc260_test_mixer[] = {
4129	/* Output driver widgets */
4130	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4131	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4132	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4133	HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4134	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4135	HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4136
4137	/* Modes for retasking pin widgets
4138	 * Note: the ALC260 doesn't seem to act on requests to enable mic
4139         * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
4140         * mention this restriction.  At this stage it's not clear whether
4141         * this behaviour is intentional or is a hardware bug in chip
4142         * revisions available at least up until early 2006.  Therefore for
4143         * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4144         * choices, but if it turns out that the lack of mic bias for these
4145         * NIDs is intentional we could change their modes from
4146         * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4147	 */
4148	ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4149	ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4150	ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4151	ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4152	ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4153	ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4154
4155	/* Loopback mixer controls */
4156	HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4157	HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4158	HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4159	HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4160	HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4161	HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4162	HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4163	HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4164	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4165	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4166	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4167	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4168	HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4169	HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4170	HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4171	HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4172
4173	/* Controls for GPIO pins, assuming they are configured as outputs */
4174	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4175	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4176	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4177	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4178
4179	/* Switches to allow the digital IO pins to be enabled.  The datasheet
4180	 * is ambigious as to which NID is which; testing on laptops which
4181	 * make this output available should provide clarification.
4182	 */
4183	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4184	ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4185
4186	{ } /* end */
4187};
4188static struct hda_verb alc260_test_init_verbs[] = {
4189	/* Enable all GPIOs as outputs with an initial value of 0 */
4190	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4191	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4192	{0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4193
4194	/* Enable retasking pins as output, initially without power amp */
4195	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4196	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4197	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4198	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4199	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4200	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4201
4202	/* Disable digital (SPDIF) pins initially, but users can enable
4203	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
4204	 * payload also sets the generation to 0, output to be in "consumer"
4205	 * PCM format, copyright asserted, no pre-emphasis and no validity
4206	 * control.
4207	 */
4208	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4209	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4210
4211	/* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
4212	 * OUT1 sum bus when acting as an output.
4213	 */
4214	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4215	{0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4216	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4217	{0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4218
4219	/* Start with output sum widgets muted and their output gains at min */
4220	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4221	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4222	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4223	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4224	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4225	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4226	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4227	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4228	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4229
4230	/* Unmute retasking pin widget output buffers since the default
4231	 * state appears to be output.  As the pin mode is changed by the
4232	 * user the pin mode control will take care of enabling the pin's
4233	 * input/output buffers as needed.
4234	 */
4235	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4236	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4237	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4238	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4239	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4240	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4241	/* Also unmute the mono-out pin widget */
4242	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4243
4244	/* Mute capture amp left and right */
4245	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4246	/* Set ADC connection select to match default mixer setting (mic1
4247	 * pin)
4248	 */
4249	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4250
4251	/* Do the same for the second ADC: mute capture input amp and
4252	 * set ADC connection to mic1 pin
4253	 */
4254	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4255	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4256
4257	/* Mute all inputs to mixer widget (even unconnected ones) */
4258	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4259	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4260	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4261	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4262	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4263	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4264	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4265	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4266
4267	{ }
4268};
4269#endif
4270
4271static struct hda_pcm_stream alc260_pcm_analog_playback = {
4272	.substreams = 1,
4273	.channels_min = 2,
4274	.channels_max = 2,
4275};
4276
4277static struct hda_pcm_stream alc260_pcm_analog_capture = {
4278	.substreams = 1,
4279	.channels_min = 2,
4280	.channels_max = 2,
4281};
4282
4283#define alc260_pcm_digital_playback	alc880_pcm_digital_playback
4284#define alc260_pcm_digital_capture	alc880_pcm_digital_capture
4285
4286/*
4287 * for BIOS auto-configuration
4288 */
4289
4290static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4291					const char *pfx)
4292{
4293	hda_nid_t nid_vol;
4294	unsigned long vol_val, sw_val;
4295	char name[32];
4296	int err;
4297
4298	if (nid >= 0x0f && nid < 0x11) {
4299		nid_vol = nid - 0x7;
4300		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4301		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4302	} else if (nid == 0x11) {
4303		nid_vol = nid - 0x7;
4304		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4305		sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4306	} else if (nid >= 0x12 && nid <= 0x15) {
4307		nid_vol = 0x08;
4308		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4309		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4310	} else
4311		return 0; /* N/A */
4312
4313	snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4314	err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4315	if (err < 0)
4316		return err;
4317	snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4318	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4319	if (err < 0)
4320		return err;
4321	return 1;
4322}
4323
4324/* add playback controls from the parsed DAC table */
4325static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4326					     const struct auto_pin_cfg *cfg)
4327{
4328	hda_nid_t nid;
4329	int err;
4330
4331	spec->multiout.num_dacs = 1;
4332	spec->multiout.dac_nids = spec->private_dac_nids;
4333	spec->multiout.dac_nids[0] = 0x02;
4334
4335	nid = cfg->line_out_pins[0];
4336	if (nid) {
4337		err = alc260_add_playback_controls(spec, nid, "Front");
4338		if (err < 0)
4339			return err;
4340	}
4341
4342	nid = cfg->speaker_pins[0];
4343	if (nid) {
4344		err = alc260_add_playback_controls(spec, nid, "Speaker");
4345		if (err < 0)
4346			return err;
4347	}
4348
4349	nid = cfg->hp_pins[0];
4350	if (nid) {
4351		err = alc260_add_playback_controls(spec, nid, "Headphone");
4352		if (err < 0)
4353			return err;
4354	}
4355	return 0;
4356}
4357
4358/* create playback/capture controls for input pins */
4359static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4360						const struct auto_pin_cfg *cfg)
4361{
4362	struct hda_input_mux *imux = &spec->private_imux;
4363	int i, err, idx;
4364
4365	for (i = 0; i < AUTO_PIN_LAST; i++) {
4366		if (cfg->input_pins[i] >= 0x12) {
4367			idx = cfg->input_pins[i] - 0x12;
4368			err = new_analog_input(spec, cfg->input_pins[i],
4369					       auto_pin_cfg_labels[i], idx,
4370					       0x07);
4371			if (err < 0)
4372				return err;
4373			imux->items[imux->num_items].label =
4374				auto_pin_cfg_labels[i];
4375			imux->items[imux->num_items].index = idx;
4376			imux->num_items++;
4377		}
4378		if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
4379			idx = cfg->input_pins[i] - 0x09;
4380			err = new_analog_input(spec, cfg->input_pins[i],
4381					       auto_pin_cfg_labels[i], idx,
4382					       0x07);
4383			if (err < 0)
4384				return err;
4385			imux->items[imux->num_items].label =
4386				auto_pin_cfg_labels[i];
4387			imux->items[imux->num_items].index = idx;
4388			imux->num_items++;
4389		}
4390	}
4391	return 0;
4392}
4393
4394static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4395					      hda_nid_t nid, int pin_type,
4396					      int sel_idx)
4397{
4398	/* set as output */
4399	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4400			    pin_type);
4401	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4402			    AMP_OUT_UNMUTE);
4403	/* need the manual connection? */
4404	if (nid >= 0x12) {
4405		int idx = nid - 0x12;
4406		snd_hda_codec_write(codec, idx + 0x0b, 0,
4407				    AC_VERB_SET_CONNECT_SEL, sel_idx);
4408	}
4409}
4410
4411static void alc260_auto_init_multi_out(struct hda_codec *codec)
4412{
4413	struct alc_spec *spec = codec->spec;
4414	hda_nid_t nid;
4415
4416	alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
4417	nid = spec->autocfg.line_out_pins[0];
4418	if (nid) {
4419		int pin_type = get_pin_type(spec->autocfg.line_out_type);
4420		alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4421	}
4422
4423	nid = spec->autocfg.speaker_pins[0];
4424	if (nid)
4425		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4426
4427	nid = spec->autocfg.hp_pins[0];
4428	if (nid)
4429		alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
4430}
4431
4432#define ALC260_PIN_CD_NID		0x16
4433static void alc260_auto_init_analog_input(struct hda_codec *codec)
4434{
4435	struct alc_spec *spec = codec->spec;
4436	int i;
4437
4438	for (i = 0; i < AUTO_PIN_LAST; i++) {
4439		hda_nid_t nid = spec->autocfg.input_pins[i];
4440		if (nid >= 0x12) {
4441			snd_hda_codec_write(codec, nid, 0,
4442					    AC_VERB_SET_PIN_WIDGET_CONTROL,
4443					    i <= AUTO_PIN_FRONT_MIC ?
4444					    PIN_VREF80 : PIN_IN);
4445			if (nid != ALC260_PIN_CD_NID)
4446				snd_hda_codec_write(codec, nid, 0,
4447						    AC_VERB_SET_AMP_GAIN_MUTE,
4448						    AMP_OUT_MUTE);
4449		}
4450	}
4451}
4452
4453/*
4454 * generic initialization of ADC, input mixers and output mixers
4455 */
4456static struct hda_verb alc260_volume_init_verbs[] = {
4457	/*
4458	 * Unmute ADC0-1 and set the default input to mic-in
4459	 */
4460	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4461	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4462	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4463	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4464
4465	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4466	 * mixer widget
4467	 * Note: PASD motherboards uses the Line In 2 as the input for
4468	 * front panel mic (mic 2)
4469	 */
4470	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4471	/* mute analog inputs */
4472	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4473	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4474	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4475	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4476	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4477
4478	/*
4479	 * Set up output mixers (0x08 - 0x0a)
4480	 */
4481	/* set vol=0 to output mixers */
4482	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4483	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4484	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4485	/* set up input amps for analog loopback */
4486	/* Amp Indices: DAC = 0, mixer = 1 */
4487	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4488	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4489	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4490	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4491	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4492	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4493
4494	{ }
4495};
4496
4497static int alc260_parse_auto_config(struct hda_codec *codec)
4498{
4499	struct alc_spec *spec = codec->spec;
4500	unsigned int wcap;
4501	int err;
4502	static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4503
4504	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4505					   alc260_ignore);
4506	if (err < 0)
4507		return err;
4508	err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
4509	if (err < 0)
4510		return err;
4511	if (!spec->kctl_alloc)
4512		return 0; /* can't find valid BIOS pin config */
4513	err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
4514	if (err < 0)
4515		return err;
4516
4517	spec->multiout.max_channels = 2;
4518
4519	if (spec->autocfg.dig_out_pin)
4520		spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4521	if (spec->kctl_alloc)
4522		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4523
4524	spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4525
4526	spec->num_mux_defs = 1;
4527	spec->input_mux = &spec->private_imux;
4528
4529	/* check whether NID 0x04 is valid */
4530	wcap = get_wcaps(codec, 0x04);
4531	wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4532	if (wcap != AC_WID_AUD_IN) {
4533		spec->adc_nids = alc260_adc_nids_alt;
4534		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4535		spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
4536	} else {
4537		spec->adc_nids = alc260_adc_nids;
4538		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4539		spec->mixers[spec->num_mixers] = alc260_capture_mixer;
4540	}
4541	spec->num_mixers++;
4542
4543	return 1;
4544}
4545
4546/* additional initialization for auto-configuration model */
4547static void alc260_auto_init(struct hda_codec *codec)
4548{
4549	alc260_auto_init_multi_out(codec);
4550	alc260_auto_init_analog_input(codec);
4551}
4552
4553#ifdef CONFIG_SND_HDA_POWER_SAVE
4554static struct hda_amp_list alc260_loopbacks[] = {
4555	{ 0x07, HDA_INPUT, 0 },
4556	{ 0x07, HDA_INPUT, 1 },
4557	{ 0x07, HDA_INPUT, 2 },
4558	{ 0x07, HDA_INPUT, 3 },
4559	{ 0x07, HDA_INPUT, 4 },
4560	{ } /* end */
4561};
4562#endif
4563
4564/*
4565 * ALC260 configurations
4566 */
4567static const char *alc260_models[ALC260_MODEL_LAST] = {
4568	[ALC260_BASIC]		= "basic",
4569	[ALC260_HP]		= "hp",
4570	[ALC260_HP_3013]	= "hp-3013",
4571	[ALC260_FUJITSU_S702X]	= "fujitsu",
4572	[ALC260_ACER]		= "acer",
4573	[ALC260_WILL]		= "will",
4574	[ALC260_REPLACER_672V]	= "replacer",
4575#ifdef CONFIG_SND_DEBUG
4576	[ALC260_TEST]		= "test",
4577#endif
4578	[ALC260_AUTO]		= "auto",
4579};
4580
4581static struct snd_pci_quirk alc260_cfg_tbl[] = {
4582	SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
4583	SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
4584	SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4585	SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
4586	SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
4587	SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
4588	SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
4589	SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
4590	SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
4591	SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
4592	SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
4593	SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
4594	SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
4595	SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
4596	SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
4597	SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
4598	SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
4599	SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
4600	{}
4601};
4602
4603static struct alc_config_preset alc260_presets[] = {
4604	[ALC260_BASIC] = {
4605		.mixers = { alc260_base_output_mixer,
4606			    alc260_input_mixer,
4607			    alc260_pc_beep_mixer,
4608			    alc260_capture_mixer },
4609		.init_verbs = { alc260_init_verbs },
4610		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4611		.dac_nids = alc260_dac_nids,
4612		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4613		.adc_nids = alc260_adc_nids,
4614		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4615		.channel_mode = alc260_modes,
4616		.input_mux = &alc260_capture_source,
4617	},
4618	[ALC260_HP] = {
4619		.mixers = { alc260_base_output_mixer,
4620			    alc260_input_mixer,
4621			    alc260_capture_alt_mixer },
4622		.init_verbs = { alc260_init_verbs },
4623		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4624		.dac_nids = alc260_dac_nids,
4625		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4626		.adc_nids = alc260_hp_adc_nids,
4627		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4628		.channel_mode = alc260_modes,
4629		.input_mux = &alc260_capture_source,
4630	},
4631	[ALC260_HP_3013] = {
4632		.mixers = { alc260_hp_3013_mixer,
4633			    alc260_input_mixer,
4634			    alc260_capture_alt_mixer },
4635		.init_verbs = { alc260_hp_3013_init_verbs },
4636		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4637		.dac_nids = alc260_dac_nids,
4638		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4639		.adc_nids = alc260_hp_adc_nids,
4640		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4641		.channel_mode = alc260_modes,
4642		.input_mux = &alc260_capture_source,
4643	},
4644	[ALC260_FUJITSU_S702X] = {
4645		.mixers = { alc260_fujitsu_mixer,
4646			    alc260_capture_mixer },
4647		.init_verbs = { alc260_fujitsu_init_verbs },
4648		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4649		.dac_nids = alc260_dac_nids,
4650		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4651		.adc_nids = alc260_dual_adc_nids,
4652		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4653		.channel_mode = alc260_modes,
4654		.num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
4655		.input_mux = alc260_fujitsu_capture_sources,
4656	},
4657	[ALC260_ACER] = {
4658		.mixers = { alc260_acer_mixer,
4659			    alc260_capture_mixer },
4660		.init_verbs = { alc260_acer_init_verbs },
4661		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4662		.dac_nids = alc260_dac_nids,
4663		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4664		.adc_nids = alc260_dual_adc_nids,
4665		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4666		.channel_mode = alc260_modes,
4667		.num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
4668		.input_mux = alc260_acer_capture_sources,
4669	},
4670	[ALC260_WILL] = {
4671		.mixers = { alc260_will_mixer,
4672			    alc260_capture_mixer },
4673		.init_verbs = { alc260_init_verbs, alc260_will_verbs },
4674		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4675		.dac_nids = alc260_dac_nids,
4676		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4677		.adc_nids = alc260_adc_nids,
4678		.dig_out_nid = ALC260_DIGOUT_NID,
4679		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4680		.channel_mode = alc260_modes,
4681		.input_mux = &alc260_capture_source,
4682	},
4683	[ALC260_REPLACER_672V] = {
4684		.mixers = { alc260_replacer_672v_mixer,
4685			    alc260_capture_mixer },
4686		.init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
4687		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4688		.dac_nids = alc260_dac_nids,
4689		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4690		.adc_nids = alc260_adc_nids,
4691		.dig_out_nid = ALC260_DIGOUT_NID,
4692		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4693		.channel_mode = alc260_modes,
4694		.input_mux = &alc260_capture_source,
4695		.unsol_event = alc260_replacer_672v_unsol_event,
4696		.init_hook = alc260_replacer_672v_automute,
4697	},
4698#ifdef CONFIG_SND_DEBUG
4699	[ALC260_TEST] = {
4700		.mixers = { alc260_test_mixer,
4701			    alc260_capture_mixer },
4702		.init_verbs = { alc260_test_init_verbs },
4703		.num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
4704		.dac_nids = alc260_test_dac_nids,
4705		.num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
4706		.adc_nids = alc260_test_adc_nids,
4707		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4708		.channel_mode = alc260_modes,
4709		.num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
4710		.input_mux = alc260_test_capture_sources,
4711	},
4712#endif
4713};
4714
4715static int patch_alc260(struct hda_codec *codec)
4716{
4717	struct alc_spec *spec;
4718	int err, board_config;
4719
4720	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4721	if (spec == NULL)
4722		return -ENOMEM;
4723
4724	codec->spec = spec;
4725
4726	board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
4727						  alc260_models,
4728						  alc260_cfg_tbl);
4729	if (board_config < 0) {
4730		snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
4731			   "trying auto-probe from BIOS...\n");
4732		board_config = ALC260_AUTO;
4733	}
4734
4735	if (board_config == ALC260_AUTO) {
4736		/* automatic parse from the BIOS config */
4737		err = alc260_parse_auto_config(codec);
4738		if (err < 0) {
4739			alc_free(codec);
4740			return err;
4741		} else if (!err) {
4742			printk(KERN_INFO
4743			       "hda_codec: Cannot set up configuration "
4744			       "from BIOS.  Using base mode...\n");
4745			board_config = ALC260_BASIC;
4746		}
4747	}
4748
4749	if (board_config != ALC260_AUTO)
4750		setup_preset(spec, &alc260_presets[board_config]);
4751
4752	spec->stream_name_analog = "ALC260 Analog";
4753	spec->stream_analog_playback = &alc260_pcm_analog_playback;
4754	spec->stream_analog_capture = &alc260_pcm_analog_capture;
4755
4756	spec->stream_name_digital = "ALC260 Digital";
4757	spec->stream_digital_playback = &alc260_pcm_digital_playback;
4758	spec->stream_digital_capture = &alc260_pcm_digital_capture;
4759
4760	codec->patch_ops = alc_patch_ops;
4761	if (board_config == ALC260_AUTO)
4762		spec->init_hook = alc260_auto_init;
4763#ifdef CONFIG_SND_HDA_POWER_SAVE
4764	if (!spec->loopback.amplist)
4765		spec->loopback.amplist = alc260_loopbacks;
4766#endif
4767
4768	return 0;
4769}
4770
4771
4772/*
4773 * ALC882 support
4774 *
4775 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
4776 * configuration.  Each pin widget can choose any input DACs and a mixer.
4777 * Each ADC is connected from a mixer of all inputs.  This makes possible
4778 * 6-channel independent captures.
4779 *
4780 * In addition, an independent DAC for the multi-playback (not used in this
4781 * driver yet).
4782 */
4783#define ALC882_DIGOUT_NID	0x06
4784#define ALC882_DIGIN_NID	0x0a
4785
4786static struct hda_channel_mode alc882_ch_modes[1] = {
4787	{ 8, NULL }
4788};
4789
4790static hda_nid_t alc882_dac_nids[4] = {
4791	/* front, rear, clfe, rear_surr */
4792	0x02, 0x03, 0x04, 0x05
4793};
4794
4795/* identical with ALC880 */
4796#define alc882_adc_nids		alc880_adc_nids
4797#define alc882_adc_nids_alt	alc880_adc_nids_alt
4798
4799/* input MUX */
4800/* FIXME: should be a matrix-type input source selection */
4801
4802static struct hda_input_mux alc882_capture_source = {
4803	.num_items = 4,
4804	.items = {
4805		{ "Mic", 0x0 },
4806		{ "Front Mic", 0x1 },
4807		{ "Line", 0x2 },
4808		{ "CD", 0x4 },
4809	},
4810};
4811#define alc882_mux_enum_info alc_mux_enum_info
4812#define alc882_mux_enum_get alc_mux_enum_get
4813
4814static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
4815			       struct snd_ctl_elem_value *ucontrol)
4816{
4817	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4818	struct alc_spec *spec = codec->spec;
4819	const struct hda_input_mux *imux = spec->input_mux;
4820	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
4821	static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
4822	hda_nid_t nid = capture_mixers[adc_idx];
4823	unsigned int *cur_val = &spec->cur_mux[adc_idx];
4824	unsigned int i, idx;
4825
4826	idx = ucontrol->value.enumerated.item[0];
4827	if (idx >= imux->num_items)
4828		idx = imux->num_items - 1;
4829	if (*cur_val == idx)
4830		return 0;
4831	for (i = 0; i < imux->num_items; i++) {
4832		unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
4833		snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
4834					 imux->items[i].index,
4835					 HDA_AMP_MUTE, v);
4836	}
4837	*cur_val = idx;
4838	return 1;
4839}
4840
4841/*
4842 * 2ch mode
4843 */
4844static struct hda_verb alc882_3ST_ch2_init[] = {
4845	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
4846	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4847	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
4848	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4849	{ } /* end */
4850};
4851
4852/*
4853 * 6ch mode
4854 */
4855static struct hda_verb alc882_3ST_ch6_init[] = {
4856	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4857	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4858	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
4859	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4860	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4861	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
4862	{ } /* end */
4863};
4864
4865static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
4866	{ 2, alc882_3ST_ch2_init },
4867	{ 6, alc882_3ST_ch6_init },
4868};
4869
4870/*
4871 * 6ch mode
4872 */
4873static struct hda_verb alc882_sixstack_ch6_init[] = {
4874	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
4875	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4876	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4877	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4878	{ } /* end */
4879};
4880
4881/*
4882 * 8ch mode
4883 */
4884static struct hda_verb alc882_sixstack_ch8_init[] = {
4885	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4886	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4887	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4888	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4889	{ } /* end */
4890};
4891
4892static struct hda_channel_mode alc882_sixstack_modes[2] = {
4893	{ 6, alc882_sixstack_ch6_init },
4894	{ 8, alc882_sixstack_ch8_init },
4895};
4896
4897/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
4898 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
4899 */
4900static struct snd_kcontrol_new alc882_base_mixer[] = {
4901	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4902	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4903	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4904	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4905	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
4906	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4907	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
4908	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
4909	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4910	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4911	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4912	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4913	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4914	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4915	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4916	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4917	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4918	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4919	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4920	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
4921	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4922	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4923	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4924	{ } /* end */
4925};
4926
4927static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
4928	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4929	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4930	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4931	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4932	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4933	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4934	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4935	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4936	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4937	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4938	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4939	{ } /* end */
4940};
4941
4942static struct snd_kcontrol_new alc882_targa_mixer[] = {
4943	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4944	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4945	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4946	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4947	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4948	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4949	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4950	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4951	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4952	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4953	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4954	{ } /* end */
4955};
4956
4957/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
4958 *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
4959 */
4960static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
4961	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4962	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
4963	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4964	HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
4965	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4966	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4967	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4968	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4969	HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
4970	HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
4971	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4972	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4973	{ } /* end */
4974};
4975
4976static struct snd_kcontrol_new alc882_chmode_mixer[] = {
4977	{
4978		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4979		.name = "Channel Mode",
4980		.info = alc_ch_mode_info,
4981		.get = alc_ch_mode_get,
4982		.put = alc_ch_mode_put,
4983	},
4984	{ } /* end */
4985};
4986
4987static struct hda_verb alc882_init_verbs[] = {
4988	/* Front mixer: unmute input/output amp left and right (volume = 0) */
4989	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4990	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4991	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4992	/* Rear mixer */
4993	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4994	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4995	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4996	/* CLFE mixer */
4997	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4998	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4999	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5000	/* Side mixer */
5001	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5002	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5003	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5004
5005	/* Front Pin: output 0 (0x0c) */
5006	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5007	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5008	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5009	/* Rear Pin: output 1 (0x0d) */
5010	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5011	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5012	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5013	/* CLFE Pin: output 2 (0x0e) */
5014	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5015	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5016	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5017	/* Side Pin: output 3 (0x0f) */
5018	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5019	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5020	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5021	/* Mic (rear) pin: input vref at 80% */
5022	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5023	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5024	/* Front Mic pin: input vref at 80% */
5025	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5026	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5027	/* Line In pin: input */
5028	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5029	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5030	/* Line-2 In: Headphone output (output 0 - 0x0c) */
5031	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5032	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5033	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5034	/* CD pin widget for input */
5035	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5036
5037	/* FIXME: use matrix-type input source selection */
5038	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5039	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5040	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5041	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5042	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5043	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5044	/* Input mixer2 */
5045	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5046	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5047	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5048	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5049	/* Input mixer3 */
5050	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5051	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5052	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5053	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5054	/* ADC1: mute amp left and right */
5055	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5056	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5057	/* ADC2: mute amp left and right */
5058	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5059	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5060	/* ADC3: mute amp left and right */
5061	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5062	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5063
5064	{ }
5065};
5066
5067static struct hda_verb alc882_eapd_verbs[] = {
5068	/* change to EAPD mode */
5069	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5070	{0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5071	{ }
5072};
5073
5074/* Mac Pro test */
5075static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5076	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5077	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5078	HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5079	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5080	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5081	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5082	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5083	{ } /* end */
5084};
5085
5086static struct hda_verb alc882_macpro_init_verbs[] = {
5087	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5088	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5089	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5090	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5091	/* Front Pin: output 0 (0x0c) */
5092	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5093	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5094	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5095	/* Front Mic pin: input vref at 80% */
5096	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5097	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5098	/* Speaker:  output */
5099	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5100	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5101	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5102	/* Headphone output (output 0 - 0x0c) */
5103	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5104	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5105	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5106
5107	/* FIXME: use matrix-type input source selection */
5108	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5109	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5110	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5111	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5112	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5113	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5114	/* Input mixer2 */
5115	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5116	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5117	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5118	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5119	/* Input mixer3 */
5120	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5121	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5122	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5123	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5124	/* ADC1: mute amp left and right */
5125	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5126	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5127	/* ADC2: mute amp left and right */
5128	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5129	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5130	/* ADC3: mute amp left and right */
5131	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5132	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5133
5134	{ }
5135};
5136
5137/* iMac 24 mixer. */
5138static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5139	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5140	HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5141	{ } /* end */
5142};
5143
5144/* iMac 24 init verbs. */
5145static struct hda_verb alc885_imac24_init_verbs[] = {
5146	/* Internal speakers: output 0 (0x0c) */
5147	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5148	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5149	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5150	/* Internal speakers: output 0 (0x0c) */
5151	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5152	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5153	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5154	/* Headphone: output 0 (0x0c) */
5155	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5156	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5157	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5158	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5159	/* Front Mic: input vref at 80% */
5160	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5161	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5162	{ }
5163};
5164
5165/* Toggle speaker-output according to the hp-jack state */
5166static void alc885_imac24_automute(struct hda_codec *codec)
5167{
5168 	unsigned int present;
5169
5170 	present = snd_hda_codec_read(codec, 0x14, 0,
5171				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5172	snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5173				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5174	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5175				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5176}
5177
5178/* Processes unsolicited events. */
5179static void alc885_imac24_unsol_event(struct hda_codec *codec,
5180				      unsigned int res)
5181{
5182	/* Headphone insertion or removal. */
5183	if ((res >> 26) == ALC880_HP_EVENT)
5184		alc885_imac24_automute(codec);
5185}
5186
5187static struct hda_verb alc882_targa_verbs[] = {
5188	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5189	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5190
5191	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5192	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5193
5194	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5195	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5196	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5197
5198	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5199	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5200	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5201	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5202	{ } /* end */
5203};
5204
5205/* toggle speaker-output according to the hp-jack state */
5206static void alc882_targa_automute(struct hda_codec *codec)
5207{
5208 	unsigned int present;
5209
5210 	present = snd_hda_codec_read(codec, 0x14, 0,
5211				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5212	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
5213				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5214	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
5215				  present ? 1 : 3);
5216}
5217
5218static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5219{
5220	/* Looks like the unsol event is incompatible with the standard
5221	 * definition.  4bit tag is placed at 26 bit!
5222	 */
5223	if (((res >> 26) == ALC880_HP_EVENT)) {
5224		alc882_targa_automute(codec);
5225	}
5226}
5227
5228static struct hda_verb alc882_asus_a7j_verbs[] = {
5229	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5230	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5231
5232	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5233	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5234	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5235
5236	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5237	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5238	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5239
5240	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5241	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5242	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5243	{ } /* end */
5244};
5245
5246static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5247{
5248	unsigned int gpiostate, gpiomask, gpiodir;
5249
5250	gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5251				       AC_VERB_GET_GPIO_DATA, 0);
5252
5253	if (!muted)
5254		gpiostate |= (1 << pin);
5255	else
5256		gpiostate &= ~(1 << pin);
5257
5258	gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5259				      AC_VERB_GET_GPIO_MASK, 0);
5260	gpiomask |= (1 << pin);
5261
5262	gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5263				     AC_VERB_GET_GPIO_DIRECTION, 0);
5264	gpiodir |= (1 << pin);
5265
5266
5267	snd_hda_codec_write(codec, codec->afg, 0,
5268			    AC_VERB_SET_GPIO_MASK, gpiomask);
5269	snd_hda_codec_write(codec, codec->afg, 0,
5270			    AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5271
5272	msleep(1);
5273
5274	snd_hda_codec_write(codec, codec->afg, 0,
5275			    AC_VERB_SET_GPIO_DATA, gpiostate);
5276}
5277
5278/*
5279 * generic initialization of ADC, input mixers and output mixers
5280 */
5281static struct hda_verb alc882_auto_init_verbs[] = {
5282	/*
5283	 * Unmute ADC0-2 and set the default input to mic-in
5284	 */
5285	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5286	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5287	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5288	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5289	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5290	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5291
5292	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5293	 * mixer widget
5294	 * Note: PASD motherboards uses the Line In 2 as the input for
5295	 * front panel mic (mic 2)
5296	 */
5297	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5298	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5299	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5300	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5301	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5302	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5303
5304	/*
5305	 * Set up output mixers (0x0c - 0x0f)
5306	 */
5307	/* set vol=0 to output mixers */
5308	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5309	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5310	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5311	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5312	/* set up input amps for analog loopback */
5313	/* Amp Indices: DAC = 0, mixer = 1 */
5314	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5315	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5316	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5317	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5318	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5319	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5320	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5321	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5322	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5323	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5324
5325	/* FIXME: use matrix-type input source selection */
5326	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5327	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5328	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5329	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5330	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5331	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5332	/* Input mixer2 */
5333	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5334	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5335	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5336	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5337	/* Input mixer3 */
5338	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5339	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5340	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5341	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5342
5343	{ }
5344};
5345
5346/* capture mixer elements */
5347static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
5348	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5349	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5350	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5351	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5352	{
5353		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5354		/* The multiple "Capture Source" controls confuse alsamixer
5355		 * So call somewhat different..
5356		 * FIXME: the controls appear in the "playback" view!
5357		 */
5358		/* .name = "Capture Source", */
5359		.name = "Input Source",
5360		.count = 2,
5361		.info = alc882_mux_enum_info,
5362		.get = alc882_mux_enum_get,
5363		.put = alc882_mux_enum_put,
5364	},
5365	{ } /* end */
5366};
5367
5368static struct snd_kcontrol_new alc882_capture_mixer[] = {
5369	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
5370	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
5371	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
5372	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
5373	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
5374	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
5375	{
5376		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5377		/* The multiple "Capture Source" controls confuse alsamixer
5378		 * So call somewhat different..
5379		 * FIXME: the controls appear in the "playback" view!
5380		 */
5381		/* .name = "Capture Source", */
5382		.name = "Input Source",
5383		.count = 3,
5384		.info = alc882_mux_enum_info,
5385		.get = alc882_mux_enum_get,
5386		.put = alc882_mux_enum_put,
5387	},
5388	{ } /* end */
5389};
5390
5391#ifdef CONFIG_SND_HDA_POWER_SAVE
5392#define alc882_loopbacks	alc880_loopbacks
5393#endif
5394
5395/* pcm configuration: identiacal with ALC880 */
5396#define alc882_pcm_analog_playback	alc880_pcm_analog_playback
5397#define alc882_pcm_analog_capture	alc880_pcm_analog_capture
5398#define alc882_pcm_digital_playback	alc880_pcm_digital_playback
5399#define alc882_pcm_digital_capture	alc880_pcm_digital_capture
5400
5401/*
5402 * configuration and preset
5403 */
5404static const char *alc882_models[ALC882_MODEL_LAST] = {
5405	[ALC882_3ST_DIG]	= "3stack-dig",
5406	[ALC882_6ST_DIG]	= "6stack-dig",
5407	[ALC882_ARIMA]		= "arima",
5408	[ALC882_W2JC]		= "w2jc",
5409	[ALC885_MACPRO]		= "macpro",
5410	[ALC885_IMAC24]		= "imac24",
5411	[ALC882_AUTO]		= "auto",
5412};
5413
5414static struct snd_pci_quirk alc882_cfg_tbl[] = {
5415	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
5416	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
5417	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
5418	SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
5419	SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
5420	SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
5421	SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
5422	SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
5423	SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
5424	{}
5425};
5426
5427static struct alc_config_preset alc882_presets[] = {
5428	[ALC882_3ST_DIG] = {
5429		.mixers = { alc882_base_mixer },
5430		.init_verbs = { alc882_init_verbs },
5431		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5432		.dac_nids = alc882_dac_nids,
5433		.dig_out_nid = ALC882_DIGOUT_NID,
5434		.dig_in_nid = ALC882_DIGIN_NID,
5435		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5436		.channel_mode = alc882_ch_modes,
5437		.need_dac_fix = 1,
5438		.input_mux = &alc882_capture_source,
5439	},
5440	[ALC882_6ST_DIG] = {
5441		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
5442		.init_verbs = { alc882_init_verbs },
5443		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5444		.dac_nids = alc882_dac_nids,
5445		.dig_out_nid = ALC882_DIGOUT_NID,
5446		.dig_in_nid = ALC882_DIGIN_NID,
5447		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5448		.channel_mode = alc882_sixstack_modes,
5449		.input_mux = &alc882_capture_source,
5450	},
5451	[ALC882_ARIMA] = {
5452		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
5453		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
5454		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5455		.dac_nids = alc882_dac_nids,
5456		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5457		.channel_mode = alc882_sixstack_modes,
5458		.input_mux = &alc882_capture_source,
5459	},
5460	[ALC882_W2JC] = {
5461		.mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
5462		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5463				alc880_gpio1_init_verbs },
5464		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5465		.dac_nids = alc882_dac_nids,
5466		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5467		.channel_mode = alc880_threestack_modes,
5468		.need_dac_fix = 1,
5469		.input_mux = &alc882_capture_source,
5470		.dig_out_nid = ALC882_DIGOUT_NID,
5471	},
5472	[ALC885_MACPRO] = {
5473		.mixers = { alc882_macpro_mixer },
5474		.init_verbs = { alc882_macpro_init_verbs },
5475		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5476		.dac_nids = alc882_dac_nids,
5477		.dig_out_nid = ALC882_DIGOUT_NID,
5478		.dig_in_nid = ALC882_DIGIN_NID,
5479		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5480		.channel_mode = alc882_ch_modes,
5481		.input_mux = &alc882_capture_source,
5482	},
5483	[ALC885_IMAC24] = {
5484		.mixers = { alc885_imac24_mixer },
5485		.init_verbs = { alc885_imac24_init_verbs },
5486		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5487		.dac_nids = alc882_dac_nids,
5488		.dig_out_nid = ALC882_DIGOUT_NID,
5489		.dig_in_nid = ALC882_DIGIN_NID,
5490		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5491		.channel_mode = alc882_ch_modes,
5492		.input_mux = &alc882_capture_source,
5493		.unsol_event = alc885_imac24_unsol_event,
5494		.init_hook = alc885_imac24_automute,
5495	},
5496	[ALC882_TARGA] = {
5497		.mixers = { alc882_targa_mixer, alc882_chmode_mixer,
5498			    alc882_capture_mixer },
5499		.init_verbs = { alc882_init_verbs, alc882_targa_verbs},
5500		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5501		.dac_nids = alc882_dac_nids,
5502		.dig_out_nid = ALC882_DIGOUT_NID,
5503		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5504		.adc_nids = alc882_adc_nids,
5505		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5506		.channel_mode = alc882_3ST_6ch_modes,
5507		.need_dac_fix = 1,
5508		.input_mux = &alc882_capture_source,
5509		.unsol_event = alc882_targa_unsol_event,
5510		.init_hook = alc882_targa_automute,
5511	},
5512	[ALC882_ASUS_A7J] = {
5513		.mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
5514			    alc882_capture_mixer },
5515		.init_verbs = { alc882_init_verbs, alc882_asus_a7j_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	},
5526};
5527
5528
5529/*
5530 * Pin config fixes
5531 */
5532enum {
5533	PINFIX_ABIT_AW9D_MAX
5534};
5535
5536static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
5537	{ 0x15, 0x01080104 }, /* side */
5538	{ 0x16, 0x01011012 }, /* rear */
5539	{ 0x17, 0x01016011 }, /* clfe */
5540	{ }
5541};
5542
5543static const struct alc_pincfg *alc882_pin_fixes[] = {
5544	[PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
5545};
5546
5547static struct snd_pci_quirk alc882_pinfix_tbl[] = {
5548	SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
5549	{}
5550};
5551
5552/*
5553 * BIOS auto configuration
5554 */
5555static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
5556					      hda_nid_t nid, int pin_type,
5557					      int dac_idx)
5558{
5559	/* set as output */
5560	struct alc_spec *spec = codec->spec;
5561	int idx;
5562
5563	if (spec->multiout.dac_nids[dac_idx] == 0x25)
5564		idx = 4;
5565	else
5566		idx = spec->multiout.dac_nids[dac_idx] - 2;
5567
5568	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5569			    pin_type);
5570	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5571			    AMP_OUT_UNMUTE);
5572	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
5573
5574}
5575
5576static void alc882_auto_init_multi_out(struct hda_codec *codec)
5577{
5578	struct alc_spec *spec = codec->spec;
5579	int i;
5580
5581	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
5582	for (i = 0; i <= HDA_SIDE; i++) {
5583		hda_nid_t nid = spec->autocfg.line_out_pins[i];
5584		int pin_type = get_pin_type(spec->autocfg.line_out_type);
5585		if (nid)
5586			alc882_auto_set_output_and_unmute(codec, nid, pin_type,
5587							  i);
5588	}
5589}
5590
5591static void alc882_auto_init_hp_out(struct hda_codec *codec)
5592{
5593	struct alc_spec *spec = codec->spec;
5594	hda_nid_t pin;
5595
5596	pin = spec->autocfg.hp_pins[0];
5597	if (pin) /* connect to front */
5598		/* use dac 0 */
5599		alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5600}
5601
5602#define alc882_is_input_pin(nid)	alc880_is_input_pin(nid)
5603#define ALC882_PIN_CD_NID		ALC880_PIN_CD_NID
5604
5605static void alc882_auto_init_analog_input(struct hda_codec *codec)
5606{
5607	struct alc_spec *spec = codec->spec;
5608	int i;
5609
5610	for (i = 0; i < AUTO_PIN_LAST; i++) {
5611		hda_nid_t nid = spec->autocfg.input_pins[i];
5612		if (alc882_is_input_pin(nid)) {
5613			snd_hda_codec_write(codec, nid, 0,
5614					    AC_VERB_SET_PIN_WIDGET_CONTROL,
5615					    i <= AUTO_PIN_FRONT_MIC ?
5616					    PIN_VREF80 : PIN_IN);
5617			if (nid != ALC882_PIN_CD_NID)
5618				snd_hda_codec_write(codec, nid, 0,
5619						    AC_VERB_SET_AMP_GAIN_MUTE,
5620						    AMP_OUT_MUTE);
5621		}
5622	}
5623}
5624
5625/* almost identical with ALC880 parser... */
5626static int alc882_parse_auto_config(struct hda_codec *codec)
5627{
5628	struct alc_spec *spec = codec->spec;
5629	int err = alc880_parse_auto_config(codec);
5630
5631	if (err < 0)
5632		return err;
5633	else if (err > 0)
5634		/* hack - override the init verbs */
5635		spec->init_verbs[0] = alc882_auto_init_verbs;
5636	return err;
5637}
5638
5639/* additional initialization for auto-configuration model */
5640static void alc882_auto_init(struct hda_codec *codec)
5641{
5642	alc882_auto_init_multi_out(codec);
5643	alc882_auto_init_hp_out(codec);
5644	alc882_auto_init_analog_input(codec);
5645}
5646
5647static int patch_alc882(struct hda_codec *codec)
5648{
5649	struct alc_spec *spec;
5650	int err, board_config;
5651
5652	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5653	if (spec == NULL)
5654		return -ENOMEM;
5655
5656	codec->spec = spec;
5657
5658	board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
5659						  alc882_models,
5660						  alc882_cfg_tbl);
5661
5662	if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
5663		/* Pick up systems that don't supply PCI SSID */
5664		switch (codec->subsystem_id) {
5665		case 0x106b0c00: /* Mac Pro */
5666			board_config = ALC885_MACPRO;
5667			break;
5668		case 0x106b1000: /* iMac 24 */
5669			board_config = ALC885_IMAC24;
5670			break;
5671		default:
5672			printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
5673		       			 "trying auto-probe from BIOS...\n");
5674			board_config = ALC882_AUTO;
5675		}
5676	}
5677
5678	alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
5679
5680	if (board_config == ALC882_AUTO) {
5681		/* automatic parse from the BIOS config */
5682		err = alc882_parse_auto_config(codec);
5683		if (err < 0) {
5684			alc_free(codec);
5685			return err;
5686		} else if (!err) {
5687			printk(KERN_INFO
5688			       "hda_codec: Cannot set up configuration "
5689			       "from BIOS.  Using base mode...\n");
5690			board_config = ALC882_3ST_DIG;
5691		}
5692	}
5693
5694	if (board_config != ALC882_AUTO)
5695		setup_preset(spec, &alc882_presets[board_config]);
5696
5697	if (board_config == ALC885_MACPRO || board_config == ALC885_IMAC24) {
5698		alc882_gpio_mute(codec, 0, 0);
5699		alc882_gpio_mute(codec, 1, 0);
5700	}
5701
5702	spec->stream_name_analog = "ALC882 Analog";
5703	spec->stream_analog_playback = &alc882_pcm_analog_playback;
5704	spec->stream_analog_capture = &alc882_pcm_analog_capture;
5705
5706	spec->stream_name_digital = "ALC882 Digital";
5707	spec->stream_digital_playback = &alc882_pcm_digital_playback;
5708	spec->stream_digital_capture = &alc882_pcm_digital_capture;
5709
5710	if (!spec->adc_nids && spec->input_mux) {
5711		/* check whether NID 0x07 is valid */
5712		unsigned int wcap = get_wcaps(codec, 0x07);
5713		/* get type */
5714		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
5715		if (wcap != AC_WID_AUD_IN) {
5716			spec->adc_nids = alc882_adc_nids_alt;
5717			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
5718			spec->mixers[spec->num_mixers] =
5719				alc882_capture_alt_mixer;
5720			spec->num_mixers++;
5721		} else {
5722			spec->adc_nids = alc882_adc_nids;
5723			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
5724			spec->mixers[spec->num_mixers] = alc882_capture_mixer;
5725			spec->num_mixers++;
5726		}
5727	}
5728
5729	codec->patch_ops = alc_patch_ops;
5730	if (board_config == ALC882_AUTO)
5731		spec->init_hook = alc882_auto_init;
5732#ifdef CONFIG_SND_HDA_POWER_SAVE
5733	if (!spec->loopback.amplist)
5734		spec->loopback.amplist = alc882_loopbacks;
5735#endif
5736
5737	return 0;
5738}
5739
5740/*
5741 * ALC883 support
5742 *
5743 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
5744 * configuration.  Each pin widget can choose any input DACs and a mixer.
5745 * Each ADC is connected from a mixer of all inputs.  This makes possible
5746 * 6-channel independent captures.
5747 *
5748 * In addition, an independent DAC for the multi-playback (not used in this
5749 * driver yet).
5750 */
5751#define ALC883_DIGOUT_NID	0x06
5752#define ALC883_DIGIN_NID	0x0a
5753
5754static hda_nid_t alc883_dac_nids[4] = {
5755	/* front, rear, clfe, rear_surr */
5756	0x02, 0x04, 0x03, 0x05
5757};
5758
5759static hda_nid_t alc883_adc_nids[2] = {
5760	/* ADC1-2 */
5761	0x08, 0x09,
5762};
5763
5764/* input MUX */
5765/* FIXME: should be a matrix-type input source selection */
5766
5767static struct hda_input_mux alc883_capture_source = {
5768	.num_items = 4,
5769	.items = {
5770		{ "Mic", 0x0 },
5771		{ "Front Mic", 0x1 },
5772		{ "Line", 0x2 },
5773		{ "CD", 0x4 },
5774	},
5775};
5776
5777static struct hda_input_mux alc883_lenovo_101e_capture_source = {
5778	.num_items = 2,
5779	.items = {
5780		{ "Mic", 0x1 },
5781		{ "Line", 0x2 },
5782	},
5783};
5784
5785static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
5786	.num_items = 4,
5787	.items = {
5788		{ "Mic", 0x0 },
5789		{ "iMic", 0x1 },
5790		{ "Line", 0x2 },
5791		{ "CD", 0x4 },
5792	},
5793};
5794
5795#define alc883_mux_enum_info alc_mux_enum_info
5796#define alc883_mux_enum_get alc_mux_enum_get
5797
5798static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
5799			       struct snd_ctl_elem_value *ucontrol)
5800{
5801	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5802	struct alc_spec *spec = codec->spec;
5803	const struct hda_input_mux *imux = spec->input_mux;
5804	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5805	static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
5806	hda_nid_t nid = capture_mixers[adc_idx];
5807	unsigned int *cur_val = &spec->cur_mux[adc_idx];
5808	unsigned int i, idx;
5809
5810	idx = ucontrol->value.enumerated.item[0];
5811	if (idx >= imux->num_items)
5812		idx = imux->num_items - 1;
5813	if (*cur_val == idx)
5814		return 0;
5815	for (i = 0; i < imux->num_items; i++) {
5816		unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5817		snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
5818					 imux->items[i].index,
5819					 HDA_AMP_MUTE, v);
5820	}
5821	*cur_val = idx;
5822	return 1;
5823}
5824
5825/*
5826 * 2ch mode
5827 */
5828static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
5829	{ 2, NULL }
5830};
5831
5832/*
5833 * 2ch mode
5834 */
5835static struct hda_verb alc883_3ST_ch2_init[] = {
5836	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5837	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5838	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5839	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5840	{ } /* end */
5841};
5842
5843/*
5844 * 6ch mode
5845 */
5846static struct hda_verb alc883_3ST_ch6_init[] = {
5847	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5848	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5849	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5850	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5851	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5852	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5853	{ } /* end */
5854};
5855
5856static struct hda_channel_mode alc883_3ST_6ch_modes[2] = {
5857	{ 2, alc883_3ST_ch2_init },
5858	{ 6, alc883_3ST_ch6_init },
5859};
5860
5861/*
5862 * 6ch mode
5863 */
5864static struct hda_verb alc883_sixstack_ch6_init[] = {
5865	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5866	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5867	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5868	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5869	{ } /* end */
5870};
5871
5872/*
5873 * 8ch mode
5874 */
5875static struct hda_verb alc883_sixstack_ch8_init[] = {
5876	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
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
5883static struct hda_channel_mode alc883_sixstack_modes[2] = {
5884	{ 6, alc883_sixstack_ch6_init },
5885	{ 8, alc883_sixstack_ch8_init },
5886};
5887
5888static struct hda_verb alc883_medion_eapd_verbs[] = {
5889        /* eanable EAPD on medion laptop */
5890	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5891	{0x20, AC_VERB_SET_PROC_COEF, 0x3070},
5892	{ }
5893};
5894
5895/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5896 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5897 */
5898
5899static struct snd_kcontrol_new alc883_base_mixer[] = {
5900	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5901	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5902	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5903	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5904	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5905	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5906	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5907	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5908	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5909	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5910	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5911	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5912	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5913	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5914	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5915	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5916	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5917	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5918	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5919	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5920	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5921	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5922	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5923	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5924	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5925	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5926	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5927	{
5928		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5929		/* .name = "Capture Source", */
5930		.name = "Input Source",
5931		.count = 2,
5932		.info = alc883_mux_enum_info,
5933		.get = alc883_mux_enum_get,
5934		.put = alc883_mux_enum_put,
5935	},
5936	{ } /* end */
5937};
5938
5939static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
5940	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5941	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5942	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5943	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5944	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5945	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5946	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5947	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5948	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5949	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5950	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5951	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5952	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5953	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5954	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5955	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5956	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5957	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5958	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5959	{
5960		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5961		/* .name = "Capture Source", */
5962		.name = "Input Source",
5963		.count = 2,
5964		.info = alc883_mux_enum_info,
5965		.get = alc883_mux_enum_get,
5966		.put = alc883_mux_enum_put,
5967	},
5968	{ } /* end */
5969};
5970
5971static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
5972	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5973	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5974	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5975	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5976	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5977	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5978	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5979	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5980	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5981	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5982	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5983	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5984	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5985	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5986	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5987	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5988	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5989	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5990	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5991	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5992	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5993	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5994	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5995	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5996	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5997	{
5998		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5999		/* .name = "Capture Source", */
6000		.name = "Input Source",
6001		.count = 2,
6002		.info = alc883_mux_enum_info,
6003		.get = alc883_mux_enum_get,
6004		.put = alc883_mux_enum_put,
6005	},
6006	{ } /* end */
6007};
6008
6009static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
6010	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6011	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6012	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6013	HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6014	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6015	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6016	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
6017	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6018	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6019	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6020	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6021	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6022	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6023	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6024	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6025	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6026	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6027	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6028	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6029	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6030	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6031	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6032	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6033
6034	{
6035		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6036		/* .name = "Capture Source", */
6037		.name = "Input Source",
6038		.count = 1,
6039		.info = alc883_mux_enum_info,
6040		.get = alc883_mux_enum_get,
6041		.put = alc883_mux_enum_put,
6042	},
6043	{ } /* end */
6044};
6045
6046static struct snd_kcontrol_new alc883_tagra_mixer[] = {
6047	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6048	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6049	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6050	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6051	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6052	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6053	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6054	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6055	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6056	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6057	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6058	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6059	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6060	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6061	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6062	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6063	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6064	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6065	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6066	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6067	{
6068		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6069		/* .name = "Capture Source", */
6070		.name = "Input Source",
6071		.count = 2,
6072		.info = alc883_mux_enum_info,
6073		.get = alc883_mux_enum_get,
6074		.put = alc883_mux_enum_put,
6075	},
6076	{ } /* end */
6077};
6078
6079static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
6080	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6081	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6082	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6083	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6084	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6085	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6086	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6087	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6088	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6089	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6090	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6091	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6092	{
6093		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6094		/* .name = "Capture Source", */
6095		.name = "Input Source",
6096		.count = 2,
6097		.info = alc883_mux_enum_info,
6098		.get = alc883_mux_enum_get,
6099		.put = alc883_mux_enum_put,
6100	},
6101	{ } /* end */
6102};
6103
6104static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
6105	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6106	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6107	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6108	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
6109	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6110	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6111	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6112	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6113	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6114	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6115	{
6116		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6117		/* .name = "Capture Source", */
6118		.name = "Input Source",
6119		.count = 1,
6120		.info = alc883_mux_enum_info,
6121		.get = alc883_mux_enum_get,
6122		.put = alc883_mux_enum_put,
6123	},
6124	{ } /* end */
6125};
6126
6127static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
6128	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6129	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
6130	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6131	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6132	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6133	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6134	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6135	HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6136	HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6137	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6138	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6139	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6140	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6141	{
6142		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6143		/* .name = "Capture Source", */
6144		.name = "Input Source",
6145		.count = 2,
6146		.info = alc883_mux_enum_info,
6147		.get = alc883_mux_enum_get,
6148		.put = alc883_mux_enum_put,
6149	},
6150	{ } /* end */
6151};
6152
6153static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
6154	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6155	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6156	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6157	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6158	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6159	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6160	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6161	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6162	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6163	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6164	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6165	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6166	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6167	{
6168		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6169		/* .name = "Capture Source", */
6170		.name = "Input Source",
6171		.count = 2,
6172		.info = alc883_mux_enum_info,
6173		.get = alc883_mux_enum_get,
6174		.put = alc883_mux_enum_put,
6175	},
6176	{ } /* end */
6177};
6178
6179static struct snd_kcontrol_new alc888_6st_hp_mixer[] = {
6180	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6181	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6182	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6183	HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6184	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6185	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6186	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6187	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6188	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6189	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6190	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6191	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6192	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6193	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6194	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6195	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6196	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6197	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6198	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6199	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6200	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6201	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6202	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6203	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6204	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6205	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6206	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6207	{
6208		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6209		/* .name = "Capture Source", */
6210		.name = "Input Source",
6211		.count = 2,
6212		.info = alc883_mux_enum_info,
6213		.get = alc883_mux_enum_get,
6214		.put = alc883_mux_enum_put,
6215	},
6216	{ } /* end */
6217};
6218
6219static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
6220	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6221	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6222	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6223	HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6224	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6225	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6226	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6227	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6228	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6229	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6230	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6231	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6232	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6233	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6234	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6235	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6236	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6237	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6238	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6239	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6240	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6241	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6242	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6243	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6244	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6245	{
6246		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6247		/* .name = "Capture Source", */
6248		.name = "Input Source",
6249		.count = 2,
6250		.info = alc883_mux_enum_info,
6251		.get = alc883_mux_enum_get,
6252		.put = alc883_mux_enum_put,
6253	},
6254	{ } /* end */
6255};
6256
6257static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
6258	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6259	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6260	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6261	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6262	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6263	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6264	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6265	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6266	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6267	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6268	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6269	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6270	{
6271		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6272		/* .name = "Capture Source", */
6273		.name = "Input Source",
6274		.count = 2,
6275		.info = alc883_mux_enum_info,
6276		.get = alc883_mux_enum_get,
6277		.put = alc883_mux_enum_put,
6278	},
6279	{ } /* end */
6280};
6281
6282static struct snd_kcontrol_new alc883_chmode_mixer[] = {
6283	{
6284		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6285		.name = "Channel Mode",
6286		.info = alc_ch_mode_info,
6287		.get = alc_ch_mode_get,
6288		.put = alc_ch_mode_put,
6289	},
6290	{ } /* end */
6291};
6292
6293static struct hda_verb alc883_init_verbs[] = {
6294	/* ADC1: mute amp left and right */
6295	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6296	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6297	/* ADC2: mute amp left and right */
6298	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6299	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6300	/* Front mixer: unmute input/output amp left and right (volume = 0) */
6301	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6302	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6303	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6304	/* Rear mixer */
6305	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6306	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6307	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6308	/* CLFE mixer */
6309	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6310	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6311	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6312	/* Side mixer */
6313	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6314	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6315	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6316
6317	/* mute analog input loopbacks */
6318	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6319	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6320	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6321	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6322	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6323
6324	/* Front Pin: output 0 (0x0c) */
6325	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6326	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6327	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6328	/* Rear Pin: output 1 (0x0d) */
6329	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6330	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6331	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6332	/* CLFE Pin: output 2 (0x0e) */
6333	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6334	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6335	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6336	/* Side Pin: output 3 (0x0f) */
6337	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6338	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6339	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6340	/* Mic (rear) pin: input vref at 80% */
6341	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6342	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6343	/* Front Mic pin: input vref at 80% */
6344	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6345	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6346	/* Line In pin: input */
6347	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6348	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6349	/* Line-2 In: Headphone output (output 0 - 0x0c) */
6350	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6351	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6352	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6353	/* CD pin widget for input */
6354	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6355
6356	/* FIXME: use matrix-type input source selection */
6357	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6358	/* Input mixer2 */
6359	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6360	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6361	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6362	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6363	/* Input mixer3 */
6364	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6365	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6366	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6367	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6368	{ }
6369};
6370
6371static struct hda_verb alc883_tagra_verbs[] = {
6372	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6373	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6374
6375	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6376	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6377
6378	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6379	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6380	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6381
6382	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6383	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6384	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6385	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6386
6387	{ } /* end */
6388};
6389
6390static struct hda_verb alc883_lenovo_101e_verbs[] = {
6391	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6392	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
6393        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
6394	{ } /* end */
6395};
6396
6397static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
6398        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6399	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6400        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6401        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6402	{ } /* end */
6403};
6404
6405static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
6406	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6407	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6408	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6409	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
6410	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
6411	{ } /* end */
6412};
6413
6414static struct hda_verb alc888_6st_hp_verbs[] = {
6415	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Front: output 0 (0x0c) */
6416	{0x15, AC_VERB_SET_CONNECT_SEL, 0x02},	/* Rear : output 2 (0x0e) */
6417	{0x16, AC_VERB_SET_CONNECT_SEL, 0x01},	/* CLFE : output 1 (0x0d) */
6418	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},	/* Side : output 3 (0x0f) */
6419	{ }
6420};
6421
6422static struct hda_verb alc888_3st_hp_verbs[] = {
6423	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Front: output 0 (0x0c) */
6424	{0x18, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Rear : output 1 (0x0d) */
6425	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},	/* CLFE : output 2 (0x0e) */
6426	{ }
6427};
6428
6429static struct hda_verb alc888_3st_hp_2ch_init[] = {
6430	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6431	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6432	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6433	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6434	{ }
6435};
6436
6437static struct hda_verb alc888_3st_hp_6ch_init[] = {
6438	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6439	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6440	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6441	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6442	{ }
6443};
6444
6445static struct hda_channel_mode alc888_3st_hp_modes[2] = {
6446	{ 2, alc888_3st_hp_2ch_init },
6447	{ 6, alc888_3st_hp_6ch_init },
6448};
6449
6450/* toggle front-jack and RCA according to the hp-jack state */
6451static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
6452{
6453 	unsigned int present;
6454
6455 	present = snd_hda_codec_read(codec, 0x1b, 0,
6456				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6457	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6458				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6459	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6460				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6461}
6462
6463/* toggle RCA according to the front-jack state */
6464static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
6465{
6466 	unsigned int present;
6467
6468 	present = snd_hda_codec_read(codec, 0x14, 0,
6469				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6470	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6471				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6472}
6473
6474static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
6475					     unsigned int res)
6476{
6477	if ((res >> 26) == ALC880_HP_EVENT)
6478		alc888_lenovo_ms7195_front_automute(codec);
6479	if ((res >> 26) == ALC880_FRONT_EVENT)
6480		alc888_lenovo_ms7195_rca_automute(codec);
6481}
6482
6483static struct hda_verb alc883_medion_md2_verbs[] = {
6484	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6485	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6486
6487	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6488
6489	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6490	{ } /* end */
6491};
6492
6493/* toggle speaker-output according to the hp-jack state */
6494static void alc883_medion_md2_automute(struct hda_codec *codec)
6495{
6496 	unsigned int present;
6497
6498 	present = snd_hda_codec_read(codec, 0x14, 0,
6499				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6500	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6501				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6502}
6503
6504static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
6505					  unsigned int res)
6506{
6507	if ((res >> 26) == ALC880_HP_EVENT)
6508		alc883_medion_md2_automute(codec);
6509}
6510
6511/* toggle speaker-output according to the hp-jack state */
6512static void alc883_tagra_automute(struct hda_codec *codec)
6513{
6514 	unsigned int present;
6515	unsigned char bits;
6516
6517 	present = snd_hda_codec_read(codec, 0x14, 0,
6518				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6519	bits = present ? HDA_AMP_MUTE : 0;
6520	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6521				 HDA_AMP_MUTE, bits);
6522	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6523				  present ? 1 : 3);
6524}
6525
6526static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
6527{
6528	if ((res >> 26) == ALC880_HP_EVENT)
6529		alc883_tagra_automute(codec);
6530}
6531
6532static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
6533{
6534 	unsigned int present;
6535	unsigned char bits;
6536
6537 	present = snd_hda_codec_read(codec, 0x14, 0,
6538				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6539	bits = present ? HDA_AMP_MUTE : 0;
6540	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6541				 HDA_AMP_MUTE, bits);
6542}
6543
6544static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
6545{
6546 	unsigned int present;
6547	unsigned char bits;
6548
6549 	present = snd_hda_codec_read(codec, 0x1b, 0,
6550				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6551	bits = present ? HDA_AMP_MUTE : 0;
6552	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6553				 HDA_AMP_MUTE, bits);
6554	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6555				 HDA_AMP_MUTE, bits);
6556}
6557
6558static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
6559					   unsigned int res)
6560{
6561	if ((res >> 26) == ALC880_HP_EVENT)
6562		alc883_lenovo_101e_all_automute(codec);
6563	if ((res >> 26) == ALC880_FRONT_EVENT)
6564		alc883_lenovo_101e_ispeaker_automute(codec);
6565}
6566
6567static struct hda_verb alc883_acer_eapd_verbs[] = {
6568	/* HP Pin: output 0 (0x0c) */
6569	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6570	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6571	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6572	/* Front Pin: output 0 (0x0c) */
6573	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6574	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6575	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
6576        /* eanable EAPD on medion laptop */
6577	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6578	{0x20, AC_VERB_SET_PROC_COEF, 0x3050},
6579	{ }
6580};
6581
6582/*
6583 * generic initialization of ADC, input mixers and output mixers
6584 */
6585static struct hda_verb alc883_auto_init_verbs[] = {
6586	/*
6587	 * Unmute ADC0-2 and set the default input to mic-in
6588	 */
6589	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6590	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6591	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6592	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6593
6594	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6595	 * mixer widget
6596	 * Note: PASD motherboards uses the Line In 2 as the input for
6597	 * front panel mic (mic 2)
6598	 */
6599	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6600	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6601	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6602	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6603	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6604	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6605
6606	/*
6607	 * Set up output mixers (0x0c - 0x0f)
6608	 */
6609	/* set vol=0 to output mixers */
6610	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6611	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6612	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6613	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6614	/* set up input amps for analog loopback */
6615	/* Amp Indices: DAC = 0, mixer = 1 */
6616	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6617	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6618	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6619	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6620	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6621	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6622	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6623	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6624	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6625	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6626
6627	/* FIXME: use matrix-type input source selection */
6628	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6629	/* Input mixer1 */
6630	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6631	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6632	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6633	/* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
6634	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6635	/* Input mixer2 */
6636	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6637	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6638	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6639	/* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
6640	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6641
6642	{ }
6643};
6644
6645/* capture mixer elements */
6646static struct snd_kcontrol_new alc883_capture_mixer[] = {
6647	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6648	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6649	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6650	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6651	{
6652		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6653		/* The multiple "Capture Source" controls confuse alsamixer
6654		 * So call somewhat different..
6655		 * FIXME: the controls appear in the "playback" view!
6656		 */
6657		/* .name = "Capture Source", */
6658		.name = "Input Source",
6659		.count = 2,
6660		.info = alc882_mux_enum_info,
6661		.get = alc882_mux_enum_get,
6662		.put = alc882_mux_enum_put,
6663	},
6664	{ } /* end */
6665};
6666
6667#ifdef CONFIG_SND_HDA_POWER_SAVE
6668#define alc883_loopbacks	alc880_loopbacks
6669#endif
6670
6671/* pcm configuration: identiacal with ALC880 */
6672#define alc883_pcm_analog_playback	alc880_pcm_analog_playback
6673#define alc883_pcm_analog_capture	alc880_pcm_analog_capture
6674#define alc883_pcm_digital_playback	alc880_pcm_digital_playback
6675#define alc883_pcm_digital_capture	alc880_pcm_digital_capture
6676
6677/*
6678 * configuration and preset
6679 */
6680static const char *alc883_models[ALC883_MODEL_LAST] = {
6681	[ALC883_3ST_2ch_DIG]	= "3stack-dig",
6682	[ALC883_3ST_6ch_DIG]	= "3stack-6ch-dig",
6683	[ALC883_3ST_6ch]	= "3stack-6ch",
6684	[ALC883_6ST_DIG]	= "6stack-dig",
6685	[ALC883_TARGA_DIG]	= "targa-dig",
6686	[ALC883_TARGA_2ch_DIG]	= "targa-2ch-dig",
6687	[ALC883_ACER]		= "acer",
6688	[ALC883_ACER_ASPIRE]	= "acer-aspire",
6689	[ALC883_MEDION]		= "medion",
6690	[ALC883_MEDION_MD2]	= "medion-md2",
6691	[ALC883_LAPTOP_EAPD]	= "laptop-eapd",
6692	[ALC883_LENOVO_101E_2ch] = "lenovo-101e",
6693	[ALC883_LENOVO_NB0763]	= "lenovo-nb0763",
6694	[ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
6695	[ALC888_6ST_HP]		= "6stack-hp",
6696	[ALC888_3ST_HP]		= "3stack-hp",
6697	[ALC883_AUTO]		= "auto",
6698};
6699
6700static struct snd_pci_quirk alc883_cfg_tbl[] = {
6701	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
6702	SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
6703	SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
6704	SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
6705	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
6706	SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
6707	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
6708	SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
6709	SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
6710	SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
6711	SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
6712	SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
6713	SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
6714	SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
6715	SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
6716	SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
6717	SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
6718	SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
6719	SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
6720	SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
6721	SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
6722	SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
6723	SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
6724	SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
6725	SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
6726	SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER),
6727	SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
6728	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
6729	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
6730	SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
6731	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
6732	SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
6733	SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
6734	SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP),
6735	SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
6736	SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
6737	SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
6738	{}
6739};
6740
6741static struct alc_config_preset alc883_presets[] = {
6742	[ALC883_3ST_2ch_DIG] = {
6743		.mixers = { alc883_3ST_2ch_mixer },
6744		.init_verbs = { alc883_init_verbs },
6745		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6746		.dac_nids = alc883_dac_nids,
6747		.dig_out_nid = ALC883_DIGOUT_NID,
6748		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6749		.adc_nids = alc883_adc_nids,
6750		.dig_in_nid = ALC883_DIGIN_NID,
6751		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6752		.channel_mode = alc883_3ST_2ch_modes,
6753		.input_mux = &alc883_capture_source,
6754	},
6755	[ALC883_3ST_6ch_DIG] = {
6756		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6757		.init_verbs = { alc883_init_verbs },
6758		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6759		.dac_nids = alc883_dac_nids,
6760		.dig_out_nid = ALC883_DIGOUT_NID,
6761		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6762		.adc_nids = alc883_adc_nids,
6763		.dig_in_nid = ALC883_DIGIN_NID,
6764		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6765		.channel_mode = alc883_3ST_6ch_modes,
6766		.need_dac_fix = 1,
6767		.input_mux = &alc883_capture_source,
6768	},
6769	[ALC883_3ST_6ch] = {
6770		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6771		.init_verbs = { alc883_init_verbs },
6772		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6773		.dac_nids = alc883_dac_nids,
6774		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6775		.adc_nids = alc883_adc_nids,
6776		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6777		.channel_mode = alc883_3ST_6ch_modes,
6778		.need_dac_fix = 1,
6779		.input_mux = &alc883_capture_source,
6780	},
6781	[ALC883_6ST_DIG] = {
6782		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
6783		.init_verbs = { alc883_init_verbs },
6784		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6785		.dac_nids = alc883_dac_nids,
6786		.dig_out_nid = ALC883_DIGOUT_NID,
6787		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6788		.adc_nids = alc883_adc_nids,
6789		.dig_in_nid = ALC883_DIGIN_NID,
6790		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6791		.channel_mode = alc883_sixstack_modes,
6792		.input_mux = &alc883_capture_source,
6793	},
6794	[ALC883_TARGA_DIG] = {
6795		.mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
6796		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
6797		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6798		.dac_nids = alc883_dac_nids,
6799		.dig_out_nid = ALC883_DIGOUT_NID,
6800		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6801		.adc_nids = alc883_adc_nids,
6802		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6803		.channel_mode = alc883_3ST_6ch_modes,
6804		.need_dac_fix = 1,
6805		.input_mux = &alc883_capture_source,
6806		.unsol_event = alc883_tagra_unsol_event,
6807		.init_hook = alc883_tagra_automute,
6808	},
6809	[ALC883_TARGA_2ch_DIG] = {
6810		.mixers = { alc883_tagra_2ch_mixer},
6811		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
6812		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6813		.dac_nids = alc883_dac_nids,
6814		.dig_out_nid = ALC883_DIGOUT_NID,
6815		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6816		.adc_nids = alc883_adc_nids,
6817		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6818		.channel_mode = alc883_3ST_2ch_modes,
6819		.input_mux = &alc883_capture_source,
6820		.unsol_event = alc883_tagra_unsol_event,
6821		.init_hook = alc883_tagra_automute,
6822	},
6823	[ALC883_ACER] = {
6824		.mixers = { alc883_base_mixer,
6825			    alc883_chmode_mixer },
6826		/* On TravelMate laptops, GPIO 0 enables the internal speaker
6827		 * and the headphone jack.  Turn this on and rely on the
6828		 * standard mute methods whenever the user wants to turn
6829		 * these outputs off.
6830		 */
6831		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
6832		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6833		.dac_nids = alc883_dac_nids,
6834		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6835		.adc_nids = alc883_adc_nids,
6836		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6837		.channel_mode = alc883_3ST_2ch_modes,
6838		.input_mux = &alc883_capture_source,
6839	},
6840	[ALC883_ACER_ASPIRE] = {
6841		.mixers = { alc883_acer_aspire_mixer, alc883_chmode_mixer },
6842		/* On TravelMate laptops, GPIO 0 enables the internal speaker
6843		 * and the headphone jack.  Turn this on and rely on the
6844		 * standard mute methods whenever the user wants to turn
6845		 * these outputs off.
6846		 */
6847		.init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
6848		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6849		.dac_nids = alc883_dac_nids,
6850		.dig_out_nid = ALC883_DIGOUT_NID,
6851		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6852		.adc_nids = alc883_adc_nids,
6853		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6854		.channel_mode = alc883_3ST_2ch_modes,
6855		.input_mux = &alc883_capture_source,
6856	},
6857	[ALC883_MEDION] = {
6858		.mixers = { alc883_fivestack_mixer,
6859			    alc883_chmode_mixer },
6860		.init_verbs = { alc883_init_verbs,
6861				alc883_medion_eapd_verbs },
6862		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6863		.dac_nids = alc883_dac_nids,
6864		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6865		.adc_nids = alc883_adc_nids,
6866		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6867		.channel_mode = alc883_sixstack_modes,
6868		.input_mux = &alc883_capture_source,
6869	},
6870	[ALC883_MEDION_MD2] = {
6871		.mixers = { alc883_medion_md2_mixer},
6872		.init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
6873		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6874		.dac_nids = alc883_dac_nids,
6875		.dig_out_nid = ALC883_DIGOUT_NID,
6876		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6877		.adc_nids = alc883_adc_nids,
6878		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6879		.channel_mode = alc883_3ST_2ch_modes,
6880		.input_mux = &alc883_capture_source,
6881		.unsol_event = alc883_medion_md2_unsol_event,
6882		.init_hook = alc883_medion_md2_automute,
6883	},
6884	[ALC883_LAPTOP_EAPD] = {
6885		.mixers = { alc883_base_mixer,
6886			    alc883_chmode_mixer },
6887		.init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
6888		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6889		.dac_nids = alc883_dac_nids,
6890		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6891		.adc_nids = alc883_adc_nids,
6892		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6893		.channel_mode = alc883_3ST_2ch_modes,
6894		.input_mux = &alc883_capture_source,
6895	},
6896	[ALC883_LENOVO_101E_2ch] = {
6897		.mixers = { alc883_lenovo_101e_2ch_mixer},
6898		.init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
6899		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6900		.dac_nids = alc883_dac_nids,
6901		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6902		.adc_nids = alc883_adc_nids,
6903		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6904		.channel_mode = alc883_3ST_2ch_modes,
6905		.input_mux = &alc883_lenovo_101e_capture_source,
6906		.unsol_event = alc883_lenovo_101e_unsol_event,
6907		.init_hook = alc883_lenovo_101e_all_automute,
6908	},
6909	[ALC883_LENOVO_NB0763] = {
6910		.mixers = { alc883_lenovo_nb0763_mixer },
6911		.init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
6912		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6913		.dac_nids = alc883_dac_nids,
6914		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6915		.adc_nids = alc883_adc_nids,
6916		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6917		.channel_mode = alc883_3ST_2ch_modes,
6918		.need_dac_fix = 1,
6919		.input_mux = &alc883_lenovo_nb0763_capture_source,
6920		.unsol_event = alc883_medion_md2_unsol_event,
6921		.init_hook = alc883_medion_md2_automute,
6922	},
6923	[ALC888_LENOVO_MS7195_DIG] = {
6924		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6925		.init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
6926		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6927		.dac_nids = alc883_dac_nids,
6928		.dig_out_nid = ALC883_DIGOUT_NID,
6929		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6930		.adc_nids = alc883_adc_nids,
6931		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6932		.channel_mode = alc883_3ST_6ch_modes,
6933		.need_dac_fix = 1,
6934		.input_mux = &alc883_capture_source,
6935		.unsol_event = alc883_lenovo_ms7195_unsol_event,
6936		.init_hook = alc888_lenovo_ms7195_front_automute,
6937	},
6938	[ALC888_6ST_HP] = {
6939		.mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer },
6940		.init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs },
6941		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6942		.dac_nids = alc883_dac_nids,
6943		.dig_out_nid = ALC883_DIGOUT_NID,
6944		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6945		.adc_nids = alc883_adc_nids,
6946		.dig_in_nid = ALC883_DIGIN_NID,
6947		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6948		.channel_mode = alc883_sixstack_modes,
6949		.input_mux = &alc883_capture_source,
6950	},
6951	[ALC888_3ST_HP] = {
6952		.mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer },
6953		.init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
6954		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6955		.dac_nids = alc883_dac_nids,
6956		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6957		.adc_nids = alc883_adc_nids,
6958		.num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
6959		.channel_mode = alc888_3st_hp_modes,
6960		.need_dac_fix = 1,
6961		.input_mux = &alc883_capture_source,
6962	},
6963};
6964
6965
6966/*
6967 * BIOS auto configuration
6968 */
6969static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
6970					      hda_nid_t nid, int pin_type,
6971					      int dac_idx)
6972{
6973	/* set as output */
6974	struct alc_spec *spec = codec->spec;
6975	int idx;
6976
6977	if (spec->multiout.dac_nids[dac_idx] == 0x25)
6978		idx = 4;
6979	else
6980		idx = spec->multiout.dac_nids[dac_idx] - 2;
6981
6982	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6983			    pin_type);
6984	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
6985			    AMP_OUT_UNMUTE);
6986	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6987
6988}
6989
6990static void alc883_auto_init_multi_out(struct hda_codec *codec)
6991{
6992	struct alc_spec *spec = codec->spec;
6993	int i;
6994
6995	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6996	for (i = 0; i <= HDA_SIDE; i++) {
6997		hda_nid_t nid = spec->autocfg.line_out_pins[i];
6998		int pin_type = get_pin_type(spec->autocfg.line_out_type);
6999		if (nid)
7000			alc883_auto_set_output_and_unmute(codec, nid, pin_type,
7001							  i);
7002	}
7003}
7004
7005static void alc883_auto_init_hp_out(struct hda_codec *codec)
7006{
7007	struct alc_spec *spec = codec->spec;
7008	hda_nid_t pin;
7009
7010	pin = spec->autocfg.hp_pins[0];
7011	if (pin) /* connect to front */
7012		/* use dac 0 */
7013		alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7014}
7015
7016#define alc883_is_input_pin(nid)	alc880_is_input_pin(nid)
7017#define ALC883_PIN_CD_NID		ALC880_PIN_CD_NID
7018
7019static void alc883_auto_init_analog_input(struct hda_codec *codec)
7020{
7021	struct alc_spec *spec = codec->spec;
7022	int i;
7023
7024	for (i = 0; i < AUTO_PIN_LAST; i++) {
7025		hda_nid_t nid = spec->autocfg.input_pins[i];
7026		if (alc883_is_input_pin(nid)) {
7027			snd_hda_codec_write(codec, nid, 0,
7028					    AC_VERB_SET_PIN_WIDGET_CONTROL,
7029					    (i <= AUTO_PIN_FRONT_MIC ?
7030					     PIN_VREF80 : PIN_IN));
7031			if (nid != ALC883_PIN_CD_NID)
7032				snd_hda_codec_write(codec, nid, 0,
7033						    AC_VERB_SET_AMP_GAIN_MUTE,
7034						    AMP_OUT_MUTE);
7035		}
7036	}
7037}
7038
7039/* almost identical with ALC880 parser... */
7040static int alc883_parse_auto_config(struct hda_codec *codec)
7041{
7042	struct alc_spec *spec = codec->spec;
7043	int err = alc880_parse_auto_config(codec);
7044
7045	if (err < 0)
7046		return err;
7047	else if (err > 0)
7048		/* hack - override the init verbs */
7049		spec->init_verbs[0] = alc883_auto_init_verbs;
7050	spec->mixers[spec->num_mixers] = alc883_capture_mixer;
7051	spec->num_mixers++;
7052	return err;
7053}
7054
7055/* additional initialization for auto-configuration model */
7056static void alc883_auto_init(struct hda_codec *codec)
7057{
7058	alc883_auto_init_multi_out(codec);
7059	alc883_auto_init_hp_out(codec);
7060	alc883_auto_init_analog_input(codec);
7061}
7062
7063static int patch_alc883(struct hda_codec *codec)
7064{
7065	struct alc_spec *spec;
7066	int err, board_config;
7067
7068	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7069	if (spec == NULL)
7070		return -ENOMEM;
7071
7072	codec->spec = spec;
7073
7074	board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
7075						  alc883_models,
7076						  alc883_cfg_tbl);
7077	if (board_config < 0) {
7078		printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
7079		       "trying auto-probe from BIOS...\n");
7080		board_config = ALC883_AUTO;
7081	}
7082
7083	if (board_config == ALC883_AUTO) {
7084		/* automatic parse from the BIOS config */
7085		err = alc883_parse_auto_config(codec);
7086		if (err < 0) {
7087			alc_free(codec);
7088			return err;
7089		} else if (!err) {
7090			printk(KERN_INFO
7091			       "hda_codec: Cannot set up configuration "
7092			       "from BIOS.  Using base mode...\n");
7093			board_config = ALC883_3ST_2ch_DIG;
7094		}
7095	}
7096
7097	if (board_config != ALC883_AUTO)
7098		setup_preset(spec, &alc883_presets[board_config]);
7099
7100	spec->stream_name_analog = "ALC883 Analog";
7101	spec->stream_analog_playback = &alc883_pcm_analog_playback;
7102	spec->stream_analog_capture = &alc883_pcm_analog_capture;
7103
7104	spec->stream_name_digital = "ALC883 Digital";
7105	spec->stream_digital_playback = &alc883_pcm_digital_playback;
7106	spec->stream_digital_capture = &alc883_pcm_digital_capture;
7107
7108	if (!spec->adc_nids && spec->input_mux) {
7109		spec->adc_nids = alc883_adc_nids;
7110		spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
7111	}
7112
7113	codec->patch_ops = alc_patch_ops;
7114	if (board_config == ALC883_AUTO)
7115		spec->init_hook = alc883_auto_init;
7116#ifdef CONFIG_SND_HDA_POWER_SAVE
7117	if (!spec->loopback.amplist)
7118		spec->loopback.amplist = alc883_loopbacks;
7119#endif
7120
7121	return 0;
7122}
7123
7124/*
7125 * ALC262 support
7126 */
7127
7128#define ALC262_DIGOUT_NID	ALC880_DIGOUT_NID
7129#define ALC262_DIGIN_NID	ALC880_DIGIN_NID
7130
7131#define alc262_dac_nids		alc260_dac_nids
7132#define alc262_adc_nids		alc882_adc_nids
7133#define alc262_adc_nids_alt	alc882_adc_nids_alt
7134
7135#define alc262_modes		alc260_modes
7136#define alc262_capture_source	alc882_capture_source
7137
7138static struct snd_kcontrol_new alc262_base_mixer[] = {
7139	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7140	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7141	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7142	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7143	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7144	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7145	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7146	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7147	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7148	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7149	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7150	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7151	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7152	   HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7153	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
7154	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7155	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7156	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7157	{ } /* end */
7158};
7159
7160static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
7161	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7162	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7163	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7164	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7165	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7166	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7167	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7168	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7169	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7170	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7171	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7172	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7173	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7174	   HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7175	/*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
7176	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7177	{ } /* end */
7178};
7179
7180static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
7181	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7182	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7183	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7184	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7185	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7186
7187	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7188	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7189	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7190	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7191	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7192	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7193	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7194	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7195	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7196	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7197	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7198	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7199	HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
7200	HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
7201	{ } /* end */
7202};
7203
7204static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
7205	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7206	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7207	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7208	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7209	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7210	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7211	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
7212	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
7213	HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
7214	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7215	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7216	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7217	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7218	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7219	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7220	{ } /* end */
7221};
7222
7223static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
7224	HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7225	HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7226	HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
7227	{ } /* end */
7228};
7229
7230static struct hda_bind_ctls alc262_sony_bind_sw = {
7231	.ops = &snd_hda_bind_sw,
7232	.values = {
7233		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
7234		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
7235		0,
7236	},
7237};
7238
7239static struct snd_kcontrol_new alc262_sony_mixer[] = {
7240	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7241	HDA_BIND_SW("Front Playback Switch", &alc262_sony_bind_sw),
7242	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7243	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7244	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7245	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7246	{ } /* end */
7247};
7248
7249static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
7250	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7251	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7252	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7253	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7254	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7255	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7256	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7257	{ } /* end */
7258};
7259
7260#define alc262_capture_mixer		alc882_capture_mixer
7261#define alc262_capture_alt_mixer	alc882_capture_alt_mixer
7262
7263/*
7264 * generic initialization of ADC, input mixers and output mixers
7265 */
7266static struct hda_verb alc262_init_verbs[] = {
7267	/*
7268	 * Unmute ADC0-2 and set the default input to mic-in
7269	 */
7270	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7271	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7272	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7273	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7274	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7275	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7276
7277	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7278	 * mixer widget
7279	 * Note: PASD motherboards uses the Line In 2 as the input for
7280	 * front panel mic (mic 2)
7281	 */
7282	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7283	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7284	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7285	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7286	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7287	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7288
7289	/*
7290	 * Set up output mixers (0x0c - 0x0e)
7291	 */
7292	/* set vol=0 to output mixers */
7293	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7294	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7295	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7296	/* set up input amps for analog loopback */
7297	/* Amp Indices: DAC = 0, mixer = 1 */
7298	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7299	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7300	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7301	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7302	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7303	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7304
7305	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7306	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7307	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7308	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7309	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7310	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7311
7312	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7313	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7314	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7315	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7316	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7317
7318	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7319	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7320
7321	/* FIXME: use matrix-type input source selection */
7322	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7323	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7324	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7325	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7326	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7327	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7328	/* Input mixer2 */
7329	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7330	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7331	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7332	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7333	/* Input mixer3 */
7334	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7335	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7336	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7337	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7338
7339	{ }
7340};
7341
7342static struct hda_verb alc262_hippo_unsol_verbs[] = {
7343	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7344	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7345	{}
7346};
7347
7348static struct hda_verb alc262_hippo1_unsol_verbs[] = {
7349	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7350	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7351	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7352
7353	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7354	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7355	{}
7356};
7357
7358static struct hda_verb alc262_sony_unsol_verbs[] = {
7359	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7360	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7361	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},	// Front Mic
7362
7363	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7364	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7365};
7366
7367/* mute/unmute internal speaker according to the hp jack and mute state */
7368static void alc262_hippo_automute(struct hda_codec *codec)
7369{
7370	struct alc_spec *spec = codec->spec;
7371	unsigned int mute;
7372	unsigned int present;
7373
7374	/* need to execute and sync at first */
7375	snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
7376	present = snd_hda_codec_read(codec, 0x15, 0,
7377				     AC_VERB_GET_PIN_SENSE, 0);
7378	spec->jack_present = (present & 0x80000000) != 0;
7379	if (spec->jack_present) {
7380		/* mute internal speaker */
7381		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7382					 HDA_AMP_MUTE, HDA_AMP_MUTE);
7383	} else {
7384		/* unmute internal speaker if necessary */
7385		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
7386		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7387					 HDA_AMP_MUTE, mute);
7388	}
7389}
7390
7391/* unsolicited event for HP jack sensing */
7392static void alc262_hippo_unsol_event(struct hda_codec *codec,
7393				       unsigned int res)
7394{
7395	if ((res >> 26) != ALC880_HP_EVENT)
7396		return;
7397	alc262_hippo_automute(codec);
7398}
7399
7400static void alc262_hippo1_automute(struct hda_codec *codec)
7401{
7402	unsigned int mute;
7403	unsigned int present;
7404
7405	snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
7406	present = snd_hda_codec_read(codec, 0x1b, 0,
7407				     AC_VERB_GET_PIN_SENSE, 0);
7408	present = (present & 0x80000000) != 0;
7409	if (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, 0x1b, 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_hippo1_unsol_event(struct hda_codec *codec,
7423				       unsigned int res)
7424{
7425	if ((res >> 26) != ALC880_HP_EVENT)
7426		return;
7427	alc262_hippo1_automute(codec);
7428}
7429
7430/*
7431 * fujitsu model
7432 *  0x14 = headphone/spdif-out, 0x15 = internal speaker
7433 */
7434
7435#define ALC_HP_EVENT	0x37
7436
7437static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
7438	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
7439	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7440	{}
7441};
7442
7443static struct hda_input_mux alc262_fujitsu_capture_source = {
7444	.num_items = 2,
7445	.items = {
7446		{ "Mic", 0x0 },
7447		{ "CD", 0x4 },
7448	},
7449};
7450
7451static struct hda_input_mux alc262_HP_capture_source = {
7452	.num_items = 5,
7453	.items = {
7454		{ "Mic", 0x0 },
7455		{ "Front Mic", 0x3 },
7456		{ "Line", 0x2 },
7457		{ "CD", 0x4 },
7458		{ "AUX IN", 0x6 },
7459	},
7460};
7461
7462/* mute/unmute internal speaker according to the hp jack and mute state */
7463static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
7464{
7465	struct alc_spec *spec = codec->spec;
7466	unsigned int mute;
7467
7468	if (force || !spec->sense_updated) {
7469		unsigned int present;
7470		/* need to execute and sync at first */
7471		snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
7472		present = snd_hda_codec_read(codec, 0x14, 0,
7473				    	 AC_VERB_GET_PIN_SENSE, 0);
7474		spec->jack_present = (present & 0x80000000) != 0;
7475		spec->sense_updated = 1;
7476	}
7477	if (spec->jack_present) {
7478		/* mute internal speaker */
7479		snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7480					 HDA_AMP_MUTE, HDA_AMP_MUTE);
7481	} else {
7482		/* unmute internal speaker if necessary */
7483		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
7484		snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7485					 HDA_AMP_MUTE, mute);
7486	}
7487}
7488
7489/* unsolicited event for HP jack sensing */
7490static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
7491				       unsigned int res)
7492{
7493	if ((res >> 26) != ALC_HP_EVENT)
7494		return;
7495	alc262_fujitsu_automute(codec, 1);
7496}
7497
7498/* bind volumes of both NID 0x0c and 0x0d */
7499static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
7500	.ops = &snd_hda_bind_vol,
7501	.values = {
7502		HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
7503		HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
7504		0
7505	},
7506};
7507
7508/* bind hp and internal speaker mute (with plug check) */
7509static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
7510					 struct snd_ctl_elem_value *ucontrol)
7511{
7512	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7513	long *valp = ucontrol->value.integer.value;
7514	int change;
7515
7516	change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7517					  HDA_AMP_MUTE,
7518					  valp[0] ? 0 : HDA_AMP_MUTE);
7519	change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7520					   HDA_AMP_MUTE,
7521					   valp[1] ? 0 : HDA_AMP_MUTE);
7522	if (change)
7523		alc262_fujitsu_automute(codec, 0);
7524	return change;
7525}
7526
7527static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
7528	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
7529	{
7530		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7531		.name = "Master Playback Switch",
7532		.info = snd_hda_mixer_amp_switch_info,
7533		.get = snd_hda_mixer_amp_switch_get,
7534		.put = alc262_fujitsu_master_sw_put,
7535		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
7536	},
7537	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7538	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7539	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7540	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7541	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7542	{ } /* end */
7543};
7544
7545/* additional init verbs for Benq laptops */
7546static struct hda_verb alc262_EAPD_verbs[] = {
7547	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7548	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
7549	{}
7550};
7551
7552static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
7553	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7554	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7555
7556	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7557	{0x20, AC_VERB_SET_PROC_COEF,  0x3050},
7558	{}
7559};
7560
7561/* add playback controls from the parsed DAC table */
7562static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
7563					     const struct auto_pin_cfg *cfg)
7564{
7565	hda_nid_t nid;
7566	int err;
7567
7568	spec->multiout.num_dacs = 1;	/* only use one dac */
7569	spec->multiout.dac_nids = spec->private_dac_nids;
7570	spec->multiout.dac_nids[0] = 2;
7571
7572	nid = cfg->line_out_pins[0];
7573	if (nid) {
7574		err = add_control(spec, ALC_CTL_WIDGET_VOL,
7575				  "Front Playback Volume",
7576				  HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
7577		if (err < 0)
7578			return err;
7579		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7580				  "Front Playback Switch",
7581				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
7582		if (err < 0)
7583			return err;
7584	}
7585
7586	nid = cfg->speaker_pins[0];
7587	if (nid) {
7588		if (nid == 0x16) {
7589			err = add_control(spec, ALC_CTL_WIDGET_VOL,
7590					  "Speaker Playback Volume",
7591					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
7592							      HDA_OUTPUT));
7593			if (err < 0)
7594				return err;
7595			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7596					  "Speaker Playback Switch",
7597					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
7598							      HDA_OUTPUT));
7599			if (err < 0)
7600				return err;
7601		} else {
7602			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7603					  "Speaker Playback Switch",
7604					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
7605							      HDA_OUTPUT));
7606			if (err < 0)
7607				return err;
7608		}
7609	}
7610	nid = cfg->hp_pins[0];
7611	if (nid) {
7612		/* spec->multiout.hp_nid = 2; */
7613		if (nid == 0x16) {
7614			err = add_control(spec, ALC_CTL_WIDGET_VOL,
7615					  "Headphone Playback Volume",
7616					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
7617							      HDA_OUTPUT));
7618			if (err < 0)
7619				return err;
7620			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7621					  "Headphone Playback Switch",
7622					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
7623							      HDA_OUTPUT));
7624			if (err < 0)
7625				return err;
7626		} else {
7627			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7628					  "Headphone Playback Switch",
7629					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
7630							      HDA_OUTPUT));
7631			if (err < 0)
7632				return err;
7633		}
7634	}
7635	return 0;
7636}
7637
7638/* identical with ALC880 */
7639#define alc262_auto_create_analog_input_ctls \
7640	alc880_auto_create_analog_input_ctls
7641
7642/*
7643 * generic initialization of ADC, input mixers and output mixers
7644 */
7645static struct hda_verb alc262_volume_init_verbs[] = {
7646	/*
7647	 * Unmute ADC0-2 and set the default input to mic-in
7648	 */
7649	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7650	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7651	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7652	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7653	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7654	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7655
7656	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7657	 * mixer widget
7658	 * Note: PASD motherboards uses the Line In 2 as the input for
7659	 * front panel mic (mic 2)
7660	 */
7661	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7662	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7663	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7664	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7665	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7666	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7667
7668	/*
7669	 * Set up output mixers (0x0c - 0x0f)
7670	 */
7671	/* set vol=0 to output mixers */
7672	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7673	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7674	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7675
7676	/* set up input amps for analog loopback */
7677	/* Amp Indices: DAC = 0, mixer = 1 */
7678	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7679	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7680	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7681	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7682	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7683	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7684
7685	/* FIXME: use matrix-type input source selection */
7686	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7687	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7688	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7689	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7690	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7691	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7692	/* Input mixer2 */
7693	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7694	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7695	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7696	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7697	/* Input mixer3 */
7698	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7699	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7700	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7701	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7702
7703	{ }
7704};
7705
7706static struct hda_verb alc262_HP_BPC_init_verbs[] = {
7707	/*
7708	 * Unmute ADC0-2 and set the default input to mic-in
7709	 */
7710	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7711	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7712	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7713	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7714	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7715	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7716
7717	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7718	 * mixer widget
7719	 * Note: PASD motherboards uses the Line In 2 as the input for
7720	 * front panel mic (mic 2)
7721	 */
7722	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7723	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7724	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7725	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7726	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7727	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7728	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
7729        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
7730
7731	/*
7732	 * Set up output mixers (0x0c - 0x0e)
7733	 */
7734	/* set vol=0 to output mixers */
7735	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7736	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7737	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7738
7739	/* set up input amps for analog loopback */
7740	/* Amp Indices: DAC = 0, mixer = 1 */
7741	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7742	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7743	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7744	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7745	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7746	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7747
7748	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7749	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7750	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7751
7752	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7753	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7754
7755	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7756	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7757
7758	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7759	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7760        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7761	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7762	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7763
7764	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7765	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7766        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7767	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7768	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7769	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7770
7771
7772	/* FIXME: use matrix-type input source selection */
7773	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7774	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7775	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7776	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7777	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7778	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7779	/* Input mixer2 */
7780	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7781	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7782	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7783	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7784	/* Input mixer3 */
7785	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7786	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7787	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7788	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7789
7790	{ }
7791};
7792
7793static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
7794	/*
7795	 * Unmute ADC0-2 and set the default input to mic-in
7796	 */
7797	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7798	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7799	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7800	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7801	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7802	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7803
7804	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7805	 * mixer widget
7806	 * Note: PASD motherboards uses the Line In 2 as the input for front
7807	 * panel mic (mic 2)
7808	 */
7809	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7810	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7811	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7812	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7813	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7814	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7815	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
7816	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
7817	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
7818	/*
7819	 * Set up output mixers (0x0c - 0x0e)
7820	 */
7821	/* set vol=0 to output mixers */
7822	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7823	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7824	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7825
7826	/* set up input amps for analog loopback */
7827	/* Amp Indices: DAC = 0, mixer = 1 */
7828	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7829	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7830	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7831	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7832	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7833	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7834
7835
7836	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },	/* HP */
7837	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Mono */
7838	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* rear MIC */
7839	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* Line in */
7840	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* Front MIC */
7841	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Line out */
7842	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* CD in */
7843
7844	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7845	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7846
7847	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7848	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7849
7850	/* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
7851	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7852	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7853	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7854	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7855	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7856
7857	/* FIXME: use matrix-type input source selection */
7858	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7859	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7860	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
7861	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
7862	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
7863	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
7864	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
7865        /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
7866	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
7867	/* Input mixer2 */
7868	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7869	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
7870	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7871	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7872	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7873        /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
7874	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
7875	/* Input mixer3 */
7876	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7877	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
7878	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7879	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7880	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7881        /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
7882	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
7883
7884	{ }
7885};
7886
7887#ifdef CONFIG_SND_HDA_POWER_SAVE
7888#define alc262_loopbacks	alc880_loopbacks
7889#endif
7890
7891/* pcm configuration: identiacal with ALC880 */
7892#define alc262_pcm_analog_playback	alc880_pcm_analog_playback
7893#define alc262_pcm_analog_capture	alc880_pcm_analog_capture
7894#define alc262_pcm_digital_playback	alc880_pcm_digital_playback
7895#define alc262_pcm_digital_capture	alc880_pcm_digital_capture
7896
7897/*
7898 * BIOS auto configuration
7899 */
7900static int alc262_parse_auto_config(struct hda_codec *codec)
7901{
7902	struct alc_spec *spec = codec->spec;
7903	int err;
7904	static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
7905
7906	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7907					   alc262_ignore);
7908	if (err < 0)
7909		return err;
7910	if (!spec->autocfg.line_outs)
7911		return 0; /* can't find valid BIOS pin config */
7912	err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
7913	if (err < 0)
7914		return err;
7915	err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
7916	if (err < 0)
7917		return err;
7918
7919	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
7920
7921	if (spec->autocfg.dig_out_pin)
7922		spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
7923	if (spec->autocfg.dig_in_pin)
7924		spec->dig_in_nid = ALC262_DIGIN_NID;
7925
7926	if (spec->kctl_alloc)
7927		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
7928
7929	spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
7930	spec->num_mux_defs = 1;
7931	spec->input_mux = &spec->private_imux;
7932
7933	return 1;
7934}
7935
7936#define alc262_auto_init_multi_out	alc882_auto_init_multi_out
7937#define alc262_auto_init_hp_out		alc882_auto_init_hp_out
7938#define alc262_auto_init_analog_input	alc882_auto_init_analog_input
7939
7940
7941/* init callback for auto-configuration model -- overriding the default init */
7942static void alc262_auto_init(struct hda_codec *codec)
7943{
7944	alc262_auto_init_multi_out(codec);
7945	alc262_auto_init_hp_out(codec);
7946	alc262_auto_init_analog_input(codec);
7947}
7948
7949/*
7950 * configuration and preset
7951 */
7952static const char *alc262_models[ALC262_MODEL_LAST] = {
7953	[ALC262_BASIC]		= "basic",
7954	[ALC262_HIPPO]		= "hippo",
7955	[ALC262_HIPPO_1]	= "hippo_1",
7956	[ALC262_FUJITSU]	= "fujitsu",
7957	[ALC262_HP_BPC]		= "hp-bpc",
7958	[ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
7959	[ALC262_BENQ_ED8]	= "benq",
7960	[ALC262_BENQ_T31]	= "benq-t31",
7961	[ALC262_SONY_ASSAMD]	= "sony-assamd",
7962	[ALC262_AUTO]		= "auto",
7963};
7964
7965static struct snd_pci_quirk alc262_cfg_tbl[] = {
7966	SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
7967	SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
7968	SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
7969	SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
7970	SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
7971	SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
7972	SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
7973	SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
7974	SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
7975	SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
7976	SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
7977	SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
7978	SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
7979	SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
7980	SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
7981	SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
7982	SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
7983	SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
7984	SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
7985	SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
7986	SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
7987	SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
7988	SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
7989	SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
7990	SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
7991	SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
7992	{}
7993};
7994
7995static struct alc_config_preset alc262_presets[] = {
7996	[ALC262_BASIC] = {
7997		.mixers = { alc262_base_mixer },
7998		.init_verbs = { alc262_init_verbs },
7999		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8000		.dac_nids = alc262_dac_nids,
8001		.hp_nid = 0x03,
8002		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8003		.channel_mode = alc262_modes,
8004		.input_mux = &alc262_capture_source,
8005	},
8006	[ALC262_HIPPO] = {
8007		.mixers = { alc262_base_mixer },
8008		.init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
8009		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8010		.dac_nids = alc262_dac_nids,
8011		.hp_nid = 0x03,
8012		.dig_out_nid = ALC262_DIGOUT_NID,
8013		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8014		.channel_mode = alc262_modes,
8015		.input_mux = &alc262_capture_source,
8016		.unsol_event = alc262_hippo_unsol_event,
8017		.init_hook = alc262_hippo_automute,
8018	},
8019	[ALC262_HIPPO_1] = {
8020		.mixers = { alc262_hippo1_mixer },
8021		.init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
8022		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8023		.dac_nids = alc262_dac_nids,
8024		.hp_nid = 0x02,
8025		.dig_out_nid = ALC262_DIGOUT_NID,
8026		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8027		.channel_mode = alc262_modes,
8028		.input_mux = &alc262_capture_source,
8029		.unsol_event = alc262_hippo1_unsol_event,
8030		.init_hook = alc262_hippo1_automute,
8031	},
8032	[ALC262_FUJITSU] = {
8033		.mixers = { alc262_fujitsu_mixer },
8034		.init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs },
8035		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8036		.dac_nids = alc262_dac_nids,
8037		.hp_nid = 0x03,
8038		.dig_out_nid = ALC262_DIGOUT_NID,
8039		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8040		.channel_mode = alc262_modes,
8041		.input_mux = &alc262_fujitsu_capture_source,
8042		.unsol_event = alc262_fujitsu_unsol_event,
8043	},
8044	[ALC262_HP_BPC] = {
8045		.mixers = { alc262_HP_BPC_mixer },
8046		.init_verbs = { alc262_HP_BPC_init_verbs },
8047		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8048		.dac_nids = alc262_dac_nids,
8049		.hp_nid = 0x03,
8050		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8051		.channel_mode = alc262_modes,
8052		.input_mux = &alc262_HP_capture_source,
8053	},
8054	[ALC262_HP_BPC_D7000_WF] = {
8055		.mixers = { alc262_HP_BPC_WildWest_mixer },
8056		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8057		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8058		.dac_nids = alc262_dac_nids,
8059		.hp_nid = 0x03,
8060		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8061		.channel_mode = alc262_modes,
8062		.input_mux = &alc262_HP_capture_source,
8063	},
8064	[ALC262_HP_BPC_D7000_WL] = {
8065		.mixers = { alc262_HP_BPC_WildWest_mixer,
8066			    alc262_HP_BPC_WildWest_option_mixer },
8067		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8068		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8069		.dac_nids = alc262_dac_nids,
8070		.hp_nid = 0x03,
8071		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8072		.channel_mode = alc262_modes,
8073		.input_mux = &alc262_HP_capture_source,
8074	},
8075	[ALC262_BENQ_ED8] = {
8076		.mixers = { alc262_base_mixer },
8077		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
8078		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8079		.dac_nids = alc262_dac_nids,
8080		.hp_nid = 0x03,
8081		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8082		.channel_mode = alc262_modes,
8083		.input_mux = &alc262_capture_source,
8084	},
8085	[ALC262_SONY_ASSAMD] = {
8086		.mixers = { alc262_sony_mixer },
8087		.init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
8088		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8089		.dac_nids = alc262_dac_nids,
8090		.hp_nid = 0x02,
8091		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8092		.channel_mode = alc262_modes,
8093		.input_mux = &alc262_capture_source,
8094		.unsol_event = alc262_hippo_unsol_event,
8095		.init_hook = alc262_hippo_automute,
8096	},
8097	[ALC262_BENQ_T31] = {
8098		.mixers = { alc262_benq_t31_mixer },
8099		.init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
8100		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8101		.dac_nids = alc262_dac_nids,
8102		.hp_nid = 0x03,
8103		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8104		.channel_mode = alc262_modes,
8105		.input_mux = &alc262_capture_source,
8106		.unsol_event = alc262_hippo_unsol_event,
8107		.init_hook = alc262_hippo_automute,
8108	},
8109};
8110
8111static int patch_alc262(struct hda_codec *codec)
8112{
8113	struct alc_spec *spec;
8114	int board_config;
8115	int err;
8116
8117	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8118	if (spec == NULL)
8119		return -ENOMEM;
8120
8121	codec->spec = spec;
8122#if 0
8123	/* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
8124	 * under-run
8125	 */
8126	{
8127	int tmp;
8128	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8129	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
8130	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8131	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
8132	}
8133#endif
8134
8135	board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
8136						  alc262_models,
8137						  alc262_cfg_tbl);
8138
8139	if (board_config < 0) {
8140		printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
8141		       "trying auto-probe from BIOS...\n");
8142		board_config = ALC262_AUTO;
8143	}
8144
8145	if (board_config == ALC262_AUTO) {
8146		/* automatic parse from the BIOS config */
8147		err = alc262_parse_auto_config(codec);
8148		if (err < 0) {
8149			alc_free(codec);
8150			return err;
8151		} else if (!err) {
8152			printk(KERN_INFO
8153			       "hda_codec: Cannot set up configuration "
8154			       "from BIOS.  Using base mode...\n");
8155			board_config = ALC262_BASIC;
8156		}
8157	}
8158
8159	if (board_config != ALC262_AUTO)
8160		setup_preset(spec, &alc262_presets[board_config]);
8161
8162	spec->stream_name_analog = "ALC262 Analog";
8163	spec->stream_analog_playback = &alc262_pcm_analog_playback;
8164	spec->stream_analog_capture = &alc262_pcm_analog_capture;
8165
8166	spec->stream_name_digital = "ALC262 Digital";
8167	spec->stream_digital_playback = &alc262_pcm_digital_playback;
8168	spec->stream_digital_capture = &alc262_pcm_digital_capture;
8169
8170	if (!spec->adc_nids && spec->input_mux) {
8171		/* check whether NID 0x07 is valid */
8172		unsigned int wcap = get_wcaps(codec, 0x07);
8173
8174		/* get type */
8175		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
8176		if (wcap != AC_WID_AUD_IN) {
8177			spec->adc_nids = alc262_adc_nids_alt;
8178			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
8179			spec->mixers[spec->num_mixers] =
8180				alc262_capture_alt_mixer;
8181			spec->num_mixers++;
8182		} else {
8183			spec->adc_nids = alc262_adc_nids;
8184			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
8185			spec->mixers[spec->num_mixers] = alc262_capture_mixer;
8186			spec->num_mixers++;
8187		}
8188	}
8189
8190	codec->patch_ops = alc_patch_ops;
8191	if (board_config == ALC262_AUTO)
8192		spec->init_hook = alc262_auto_init;
8193#ifdef CONFIG_SND_HDA_POWER_SAVE
8194	if (!spec->loopback.amplist)
8195		spec->loopback.amplist = alc262_loopbacks;
8196#endif
8197
8198	return 0;
8199}
8200
8201/*
8202 *  ALC268 channel source setting (2 channel)
8203 */
8204#define ALC268_DIGOUT_NID	ALC880_DIGOUT_NID
8205#define alc268_modes		alc260_modes
8206
8207static hda_nid_t alc268_dac_nids[2] = {
8208	/* front, hp */
8209	0x02, 0x03
8210};
8211
8212static hda_nid_t alc268_adc_nids[2] = {
8213	/* ADC0-1 */
8214	0x08, 0x07
8215};
8216
8217static hda_nid_t alc268_adc_nids_alt[1] = {
8218	/* ADC0 */
8219	0x08
8220};
8221
8222static struct snd_kcontrol_new alc268_base_mixer[] = {
8223	/* output mixer control */
8224	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
8225	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8226	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
8227	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8228	{ }
8229};
8230
8231static struct hda_verb alc268_eapd_verbs[] = {
8232	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8233	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8234	{ }
8235};
8236
8237/*
8238 * generic initialization of ADC, input mixers and output mixers
8239 */
8240static struct hda_verb alc268_base_init_verbs[] = {
8241	/* Unmute DAC0-1 and set vol = 0 */
8242	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8243	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8244	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8245	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8246	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8247	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8248
8249	/*
8250	 * Set up output mixers (0x0c - 0x0e)
8251	 */
8252	/* set vol=0 to output mixers */
8253	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8254	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8255	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8256        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
8257
8258	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8259	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8260
8261	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8262	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8263	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8264	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8265	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8266	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8267	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8268	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8269
8270	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8271	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8272	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8273	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8274	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8275	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8276	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8277	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8278
8279	/* FIXME: use matrix-type input source selection */
8280	/* Mixer elements: 0x18, 19, 1a, 1c, 14, 15, 0b */
8281	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8282	/* Input mixer2 */
8283	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8284	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8285	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8286	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8287
8288	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8289	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8290	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8291	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8292	{ }
8293};
8294
8295/*
8296 * generic initialization of ADC, input mixers and output mixers
8297 */
8298static struct hda_verb alc268_volume_init_verbs[] = {
8299	/* set output DAC */
8300	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8301	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8302	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8303	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8304
8305	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8306	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8307	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8308	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8309	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8310
8311	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8312	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8313	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8314	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8315	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8316
8317	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8318	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8319	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8320	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8321
8322	/* set PCBEEP vol = 0 */
8323	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
8324
8325	{ }
8326};
8327
8328#define alc268_mux_enum_info alc_mux_enum_info
8329#define alc268_mux_enum_get alc_mux_enum_get
8330
8331static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol,
8332			       struct snd_ctl_elem_value *ucontrol)
8333{
8334	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8335	struct alc_spec *spec = codec->spec;
8336	const struct hda_input_mux *imux = spec->input_mux;
8337	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
8338	static hda_nid_t capture_mixers[3] = { 0x23, 0x24 };
8339	hda_nid_t nid = capture_mixers[adc_idx];
8340	unsigned int *cur_val = &spec->cur_mux[adc_idx];
8341	unsigned int i, idx;
8342
8343	idx = ucontrol->value.enumerated.item[0];
8344	if (idx >= imux->num_items)
8345		idx = imux->num_items - 1;
8346	if (*cur_val == idx)
8347		return 0;
8348	for (i = 0; i < imux->num_items; i++) {
8349		unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
8350		snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
8351					 imux->items[i].index,
8352					 HDA_AMP_MUTE, v);
8353                snd_hda_codec_write_cache(codec, nid, 0,
8354					  AC_VERB_SET_CONNECT_SEL,
8355					  idx );
8356	}
8357	*cur_val = idx;
8358	return 1;
8359}
8360
8361static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
8362	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
8363	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
8364	{
8365		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8366		/* The multiple "Capture Source" controls confuse alsamixer
8367		 * So call somewhat different..
8368		 * FIXME: the controls appear in the "playback" view!
8369		 */
8370		/* .name = "Capture Source", */
8371		.name = "Input Source",
8372		.count = 1,
8373		.info = alc268_mux_enum_info,
8374		.get = alc268_mux_enum_get,
8375		.put = alc268_mux_enum_put,
8376	},
8377	{ } /* end */
8378};
8379
8380static struct snd_kcontrol_new alc268_capture_mixer[] = {
8381	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
8382	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
8383	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
8384	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
8385	{
8386		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8387		/* The multiple "Capture Source" controls confuse alsamixer
8388		 * So call somewhat different..
8389		 * FIXME: the controls appear in the "playback" view!
8390		 */
8391		/* .name = "Capture Source", */
8392		.name = "Input Source",
8393		.count = 2,
8394		.info = alc268_mux_enum_info,
8395		.get = alc268_mux_enum_get,
8396		.put = alc268_mux_enum_put,
8397	},
8398	{ } /* end */
8399};
8400
8401static struct hda_input_mux alc268_capture_source = {
8402	.num_items = 4,
8403	.items = {
8404		{ "Mic", 0x0 },
8405		{ "Front Mic", 0x1 },
8406		{ "Line", 0x2 },
8407		{ "CD", 0x3 },
8408	},
8409};
8410
8411/* create input playback/capture controls for the given pin */
8412static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
8413				    const char *ctlname, int idx)
8414{
8415	char name[32];
8416	int err;
8417
8418	sprintf(name, "%s Playback Volume", ctlname);
8419	if (nid == 0x14) {
8420		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
8421				  HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
8422						      HDA_OUTPUT));
8423		if (err < 0)
8424			return err;
8425	} else if (nid == 0x15) {
8426		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
8427				  HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
8428						      HDA_OUTPUT));
8429		if (err < 0)
8430			return err;
8431	} else
8432		return -1;
8433	sprintf(name, "%s Playback Switch", ctlname);
8434	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
8435			  HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
8436	if (err < 0)
8437		return err;
8438	return 0;
8439}
8440
8441/* add playback controls from the parsed DAC table */
8442static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
8443					     const struct auto_pin_cfg *cfg)
8444{
8445	hda_nid_t nid;
8446	int err;
8447
8448	spec->multiout.num_dacs = 2;	/* only use one dac */
8449	spec->multiout.dac_nids = spec->private_dac_nids;
8450	spec->multiout.dac_nids[0] = 2;
8451	spec->multiout.dac_nids[1] = 3;
8452
8453	nid = cfg->line_out_pins[0];
8454	if (nid)
8455		alc268_new_analog_output(spec, nid, "Front", 0);
8456
8457	nid = cfg->speaker_pins[0];
8458	if (nid == 0x1d) {
8459		err = add_control(spec, ALC_CTL_WIDGET_VOL,
8460				  "Speaker Playback Volume",
8461				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
8462		if (err < 0)
8463			return err;
8464	}
8465	nid = cfg->hp_pins[0];
8466	if (nid)
8467		alc268_new_analog_output(spec, nid, "Headphone", 0);
8468
8469	nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
8470	if (nid == 0x16) {
8471		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8472				  "Mono Playback Switch",
8473				  HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
8474		if (err < 0)
8475			return err;
8476	}
8477	return 0;
8478}
8479
8480/* create playback/capture controls for input pins */
8481static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
8482						const struct auto_pin_cfg *cfg)
8483{
8484	struct hda_input_mux *imux = &spec->private_imux;
8485	int i, idx1;
8486
8487	for (i = 0; i < AUTO_PIN_LAST; i++) {
8488		switch(cfg->input_pins[i]) {
8489		case 0x18:
8490			idx1 = 0;	/* Mic 1 */
8491			break;
8492		case 0x19:
8493			idx1 = 1;	/* Mic 2 */
8494			break;
8495		case 0x1a:
8496			idx1 = 2;	/* Line In */
8497			break;
8498		case 0x1c:
8499			idx1 = 3;	/* CD */
8500			break;
8501		default:
8502			continue;
8503		}
8504		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
8505		imux->items[imux->num_items].index = idx1;
8506		imux->num_items++;
8507	}
8508	return 0;
8509}
8510
8511static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
8512{
8513	struct alc_spec *spec = codec->spec;
8514	hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
8515	hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
8516	hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
8517	unsigned int	dac_vol1, dac_vol2;
8518
8519	if (speaker_nid) {
8520		snd_hda_codec_write(codec, speaker_nid, 0,
8521				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
8522		snd_hda_codec_write(codec, 0x0f, 0,
8523				    AC_VERB_SET_AMP_GAIN_MUTE,
8524				    AMP_IN_UNMUTE(1));
8525		snd_hda_codec_write(codec, 0x10, 0,
8526				    AC_VERB_SET_AMP_GAIN_MUTE,
8527				    AMP_IN_UNMUTE(1));
8528	} else {
8529		snd_hda_codec_write(codec, 0x0f, 0,
8530				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
8531		snd_hda_codec_write(codec, 0x10, 0,
8532				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
8533	}
8534
8535	dac_vol1 = dac_vol2 = 0xb000 | 0x40;	/* set max volume  */
8536	if (line_nid == 0x14)
8537		dac_vol2 = AMP_OUT_ZERO;
8538	else if (line_nid == 0x15)
8539		dac_vol1 = AMP_OUT_ZERO;
8540	if (hp_nid == 0x14)
8541		dac_vol2 = AMP_OUT_ZERO;
8542	else if (hp_nid == 0x15)
8543		dac_vol1 = AMP_OUT_ZERO;
8544	if (line_nid != 0x16 || hp_nid != 0x16 ||
8545	    spec->autocfg.line_out_pins[1] != 0x16 ||
8546	    spec->autocfg.line_out_pins[2] != 0x16)
8547		dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
8548
8549	snd_hda_codec_write(codec, 0x02, 0,
8550			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
8551	snd_hda_codec_write(codec, 0x03, 0,
8552			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
8553}
8554
8555/* pcm configuration: identiacal with ALC880 */
8556#define alc268_pcm_analog_playback	alc880_pcm_analog_playback
8557#define alc268_pcm_analog_capture	alc880_pcm_analog_capture
8558#define alc268_pcm_digital_playback	alc880_pcm_digital_playback
8559
8560/*
8561 * BIOS auto configuration
8562 */
8563static int alc268_parse_auto_config(struct hda_codec *codec)
8564{
8565	struct alc_spec *spec = codec->spec;
8566	int err;
8567	static hda_nid_t alc268_ignore[] = { 0 };
8568
8569	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
8570					   alc268_ignore);
8571	if (err < 0)
8572		return err;
8573	if (!spec->autocfg.line_outs)
8574		return 0; /* can't find valid BIOS pin config */
8575
8576	err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
8577	if (err < 0)
8578		return err;
8579	err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
8580	if (err < 0)
8581		return err;
8582
8583	spec->multiout.max_channels = 2;
8584
8585	/* digital only support output */
8586	if (spec->autocfg.dig_out_pin)
8587		spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
8588
8589	if (spec->kctl_alloc)
8590		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
8591
8592	spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
8593	spec->num_mux_defs = 1;
8594	spec->input_mux = &spec->private_imux;
8595
8596	return 1;
8597}
8598
8599#define alc268_auto_init_multi_out	alc882_auto_init_multi_out
8600#define alc268_auto_init_hp_out		alc882_auto_init_hp_out
8601#define alc268_auto_init_analog_input	alc882_auto_init_analog_input
8602
8603/* init callback for auto-configuration model -- overriding the default init */
8604static void alc268_auto_init(struct hda_codec *codec)
8605{
8606	alc268_auto_init_multi_out(codec);
8607	alc268_auto_init_hp_out(codec);
8608	alc268_auto_init_mono_speaker_out(codec);
8609	alc268_auto_init_analog_input(codec);
8610}
8611
8612#ifdef CONFIG_SND_HDA_POWER_SAVE
8613#define alc883_loopbacks	alc880_loopbacks
8614#endif
8615
8616/*
8617 * configuration and preset
8618 */
8619static const char *alc268_models[ALC268_MODEL_LAST] = {
8620	[ALC268_3ST]		= "3stack",
8621	[ALC268_TOSHIBA]	= "toshiba",
8622	[ALC268_AUTO]		= "auto",
8623};
8624
8625static struct snd_pci_quirk alc268_cfg_tbl[] = {
8626	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8627	SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
8628	{}
8629};
8630
8631static struct alc_config_preset alc268_presets[] = {
8632	[ALC268_3ST] = {
8633		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
8634		.init_verbs = { alc268_base_init_verbs },
8635		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
8636		.dac_nids = alc268_dac_nids,
8637                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
8638                .adc_nids = alc268_adc_nids_alt,
8639		.hp_nid = 0x03,
8640		.dig_out_nid = ALC268_DIGOUT_NID,
8641		.num_channel_mode = ARRAY_SIZE(alc268_modes),
8642		.channel_mode = alc268_modes,
8643		.input_mux = &alc268_capture_source,
8644	},
8645	[ALC268_TOSHIBA] = {
8646		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
8647		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs },
8648		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
8649		.dac_nids = alc268_dac_nids,
8650		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
8651		.adc_nids = alc268_adc_nids_alt,
8652		.hp_nid = 0x03,
8653		.num_channel_mode = ARRAY_SIZE(alc268_modes),
8654		.channel_mode = alc268_modes,
8655		.input_mux = &alc268_capture_source,
8656	},
8657};
8658
8659static int patch_alc268(struct hda_codec *codec)
8660{
8661	struct alc_spec *spec;
8662	int board_config;
8663	int err;
8664
8665	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
8666	if (spec == NULL)
8667		return -ENOMEM;
8668
8669	codec->spec = spec;
8670
8671	board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
8672						  alc268_models,
8673						  alc268_cfg_tbl);
8674
8675	if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
8676		printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
8677		       "trying auto-probe from BIOS...\n");
8678		board_config = ALC268_AUTO;
8679	}
8680
8681	if (board_config == ALC268_AUTO) {
8682		/* automatic parse from the BIOS config */
8683		err = alc268_parse_auto_config(codec);
8684		if (err < 0) {
8685			alc_free(codec);
8686			return err;
8687		} else if (!err) {
8688			printk(KERN_INFO
8689			       "hda_codec: Cannot set up configuration "
8690			       "from BIOS.  Using base mode...\n");
8691			board_config = ALC268_3ST;
8692		}
8693	}
8694
8695	if (board_config != ALC268_AUTO)
8696		setup_preset(spec, &alc268_presets[board_config]);
8697
8698	spec->stream_name_analog = "ALC268 Analog";
8699	spec->stream_analog_playback = &alc268_pcm_analog_playback;
8700	spec->stream_analog_capture = &alc268_pcm_analog_capture;
8701
8702	spec->stream_name_digital = "ALC268 Digital";
8703	spec->stream_digital_playback = &alc268_pcm_digital_playback;
8704
8705	if (board_config == ALC268_AUTO) {
8706		if (!spec->adc_nids && spec->input_mux) {
8707			/* check whether NID 0x07 is valid */
8708			unsigned int wcap = get_wcaps(codec, 0x07);
8709
8710			/* get type */
8711			wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
8712			if (wcap != AC_WID_AUD_IN) {
8713				spec->adc_nids = alc268_adc_nids_alt;
8714				spec->num_adc_nids =
8715					ARRAY_SIZE(alc268_adc_nids_alt);
8716				spec->mixers[spec->num_mixers] =
8717					alc268_capture_alt_mixer;
8718				spec->num_mixers++;
8719			} else {
8720				spec->adc_nids = alc268_adc_nids;
8721				spec->num_adc_nids =
8722					ARRAY_SIZE(alc268_adc_nids);
8723				spec->mixers[spec->num_mixers] =
8724					alc268_capture_mixer;
8725				spec->num_mixers++;
8726			}
8727		}
8728	}
8729	codec->patch_ops = alc_patch_ops;
8730	if (board_config == ALC268_AUTO)
8731		spec->init_hook = alc268_auto_init;
8732
8733	return 0;
8734}
8735
8736/*
8737 *  ALC861 channel source setting (2/6 channel selection for 3-stack)
8738 */
8739
8740/*
8741 * set the path ways for 2 channel output
8742 * need to set the codec line out and mic 1 pin widgets to inputs
8743 */
8744static struct hda_verb alc861_threestack_ch2_init[] = {
8745	/* set pin widget 1Ah (line in) for input */
8746	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8747	/* set pin widget 18h (mic1/2) for input, for mic also enable
8748	 * the vref
8749	 */
8750	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8751
8752	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
8753#if 0
8754	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8755	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
8756#endif
8757	{ } /* end */
8758};
8759/*
8760 * 6ch mode
8761 * need to set the codec line out and mic 1 pin widgets to outputs
8762 */
8763static struct hda_verb alc861_threestack_ch6_init[] = {
8764	/* set pin widget 1Ah (line in) for output (Back Surround)*/
8765	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8766	/* set pin widget 18h (mic1) for output (CLFE)*/
8767	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8768
8769	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
8770	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
8771
8772	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
8773#if 0
8774	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8775	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
8776#endif
8777	{ } /* end */
8778};
8779
8780static struct hda_channel_mode alc861_threestack_modes[2] = {
8781	{ 2, alc861_threestack_ch2_init },
8782	{ 6, alc861_threestack_ch6_init },
8783};
8784/* Set mic1 as input and unmute the mixer */
8785static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
8786	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8787	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8788	{ } /* end */
8789};
8790/* Set mic1 as output and mute mixer */
8791static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
8792	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8793	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8794	{ } /* end */
8795};
8796
8797static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
8798	{ 2, alc861_uniwill_m31_ch2_init },
8799	{ 4, alc861_uniwill_m31_ch4_init },
8800};
8801
8802/* Set mic1 and line-in as input and unmute the mixer */
8803static struct hda_verb alc861_asus_ch2_init[] = {
8804	/* set pin widget 1Ah (line in) for input */
8805	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8806	/* set pin widget 18h (mic1/2) for input, for mic also enable
8807	 * the vref
8808	 */
8809	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8810
8811	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
8812#if 0
8813	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8814	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
8815#endif
8816	{ } /* end */
8817};
8818/* Set mic1 nad line-in as output and mute mixer */
8819static struct hda_verb alc861_asus_ch6_init[] = {
8820	/* set pin widget 1Ah (line in) for output (Back Surround)*/
8821	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8822	/* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
8823	/* set pin widget 18h (mic1) for output (CLFE)*/
8824	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8825	/* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
8826	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
8827	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
8828
8829	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
8830#if 0
8831	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8832	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
8833#endif
8834	{ } /* end */
8835};
8836
8837static struct hda_channel_mode alc861_asus_modes[2] = {
8838	{ 2, alc861_asus_ch2_init },
8839	{ 6, alc861_asus_ch6_init },
8840};
8841
8842/* patch-ALC861 */
8843
8844static struct snd_kcontrol_new alc861_base_mixer[] = {
8845        /* output mixer control */
8846	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8847	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8848	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8849	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8850	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
8851
8852        /*Input mixer control */
8853	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8854	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8855	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8856	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8857	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8858	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8859	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8860	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8861	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8862	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
8863
8864        /* Capture mixer control */
8865	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8866	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8867	{
8868		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8869		.name = "Capture Source",
8870		.count = 1,
8871		.info = alc_mux_enum_info,
8872		.get = alc_mux_enum_get,
8873		.put = alc_mux_enum_put,
8874	},
8875	{ } /* end */
8876};
8877
8878static struct snd_kcontrol_new alc861_3ST_mixer[] = {
8879        /* output mixer control */
8880	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8881	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8882	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8883	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8884	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
8885
8886	/* Input mixer control */
8887	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8888	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8889	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8890	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8891	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8892	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8893	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8894	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8895	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8896	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
8897
8898	/* Capture mixer control */
8899	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8900	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8901	{
8902		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8903		.name = "Capture Source",
8904		.count = 1,
8905		.info = alc_mux_enum_info,
8906		.get = alc_mux_enum_get,
8907		.put = alc_mux_enum_put,
8908	},
8909	{
8910		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8911		.name = "Channel Mode",
8912		.info = alc_ch_mode_info,
8913		.get = alc_ch_mode_get,
8914		.put = alc_ch_mode_put,
8915                .private_value = ARRAY_SIZE(alc861_threestack_modes),
8916	},
8917	{ } /* end */
8918};
8919
8920static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
8921        /* output mixer control */
8922	HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8923	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8924	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8925
8926        /*Capture mixer control */
8927	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8928	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8929	{
8930		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8931		.name = "Capture Source",
8932		.count = 1,
8933		.info = alc_mux_enum_info,
8934		.get = alc_mux_enum_get,
8935		.put = alc_mux_enum_put,
8936	},
8937
8938	{ } /* end */
8939};
8940
8941static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
8942        /* output mixer control */
8943	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8944	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8945	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8946	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8947	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
8948
8949	/* Input mixer control */
8950	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8951	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8952	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8953	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8954	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8955	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8956	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8957	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8958	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8959	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
8960
8961	/* Capture mixer control */
8962	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8963	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8964	{
8965		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8966		.name = "Capture Source",
8967		.count = 1,
8968		.info = alc_mux_enum_info,
8969		.get = alc_mux_enum_get,
8970		.put = alc_mux_enum_put,
8971	},
8972	{
8973		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8974		.name = "Channel Mode",
8975		.info = alc_ch_mode_info,
8976		.get = alc_ch_mode_get,
8977		.put = alc_ch_mode_put,
8978                .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
8979	},
8980	{ } /* end */
8981};
8982
8983static struct snd_kcontrol_new alc861_asus_mixer[] = {
8984        /* output mixer control */
8985	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8986	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8987	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8988	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8989	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
8990
8991	/* Input mixer control */
8992	HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8993	HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8994	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8995	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8996	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8997	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8998	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8999	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
9000	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
9001	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
9002
9003	/* Capture mixer control */
9004	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9005	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9006	{
9007		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9008		.name = "Capture Source",
9009		.count = 1,
9010		.info = alc_mux_enum_info,
9011		.get = alc_mux_enum_get,
9012		.put = alc_mux_enum_put,
9013	},
9014	{
9015		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9016		.name = "Channel Mode",
9017		.info = alc_ch_mode_info,
9018		.get = alc_ch_mode_get,
9019		.put = alc_ch_mode_put,
9020                .private_value = ARRAY_SIZE(alc861_asus_modes),
9021	},
9022	{ }
9023};
9024
9025/* additional mixer */
9026static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
9027	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9028	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9029	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
9030	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
9031	{ }
9032};
9033
9034/*
9035 * generic initialization of ADC, input mixers and output mixers
9036 */
9037static struct hda_verb alc861_base_init_verbs[] = {
9038	/*
9039	 * Unmute ADC0 and set the default input to mic-in
9040	 */
9041	/* port-A for surround (rear panel) */
9042	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9043	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
9044	/* port-B for mic-in (rear panel) with vref */
9045	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9046	/* port-C for line-in (rear panel) */
9047	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9048	/* port-D for Front */
9049	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9050	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9051	/* port-E for HP out (front panel) */
9052	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
9053	/* route front PCM to HP */
9054	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9055	/* port-F for mic-in (front panel) with vref */
9056	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9057	/* port-G for CLFE (rear panel) */
9058	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9059	{ 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9060	/* port-H for side (rear panel) */
9061	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9062	{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
9063	/* CD-in */
9064	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9065	/* route front mic to ADC1*/
9066	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9067	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9068
9069	/* Unmute DAC0~3 & spdif out*/
9070	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9071	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9072	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9073	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9074	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9075
9076	/* Unmute Mixer 14 (mic) 1c (Line in)*/
9077	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9078        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9079	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9080        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9081
9082	/* Unmute Stereo Mixer 15 */
9083	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9084	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9085	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9086	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9087
9088	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9089	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9090	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9091	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9092	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9093	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9094	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9095	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9096	/* hp used DAC 3 (Front) */
9097	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9098        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9099
9100	{ }
9101};
9102
9103static struct hda_verb alc861_threestack_init_verbs[] = {
9104	/*
9105	 * Unmute ADC0 and set the default input to mic-in
9106	 */
9107	/* port-A for surround (rear panel) */
9108	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9109	/* port-B for mic-in (rear panel) with vref */
9110	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9111	/* port-C for line-in (rear panel) */
9112	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9113	/* port-D for Front */
9114	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9115	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9116	/* port-E for HP out (front panel) */
9117	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
9118	/* route front PCM to HP */
9119	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9120	/* port-F for mic-in (front panel) with vref */
9121	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9122	/* port-G for CLFE (rear panel) */
9123	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9124	/* port-H for side (rear panel) */
9125	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9126	/* CD-in */
9127	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9128	/* route front mic to ADC1*/
9129	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9130	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9131	/* Unmute DAC0~3 & spdif out*/
9132	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9133	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9134	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9135	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9136	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9137
9138	/* Unmute Mixer 14 (mic) 1c (Line in)*/
9139	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9140        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9141	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9142        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9143
9144	/* Unmute Stereo Mixer 15 */
9145	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9146	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9147	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9148	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9149
9150	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9151	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9152	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9153	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9154	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9155	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9156	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9157	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9158	/* hp used DAC 3 (Front) */
9159	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9160        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9161	{ }
9162};
9163
9164static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
9165	/*
9166	 * Unmute ADC0 and set the default input to mic-in
9167	 */
9168	/* port-A for surround (rear panel) */
9169	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9170	/* port-B for mic-in (rear panel) with vref */
9171	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9172	/* port-C for line-in (rear panel) */
9173	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9174	/* port-D for Front */
9175	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9176	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9177	/* port-E for HP out (front panel) */
9178	/* this has to be set to VREF80 */
9179	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9180	/* route front PCM to HP */
9181	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9182	/* port-F for mic-in (front panel) with vref */
9183	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9184	/* port-G for CLFE (rear panel) */
9185	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9186	/* port-H for side (rear panel) */
9187	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9188	/* CD-in */
9189	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9190	/* route front mic to ADC1*/
9191	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9192	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9193	/* Unmute DAC0~3 & spdif out*/
9194	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9195	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9196	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9197	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9198	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9199
9200	/* Unmute Mixer 14 (mic) 1c (Line in)*/
9201	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9202        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9203	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9204        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9205
9206	/* Unmute Stereo Mixer 15 */
9207	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9208	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9209	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9210	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9211
9212	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9213	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9214	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9215	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9216	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9217	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9218	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9219	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9220	/* hp used DAC 3 (Front) */
9221	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9222        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9223	{ }
9224};
9225
9226static struct hda_verb alc861_asus_init_verbs[] = {
9227	/*
9228	 * Unmute ADC0 and set the default input to mic-in
9229	 */
9230	/* port-A for surround (rear panel)
9231	 * according to codec#0 this is the HP jack
9232	 */
9233	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
9234	/* route front PCM to HP */
9235	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
9236	/* port-B for mic-in (rear panel) with vref */
9237	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9238	/* port-C for line-in (rear panel) */
9239	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9240	/* port-D for Front */
9241	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9242	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9243	/* port-E for HP out (front panel) */
9244	/* this has to be set to VREF80 */
9245	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9246	/* route front PCM to HP */
9247	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9248	/* port-F for mic-in (front panel) with vref */
9249	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9250	/* port-G for CLFE (rear panel) */
9251	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9252	/* port-H for side (rear panel) */
9253	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9254	/* CD-in */
9255	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9256	/* route front mic to ADC1*/
9257	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9258	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9259	/* Unmute DAC0~3 & spdif out*/
9260	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9261	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9262	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9263	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9264	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9265	/* Unmute Mixer 14 (mic) 1c (Line in)*/
9266	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9267        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9268	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9269        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9270
9271	/* Unmute Stereo Mixer 15 */
9272	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9273	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9274	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9275	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9276
9277	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9278	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9279	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9280	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9281	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9282	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9283	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9284	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9285	/* hp used DAC 3 (Front) */
9286	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9287	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9288	{ }
9289};
9290
9291/* additional init verbs for ASUS laptops */
9292static struct hda_verb alc861_asus_laptop_init_verbs[] = {
9293	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
9294	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
9295	{ }
9296};
9297
9298/*
9299 * generic initialization of ADC, input mixers and output mixers
9300 */
9301static struct hda_verb alc861_auto_init_verbs[] = {
9302	/*
9303	 * Unmute ADC0 and set the default input to mic-in
9304	 */
9305	/* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
9306	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9307
9308	/* Unmute DAC0~3 & spdif out*/
9309	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9310	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9311	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9312	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9313	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9314
9315	/* Unmute Mixer 14 (mic) 1c (Line in)*/
9316	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9317	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9318	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9319	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9320
9321	/* Unmute Stereo Mixer 15 */
9322	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9323	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9324	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9325	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
9326
9327	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9328	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9329	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9330	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9331	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9332	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9333	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9334	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9335
9336	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9337	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9338	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9339	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9340	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9341	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9342	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9343	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9344
9345	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},	/* set Mic 1 */
9346
9347	{ }
9348};
9349
9350static struct hda_verb alc861_toshiba_init_verbs[] = {
9351	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9352
9353	{ }
9354};
9355
9356/* toggle speaker-output according to the hp-jack state */
9357static void alc861_toshiba_automute(struct hda_codec *codec)
9358{
9359	unsigned int present;
9360
9361	present = snd_hda_codec_read(codec, 0x0f, 0,
9362				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9363	snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
9364				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9365	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
9366				 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
9367}
9368
9369static void alc861_toshiba_unsol_event(struct hda_codec *codec,
9370				       unsigned int res)
9371{
9372	if ((res >> 26) == ALC880_HP_EVENT)
9373		alc861_toshiba_automute(codec);
9374}
9375
9376/* pcm configuration: identiacal with ALC880 */
9377#define alc861_pcm_analog_playback	alc880_pcm_analog_playback
9378#define alc861_pcm_analog_capture	alc880_pcm_analog_capture
9379#define alc861_pcm_digital_playback	alc880_pcm_digital_playback
9380#define alc861_pcm_digital_capture	alc880_pcm_digital_capture
9381
9382
9383#define ALC861_DIGOUT_NID	0x07
9384
9385static struct hda_channel_mode alc861_8ch_modes[1] = {
9386	{ 8, NULL }
9387};
9388
9389static hda_nid_t alc861_dac_nids[4] = {
9390	/* front, surround, clfe, side */
9391	0x03, 0x06, 0x05, 0x04
9392};
9393
9394static hda_nid_t alc660_dac_nids[3] = {
9395	/* front, clfe, surround */
9396	0x03, 0x05, 0x06
9397};
9398
9399static hda_nid_t alc861_adc_nids[1] = {
9400	/* ADC0-2 */
9401	0x08,
9402};
9403
9404static struct hda_input_mux alc861_capture_source = {
9405	.num_items = 5,
9406	.items = {
9407		{ "Mic", 0x0 },
9408		{ "Front Mic", 0x3 },
9409		{ "Line", 0x1 },
9410		{ "CD", 0x4 },
9411		{ "Mixer", 0x5 },
9412	},
9413};
9414
9415/* fill in the dac_nids table from the parsed pin configuration */
9416static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
9417				     const struct auto_pin_cfg *cfg)
9418{
9419	int i;
9420	hda_nid_t nid;
9421
9422	spec->multiout.dac_nids = spec->private_dac_nids;
9423	for (i = 0; i < cfg->line_outs; i++) {
9424		nid = cfg->line_out_pins[i];
9425		if (nid) {
9426			if (i >= ARRAY_SIZE(alc861_dac_nids))
9427				continue;
9428			spec->multiout.dac_nids[i] = alc861_dac_nids[i];
9429		}
9430	}
9431	spec->multiout.num_dacs = cfg->line_outs;
9432	return 0;
9433}
9434
9435/* add playback controls from the parsed DAC table */
9436static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
9437					     const struct auto_pin_cfg *cfg)
9438{
9439	char name[32];
9440	static const char *chname[4] = {
9441		"Front", "Surround", NULL /*CLFE*/, "Side"
9442	};
9443	hda_nid_t nid;
9444	int i, idx, err;
9445
9446	for (i = 0; i < cfg->line_outs; i++) {
9447		nid = spec->multiout.dac_nids[i];
9448		if (!nid)
9449			continue;
9450		if (nid == 0x05) {
9451			/* Center/LFE */
9452			err = add_control(spec, ALC_CTL_BIND_MUTE,
9453					  "Center Playback Switch",
9454					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
9455							      HDA_OUTPUT));
9456			if (err < 0)
9457				return err;
9458			err = add_control(spec, ALC_CTL_BIND_MUTE,
9459					  "LFE Playback Switch",
9460					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9461							      HDA_OUTPUT));
9462			if (err < 0)
9463				return err;
9464		} else {
9465			for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
9466			     idx++)
9467				if (nid == alc861_dac_nids[idx])
9468					break;
9469			sprintf(name, "%s Playback Switch", chname[idx]);
9470			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
9471					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9472							      HDA_OUTPUT));
9473			if (err < 0)
9474				return err;
9475		}
9476	}
9477	return 0;
9478}
9479
9480static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
9481{
9482	int err;
9483	hda_nid_t nid;
9484
9485	if (!pin)
9486		return 0;
9487
9488	if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
9489		nid = 0x03;
9490		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9491				  "Headphone Playback Switch",
9492				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9493		if (err < 0)
9494			return err;
9495		spec->multiout.hp_nid = nid;
9496	}
9497	return 0;
9498}
9499
9500/* create playback/capture controls for input pins */
9501static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
9502						const struct auto_pin_cfg *cfg)
9503{
9504	struct hda_input_mux *imux = &spec->private_imux;
9505	int i, err, idx, idx1;
9506
9507	for (i = 0; i < AUTO_PIN_LAST; i++) {
9508		switch (cfg->input_pins[i]) {
9509		case 0x0c:
9510			idx1 = 1;
9511			idx = 2;	/* Line In */
9512			break;
9513		case 0x0f:
9514			idx1 = 2;
9515			idx = 2;	/* Line In */
9516			break;
9517		case 0x0d:
9518			idx1 = 0;
9519			idx = 1;	/* Mic In */
9520			break;
9521		case 0x10:
9522			idx1 = 3;
9523			idx = 1;	/* Mic In */
9524			break;
9525		case 0x11:
9526			idx1 = 4;
9527			idx = 0;	/* CD */
9528			break;
9529		default:
9530			continue;
9531		}
9532
9533		err = new_analog_input(spec, cfg->input_pins[i],
9534				       auto_pin_cfg_labels[i], idx, 0x15);
9535		if (err < 0)
9536			return err;
9537
9538		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
9539		imux->items[imux->num_items].index = idx1;
9540		imux->num_items++;
9541	}
9542	return 0;
9543}
9544
9545static struct snd_kcontrol_new alc861_capture_mixer[] = {
9546	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9547	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9548
9549	{
9550		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9551		/* The multiple "Capture Source" controls confuse alsamixer
9552		 * So call somewhat different..
9553		 *FIXME: the controls appear in the "playback" view!
9554		 */
9555		/* .name = "Capture Source", */
9556		.name = "Input Source",
9557		.count = 1,
9558		.info = alc_mux_enum_info,
9559		.get = alc_mux_enum_get,
9560		.put = alc_mux_enum_put,
9561	},
9562	{ } /* end */
9563};
9564
9565static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
9566					      hda_nid_t nid,
9567					      int pin_type, int dac_idx)
9568{
9569	/* set as output */
9570
9571	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
9572			    pin_type);
9573	snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
9574			    AMP_OUT_UNMUTE);
9575
9576}
9577
9578static void alc861_auto_init_multi_out(struct hda_codec *codec)
9579{
9580	struct alc_spec *spec = codec->spec;
9581	int i;
9582
9583	alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
9584	for (i = 0; i < spec->autocfg.line_outs; i++) {
9585		hda_nid_t nid = spec->autocfg.line_out_pins[i];
9586		int pin_type = get_pin_type(spec->autocfg.line_out_type);
9587		if (nid)
9588			alc861_auto_set_output_and_unmute(codec, nid, pin_type,
9589							  spec->multiout.dac_nids[i]);
9590	}
9591}
9592
9593static void alc861_auto_init_hp_out(struct hda_codec *codec)
9594{
9595	struct alc_spec *spec = codec->spec;
9596	hda_nid_t pin;
9597
9598	pin = spec->autocfg.hp_pins[0];
9599	if (pin) /* connect to front */
9600		alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
9601						  spec->multiout.dac_nids[0]);
9602}
9603
9604static void alc861_auto_init_analog_input(struct hda_codec *codec)
9605{
9606	struct alc_spec *spec = codec->spec;
9607	int i;
9608
9609	for (i = 0; i < AUTO_PIN_LAST; i++) {
9610		hda_nid_t nid = spec->autocfg.input_pins[i];
9611		if (nid >= 0x0c && nid <= 0x11) {
9612			snd_hda_codec_write(codec, nid, 0,
9613					    AC_VERB_SET_PIN_WIDGET_CONTROL,
9614					    i <= AUTO_PIN_FRONT_MIC ?
9615					    PIN_VREF80 : PIN_IN);
9616		}
9617	}
9618}
9619
9620/* parse the BIOS configuration and set up the alc_spec */
9621/* return 1 if successful, 0 if the proper config is not found,
9622 * or a negative error code
9623 */
9624static int alc861_parse_auto_config(struct hda_codec *codec)
9625{
9626	struct alc_spec *spec = codec->spec;
9627	int err;
9628	static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
9629
9630	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9631					   alc861_ignore);
9632	if (err < 0)
9633		return err;
9634	if (!spec->autocfg.line_outs)
9635		return 0; /* can't find valid BIOS pin config */
9636
9637	err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
9638	if (err < 0)
9639		return err;
9640	err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
9641	if (err < 0)
9642		return err;
9643	err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
9644	if (err < 0)
9645		return err;
9646	err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
9647	if (err < 0)
9648		return err;
9649
9650	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9651
9652	if (spec->autocfg.dig_out_pin)
9653		spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
9654
9655	if (spec->kctl_alloc)
9656		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9657
9658	spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
9659
9660	spec->num_mux_defs = 1;
9661	spec->input_mux = &spec->private_imux;
9662
9663	spec->adc_nids = alc861_adc_nids;
9664	spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
9665	spec->mixers[spec->num_mixers] = alc861_capture_mixer;
9666	spec->num_mixers++;
9667
9668	return 1;
9669}
9670
9671/* additional initialization for auto-configuration model */
9672static void alc861_auto_init(struct hda_codec *codec)
9673{
9674	alc861_auto_init_multi_out(codec);
9675	alc861_auto_init_hp_out(codec);
9676	alc861_auto_init_analog_input(codec);
9677}
9678
9679#ifdef CONFIG_SND_HDA_POWER_SAVE
9680static struct hda_amp_list alc861_loopbacks[] = {
9681	{ 0x15, HDA_INPUT, 0 },
9682	{ 0x15, HDA_INPUT, 1 },
9683	{ 0x15, HDA_INPUT, 2 },
9684	{ 0x15, HDA_INPUT, 3 },
9685	{ } /* end */
9686};
9687#endif
9688
9689
9690/*
9691 * configuration and preset
9692 */
9693static const char *alc861_models[ALC861_MODEL_LAST] = {
9694	[ALC861_3ST]		= "3stack",
9695	[ALC660_3ST]		= "3stack-660",
9696	[ALC861_3ST_DIG]	= "3stack-dig",
9697	[ALC861_6ST_DIG]	= "6stack-dig",
9698	[ALC861_UNIWILL_M31]	= "uniwill-m31",
9699	[ALC861_TOSHIBA]	= "toshiba",
9700	[ALC861_ASUS]		= "asus",
9701	[ALC861_ASUS_LAPTOP]	= "asus-laptop",
9702	[ALC861_AUTO]		= "auto",
9703};
9704
9705static struct snd_pci_quirk alc861_cfg_tbl[] = {
9706	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
9707	SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
9708	SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
9709	SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
9710	SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
9711	SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
9712	SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
9713	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
9714	/* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
9715	 *        Any other models that need this preset?
9716	 */
9717	/* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
9718	SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
9719	SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31),
9720	SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
9721	SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
9722	SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
9723	SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
9724	SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
9725	{}
9726};
9727
9728static struct alc_config_preset alc861_presets[] = {
9729	[ALC861_3ST] = {
9730		.mixers = { alc861_3ST_mixer },
9731		.init_verbs = { alc861_threestack_init_verbs },
9732		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9733		.dac_nids = alc861_dac_nids,
9734		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9735		.channel_mode = alc861_threestack_modes,
9736		.need_dac_fix = 1,
9737		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9738		.adc_nids = alc861_adc_nids,
9739		.input_mux = &alc861_capture_source,
9740	},
9741	[ALC861_3ST_DIG] = {
9742		.mixers = { alc861_base_mixer },
9743		.init_verbs = { alc861_threestack_init_verbs },
9744		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9745		.dac_nids = alc861_dac_nids,
9746		.dig_out_nid = ALC861_DIGOUT_NID,
9747		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9748		.channel_mode = alc861_threestack_modes,
9749		.need_dac_fix = 1,
9750		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9751		.adc_nids = alc861_adc_nids,
9752		.input_mux = &alc861_capture_source,
9753	},
9754	[ALC861_6ST_DIG] = {
9755		.mixers = { alc861_base_mixer },
9756		.init_verbs = { alc861_base_init_verbs },
9757		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9758		.dac_nids = alc861_dac_nids,
9759		.dig_out_nid = ALC861_DIGOUT_NID,
9760		.num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
9761		.channel_mode = alc861_8ch_modes,
9762		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9763		.adc_nids = alc861_adc_nids,
9764		.input_mux = &alc861_capture_source,
9765	},
9766	[ALC660_3ST] = {
9767		.mixers = { alc861_3ST_mixer },
9768		.init_verbs = { alc861_threestack_init_verbs },
9769		.num_dacs = ARRAY_SIZE(alc660_dac_nids),
9770		.dac_nids = alc660_dac_nids,
9771		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9772		.channel_mode = alc861_threestack_modes,
9773		.need_dac_fix = 1,
9774		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9775		.adc_nids = alc861_adc_nids,
9776		.input_mux = &alc861_capture_source,
9777	},
9778	[ALC861_UNIWILL_M31] = {
9779		.mixers = { alc861_uniwill_m31_mixer },
9780		.init_verbs = { alc861_uniwill_m31_init_verbs },
9781		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9782		.dac_nids = alc861_dac_nids,
9783		.dig_out_nid = ALC861_DIGOUT_NID,
9784		.num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
9785		.channel_mode = alc861_uniwill_m31_modes,
9786		.need_dac_fix = 1,
9787		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9788		.adc_nids = alc861_adc_nids,
9789		.input_mux = &alc861_capture_source,
9790	},
9791	[ALC861_TOSHIBA] = {
9792		.mixers = { alc861_toshiba_mixer },
9793		.init_verbs = { alc861_base_init_verbs,
9794				alc861_toshiba_init_verbs },
9795		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9796		.dac_nids = alc861_dac_nids,
9797		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9798		.channel_mode = alc883_3ST_2ch_modes,
9799		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9800		.adc_nids = alc861_adc_nids,
9801		.input_mux = &alc861_capture_source,
9802		.unsol_event = alc861_toshiba_unsol_event,
9803		.init_hook = alc861_toshiba_automute,
9804	},
9805	[ALC861_ASUS] = {
9806		.mixers = { alc861_asus_mixer },
9807		.init_verbs = { alc861_asus_init_verbs },
9808		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9809		.dac_nids = alc861_dac_nids,
9810		.dig_out_nid = ALC861_DIGOUT_NID,
9811		.num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
9812		.channel_mode = alc861_asus_modes,
9813		.need_dac_fix = 1,
9814		.hp_nid = 0x06,
9815		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9816		.adc_nids = alc861_adc_nids,
9817		.input_mux = &alc861_capture_source,
9818	},
9819	[ALC861_ASUS_LAPTOP] = {
9820		.mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
9821		.init_verbs = { alc861_asus_init_verbs,
9822				alc861_asus_laptop_init_verbs },
9823		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9824		.dac_nids = alc861_dac_nids,
9825		.dig_out_nid = ALC861_DIGOUT_NID,
9826		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9827		.channel_mode = alc883_3ST_2ch_modes,
9828		.need_dac_fix = 1,
9829		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9830		.adc_nids = alc861_adc_nids,
9831		.input_mux = &alc861_capture_source,
9832	},
9833};
9834
9835
9836static int patch_alc861(struct hda_codec *codec)
9837{
9838	struct alc_spec *spec;
9839	int board_config;
9840	int err;
9841
9842	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9843	if (spec == NULL)
9844		return -ENOMEM;
9845
9846	codec->spec = spec;
9847
9848        board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
9849						  alc861_models,
9850						  alc861_cfg_tbl);
9851
9852	if (board_config < 0) {
9853		printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
9854		       "trying auto-probe from BIOS...\n");
9855		board_config = ALC861_AUTO;
9856	}
9857
9858	if (board_config == ALC861_AUTO) {
9859		/* automatic parse from the BIOS config */
9860		err = alc861_parse_auto_config(codec);
9861		if (err < 0) {
9862			alc_free(codec);
9863			return err;
9864		} else if (!err) {
9865			printk(KERN_INFO
9866			       "hda_codec: Cannot set up configuration "
9867			       "from BIOS.  Using base mode...\n");
9868		   board_config = ALC861_3ST_DIG;
9869		}
9870	}
9871
9872	if (board_config != ALC861_AUTO)
9873		setup_preset(spec, &alc861_presets[board_config]);
9874
9875	spec->stream_name_analog = "ALC861 Analog";
9876	spec->stream_analog_playback = &alc861_pcm_analog_playback;
9877	spec->stream_analog_capture = &alc861_pcm_analog_capture;
9878
9879	spec->stream_name_digital = "ALC861 Digital";
9880	spec->stream_digital_playback = &alc861_pcm_digital_playback;
9881	spec->stream_digital_capture = &alc861_pcm_digital_capture;
9882
9883	codec->patch_ops = alc_patch_ops;
9884	if (board_config == ALC861_AUTO)
9885		spec->init_hook = alc861_auto_init;
9886#ifdef CONFIG_SND_HDA_POWER_SAVE
9887	if (!spec->loopback.amplist)
9888		spec->loopback.amplist = alc861_loopbacks;
9889#endif
9890
9891	return 0;
9892}
9893
9894/*
9895 * ALC861-VD support
9896 *
9897 * Based on ALC882
9898 *
9899 * In addition, an independent DAC
9900 */
9901#define ALC861VD_DIGOUT_NID	0x06
9902
9903static hda_nid_t alc861vd_dac_nids[4] = {
9904	/* front, surr, clfe, side surr */
9905	0x02, 0x03, 0x04, 0x05
9906};
9907
9908/* dac_nids for ALC660vd are in a different order - according to
9909 * Realtek's driver.
9910 * This should probably tesult in a different mixer for 6stack models
9911 * of ALC660vd codecs, but for now there is only 3stack mixer
9912 * - and it is the same as in 861vd.
9913 * adc_nids in ALC660vd are (is) the same as in 861vd
9914 */
9915static hda_nid_t alc660vd_dac_nids[3] = {
9916	/* front, rear, clfe, rear_surr */
9917	0x02, 0x04, 0x03
9918};
9919
9920static hda_nid_t alc861vd_adc_nids[1] = {
9921	/* ADC0 */
9922	0x09,
9923};
9924
9925/* input MUX */
9926/* FIXME: should be a matrix-type input source selection */
9927static struct hda_input_mux alc861vd_capture_source = {
9928	.num_items = 4,
9929	.items = {
9930		{ "Mic", 0x0 },
9931		{ "Front Mic", 0x1 },
9932		{ "Line", 0x2 },
9933		{ "CD", 0x4 },
9934	},
9935};
9936
9937static struct hda_input_mux alc861vd_dallas_capture_source = {
9938	.num_items = 3,
9939	.items = {
9940		{ "Front Mic", 0x0 },
9941		{ "ATAPI Mic", 0x1 },
9942		{ "Line In", 0x5 },
9943	},
9944};
9945
9946static struct hda_input_mux alc861vd_hp_capture_source = {
9947	.num_items = 2,
9948	.items = {
9949		{ "Front Mic", 0x0 },
9950		{ "ATAPI Mic", 0x1 },
9951	},
9952};
9953
9954#define alc861vd_mux_enum_info alc_mux_enum_info
9955#define alc861vd_mux_enum_get alc_mux_enum_get
9956
9957static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
9958				struct snd_ctl_elem_value *ucontrol)
9959{
9960	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9961	struct alc_spec *spec = codec->spec;
9962	const struct hda_input_mux *imux = spec->input_mux;
9963	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
9964	static hda_nid_t capture_mixers[1] = { 0x22 };
9965	hda_nid_t nid = capture_mixers[adc_idx];
9966	unsigned int *cur_val = &spec->cur_mux[adc_idx];
9967	unsigned int i, idx;
9968
9969	idx = ucontrol->value.enumerated.item[0];
9970	if (idx >= imux->num_items)
9971		idx = imux->num_items - 1;
9972	if (*cur_val == idx)
9973		return 0;
9974	for (i = 0; i < imux->num_items; i++) {
9975		unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
9976		snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
9977					 imux->items[i].index,
9978					 HDA_AMP_MUTE, v);
9979	}
9980	*cur_val = idx;
9981	return 1;
9982}
9983
9984/*
9985 * 2ch mode
9986 */
9987static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
9988	{ 2, NULL }
9989};
9990
9991/*
9992 * 6ch mode
9993 */
9994static struct hda_verb alc861vd_6stack_ch6_init[] = {
9995	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9996	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9997	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9998	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9999	{ } /* end */
10000};
10001
10002/*
10003 * 8ch mode
10004 */
10005static struct hda_verb alc861vd_6stack_ch8_init[] = {
10006	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10007	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10008	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10009	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10010	{ } /* end */
10011};
10012
10013static struct hda_channel_mode alc861vd_6stack_modes[2] = {
10014	{ 6, alc861vd_6stack_ch6_init },
10015	{ 8, alc861vd_6stack_ch8_init },
10016};
10017
10018static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
10019	{
10020		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10021		.name = "Channel Mode",
10022		.info = alc_ch_mode_info,
10023		.get = alc_ch_mode_get,
10024		.put = alc_ch_mode_put,
10025	},
10026	{ } /* end */
10027};
10028
10029static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
10030	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10031	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10032
10033	{
10034		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10035		/* The multiple "Capture Source" controls confuse alsamixer
10036		 * So call somewhat different..
10037		 *FIXME: the controls appear in the "playback" view!
10038		 */
10039		/* .name = "Capture Source", */
10040		.name = "Input Source",
10041		.count = 1,
10042		.info = alc861vd_mux_enum_info,
10043		.get = alc861vd_mux_enum_get,
10044		.put = alc861vd_mux_enum_put,
10045	},
10046	{ } /* end */
10047};
10048
10049/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
10050 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
10051 */
10052static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
10053	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10054	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10055
10056	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10057	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
10058
10059	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
10060				HDA_OUTPUT),
10061	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
10062				HDA_OUTPUT),
10063	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
10064	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
10065
10066	HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
10067	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
10068
10069	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10070
10071	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10072	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10073	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10074
10075	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10076	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10077	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10078
10079	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10080	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10081
10082	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10083	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10084
10085	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10086	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10087
10088	{ } /* end */
10089};
10090
10091static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
10092	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10093	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10094
10095	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10096
10097	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10098	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10099	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10100
10101	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10102	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10103	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10104
10105	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10106	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10107
10108	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10109	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10110
10111	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10112	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10113
10114	{ } /* end */
10115};
10116
10117static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
10118	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10119	/*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
10120	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10121
10122	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10123
10124	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10125	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10126	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10127
10128	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10129	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10130	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10131
10132	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10133	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10134
10135	{ } /* end */
10136};
10137
10138/* Pin assignment: Front=0x14, HP = 0x15,
10139 *                 Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
10140 */
10141static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
10142	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10143	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10144	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10145	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
10146	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10147	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10148	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10149	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10150	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
10151	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
10152	{ } /* end */
10153};
10154
10155/* Pin assignment: Speaker=0x14, Line-out = 0x15,
10156 *                 Front Mic=0x18, ATAPI Mic = 0x19,
10157 */
10158static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
10159	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10160	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10161	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10162	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
10163	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10164	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10165	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10166	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10167
10168	{ } /* end */
10169};
10170
10171/*
10172 * generic initialization of ADC, input mixers and output mixers
10173 */
10174static struct hda_verb alc861vd_volume_init_verbs[] = {
10175	/*
10176	 * Unmute ADC0 and set the default input to mic-in
10177	 */
10178	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10179	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10180
10181	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
10182	 * the analog-loopback mixer widget
10183	 */
10184	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10185	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10186	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10187	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10188	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10189	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10190
10191	/* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
10192	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10193	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10194	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10195	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10196
10197	/*
10198	 * Set up output mixers (0x02 - 0x05)
10199	 */
10200	/* set vol=0 to output mixers */
10201	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10202	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10203	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10204	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10205
10206	/* set up input amps for analog loopback */
10207	/* Amp Indices: DAC = 0, mixer = 1 */
10208	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10209	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10210	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10211	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10212	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10213	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10214	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10215	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10216
10217	{ }
10218};
10219
10220/*
10221 * 3-stack pin configuration:
10222 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
10223 */
10224static struct hda_verb alc861vd_3stack_init_verbs[] = {
10225	/*
10226	 * Set pin mode and muting
10227	 */
10228	/* set front pin widgets 0x14 for output */
10229	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10230	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10231	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10232
10233	/* Mic (rear) pin: input vref at 80% */
10234	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10235	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10236	/* Front Mic pin: input vref at 80% */
10237	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10238	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10239	/* Line In pin: input */
10240	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10241	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10242	/* Line-2 In: Headphone output (output 0 - 0x0c) */
10243	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10244	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10245	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10246	/* CD pin widget for input */
10247	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10248
10249	{ }
10250};
10251
10252/*
10253 * 6-stack pin configuration:
10254 */
10255static struct hda_verb alc861vd_6stack_init_verbs[] = {
10256	/*
10257	 * Set pin mode and muting
10258	 */
10259	/* set front pin widgets 0x14 for output */
10260	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10261	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10262	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10263
10264	/* Rear Pin: output 1 (0x0d) */
10265	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10266	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10267	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10268	/* CLFE Pin: output 2 (0x0e) */
10269	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10270	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10271	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
10272	/* Side Pin: output 3 (0x0f) */
10273	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10274	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10275	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
10276
10277	/* Mic (rear) pin: input vref at 80% */
10278	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10279	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10280	/* Front Mic pin: input vref at 80% */
10281	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10282	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10283	/* Line In pin: input */
10284	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10285	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10286	/* Line-2 In: Headphone output (output 0 - 0x0c) */
10287	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10288	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10289	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10290	/* CD pin widget for input */
10291	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10292
10293	{ }
10294};
10295
10296static struct hda_verb alc861vd_eapd_verbs[] = {
10297	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10298	{ }
10299};
10300
10301static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
10302	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10303	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10304	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10305	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10306	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10307	{}
10308};
10309
10310/* toggle speaker-output according to the hp-jack state */
10311static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
10312{
10313	unsigned int present;
10314	unsigned char bits;
10315
10316	present = snd_hda_codec_read(codec, 0x1b, 0,
10317				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10318	bits = present ? HDA_AMP_MUTE : 0;
10319	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10320				 HDA_AMP_MUTE, bits);
10321}
10322
10323static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
10324{
10325	unsigned int present;
10326	unsigned char bits;
10327
10328	present = snd_hda_codec_read(codec, 0x18, 0,
10329				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10330	bits = present ? HDA_AMP_MUTE : 0;
10331	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
10332				 HDA_AMP_MUTE, bits);
10333}
10334
10335static void alc861vd_lenovo_automute(struct hda_codec *codec)
10336{
10337	alc861vd_lenovo_hp_automute(codec);
10338	alc861vd_lenovo_mic_automute(codec);
10339}
10340
10341static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
10342					unsigned int res)
10343{
10344	switch (res >> 26) {
10345	case ALC880_HP_EVENT:
10346		alc861vd_lenovo_hp_automute(codec);
10347		break;
10348	case ALC880_MIC_EVENT:
10349		alc861vd_lenovo_mic_automute(codec);
10350		break;
10351	}
10352}
10353
10354static struct hda_verb alc861vd_dallas_verbs[] = {
10355	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10356	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10357	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10358	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10359
10360	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10361	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10362	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10363	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10364	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10365	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10366	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10367	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10368
10369	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10370	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10371	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10372	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10373	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10374	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10375	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10376	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10377
10378	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
10379	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10380	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
10381	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10382	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10383	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10384	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10385	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10386
10387	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10388	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10389	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10390	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10391
10392	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10393	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10394	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10395
10396	{ } /* end */
10397};
10398
10399/* toggle speaker-output according to the hp-jack state */
10400static void alc861vd_dallas_automute(struct hda_codec *codec)
10401{
10402	unsigned int present;
10403
10404	present = snd_hda_codec_read(codec, 0x15, 0,
10405				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10406	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10407				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
10408}
10409
10410static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
10411{
10412	if ((res >> 26) == ALC880_HP_EVENT)
10413		alc861vd_dallas_automute(codec);
10414}
10415
10416#ifdef CONFIG_SND_HDA_POWER_SAVE
10417#define alc861vd_loopbacks	alc880_loopbacks
10418#endif
10419
10420/* pcm configuration: identiacal with ALC880 */
10421#define alc861vd_pcm_analog_playback	alc880_pcm_analog_playback
10422#define alc861vd_pcm_analog_capture	alc880_pcm_analog_capture
10423#define alc861vd_pcm_digital_playback	alc880_pcm_digital_playback
10424#define alc861vd_pcm_digital_capture	alc880_pcm_digital_capture
10425
10426/*
10427 * configuration and preset
10428 */
10429static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
10430	[ALC660VD_3ST]		= "3stack-660",
10431	[ALC660VD_3ST_DIG]	= "3stack-660-digout",
10432	[ALC861VD_3ST]		= "3stack",
10433	[ALC861VD_3ST_DIG]	= "3stack-digout",
10434	[ALC861VD_6ST_DIG]	= "6stack-digout",
10435	[ALC861VD_LENOVO]	= "lenovo",
10436	[ALC861VD_DALLAS]	= "dallas",
10437	[ALC861VD_HP]		= "hp",
10438	[ALC861VD_AUTO]		= "auto",
10439};
10440
10441static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
10442	SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
10443	SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
10444	SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
10445	SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
10446	SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
10447
10448	SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),
10449	SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
10450	SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
10451	SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
10452	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
10453	SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
10454	SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
10455	SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
10456	{}
10457};
10458
10459static struct alc_config_preset alc861vd_presets[] = {
10460	[ALC660VD_3ST] = {
10461		.mixers = { alc861vd_3st_mixer },
10462		.init_verbs = { alc861vd_volume_init_verbs,
10463				 alc861vd_3stack_init_verbs },
10464		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10465		.dac_nids = alc660vd_dac_nids,
10466		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10467		.adc_nids = alc861vd_adc_nids,
10468		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10469		.channel_mode = alc861vd_3stack_2ch_modes,
10470		.input_mux = &alc861vd_capture_source,
10471	},
10472	[ALC660VD_3ST_DIG] = {
10473		.mixers = { alc861vd_3st_mixer },
10474		.init_verbs = { alc861vd_volume_init_verbs,
10475				 alc861vd_3stack_init_verbs },
10476		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10477		.dac_nids = alc660vd_dac_nids,
10478		.dig_out_nid = ALC861VD_DIGOUT_NID,
10479		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10480		.adc_nids = alc861vd_adc_nids,
10481		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10482		.channel_mode = alc861vd_3stack_2ch_modes,
10483		.input_mux = &alc861vd_capture_source,
10484	},
10485	[ALC861VD_3ST] = {
10486		.mixers = { alc861vd_3st_mixer },
10487		.init_verbs = { alc861vd_volume_init_verbs,
10488				 alc861vd_3stack_init_verbs },
10489		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10490		.dac_nids = alc861vd_dac_nids,
10491		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10492		.channel_mode = alc861vd_3stack_2ch_modes,
10493		.input_mux = &alc861vd_capture_source,
10494	},
10495	[ALC861VD_3ST_DIG] = {
10496		.mixers = { alc861vd_3st_mixer },
10497		.init_verbs = { alc861vd_volume_init_verbs,
10498		 		 alc861vd_3stack_init_verbs },
10499		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10500		.dac_nids = alc861vd_dac_nids,
10501		.dig_out_nid = ALC861VD_DIGOUT_NID,
10502		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10503		.channel_mode = alc861vd_3stack_2ch_modes,
10504		.input_mux = &alc861vd_capture_source,
10505	},
10506	[ALC861VD_6ST_DIG] = {
10507		.mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
10508		.init_verbs = { alc861vd_volume_init_verbs,
10509				alc861vd_6stack_init_verbs },
10510		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10511		.dac_nids = alc861vd_dac_nids,
10512		.dig_out_nid = ALC861VD_DIGOUT_NID,
10513		.num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
10514		.channel_mode = alc861vd_6stack_modes,
10515		.input_mux = &alc861vd_capture_source,
10516	},
10517	[ALC861VD_LENOVO] = {
10518		.mixers = { alc861vd_lenovo_mixer },
10519		.init_verbs = { alc861vd_volume_init_verbs,
10520				alc861vd_3stack_init_verbs,
10521				alc861vd_eapd_verbs,
10522				alc861vd_lenovo_unsol_verbs },
10523		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10524		.dac_nids = alc660vd_dac_nids,
10525		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10526		.adc_nids = alc861vd_adc_nids,
10527		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10528		.channel_mode = alc861vd_3stack_2ch_modes,
10529		.input_mux = &alc861vd_capture_source,
10530		.unsol_event = alc861vd_lenovo_unsol_event,
10531		.init_hook = alc861vd_lenovo_automute,
10532	},
10533	[ALC861VD_DALLAS] = {
10534		.mixers = { alc861vd_dallas_mixer },
10535		.init_verbs = { alc861vd_dallas_verbs },
10536		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10537		.dac_nids = alc861vd_dac_nids,
10538		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10539		.adc_nids = alc861vd_adc_nids,
10540		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10541		.channel_mode = alc861vd_3stack_2ch_modes,
10542		.input_mux = &alc861vd_dallas_capture_source,
10543		.unsol_event = alc861vd_dallas_unsol_event,
10544		.init_hook = alc861vd_dallas_automute,
10545	},
10546	[ALC861VD_HP] = {
10547		.mixers = { alc861vd_hp_mixer },
10548		.init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
10549		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10550		.dac_nids = alc861vd_dac_nids,
10551		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10552		.dig_out_nid = ALC861VD_DIGOUT_NID,
10553		.adc_nids = alc861vd_adc_nids,
10554		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10555		.channel_mode = alc861vd_3stack_2ch_modes,
10556		.input_mux = &alc861vd_hp_capture_source,
10557		.unsol_event = alc861vd_dallas_unsol_event,
10558		.init_hook = alc861vd_dallas_automute,
10559	},
10560};
10561
10562/*
10563 * BIOS auto configuration
10564 */
10565static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
10566				hda_nid_t nid, int pin_type, int dac_idx)
10567{
10568	/* set as output */
10569	snd_hda_codec_write(codec, nid, 0,
10570				AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
10571	snd_hda_codec_write(codec, nid, 0,
10572				AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
10573}
10574
10575static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
10576{
10577	struct alc_spec *spec = codec->spec;
10578	int i;
10579
10580	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
10581	for (i = 0; i <= HDA_SIDE; i++) {
10582		hda_nid_t nid = spec->autocfg.line_out_pins[i];
10583		int pin_type = get_pin_type(spec->autocfg.line_out_type);
10584		if (nid)
10585			alc861vd_auto_set_output_and_unmute(codec, nid,
10586							    pin_type, i);
10587	}
10588}
10589
10590
10591static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
10592{
10593	struct alc_spec *spec = codec->spec;
10594	hda_nid_t pin;
10595
10596	pin = spec->autocfg.hp_pins[0];
10597	if (pin) /* connect to front and  use dac 0 */
10598		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
10599}
10600
10601#define alc861vd_is_input_pin(nid)	alc880_is_input_pin(nid)
10602#define ALC861VD_PIN_CD_NID		ALC880_PIN_CD_NID
10603
10604static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
10605{
10606	struct alc_spec *spec = codec->spec;
10607	int i;
10608
10609	for (i = 0; i < AUTO_PIN_LAST; i++) {
10610		hda_nid_t nid = spec->autocfg.input_pins[i];
10611		if (alc861vd_is_input_pin(nid)) {
10612			snd_hda_codec_write(codec, nid, 0,
10613					AC_VERB_SET_PIN_WIDGET_CONTROL,
10614					i <= AUTO_PIN_FRONT_MIC ?
10615							PIN_VREF80 : PIN_IN);
10616			if (nid != ALC861VD_PIN_CD_NID)
10617				snd_hda_codec_write(codec, nid, 0,
10618						AC_VERB_SET_AMP_GAIN_MUTE,
10619						AMP_OUT_MUTE);
10620		}
10621	}
10622}
10623
10624#define alc861vd_idx_to_mixer_vol(nid)		((nid) + 0x02)
10625#define alc861vd_idx_to_mixer_switch(nid)	((nid) + 0x0c)
10626
10627/* add playback controls from the parsed DAC table */
10628/* Based on ALC880 version. But ALC861VD has separate,
10629 * different NIDs for mute/unmute switch and volume control */
10630static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
10631					     const struct auto_pin_cfg *cfg)
10632{
10633	char name[32];
10634	static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
10635	hda_nid_t nid_v, nid_s;
10636	int i, err;
10637
10638	for (i = 0; i < cfg->line_outs; i++) {
10639		if (!spec->multiout.dac_nids[i])
10640			continue;
10641		nid_v = alc861vd_idx_to_mixer_vol(
10642				alc880_dac_to_idx(
10643					spec->multiout.dac_nids[i]));
10644		nid_s = alc861vd_idx_to_mixer_switch(
10645				alc880_dac_to_idx(
10646					spec->multiout.dac_nids[i]));
10647
10648		if (i == 2) {
10649			/* Center/LFE */
10650			err = add_control(spec, ALC_CTL_WIDGET_VOL,
10651					  "Center Playback Volume",
10652					  HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
10653							      HDA_OUTPUT));
10654			if (err < 0)
10655				return err;
10656			err = add_control(spec, ALC_CTL_WIDGET_VOL,
10657					  "LFE Playback Volume",
10658					  HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
10659							      HDA_OUTPUT));
10660			if (err < 0)
10661				return err;
10662			err = add_control(spec, ALC_CTL_BIND_MUTE,
10663					  "Center Playback Switch",
10664					  HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
10665							      HDA_INPUT));
10666			if (err < 0)
10667				return err;
10668			err = add_control(spec, ALC_CTL_BIND_MUTE,
10669					  "LFE Playback Switch",
10670					  HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
10671							      HDA_INPUT));
10672			if (err < 0)
10673				return err;
10674		} else {
10675			sprintf(name, "%s Playback Volume", chname[i]);
10676			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10677					  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
10678							      HDA_OUTPUT));
10679			if (err < 0)
10680				return err;
10681			sprintf(name, "%s Playback Switch", chname[i]);
10682			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10683					  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
10684							      HDA_INPUT));
10685			if (err < 0)
10686				return err;
10687		}
10688	}
10689	return 0;
10690}
10691
10692/* add playback controls for speaker and HP outputs */
10693/* Based on ALC880 version. But ALC861VD has separate,
10694 * different NIDs for mute/unmute switch and volume control */
10695static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
10696					hda_nid_t pin, const char *pfx)
10697{
10698	hda_nid_t nid_v, nid_s;
10699	int err;
10700	char name[32];
10701
10702	if (!pin)
10703		return 0;
10704
10705	if (alc880_is_fixed_pin(pin)) {
10706		nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
10707		/* specify the DAC as the extra output */
10708		if (!spec->multiout.hp_nid)
10709			spec->multiout.hp_nid = nid_v;
10710		else
10711			spec->multiout.extra_out_nid[0] = nid_v;
10712		/* control HP volume/switch on the output mixer amp */
10713		nid_v = alc861vd_idx_to_mixer_vol(
10714				alc880_fixed_pin_idx(pin));
10715		nid_s = alc861vd_idx_to_mixer_switch(
10716				alc880_fixed_pin_idx(pin));
10717
10718		sprintf(name, "%s Playback Volume", pfx);
10719		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10720				  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
10721		if (err < 0)
10722			return err;
10723		sprintf(name, "%s Playback Switch", pfx);
10724		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10725				  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
10726		if (err < 0)
10727			return err;
10728	} else if (alc880_is_multi_pin(pin)) {
10729		/* set manual connection */
10730		/* we have only a switch on HP-out PIN */
10731		sprintf(name, "%s Playback Switch", pfx);
10732		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
10733				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
10734		if (err < 0)
10735			return err;
10736	}
10737	return 0;
10738}
10739
10740/* parse the BIOS configuration and set up the alc_spec
10741 * return 1 if successful, 0 if the proper config is not found,
10742 * or a negative error code
10743 * Based on ALC880 version - had to change it to override
10744 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
10745static int alc861vd_parse_auto_config(struct hda_codec *codec)
10746{
10747	struct alc_spec *spec = codec->spec;
10748	int err;
10749	static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
10750
10751	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10752					   alc861vd_ignore);
10753	if (err < 0)
10754		return err;
10755	if (!spec->autocfg.line_outs)
10756		return 0; /* can't find valid BIOS pin config */
10757
10758	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10759	if (err < 0)
10760		return err;
10761	err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
10762	if (err < 0)
10763		return err;
10764	err = alc861vd_auto_create_extra_out(spec,
10765					     spec->autocfg.speaker_pins[0],
10766					     "Speaker");
10767	if (err < 0)
10768		return err;
10769	err = alc861vd_auto_create_extra_out(spec,
10770					     spec->autocfg.hp_pins[0],
10771					     "Headphone");
10772	if (err < 0)
10773		return err;
10774	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
10775	if (err < 0)
10776		return err;
10777
10778	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10779
10780	if (spec->autocfg.dig_out_pin)
10781		spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
10782
10783	if (spec->kctl_alloc)
10784		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10785
10786	spec->init_verbs[spec->num_init_verbs++]
10787		= alc861vd_volume_init_verbs;
10788
10789	spec->num_mux_defs = 1;
10790	spec->input_mux = &spec->private_imux;
10791
10792	return 1;
10793}
10794
10795/* additional initialization for auto-configuration model */
10796static void alc861vd_auto_init(struct hda_codec *codec)
10797{
10798	alc861vd_auto_init_multi_out(codec);
10799	alc861vd_auto_init_hp_out(codec);
10800	alc861vd_auto_init_analog_input(codec);
10801}
10802
10803static int patch_alc861vd(struct hda_codec *codec)
10804{
10805	struct alc_spec *spec;
10806	int err, board_config;
10807
10808	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10809	if (spec == NULL)
10810		return -ENOMEM;
10811
10812	codec->spec = spec;
10813
10814	board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
10815						  alc861vd_models,
10816						  alc861vd_cfg_tbl);
10817
10818	if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
10819		printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
10820			"ALC861VD, trying auto-probe from BIOS...\n");
10821		board_config = ALC861VD_AUTO;
10822	}
10823
10824	if (board_config == ALC861VD_AUTO) {
10825		/* automatic parse from the BIOS config */
10826		err = alc861vd_parse_auto_config(codec);
10827		if (err < 0) {
10828			alc_free(codec);
10829			return err;
10830		} else if (!err) {
10831			printk(KERN_INFO
10832			       "hda_codec: Cannot set up configuration "
10833			       "from BIOS.  Using base mode...\n");
10834			board_config = ALC861VD_3ST;
10835		}
10836	}
10837
10838	if (board_config != ALC861VD_AUTO)
10839		setup_preset(spec, &alc861vd_presets[board_config]);
10840
10841	spec->stream_name_analog = "ALC861VD Analog";
10842	spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
10843	spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
10844
10845	spec->stream_name_digital = "ALC861VD Digital";
10846	spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
10847	spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
10848
10849	spec->adc_nids = alc861vd_adc_nids;
10850	spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
10851
10852	spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
10853	spec->num_mixers++;
10854
10855	codec->patch_ops = alc_patch_ops;
10856
10857	if (board_config == ALC861VD_AUTO)
10858		spec->init_hook = alc861vd_auto_init;
10859#ifdef CONFIG_SND_HDA_POWER_SAVE
10860	if (!spec->loopback.amplist)
10861		spec->loopback.amplist = alc861vd_loopbacks;
10862#endif
10863
10864	return 0;
10865}
10866
10867/*
10868 * ALC662 support
10869 *
10870 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
10871 * configuration.  Each pin widget can choose any input DACs and a mixer.
10872 * Each ADC is connected from a mixer of all inputs.  This makes possible
10873 * 6-channel independent captures.
10874 *
10875 * In addition, an independent DAC for the multi-playback (not used in this
10876 * driver yet).
10877 */
10878#define ALC662_DIGOUT_NID	0x06
10879#define ALC662_DIGIN_NID	0x0a
10880
10881static hda_nid_t alc662_dac_nids[4] = {
10882	/* front, rear, clfe, rear_surr */
10883	0x02, 0x03, 0x04
10884};
10885
10886static hda_nid_t alc662_adc_nids[1] = {
10887	/* ADC1-2 */
10888	0x09,
10889};
10890/* input MUX */
10891/* FIXME: should be a matrix-type input source selection */
10892
10893static struct hda_input_mux alc662_capture_source = {
10894	.num_items = 4,
10895	.items = {
10896		{ "Mic", 0x0 },
10897		{ "Front Mic", 0x1 },
10898		{ "Line", 0x2 },
10899		{ "CD", 0x4 },
10900	},
10901};
10902
10903static struct hda_input_mux alc662_lenovo_101e_capture_source = {
10904	.num_items = 2,
10905	.items = {
10906		{ "Mic", 0x1 },
10907		{ "Line", 0x2 },
10908	},
10909};
10910#define alc662_mux_enum_info alc_mux_enum_info
10911#define alc662_mux_enum_get alc_mux_enum_get
10912
10913static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
10914			       struct snd_ctl_elem_value *ucontrol)
10915{
10916	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10917	struct alc_spec *spec = codec->spec;
10918	const struct hda_input_mux *imux = spec->input_mux;
10919	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
10920	static hda_nid_t capture_mixers[2] = { 0x23, 0x22 };
10921	hda_nid_t nid = capture_mixers[adc_idx];
10922	unsigned int *cur_val = &spec->cur_mux[adc_idx];
10923	unsigned int i, idx;
10924
10925	idx = ucontrol->value.enumerated.item[0];
10926	if (idx >= imux->num_items)
10927		idx = imux->num_items - 1;
10928	if (*cur_val == idx)
10929		return 0;
10930	for (i = 0; i < imux->num_items; i++) {
10931		unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
10932		snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
10933					 imux->items[i].index,
10934					 HDA_AMP_MUTE, v);
10935	}
10936	*cur_val = idx;
10937	return 1;
10938}
10939/*
10940 * 2ch mode
10941 */
10942static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
10943	{ 2, NULL }
10944};
10945
10946/*
10947 * 2ch mode
10948 */
10949static struct hda_verb alc662_3ST_ch2_init[] = {
10950	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
10951	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
10952	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
10953	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
10954	{ } /* end */
10955};
10956
10957/*
10958 * 6ch mode
10959 */
10960static struct hda_verb alc662_3ST_ch6_init[] = {
10961	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10962	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10963	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
10964	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10965	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10966	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
10967	{ } /* end */
10968};
10969
10970static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
10971	{ 2, alc662_3ST_ch2_init },
10972	{ 6, alc662_3ST_ch6_init },
10973};
10974
10975/*
10976 * 2ch mode
10977 */
10978static struct hda_verb alc662_sixstack_ch6_init[] = {
10979	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10980	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10981	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10982	{ } /* end */
10983};
10984
10985/*
10986 * 6ch mode
10987 */
10988static struct hda_verb alc662_sixstack_ch8_init[] = {
10989	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10990	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10991	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10992	{ } /* end */
10993};
10994
10995static struct hda_channel_mode alc662_5stack_modes[2] = {
10996	{ 2, alc662_sixstack_ch6_init },
10997	{ 6, alc662_sixstack_ch8_init },
10998};
10999
11000/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
11001 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
11002 */
11003
11004static struct snd_kcontrol_new alc662_base_mixer[] = {
11005	/* output mixer control */
11006	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11007	HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
11008	HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11009	HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11010	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
11011	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
11012	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
11013	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
11014	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11015
11016	/*Input mixer control */
11017	HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
11018	HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
11019	HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
11020	HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
11021	HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
11022	HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
11023	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
11024	HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
11025
11026	/* Capture mixer control */
11027	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11028	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11029	{
11030		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11031		.name = "Capture Source",
11032		.count = 1,
11033		.info = alc_mux_enum_info,
11034		.get = alc_mux_enum_get,
11035		.put = alc_mux_enum_put,
11036	},
11037	{ } /* end */
11038};
11039
11040static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
11041	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11042	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
11043	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11044	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11045	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11046	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11047	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11048	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11049	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11050	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11051	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11052	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11053	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11054	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11055	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11056	{
11057		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11058		/* .name = "Capture Source", */
11059		.name = "Input Source",
11060		.count = 1,
11061		.info = alc662_mux_enum_info,
11062		.get = alc662_mux_enum_get,
11063		.put = alc662_mux_enum_put,
11064	},
11065	{ } /* end */
11066};
11067
11068static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
11069	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11070	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
11071	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11072	HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
11073	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
11074	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
11075	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
11076	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
11077	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11078	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11079	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11080	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11081	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11082	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11083	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11084	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11085	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11086	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11087	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11088	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11089	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11090	{
11091		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11092		/* .name = "Capture Source", */
11093		.name = "Input Source",
11094		.count = 1,
11095		.info = alc662_mux_enum_info,
11096		.get = alc662_mux_enum_get,
11097		.put = alc662_mux_enum_put,
11098	},
11099	{ } /* end */
11100};
11101
11102static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
11103	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11104	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
11105	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11106	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT),
11107	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11108	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11109	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11110	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11111	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11112	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11113	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11114	{
11115		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11116		/* .name = "Capture Source", */
11117		.name = "Input Source",
11118		.count = 1,
11119		.info = alc662_mux_enum_info,
11120		.get = alc662_mux_enum_get,
11121		.put = alc662_mux_enum_put,
11122	},
11123	{ } /* end */
11124};
11125
11126static struct snd_kcontrol_new alc662_chmode_mixer[] = {
11127	{
11128		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11129		.name = "Channel Mode",
11130		.info = alc_ch_mode_info,
11131		.get = alc_ch_mode_get,
11132		.put = alc_ch_mode_put,
11133	},
11134	{ } /* end */
11135};
11136
11137static struct hda_verb alc662_init_verbs[] = {
11138	/* ADC: mute amp left and right */
11139	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11140	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11141	/* Front mixer: unmute input/output amp left and right (volume = 0) */
11142
11143	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11144	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11145	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11146	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11147	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11148
11149	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11150	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11151	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11152	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11153	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11154	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11155
11156	/* Front Pin: output 0 (0x0c) */
11157	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11158	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11159
11160	/* Rear Pin: output 1 (0x0d) */
11161	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11162	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11163
11164	/* CLFE Pin: output 2 (0x0e) */
11165	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11166	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11167
11168	/* Mic (rear) pin: input vref at 80% */
11169	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11170	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11171	/* Front Mic pin: input vref at 80% */
11172	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11173	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11174	/* Line In pin: input */
11175	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11176	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11177	/* Line-2 In: Headphone output (output 0 - 0x0c) */
11178	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11179	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11180	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11181	/* CD pin widget for input */
11182	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11183
11184	/* FIXME: use matrix-type input source selection */
11185	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11186	/* Input mixer */
11187	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11188	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11189	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11190	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11191	{ }
11192};
11193
11194static struct hda_verb alc662_sue_init_verbs[] = {
11195	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
11196	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
11197        {}
11198};
11199
11200/*
11201 * generic initialization of ADC, input mixers and output mixers
11202 */
11203static struct hda_verb alc662_auto_init_verbs[] = {
11204	/*
11205	 * Unmute ADC and set the default input to mic-in
11206	 */
11207	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11208	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11209
11210	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11211	 * mixer widget
11212	 * Note: PASD motherboards uses the Line In 2 as the input for front
11213	 * panel mic (mic 2)
11214	 */
11215	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11216	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11217	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11218	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11219	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11220	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11221
11222	/*
11223	 * Set up output mixers (0x0c - 0x0f)
11224	 */
11225	/* set vol=0 to output mixers */
11226	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11227	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11228	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11229
11230	/* set up input amps for analog loopback */
11231	/* Amp Indices: DAC = 0, mixer = 1 */
11232	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11233	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11234	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11235	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11236	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11237	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11238
11239
11240	/* FIXME: use matrix-type input source selection */
11241	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11242	/* Input mixer */
11243	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11244	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11245	{ }
11246};
11247
11248/* capture mixer elements */
11249static struct snd_kcontrol_new alc662_capture_mixer[] = {
11250	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11251	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11252	{
11253		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11254		/* The multiple "Capture Source" controls confuse alsamixer
11255		 * So call somewhat different..
11256		 * FIXME: the controls appear in the "playback" view!
11257		 */
11258		/* .name = "Capture Source", */
11259		.name = "Input Source",
11260		.count = 1,
11261		.info = alc882_mux_enum_info,
11262		.get = alc882_mux_enum_get,
11263		.put = alc882_mux_enum_put,
11264	},
11265	{ } /* end */
11266};
11267
11268static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
11269{
11270	unsigned int present;
11271	unsigned char bits;
11272
11273	present = snd_hda_codec_read(codec, 0x14, 0,
11274				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11275	bits = present ? HDA_AMP_MUTE : 0;
11276	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11277				 HDA_AMP_MUTE, bits);
11278}
11279
11280static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
11281{
11282	unsigned int present;
11283	unsigned char bits;
11284
11285 	present = snd_hda_codec_read(codec, 0x1b, 0,
11286				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11287	bits = present ? HDA_AMP_MUTE : 0;
11288	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11289				 HDA_AMP_MUTE, bits);
11290	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11291				 HDA_AMP_MUTE, bits);
11292}
11293
11294static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
11295					   unsigned int res)
11296{
11297	if ((res >> 26) == ALC880_HP_EVENT)
11298		alc662_lenovo_101e_all_automute(codec);
11299	if ((res >> 26) == ALC880_FRONT_EVENT)
11300		alc662_lenovo_101e_ispeaker_automute(codec);
11301}
11302
11303#ifdef CONFIG_SND_HDA_POWER_SAVE
11304#define alc662_loopbacks	alc880_loopbacks
11305#endif
11306
11307
11308/* pcm configuration: identiacal with ALC880 */
11309#define alc662_pcm_analog_playback	alc880_pcm_analog_playback
11310#define alc662_pcm_analog_capture	alc880_pcm_analog_capture
11311#define alc662_pcm_digital_playback	alc880_pcm_digital_playback
11312#define alc662_pcm_digital_capture	alc880_pcm_digital_capture
11313
11314/*
11315 * configuration and preset
11316 */
11317static const char *alc662_models[ALC662_MODEL_LAST] = {
11318	[ALC662_3ST_2ch_DIG]	= "3stack-dig",
11319	[ALC662_3ST_6ch_DIG]	= "3stack-6ch-dig",
11320	[ALC662_3ST_6ch]	= "3stack-6ch",
11321	[ALC662_5ST_DIG]	= "6stack-dig",
11322	[ALC662_LENOVO_101E]	= "lenovo-101e",
11323	[ALC662_AUTO]		= "auto",
11324};
11325
11326static struct snd_pci_quirk alc662_cfg_tbl[] = {
11327	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
11328	{}
11329};
11330
11331static struct alc_config_preset alc662_presets[] = {
11332	[ALC662_3ST_2ch_DIG] = {
11333		.mixers = { alc662_3ST_2ch_mixer },
11334		.init_verbs = { alc662_init_verbs },
11335		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
11336		.dac_nids = alc662_dac_nids,
11337		.dig_out_nid = ALC662_DIGOUT_NID,
11338		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11339		.adc_nids = alc662_adc_nids,
11340		.dig_in_nid = ALC662_DIGIN_NID,
11341		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
11342		.channel_mode = alc662_3ST_2ch_modes,
11343		.input_mux = &alc662_capture_source,
11344	},
11345	[ALC662_3ST_6ch_DIG] = {
11346		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
11347		.init_verbs = { alc662_init_verbs },
11348		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
11349		.dac_nids = alc662_dac_nids,
11350		.dig_out_nid = ALC662_DIGOUT_NID,
11351		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11352		.adc_nids = alc662_adc_nids,
11353		.dig_in_nid = ALC662_DIGIN_NID,
11354		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
11355		.channel_mode = alc662_3ST_6ch_modes,
11356		.need_dac_fix = 1,
11357		.input_mux = &alc662_capture_source,
11358	},
11359	[ALC662_3ST_6ch] = {
11360		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
11361		.init_verbs = { alc662_init_verbs },
11362		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
11363		.dac_nids = alc662_dac_nids,
11364		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11365		.adc_nids = alc662_adc_nids,
11366		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
11367		.channel_mode = alc662_3ST_6ch_modes,
11368		.need_dac_fix = 1,
11369		.input_mux = &alc662_capture_source,
11370	},
11371	[ALC662_5ST_DIG] = {
11372		.mixers = { alc662_base_mixer, alc662_chmode_mixer },
11373		.init_verbs = { alc662_init_verbs },
11374		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
11375		.dac_nids = alc662_dac_nids,
11376		.dig_out_nid = ALC662_DIGOUT_NID,
11377		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11378		.adc_nids = alc662_adc_nids,
11379		.dig_in_nid = ALC662_DIGIN_NID,
11380		.num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
11381		.channel_mode = alc662_5stack_modes,
11382		.input_mux = &alc662_capture_source,
11383	},
11384	[ALC662_LENOVO_101E] = {
11385		.mixers = { alc662_lenovo_101e_mixer },
11386		.init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
11387		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
11388		.dac_nids = alc662_dac_nids,
11389		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11390		.adc_nids = alc662_adc_nids,
11391		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
11392		.channel_mode = alc662_3ST_2ch_modes,
11393		.input_mux = &alc662_lenovo_101e_capture_source,
11394		.unsol_event = alc662_lenovo_101e_unsol_event,
11395		.init_hook = alc662_lenovo_101e_all_automute,
11396	},
11397
11398};
11399
11400
11401/*
11402 * BIOS auto configuration
11403 */
11404
11405/* add playback controls from the parsed DAC table */
11406static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
11407					     const struct auto_pin_cfg *cfg)
11408{
11409	char name[32];
11410	static const char *chname[4] = {
11411		"Front", "Surround", NULL /*CLFE*/, "Side"
11412	};
11413	hda_nid_t nid;
11414	int i, err;
11415
11416	for (i = 0; i < cfg->line_outs; i++) {
11417		if (!spec->multiout.dac_nids[i])
11418			continue;
11419		nid = alc880_idx_to_mixer(i);
11420		if (i == 2) {
11421			/* Center/LFE */
11422			err = add_control(spec, ALC_CTL_WIDGET_VOL,
11423					  "Center Playback Volume",
11424					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
11425							      HDA_OUTPUT));
11426			if (err < 0)
11427				return err;
11428			err = add_control(spec, ALC_CTL_WIDGET_VOL,
11429					  "LFE Playback Volume",
11430					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11431							      HDA_OUTPUT));
11432			if (err < 0)
11433				return err;
11434			err = add_control(spec, ALC_CTL_BIND_MUTE,
11435					  "Center Playback Switch",
11436					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
11437							      HDA_INPUT));
11438			if (err < 0)
11439				return err;
11440			err = add_control(spec, ALC_CTL_BIND_MUTE,
11441					  "LFE Playback Switch",
11442					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
11443							      HDA_INPUT));
11444			if (err < 0)
11445				return err;
11446		} else {
11447			sprintf(name, "%s Playback Volume", chname[i]);
11448			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11449					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11450							      HDA_OUTPUT));
11451			if (err < 0)
11452				return err;
11453			sprintf(name, "%s Playback Switch", chname[i]);
11454			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11455					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
11456							      HDA_INPUT));
11457			if (err < 0)
11458				return err;
11459		}
11460	}
11461	return 0;
11462}
11463
11464/* add playback controls for speaker and HP outputs */
11465static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
11466					const char *pfx)
11467{
11468	hda_nid_t nid;
11469	int err;
11470	char name[32];
11471
11472	if (!pin)
11473		return 0;
11474
11475	if (alc880_is_fixed_pin(pin)) {
11476		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
11477                /* printk("DAC nid=%x\n",nid); */
11478		/* specify the DAC as the extra output */
11479		if (!spec->multiout.hp_nid)
11480			spec->multiout.hp_nid = nid;
11481		else
11482			spec->multiout.extra_out_nid[0] = nid;
11483		/* control HP volume/switch on the output mixer amp */
11484		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
11485		sprintf(name, "%s Playback Volume", pfx);
11486		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11487				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
11488		if (err < 0)
11489			return err;
11490		sprintf(name, "%s Playback Switch", pfx);
11491		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11492				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
11493		if (err < 0)
11494			return err;
11495	} else if (alc880_is_multi_pin(pin)) {
11496		/* set manual connection */
11497		/* we have only a switch on HP-out PIN */
11498		sprintf(name, "%s Playback Switch", pfx);
11499		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11500				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
11501		if (err < 0)
11502			return err;
11503	}
11504	return 0;
11505}
11506
11507/* create playback/capture controls for input pins */
11508static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
11509						const struct auto_pin_cfg *cfg)
11510{
11511	struct hda_input_mux *imux = &spec->private_imux;
11512	int i, err, idx;
11513
11514	for (i = 0; i < AUTO_PIN_LAST; i++) {
11515		if (alc880_is_input_pin(cfg->input_pins[i])) {
11516			idx = alc880_input_pin_idx(cfg->input_pins[i]);
11517			err = new_analog_input(spec, cfg->input_pins[i],
11518					       auto_pin_cfg_labels[i],
11519					       idx, 0x0b);
11520			if (err < 0)
11521				return err;
11522			imux->items[imux->num_items].label =
11523				auto_pin_cfg_labels[i];
11524			imux->items[imux->num_items].index =
11525				alc880_input_pin_idx(cfg->input_pins[i]);
11526			imux->num_items++;
11527		}
11528	}
11529	return 0;
11530}
11531
11532static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
11533					      hda_nid_t nid, int pin_type,
11534					      int dac_idx)
11535{
11536	/* set as output */
11537	snd_hda_codec_write(codec, nid, 0,
11538			    AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
11539	snd_hda_codec_write(codec, nid, 0,
11540			    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
11541	/* need the manual connection? */
11542	if (alc880_is_multi_pin(nid)) {
11543		struct alc_spec *spec = codec->spec;
11544		int idx = alc880_multi_pin_idx(nid);
11545		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
11546				    AC_VERB_SET_CONNECT_SEL,
11547				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
11548	}
11549}
11550
11551static void alc662_auto_init_multi_out(struct hda_codec *codec)
11552{
11553	struct alc_spec *spec = codec->spec;
11554	int i;
11555
11556	for (i = 0; i <= HDA_SIDE; i++) {
11557		hda_nid_t nid = spec->autocfg.line_out_pins[i];
11558		int pin_type = get_pin_type(spec->autocfg.line_out_type);
11559		if (nid)
11560			alc662_auto_set_output_and_unmute(codec, nid, pin_type,
11561							  i);
11562	}
11563}
11564
11565static void alc662_auto_init_hp_out(struct hda_codec *codec)
11566{
11567	struct alc_spec *spec = codec->spec;
11568	hda_nid_t pin;
11569
11570	pin = spec->autocfg.hp_pins[0];
11571	if (pin) /* connect to front */
11572		/* use dac 0 */
11573		alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
11574}
11575
11576#define alc662_is_input_pin(nid)	alc880_is_input_pin(nid)
11577#define ALC662_PIN_CD_NID		ALC880_PIN_CD_NID
11578
11579static void alc662_auto_init_analog_input(struct hda_codec *codec)
11580{
11581	struct alc_spec *spec = codec->spec;
11582	int i;
11583
11584	for (i = 0; i < AUTO_PIN_LAST; i++) {
11585		hda_nid_t nid = spec->autocfg.input_pins[i];
11586		if (alc662_is_input_pin(nid)) {
11587			snd_hda_codec_write(codec, nid, 0,
11588					    AC_VERB_SET_PIN_WIDGET_CONTROL,
11589					    (i <= AUTO_PIN_FRONT_MIC ?
11590					     PIN_VREF80 : PIN_IN));
11591			if (nid != ALC662_PIN_CD_NID)
11592				snd_hda_codec_write(codec, nid, 0,
11593						    AC_VERB_SET_AMP_GAIN_MUTE,
11594						    AMP_OUT_MUTE);
11595		}
11596	}
11597}
11598
11599static int alc662_parse_auto_config(struct hda_codec *codec)
11600{
11601	struct alc_spec *spec = codec->spec;
11602	int err;
11603	static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
11604
11605	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11606					   alc662_ignore);
11607	if (err < 0)
11608		return err;
11609	if (!spec->autocfg.line_outs)
11610		return 0; /* can't find valid BIOS pin config */
11611
11612	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
11613	if (err < 0)
11614		return err;
11615	err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
11616	if (err < 0)
11617		return err;
11618	err = alc662_auto_create_extra_out(spec,
11619					   spec->autocfg.speaker_pins[0],
11620					   "Speaker");
11621	if (err < 0)
11622		return err;
11623	err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
11624					   "Headphone");
11625	if (err < 0)
11626		return err;
11627	err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
11628	if (err < 0)
11629		return err;
11630
11631	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11632
11633	if (spec->autocfg.dig_out_pin)
11634		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
11635
11636	if (spec->kctl_alloc)
11637		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11638
11639	spec->num_mux_defs = 1;
11640	spec->input_mux = &spec->private_imux;
11641
11642	spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
11643	spec->mixers[spec->num_mixers] = alc662_capture_mixer;
11644	spec->num_mixers++;
11645	return 1;
11646}
11647
11648/* additional initialization for auto-configuration model */
11649static void alc662_auto_init(struct hda_codec *codec)
11650{
11651	alc662_auto_init_multi_out(codec);
11652	alc662_auto_init_hp_out(codec);
11653	alc662_auto_init_analog_input(codec);
11654}
11655
11656static int patch_alc662(struct hda_codec *codec)
11657{
11658	struct alc_spec *spec;
11659	int err, board_config;
11660
11661	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11662	if (!spec)
11663		return -ENOMEM;
11664
11665	codec->spec = spec;
11666
11667	board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
11668						  alc662_models,
11669			  	                  alc662_cfg_tbl);
11670	if (board_config < 0) {
11671		printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
11672		       "trying auto-probe from BIOS...\n");
11673		board_config = ALC662_AUTO;
11674	}
11675
11676	if (board_config == ALC662_AUTO) {
11677		/* automatic parse from the BIOS config */
11678		err = alc662_parse_auto_config(codec);
11679		if (err < 0) {
11680			alc_free(codec);
11681			return err;
11682		} else if (!err) {
11683			printk(KERN_INFO
11684			       "hda_codec: Cannot set up configuration "
11685			       "from BIOS.  Using base mode...\n");
11686			board_config = ALC662_3ST_2ch_DIG;
11687		}
11688	}
11689
11690	if (board_config != ALC662_AUTO)
11691		setup_preset(spec, &alc662_presets[board_config]);
11692
11693	spec->stream_name_analog = "ALC662 Analog";
11694	spec->stream_analog_playback = &alc662_pcm_analog_playback;
11695	spec->stream_analog_capture = &alc662_pcm_analog_capture;
11696
11697	spec->stream_name_digital = "ALC662 Digital";
11698	spec->stream_digital_playback = &alc662_pcm_digital_playback;
11699	spec->stream_digital_capture = &alc662_pcm_digital_capture;
11700
11701	if (!spec->adc_nids && spec->input_mux) {
11702		spec->adc_nids = alc662_adc_nids;
11703		spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
11704	}
11705
11706	codec->patch_ops = alc_patch_ops;
11707	if (board_config == ALC662_AUTO)
11708		spec->init_hook = alc662_auto_init;
11709#ifdef CONFIG_SND_HDA_POWER_SAVE
11710	if (!spec->loopback.amplist)
11711		spec->loopback.amplist = alc662_loopbacks;
11712#endif
11713
11714	return 0;
11715}
11716
11717/*
11718 * patch entries
11719 */
11720struct hda_codec_preset snd_hda_preset_realtek[] = {
11721	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
11722	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
11723	{ .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
11724	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
11725	  .patch = patch_alc861 },
11726	{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
11727	{ .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
11728	{ .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
11729	{ .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
11730	  .patch = patch_alc883 },
11731	{ .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
11732	  .patch = patch_alc662 },
11733	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
11734	{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
11735	{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
11736	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
11737	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
11738	{} /* terminator */
11739};
11740